studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
165 lines (164 loc) • 6.43 kB
JavaScript
import _logger from "studiocms:logger";
import { Mailer } from "studiocms:mailer";
import getTemplate from "studiocms:mailer/templates";
import { SDKCoreJs as sdk } from "studiocms:sdk";
import { Effect, genLogger } from "../../effect.js";
const userNotifications = {
account_updated: (name) => `Hello ${name}! There has been an update to your account. If you did not make this change, please contact a system administrator.`
};
const editorNotifications = {
page_updated: (title) => `The page "${title}" has been updated.`,
page_deleted: (title) => `The page "${title}" has been deleted.`,
new_page: (title) => `A new page "${title}" has been created.`,
folder_updated: (name) => `The folder "${name}" has been updated.`,
folder_deleted: (name) => `The folder "${name}" has been deleted.`,
new_folder: (name) => `A new folder "${name}" has been created.`
};
const adminNotifications = {
user_updated: (username) => `The user "${username}" has been updated.`,
user_deleted: (username) => `The user "${username}" has been deleted.`,
new_user: (username) => `A new user "${username}" has been created.`
};
const notificationTitleStrings = {
account_updated: "Account Updated",
page_updated: "Page Updated",
page_deleted: "Page Deleted",
new_page: "New Page",
folder_updated: "Folder Updated",
folder_deleted: "Folder Deleted",
new_folder: "New Folder",
user_updated: "User Updated",
user_deleted: "User Deleted",
new_user: "New User"
};
const notificationTypes = {
user: Object.keys(userNotifications),
editor: Object.keys(editorNotifications),
admin: Object.keys(adminNotifications)
};
const userRanks = ["visitor", "editor", "admin", "owner"];
const editorRanks = ["editor", "admin", "owner"];
const adminRanks = ["admin", "owner"];
const forked = _logger.fork("studiocms:runtime/notifier");
const makeLogger = Effect.succeed(forked);
class Notifications extends Effect.Service()(
"studiocms/lib/notifier/Notifications",
{
effect: genLogger("studiocms/lib/notifier/Notifications.effect")(function* () {
const MailService = yield* Mailer;
const logger = yield* makeLogger;
const getConfig = genLogger("studiocms/lib/notifier/Notifications.getConfig")(function* () {
const data = yield* sdk.GET.siteConfig();
if (!data) {
return {
title: "StudioCMS",
enableMailer: false
};
}
return data.data;
});
const getUsersWithNotifications = (notification, userRanks2) => genLogger("studiocms/lib/notifier/Notifications.getUsersWithNotifications")(function* () {
const userTable = yield* sdk.GET.users.all();
const users = userTable.filter(
(user) => user.permissionsData?.rank && userRanks2.includes(user.permissionsData?.rank)
);
const usersWithEnabledNotifications = [];
for (const user of users) {
if (user.notifications) {
const enabledNotifications = user.notifications.split(",");
if (enabledNotifications.includes(notification)) {
usersWithEnabledNotifications.push(user);
}
}
}
return usersWithEnabledNotifications;
});
const sendMail = ({
users,
config: { title },
message,
notification
}) => genLogger("studiocms/lib/notifier/Notifications.sendMail")(function* () {
const htmlTemplate = getTemplate("notification");
for (const { email } of users) {
if (!email) continue;
yield* MailService.sendMail({
to: email,
subject: `${title} - New Notification`,
html: htmlTemplate({
title: `New Notification - ${notificationTitleStrings[notification]}`,
message
})
});
}
});
const sendUserNotification = (notification, userId) => genLogger("studiocms/lib/notifier/Notifications.sendUserNotification")(function* () {
const config = yield* getConfig;
if (!config.enableMailer) return;
const testConnection = yield* MailService.verifyMailConnection;
if ("error" in testConnection) {
logger.error(`Error verifying mail connection: ${testConnection.error}`);
return;
}
const users = yield* getUsersWithNotifications(notification, userRanks);
const user = users.find(({ id }) => id === userId);
if (!user) return;
yield* sendMail({
users: [user],
config,
message: userNotifications[notification](user.name),
notification
});
return;
});
const sendEditorNotification = (notification, data) => genLogger("studiocms/lib/notifier/Notifications.sendEditorNotification")(function* () {
const config = yield* getConfig;
if (!config.enableMailer) return;
const testConnection = yield* MailService.verifyMailConnection;
if ("error" in testConnection) {
logger.error(`Error verifying mail connection: ${testConnection.error}`);
return;
}
const editors = yield* getUsersWithNotifications(notification, editorRanks);
yield* sendMail({
users: editors,
config,
message: editorNotifications[notification](data),
notification
});
return;
});
const sendAdminNotification = (notification, data) => genLogger("studiocms/lib/notifier/Notifications.sendAdminNotification")(function* () {
const config = yield* getConfig;
if (!config.enableMailer) return;
const testConnection = yield* MailService.verifyMailConnection;
if ("error" in testConnection) {
logger.error(`Error verifying mail connection: ${testConnection.error}`);
return;
}
const admins = yield* getUsersWithNotifications(notification, adminRanks);
yield* sendMail({
users: admins,
config,
message: adminNotifications[notification](data),
notification
});
return;
});
return {
sendUserNotification,
sendEditorNotification,
sendAdminNotification
};
}),
dependencies: [Mailer.Default]
}
) {
static Provide = Effect.provide(this.Default);
}
export {
Notifications,
makeLogger,
notificationTitleStrings,
notificationTypes
};