perf: email proxy

This commit is contained in:
xiaojunnuo
2024-08-23 11:35:34 +08:00
parent 14ab93dc2f
commit 453f1baa0b
8 changed files with 166 additions and 35 deletions

View File

@@ -1,10 +1,11 @@
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import type { EmailSend } from '@certd/pipeline';
import { IEmailService } from '@certd/pipeline';
import { IEmailService, isPlus } from '@certd/pipeline';
import nodemailer from 'nodemailer';
import type SMTPConnection from 'nodemailer/lib/smtp-connection';
import { logger } from '../../../utils/logger.js';
import { UserSettingsService } from '../../mine/service/user-settings-service.js';
import { PlusService } from './plus-service.js';
export type EmailConfig = {
host: string;
@@ -19,26 +20,57 @@ export type EmailConfig = {
rejectUnauthorized: boolean;
};
sender: string;
usePlus?: boolean;
} & SMTPConnection.Options;
@Provide()
@Scope(ScopeEnum.Singleton)
export class EmailService implements IEmailService {
@Inject()
settingsService: UserSettingsService;
@Inject()
plusService: PlusService;
async sendByPlus(email: EmailSend) {
if (!isPlus()) {
throw new Error('plus not enabled');
}
/**
* userId: number;
* subject: string;
* content: string;
* receivers: string[];
*/
await this.plusService.request('/activation/emailSend', {
subject: email.subject,
text: email.content,
to: email.receivers,
});
}
/**
*/
async send(email: EmailSend) {
console.log('sendEmail', email);
const emailConfigEntity = await this.settingsService.getByKey(
'email',
email.userId
);
const emailConfigEntity = await this.settingsService.getByKey('email', email.userId);
if (emailConfigEntity == null || !emailConfigEntity.setting) {
if (isPlus()) {
//自动使用plus发邮件
return await this.sendByPlus(email);
}
throw new Error('email settings 未设置');
}
const emailConfig = JSON.parse(emailConfigEntity.setting) as EmailConfig;
if (emailConfig.usePlus && isPlus()) {
return await this.sendByPlus(email);
}
await this.sendByCustom(emailConfig, email);
logger.info('sendEmail complete: ', email);
}
private async sendByCustom(emailConfig: EmailConfig, email: EmailSend) {
const transporter = nodemailer.createTransport(emailConfig);
const mailOptions = {
from: emailConfig.sender,
@@ -47,7 +79,6 @@ export class EmailService implements IEmailService {
text: email.content,
};
await transporter.sendMail(mailOptions);
logger.info('sendEmail complete: ', email);
}
async test(userId: number, receiver: string) {

View File

@@ -0,0 +1,54 @@
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { SysSettingsService } from '../../system/service/sys-settings-service.js';
import { SysInstallInfo } from '../../system/service/models.js';
import { appKey, getPlusInfo } from '@certd/pipeline';
import * as crypto from 'crypto';
import { request } from '../../../utils/http.js';
import { logger } from '../../../utils/logger.js';
@Provide()
@Scope(ScopeEnum.Singleton)
export class PlusService {
@Inject()
sysSettingsService: SysSettingsService;
async request(url: string, data: any) {
const timestamps = Date.now();
const installInfo: SysInstallInfo = await this.sysSettingsService.getSetting(SysInstallInfo);
const sign = await this.sign(data, timestamps);
const requestHeader = {
subjectId: installInfo.siteId,
appKey: appKey,
sign: sign,
timestamps: timestamps,
};
let requestHeaderStr = JSON.stringify(requestHeader);
requestHeaderStr = Buffer.from(requestHeaderStr).toString('base64');
const headers = {
'Content-Type': 'application/json',
'X-Plus-Subject': requestHeaderStr,
};
const baseUrl = 'http://127.0.0.1:11007';
return await request({
url: url,
baseURL: baseUrl,
method: 'POST',
data: data,
headers: headers,
});
}
async sign(body: any, timestamps: number) {
//content := fmt.Sprintf("%s.%d.%s", in.Params, in.Timestamps, secret)
const params = JSON.stringify(body);
const plusInfo = getPlusInfo();
const secret = plusInfo.secret;
const content = `${params}.${timestamps}.${secret}`;
// sha256
const sign = crypto.createHash('sha256').update(content).digest('base64');
logger.info('content:', content, 'sign:', sign);
return sign;
}
}