UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

165 lines (164 loc) 6.43 kB
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 };