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.
120 lines
3.4 KiB
120 lines
3.4 KiB
import type { User } from '../../entity/User';
|
|
import logger from '../../logger';
|
|
import { Permission } from '../permissions';
|
|
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];
|
|
logger.info('Registered notification agents', { label: 'Notifications' });
|
|
};
|
|
|
|
public sendNotification(
|
|
type: Notification,
|
|
payload: NotificationPayload
|
|
): void {
|
|
logger.info(`Sending notification(s) for ${Notification[type]}`, {
|
|
label: 'Notifications',
|
|
subject: payload.subject,
|
|
});
|
|
|
|
this.activeAgents.forEach((agent) => {
|
|
if (agent.shouldSend()) {
|
|
agent.send(type, payload);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
const notificationManager = new NotificationManager();
|
|
|
|
export default notificationManager;
|