fix(notify): audit system and JS/Python script notification results

This commit is contained in:
whyour
2026-10-13 02:20:59 +08:00
30 changed files with 2038 additions and 335 deletions
+39 -23
View File
@@ -1,3 +1,4 @@
import { persistNotificationAudit } from '../shared/notificationAudit';
import crypto from 'crypto';
import nodemailer from 'nodemailer';
import { Inject, Service } from 'typedi';
@@ -55,27 +56,33 @@ export default class NotificationService {
content: string,
notificationInfo?: NotificationInfo,
): Promise<boolean | undefined> {
let { type, ...rest } = await this.userService.getNotificationMode();
if (notificationInfo?.type) {
type = notificationInfo?.type;
}
if (type) {
this.title = title;
this.content = content;
let params = rest;
if (notificationInfo) {
const { type: _, ...others } = notificationInfo;
params = { ...rest, ...others };
}
this.params = params;
const notificationModeAction = this.modeMap.get(type);
try {
return await notificationModeAction?.call(this);
} catch (error: any) {
console.error(error);
let type: string | undefined;
let success = false;
try {
const saved = await this.userService.getNotificationMode();
type = notificationInfo?.type || saved.type;
if (type) {
this.title = title;
this.content = content;
const { type: _, ...overrides } = notificationInfo || {};
const { type: _saved, ...rest } = saved;
this.params = { ...rest, ...overrides };
try {
success = !!(await this.modeMap.get(type)?.call(this));
} catch (error) {
console.error(error);
}
}
return success;
} finally {
await persistNotificationAudit({
title,
content,
notifyType: type,
source: 'system',
status: success ? 0 : 1,
});
}
return false;
}
public async testNotify(
@@ -84,14 +91,23 @@ export default class NotificationService {
content: string,
) {
const { type, ...rest } = info;
if (type) {
if (!type) return true;
let success = false;
try {
this.title = title;
this.content = content;
this.params = rest;
const notificationModeAction = this.modeMap.get(type);
return await notificationModeAction?.call(this);
success = !!(await this.modeMap.get(type)?.call(this));
return success;
} finally {
await persistNotificationAudit({
title,
content,
notifyType: type,
source: 'system',
status: success ? 0 : 1,
});
}
return true;
}
private parseMailRecipients(value?: string) {
+5 -43
View File
@@ -1,4 +1,4 @@
import { Op } from 'sequelize';
import { persistNotificationAudit } from '../shared/notificationAudit';
import { spawn } from 'cross-spawn';
import { execFile } from 'child_process';
import { promisify } from 'util';
@@ -413,54 +413,12 @@ export default class SystemService {
notificationInfo.type = typeString;
}
let notifyType: string | undefined;
if (notificationInfo?.type) {
notifyType = typeString || (notificationInfo.type as string);
} else {
try {
const notifConfig = await this.getDb({
type: AuthDataType.notification,
});
notifyType = notifConfig.info?.type as string | undefined;
} catch (e) {}
}
const isSuccess = await this.notificationService.notify(
title,
content,
notificationInfo,
);
try {
await SystemModel.create({
type: AuthDataType.notifyLog,
info: {
timestamp: Date.now(),
title: title.slice(0, 512),
content: content.slice(0, 8192),
status: isSuccess ? NotifyStatus.success : NotifyStatus.fail,
notifyType,
},
});
const oldest = await SystemModel.findAll({
where: { type: AuthDataType.notifyLog },
attributes: ['id'],
order: [['id', 'DESC']],
offset: 200,
limit: 1,
});
if (oldest[0]?.id) {
await SystemModel.destroy({
where: {
type: AuthDataType.notifyLog,
id: { [Op.lte]: oldest[0].id },
},
});
}
} catch (error) {
this.logger.error('Failed to persist notification audit log: %o', error);
}
if (isSuccess) {
return { code: 200, message: t('通知发送成功') };
} else {
@@ -468,6 +426,10 @@ export default class SystemService {
}
}
public async recordNotifyLog(info: NotifyLogInfo): Promise<void> {
await persistNotificationAudit(info);
}
public async getNotifyLog(): Promise<Array<NotifyLogInfo>> {
const docs = await SystemModel.findAll({
where: { type: AuthDataType.notifyLog },