You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
overseerr/server/lib/notifications/index.ts

120 lines
3.4 KiB

import type { User } from '@server/entity/User';
import { Permission } from '@server/lib/permissions';
import logger from '@server/logger';
import type { NotificationAgent, NotificationPayload } from './agents/agent';
export enum Notification {
NONE = 0,
MEDIA_PENDING = 2,
MEDIA_APPROVED = 4,
MEDIA_AVAILABLE = 8,
MEDIA_FAILED = 16,
TEST_NOTIFICATION = 32,
MEDIA_DECLINED = 64,
MEDIA_AUTO_APPROVED = 128,
ISSUE_CREATED = 256,
ISSUE_COMMENT = 512,
ISSUE_RESOLVED = 1024,
ISSUE_REOPENED = 2048,
MEDIA_AUTO_REQUESTED = 4096,
}
export const hasNotificationType = (
types: Notification | Notification[],
value: number
): boolean => {
let total = 0;
// If we are not checking any notifications, bail out and return true
if (types === 0) {
return true;
}
if (Array.isArray(types)) {
// Combine all notification values into one
total = types.reduce((a, v) => a + v, 0);
} else {
total = types;
}
// Test notifications don't need to be enabled
if (!(value & Notification.TEST_NOTIFICATION)) {
value += Notification.TEST_NOTIFICATION;
}
return !!(value & total);
};
export const getAdminPermission = (type: Notification): Permission => {
switch (type) {
case Notification.MEDIA_PENDING:
case Notification.MEDIA_APPROVED:
case Notification.MEDIA_AVAILABLE:
case Notification.MEDIA_FAILED:
case Notification.MEDIA_DECLINED:
case Notification.MEDIA_AUTO_APPROVED:
return Permission.MANAGE_REQUESTS;
case Notification.ISSUE_CREATED:
case Notification.ISSUE_COMMENT:
case Notification.ISSUE_RESOLVED:
case Notification.ISSUE_REOPENED:
return Permission.MANAGE_ISSUES;
default:
return Permission.ADMIN;
}
};
export const shouldSendAdminNotification = (
type: Notification,
user: User,
payload: NotificationPayload
): boolean => {
return (
user.id !== payload.notifyUser?.id &&
user.hasPermission(getAdminPermission(type)) &&
// Check if the user submitted this request (on behalf of themself OR another user)
(type !== Notification.MEDIA_AUTO_APPROVED ||
user.id !==
(payload.request?.modifiedBy ?? payload.request?.requestedBy)?.id) &&
// Check if the user created this issue
(type !== Notification.ISSUE_CREATED ||
user.id !== payload.issue?.createdBy.id) &&
// Check if the user submitted this issue comment
(type !== Notification.ISSUE_COMMENT ||
user.id !== payload.comment?.user.id) &&
// Check if the user resolved/reopened this issue
((type !== Notification.ISSUE_RESOLVED &&
type !== Notification.ISSUE_REOPENED) ||
user.id !== payload.issue?.modifiedBy?.id)
);
};
class NotificationManager {
private activeAgents: NotificationAgent[] = [];
public registerAgents = (agents: NotificationAgent[]): void => {
this.activeAgents = [...this.activeAgents, ...agents];
feat(notif): allow users to enable/disable specific agents (#1172) * refactor(ui): add tabs to user notification settings * feat(notif): allow users to enable/disable specific agents * fix(ui): only enforce required fields when agent is enabled * fix(ui): hide unavailable notification agents * feat(notif): mention admin users for admin Discord notifications * fix(ui): modify styling of PGP key textareas to suit expected input * fix(notif): mention all admins when there are multiple and fix rebase error * fix: add missing form values, and fix Yup validation * refactor: reduce repeated logic/code in email notif agent * refactor: move 'Notification Types' label into NotificationTypeSelector component * fix(email): correct inconsistencies in email template formatting * refactor: use bitfields for storing user-enabled notif agent types * feat: improve notification agent logging * fix(ui): mark string fields as nullable so empty values are not type errors * fix: add validation for PGP-related inputs * fix: correctly fetch user in user settings & log mentioned IDs for Discord notifs * fix(ui): fix mobile nav dropdown text & add hover effect to button-style tabs * fix(notif): process admin email notifications asynchronously * fix(logging): log name of notification type instead of its enum value * fix: mark required fields and pass all user settings values to API * fix(frontend): call mutate after changing email/Discord/Telegram global notif settings * refactor: get global notif settings from relevant API endpoints instead of adding to public settings * fix(notif): fall back to email notifications being enabled (default) if user settings do not exist * fix(notif): do not set notifyUser for MEDIA_PENDING or MEDIA_AUTO_APPROVED * fix: expose notif enabled settings in user notif endpoints & remove global enable notif setting * fix(notif): remove unnecessary allowed_mentions object from Discord payload * fix(notif): use form values for email test notification * fix: make suggested changes and regenerate DB migration * fix: loosen validation of PGP keys * fix: fix user profile settings routes * fix: remove route guard from profile pages
3 years ago
logger.info('Registered notification agents', { label: 'Notifications' });
};
public sendNotification(
type: Notification,
payload: NotificationPayload
): void {
feat(notif): allow users to enable/disable specific agents (#1172) * refactor(ui): add tabs to user notification settings * feat(notif): allow users to enable/disable specific agents * fix(ui): only enforce required fields when agent is enabled * fix(ui): hide unavailable notification agents * feat(notif): mention admin users for admin Discord notifications * fix(ui): modify styling of PGP key textareas to suit expected input * fix(notif): mention all admins when there are multiple and fix rebase error * fix: add missing form values, and fix Yup validation * refactor: reduce repeated logic/code in email notif agent * refactor: move 'Notification Types' label into NotificationTypeSelector component * fix(email): correct inconsistencies in email template formatting * refactor: use bitfields for storing user-enabled notif agent types * feat: improve notification agent logging * fix(ui): mark string fields as nullable so empty values are not type errors * fix: add validation for PGP-related inputs * fix: correctly fetch user in user settings & log mentioned IDs for Discord notifs * fix(ui): fix mobile nav dropdown text & add hover effect to button-style tabs * fix(notif): process admin email notifications asynchronously * fix(logging): log name of notification type instead of its enum value * fix: mark required fields and pass all user settings values to API * fix(frontend): call mutate after changing email/Discord/Telegram global notif settings * refactor: get global notif settings from relevant API endpoints instead of adding to public settings * fix(notif): fall back to email notifications being enabled (default) if user settings do not exist * fix(notif): do not set notifyUser for MEDIA_PENDING or MEDIA_AUTO_APPROVED * fix: expose notif enabled settings in user notif endpoints & remove global enable notif setting * fix(notif): remove unnecessary allowed_mentions object from Discord payload * fix(notif): use form values for email test notification * fix: make suggested changes and regenerate DB migration * fix: loosen validation of PGP keys * fix: fix user profile settings routes * fix: remove route guard from profile pages
3 years ago
logger.info(`Sending notification(s) for ${Notification[type]}`, {
label: 'Notifications',
feat(notif): allow users to enable/disable specific agents (#1172) * refactor(ui): add tabs to user notification settings * feat(notif): allow users to enable/disable specific agents * fix(ui): only enforce required fields when agent is enabled * fix(ui): hide unavailable notification agents * feat(notif): mention admin users for admin Discord notifications * fix(ui): modify styling of PGP key textareas to suit expected input * fix(notif): mention all admins when there are multiple and fix rebase error * fix: add missing form values, and fix Yup validation * refactor: reduce repeated logic/code in email notif agent * refactor: move 'Notification Types' label into NotificationTypeSelector component * fix(email): correct inconsistencies in email template formatting * refactor: use bitfields for storing user-enabled notif agent types * feat: improve notification agent logging * fix(ui): mark string fields as nullable so empty values are not type errors * fix: add validation for PGP-related inputs * fix: correctly fetch user in user settings & log mentioned IDs for Discord notifs * fix(ui): fix mobile nav dropdown text & add hover effect to button-style tabs * fix(notif): process admin email notifications asynchronously * fix(logging): log name of notification type instead of its enum value * fix: mark required fields and pass all user settings values to API * fix(frontend): call mutate after changing email/Discord/Telegram global notif settings * refactor: get global notif settings from relevant API endpoints instead of adding to public settings * fix(notif): fall back to email notifications being enabled (default) if user settings do not exist * fix(notif): do not set notifyUser for MEDIA_PENDING or MEDIA_AUTO_APPROVED * fix: expose notif enabled settings in user notif endpoints & remove global enable notif setting * fix(notif): remove unnecessary allowed_mentions object from Discord payload * fix(notif): use form values for email test notification * fix: make suggested changes and regenerate DB migration * fix: loosen validation of PGP keys * fix: fix user profile settings routes * fix: remove route guard from profile pages
3 years ago
subject: payload.subject,
});
this.activeAgents.forEach((agent) => {
if (agent.shouldSend()) {
agent.send(type, payload);
}
});
}
}
const notificationManager = new NotificationManager();
export default notificationManager;