mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-23 23:06:06 +08:00
更新通知服务
This commit is contained in:
parent
9534cda1f9
commit
f2dac51a62
|
@ -16,65 +16,66 @@ abstract class NotificationBaseInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GoCqHttpBotNotification extends NotificationBaseInfo {
|
export class GoCqHttpBotNotification extends NotificationBaseInfo {
|
||||||
public GOBOT_URL = '';
|
public goCqHttpBotUrl = '';
|
||||||
public GOBOT_TOKEN = '';
|
public goCqHttpBotToken = '';
|
||||||
public GOBOT_QQ = '';
|
public goCqHttpBotQq = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ServerChanNotification extends NotificationBaseInfo {
|
export class ServerChanNotification extends NotificationBaseInfo {
|
||||||
public SCKEY = '';
|
public serverChanKey = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BarkNotification extends NotificationBaseInfo {
|
export class BarkNotification extends NotificationBaseInfo {
|
||||||
public BARK_PUSH = '';
|
public barkPush = '';
|
||||||
public BARK_SOUND = '';
|
public barkSound = '';
|
||||||
public BARK_GROUP = 'qinglong';
|
public barkGroup = 'qinglong';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TelegramBotNotification extends NotificationBaseInfo {
|
export class TelegramBotNotification extends NotificationBaseInfo {
|
||||||
public TG_BOT_TOKEN = '';
|
public telegramBotToken = '';
|
||||||
public TG_USER_ID = '';
|
public telegramBotUserId = '';
|
||||||
public TG_PROXY_HOST = '';
|
public telegramBotProxyHost = '';
|
||||||
public TG_PROXY_PORT = '';
|
public telegramBotProxyPort = '';
|
||||||
public TG_PROXY_AUTH = '';
|
public telegramBotProxyAuth = '';
|
||||||
public TG_API_HOST = 'api.telegram.org';
|
public telegramBotApiHost = 'api.telegram.org';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DingtalkBotNotification extends NotificationBaseInfo {
|
export class DingtalkBotNotification extends NotificationBaseInfo {
|
||||||
public DD_BOT_TOKEN = '';
|
public dingtalkBotToken = '';
|
||||||
public DD_BOT_SECRET = '';
|
public dingtalkBotSecret = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WeWorkBotNotification extends NotificationBaseInfo {
|
export class WeWorkBotNotification extends NotificationBaseInfo {
|
||||||
public QYWX_KEY = '';
|
public weWorkBotKey = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WeWorkAppNotification extends NotificationBaseInfo {
|
export class WeWorkAppNotification extends NotificationBaseInfo {
|
||||||
public QYWX_AM = '';
|
public weWorkAppKey = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class IGotNotification extends NotificationBaseInfo {
|
export class IGotNotification extends NotificationBaseInfo {
|
||||||
public IGOT_PUSH_KEY = '';
|
public iGotPushKey = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PushPlusNotification extends NotificationBaseInfo {
|
export class PushPlusNotification extends NotificationBaseInfo {
|
||||||
public PUSH_PLUS_TOKEN = '';
|
public pushPlusToken = '';
|
||||||
public PUSH_PLUS_USER = '';
|
public pushPlusUser = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EmailNotification extends NotificationBaseInfo {
|
export class EmailNotification extends NotificationBaseInfo {
|
||||||
public service: string = '';
|
public emailService: string = '';
|
||||||
public user: string = '';
|
public emailUser: string = '';
|
||||||
public pass: string = '';
|
public emailPass: string = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NotificationInfo =
|
export interface NotificationInfo
|
||||||
| GoCqHttpBotNotification
|
extends GoCqHttpBotNotification,
|
||||||
| ServerChanNotification
|
ServerChanNotification,
|
||||||
| BarkNotification
|
BarkNotification,
|
||||||
| TelegramBotNotification
|
TelegramBotNotification,
|
||||||
| DingtalkBotNotification
|
DingtalkBotNotification,
|
||||||
| WeWorkBotNotification
|
WeWorkBotNotification,
|
||||||
| IGotNotification
|
WeWorkAppNotification,
|
||||||
| PushPlusNotification
|
IGotNotification,
|
||||||
| EmailNotification;
|
PushPlusNotification,
|
||||||
|
EmailNotification {}
|
||||||
|
|
|
@ -14,12 +14,11 @@ import NotificationService from './notify';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class AuthService {
|
export default class AuthService {
|
||||||
|
@Inject((type) => NotificationService)
|
||||||
|
private notificationService!: NotificationService;
|
||||||
private authDb = new DataStore({ filename: config.authDbFile });
|
private authDb = new DataStore({ filename: config.authDbFile });
|
||||||
|
|
||||||
constructor(
|
constructor(@Inject('logger') private logger: winston.Logger) {
|
||||||
@Inject('logger') private logger: winston.Logger,
|
|
||||||
private notificationService: NotificationService,
|
|
||||||
) {
|
|
||||||
this.authDb.loadDatabase((err) => {
|
this.authDb.loadDatabase((err) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,9 +2,16 @@ import { NotificationInfo } from '../data/notify';
|
||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import winston from 'winston';
|
import winston from 'winston';
|
||||||
import AuthService from './auth';
|
import AuthService from './auth';
|
||||||
|
import got from 'got';
|
||||||
|
import nodemailer from 'nodemailer';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class NotificationService {
|
export default class NotificationService {
|
||||||
|
@Inject((type) => AuthService)
|
||||||
|
private authService!: AuthService;
|
||||||
|
|
||||||
private modeMap = new Map([
|
private modeMap = new Map([
|
||||||
['goCqHttpBot', this.goCqHttpBot],
|
['goCqHttpBot', this.goCqHttpBot],
|
||||||
['serverChan', this.serverChan],
|
['serverChan', this.serverChan],
|
||||||
|
@ -18,14 +25,12 @@ export default class NotificationService {
|
||||||
['email', this.email],
|
['email', this.email],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
private timeout = 10000;
|
||||||
private title = '';
|
private title = '';
|
||||||
private content = '';
|
private content = '';
|
||||||
private params!: Omit<NotificationInfo, 'type'>;
|
private params!: Omit<NotificationInfo, 'type'>;
|
||||||
|
|
||||||
constructor(
|
constructor(@Inject('logger') private logger: winston.Logger) {}
|
||||||
@Inject('logger') private logger: winston.Logger,
|
|
||||||
private authService: AuthService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public async notify(title: string, content: string) {
|
public async notify(title: string, content: string) {
|
||||||
const { type, ...rest } = await this.authService.getNotificationMode();
|
const { type, ...rest } = await this.authService.getNotificationMode();
|
||||||
|
@ -38,22 +43,257 @@ export default class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async goCqHttpBot() {}
|
private async goCqHttpBot() {
|
||||||
|
const { goCqHttpBotQq, goCqHttpBotToken, goCqHttpBotUrl } = this.params;
|
||||||
|
const res: any = await got
|
||||||
|
.post(
|
||||||
|
`${goCqHttpBotUrl}?access_token=${goCqHttpBotToken}&${goCqHttpBotQq}`,
|
||||||
|
{
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
json: { message: `${this.title}\n${this.content}` },
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.json();
|
||||||
|
return res.retcode === 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async serverChan() {}
|
private async serverChan() {
|
||||||
|
const { serverChanKey } = this.params;
|
||||||
|
const url = serverChanKey.includes('SCT')
|
||||||
|
? `https://sctapi.ftqq.com/${SCKEY}.send`
|
||||||
|
: `https://sc.ftqq.com/${SCKEY}.send`;
|
||||||
|
const res: any = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
body: `text=${this.title}&desp=${this.content}`,
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
return res.errno === 0 || res.data.errno === 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async bark() {}
|
private async bark() {
|
||||||
|
const { barkPush, barkSound, barkGroup } = this.params;
|
||||||
|
const url = `${barkPush}/${encodeURIComponent(
|
||||||
|
this.title,
|
||||||
|
)}/${encodeURIComponent(
|
||||||
|
this.content,
|
||||||
|
)}?sound=${barkSound}&group=${barkGroup}`;
|
||||||
|
const res: any = await got
|
||||||
|
.get(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
return res.code === 200;
|
||||||
|
}
|
||||||
|
|
||||||
private async telegramBot() {}
|
private async telegramBot() {
|
||||||
|
const {
|
||||||
|
telegramBotApiHost,
|
||||||
|
telegramBotProxyAuth,
|
||||||
|
telegramBotProxyHost,
|
||||||
|
telegramBotProxyPort,
|
||||||
|
telegramBotToken,
|
||||||
|
telegramBotUserId,
|
||||||
|
} = this.params;
|
||||||
|
const url = `https://${telegramBotApiHost}/bot${telegramBotToken}/sendMessage`;
|
||||||
|
const options = {
|
||||||
|
keepAlive: true,
|
||||||
|
keepAliveMsecs: 1000,
|
||||||
|
maxSockets: 256,
|
||||||
|
maxFreeSockets: 256,
|
||||||
|
proxy: `http://${telegramBotProxyHost}:${telegramBotProxyPort}`,
|
||||||
|
};
|
||||||
|
const httpAgent = new HttpProxyAgent(options);
|
||||||
|
const httpsAgent = new HttpsProxyAgent(options);
|
||||||
|
const res: any = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
body: `chat_id=${telegramBotUserId}&text=${this.title}\n\n${this.content}&disable_web_page_preview=true`,
|
||||||
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
agent: {
|
||||||
|
http: httpAgent,
|
||||||
|
https: httpsAgent,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
return !!res.ok;
|
||||||
|
}
|
||||||
|
|
||||||
private async dingtalkBot() {}
|
private async dingtalkBot() {
|
||||||
|
const { dingtalkBotSecret, dingtalkBotToken } = this.params;
|
||||||
|
let secretParam = '';
|
||||||
|
if (dingtalkBotSecret) {
|
||||||
|
const dateNow = Date.now();
|
||||||
|
const hmac = crypto.createHmac('sha256', dingtalkBotSecret);
|
||||||
|
hmac.update(`${dateNow}\n${dingtalkBotSecret}`);
|
||||||
|
const result = encodeURIComponent(hmac.digest('base64'));
|
||||||
|
secretParam = `×tamp=${dateNow}&sign=${result}`;
|
||||||
|
}
|
||||||
|
const url = `https://oapi.dingtalk.com/robot/send?access_token=${dingtalkBotToken}${secretParam}`;
|
||||||
|
const res: any = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
json: {
|
||||||
|
msgtype: 'text',
|
||||||
|
text: {
|
||||||
|
content: ` ${this.title}\n\n${this.content}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
return res.errcode === 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async weWorkBot() {}
|
private async weWorkBot() {
|
||||||
|
const { weWorkBotKey } = this.params;
|
||||||
|
const url = `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${weWorkBotKey}`;
|
||||||
|
const res: any = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
json: {
|
||||||
|
msgtype: 'text',
|
||||||
|
text: {
|
||||||
|
content: ` ${this.title}\n\n${this.content}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
return res.errcode === 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async weWorkApp() {}
|
private async weWorkApp() {
|
||||||
private async iGot() {}
|
const { weWorkAppKey } = this.params;
|
||||||
|
const [corpid, corpsecret, touser, agentid, thumb_media_id = '1'] =
|
||||||
|
weWorkAppKey.split(',');
|
||||||
|
const url = `https://qyapi.weixin.qq.com/cgi-bin/gettoken`;
|
||||||
|
const { access_token } = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
json: {
|
||||||
|
corpid,
|
||||||
|
corpsecret,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
|
||||||
private async pushPlus() {}
|
let options: any = {
|
||||||
|
msgtype: 'mpnews',
|
||||||
|
mpnews: {
|
||||||
|
articles: [
|
||||||
|
{
|
||||||
|
title: `${this.title}`,
|
||||||
|
thumb_media_id,
|
||||||
|
author: `智能助手`,
|
||||||
|
content_source_url: ``,
|
||||||
|
content: `${this.content.replace(/\n/g, '<br/>')}`,
|
||||||
|
digest: `${this.content}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
switch (thumb_media_id) {
|
||||||
|
case '0':
|
||||||
|
options = {
|
||||||
|
msgtype: 'textcard',
|
||||||
|
textcard: {
|
||||||
|
title: `${this.title}`,
|
||||||
|
description: `${this.content}`,
|
||||||
|
url: 'https://github.com/whyour/qinglong',
|
||||||
|
btntxt: '更多',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
private async email() {}
|
case '1':
|
||||||
|
options = {
|
||||||
|
msgtype: 'text',
|
||||||
|
text: {
|
||||||
|
content: `${this.title}\n\n${this.content}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res: any = await got
|
||||||
|
.post(
|
||||||
|
`https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${access_token}`,
|
||||||
|
{
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
json: {
|
||||||
|
touser,
|
||||||
|
agentid,
|
||||||
|
safe: '0',
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.json();
|
||||||
|
|
||||||
|
return res.errcode === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async iGot() {
|
||||||
|
const { iGotPushKey } = this.params;
|
||||||
|
const url = `https://push.hellyw.com/${iGotPushKey.toLowerCase()}`;
|
||||||
|
const res: any = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
body: `title=${this.title}&content=${this.content}`,
|
||||||
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
|
||||||
|
return res.ret === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async pushPlus() {
|
||||||
|
const { pushPlusToken, pushPlusUser } = this.params;
|
||||||
|
const url = `https://www.pushplus.plus/send`;
|
||||||
|
const res: any = await got
|
||||||
|
.post(url, {
|
||||||
|
timeout: this.timeout,
|
||||||
|
retry: 0,
|
||||||
|
json: {
|
||||||
|
token: `${pushPlusToken}`,
|
||||||
|
title: `${this.title}`,
|
||||||
|
content: `${this.content.replace(/[\n\r]/g, '<br>')}`,
|
||||||
|
topic: `${pushPlusUser}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
|
||||||
|
return res.code === 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async email() {
|
||||||
|
const { emailPass, emailService, emailUser } = this.params;
|
||||||
|
const transporter = nodemailer.createTransport({
|
||||||
|
service: emailService,
|
||||||
|
auth: {
|
||||||
|
user: emailUser,
|
||||||
|
pass: emailPass,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const info = await transporter.sendMail({
|
||||||
|
from: `"青龙快讯" <${emailUser}>`,
|
||||||
|
to: `${emailUser}`,
|
||||||
|
subject: `${this.title}`,
|
||||||
|
html: `${this.content.replace(/\n/g, '<br/>')}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
transporter.close();
|
||||||
|
|
||||||
|
return !!info.messageId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,14 @@
|
||||||
"express-jwt": "^6.0.0",
|
"express-jwt": "^6.0.0",
|
||||||
"express-urlrewrite": "^1.4.0",
|
"express-urlrewrite": "^1.4.0",
|
||||||
"got": "^11.8.2",
|
"got": "^11.8.2",
|
||||||
|
"hpagent": "^0.1.2",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"nedb": "^1.8.0",
|
"nedb": "^1.8.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"node-schedule": "^2.0.0",
|
"node-schedule": "^2.0.0",
|
||||||
|
"nodemailer": "^6.6.3",
|
||||||
"p-queue": "6.6.2",
|
"p-queue": "6.6.2",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"typedi": "^0.8.0",
|
"typedi": "^0.8.0",
|
||||||
|
@ -58,6 +60,7 @@
|
||||||
"@types/nedb": "^1.8.11",
|
"@types/nedb": "^1.8.11",
|
||||||
"@types/node": "^14.11.2",
|
"@types/node": "^14.11.2",
|
||||||
"@types/node-fetch": "^2.5.8",
|
"@types/node-fetch": "^2.5.8",
|
||||||
|
"@types/nodemailer": "^6.4.4",
|
||||||
"@types/qrcode.react": "^1.0.1",
|
"@types/qrcode.react": "^1.0.1",
|
||||||
"@types/react": "^17.0.0",
|
"@types/react": "^17.0.0",
|
||||||
"@types/react-dom": "^17.0.0",
|
"@types/react-dom": "^17.0.0",
|
||||||
|
|
|
@ -13,6 +13,7 @@ specifiers:
|
||||||
'@types/nedb': ^1.8.11
|
'@types/nedb': ^1.8.11
|
||||||
'@types/node': ^14.11.2
|
'@types/node': ^14.11.2
|
||||||
'@types/node-fetch': ^2.5.8
|
'@types/node-fetch': ^2.5.8
|
||||||
|
'@types/nodemailer': ^6.4.4
|
||||||
'@types/qrcode.react': ^1.0.1
|
'@types/qrcode.react': ^1.0.1
|
||||||
'@types/react': ^17.0.0
|
'@types/react': ^17.0.0
|
||||||
'@types/react-dom': ^17.0.0
|
'@types/react-dom': ^17.0.0
|
||||||
|
@ -30,6 +31,7 @@ specifiers:
|
||||||
express-jwt: ^6.0.0
|
express-jwt: ^6.0.0
|
||||||
express-urlrewrite: ^1.4.0
|
express-urlrewrite: ^1.4.0
|
||||||
got: ^11.8.2
|
got: ^11.8.2
|
||||||
|
hpagent: ^0.1.2
|
||||||
iconv-lite: ^0.6.3
|
iconv-lite: ^0.6.3
|
||||||
jsonwebtoken: ^8.5.1
|
jsonwebtoken: ^8.5.1
|
||||||
lint-staged: ^10.0.7
|
lint-staged: ^10.0.7
|
||||||
|
@ -37,6 +39,7 @@ specifiers:
|
||||||
nedb: ^1.8.0
|
nedb: ^1.8.0
|
||||||
node-fetch: ^2.6.1
|
node-fetch: ^2.6.1
|
||||||
node-schedule: ^2.0.0
|
node-schedule: ^2.0.0
|
||||||
|
nodemailer: ^6.6.3
|
||||||
nodemon: ^2.0.4
|
nodemon: ^2.0.4
|
||||||
p-queue: 6.6.2
|
p-queue: 6.6.2
|
||||||
prettier: ^2.2.0
|
prettier: ^2.2.0
|
||||||
|
@ -71,12 +74,14 @@ dependencies:
|
||||||
express-jwt: 6.0.0
|
express-jwt: 6.0.0
|
||||||
express-urlrewrite: 1.4.0
|
express-urlrewrite: 1.4.0
|
||||||
got: 11.8.2
|
got: 11.8.2
|
||||||
|
hpagent: 0.1.2
|
||||||
iconv-lite: 0.6.3
|
iconv-lite: 0.6.3
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 8.5.1
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
nedb: 1.8.0
|
nedb: 1.8.0
|
||||||
node-fetch: 2.6.1
|
node-fetch: 2.6.1
|
||||||
node-schedule: 2.0.0
|
node-schedule: 2.0.0
|
||||||
|
nodemailer: 6.6.3
|
||||||
p-queue: 6.6.2
|
p-queue: 6.6.2
|
||||||
reflect-metadata: 0.1.13
|
reflect-metadata: 0.1.13
|
||||||
typedi: 0.8.0
|
typedi: 0.8.0
|
||||||
|
@ -95,6 +100,7 @@ devDependencies:
|
||||||
'@types/nedb': 1.8.11
|
'@types/nedb': 1.8.11
|
||||||
'@types/node': 14.14.45
|
'@types/node': 14.14.45
|
||||||
'@types/node-fetch': 2.5.10
|
'@types/node-fetch': 2.5.10
|
||||||
|
'@types/nodemailer': 6.4.4
|
||||||
'@types/qrcode.react': 1.0.1
|
'@types/qrcode.react': 1.0.1
|
||||||
'@types/react': 17.0.5
|
'@types/react': 17.0.5
|
||||||
'@types/react-dom': 17.0.5
|
'@types/react-dom': 17.0.5
|
||||||
|
@ -1186,6 +1192,16 @@ packages:
|
||||||
resolution: {integrity: sha512-n2OQ+0Bz6WEsUjrvcHD1xZ8K+Kgo4cn9/w94s1bJS690QMUWfJPW/m7CCb7gPkA1fcYwL2UpjXP/rq/Eo41m6w==}
|
resolution: {integrity: sha512-n2OQ+0Bz6WEsUjrvcHD1xZ8K+Kgo4cn9/w94s1bJS690QMUWfJPW/m7CCb7gPkA1fcYwL2UpjXP/rq/Eo41m6w==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@types/node/14.17.16:
|
||||||
|
resolution: {integrity: sha512-WiFf2izl01P1CpeY8WqFAeKWwByMueBEkND38EcN8N68qb0aDG3oIS1P5MhAX5kUdr469qRyqsY/MjanLjsFbQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@types/nodemailer/6.4.4:
|
||||||
|
resolution: {integrity: sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 14.17.16
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/normalize-package-data/2.4.0:
|
/@types/normalize-package-data/2.4.0:
|
||||||
resolution: {integrity: sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==}
|
resolution: {integrity: sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -4232,6 +4248,10 @@ packages:
|
||||||
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
|
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/hpagent/0.1.2:
|
||||||
|
resolution: {integrity: sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/html-encoding-sniffer/1.0.2:
|
/html-encoding-sniffer/1.0.2:
|
||||||
resolution: {integrity: sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==}
|
resolution: {integrity: sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6162,6 +6182,11 @@ packages:
|
||||||
sorted-array-functions: 1.3.0
|
sorted-array-functions: 1.3.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/nodemailer/6.6.3:
|
||||||
|
resolution: {integrity: sha512-faZFufgTMrphYoDjvyVpbpJcYzwyFnbAMmQtj1lVBYAUSm3SOy2fIdd9+Mr4UxPosBa0JRw9bJoIwQn+nswiew==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/nodemon/2.0.7:
|
/nodemon/2.0.7:
|
||||||
resolution: {integrity: sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==}
|
resolution: {integrity: sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==}
|
||||||
engines: {node: '>=8.10.0'}
|
engines: {node: '>=8.10.0'}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user