完善通知模块

This commit is contained in:
chaos-zhu 2024-08-17 16:10:17 +08:00
parent 279cd90f63
commit 3d410602d6
4 changed files with 68 additions and 28 deletions

View File

@ -31,7 +31,9 @@ module.exports = {
'no-redeclare': ['error', { builtinGlobals: true }], // 禁止重复对象声明
'no-multi-assign': 0,
'no-restricted-globals': 0,
'no-case-declarations': 0,
'space-before-function-paren': 0, // 函数定义时括号前面空格
'no-async-promise-executor': 0, // 允许在回调中使用async函数
'one-var': 0, // 允许连续声明
// 'no-undef': 0, // 允许未定义的变量【会使env配置无效】
'linebreak-style': 0, // 检测CRLF/LF检测【默认LF】

View File

@ -1,5 +1,5 @@
const { readNotifyConfig, writeNotifyConfig, readNotifyList, writeNotifyList } = require('../utils')
const { sctTest, emailTest } = require('../utils/notify')
const { sendServerChan, sendEmail } = require('../utils/notify')
// const commonTemp = require('../template/commonTemp')
async function getNotifyConfig({ res }) {
@ -13,10 +13,10 @@ async function updateNotifyConfig({ res, request }) {
try {
switch(type) {
case 'sct':
await sctTest(noticeConfig[type])
await sendServerChan(noticeConfig[type]['sendKey'], 'EasyNode通知测试', '这是一条测试通知')
break
case 'email':
await emailTest(noticeConfig[type])
await sendEmail(noticeConfig[type], 'EasyNode通知测试', '这是一条测试通知')
break
}
await writeNotifyConfig(noticeConfig)

View File

@ -1,6 +1,7 @@
const jwt = require('jsonwebtoken')
const axios = require('axios')
const { getNetIPInfo, readKey, writeKey, RSADecryptSync, AESEncryptSync, SHA1Encrypt, sendEmailToConfList, getNotifySwByType } = require('../utils')
const { getNetIPInfo, readKey, writeKey, RSADecryptSync, AESEncryptSync, SHA1Encrypt, getNotifySwByType } = require('../utils')
const { asyncSendNotice } = require('../utils/notify')
const getpublicKey = async ({ res }) => {
let { publicKey: data } = await readKey()
@ -24,9 +25,8 @@ const login = async ({ res, request }) => {
loginErrTotal++
if (loginErrCount >= allowErrCount) {
const { ip, country, city } = await getNetIPInfo(clientIp)
// 发送通知&禁止登录
let sw = getNotifySwByType('err_login')
if (sw) sendEmailToConfList('登录错误提醒', `重新登录次数: ${ loginErrTotal }<br/>地点:${ country + city }<br/>IP: ${ ip }`)
// 异步发送通知&禁止登录
asyncSendNotice('err_login', 'EasyNode登录错误提醒', `错误登录次数: ${ loginErrTotal }<br/>地点:${ country + city }<br/>IP: ${ ip }`)
forbidLogin = true
loginErrCount = 0
@ -82,8 +82,7 @@ const beforeLoginHandler = async (clientIp, jwtExpires) => {
consola.info('登录成功:', new Date(), { ip, country, city })
// 邮件登录通知
let sw = getNotifySwByType('login')
if (sw) sendEmailToConfList('登录提醒', `地点:${ country + city }<br/>IP: ${ ip }`)
asyncSendNotice('login', 'EasyNode登录提醒', `地点:${ country + city }<br/>IP: ${ ip }`)
global.loginRecord.unshift(clientIPInfo)
if (global.loginRecord.length > 10) global.loginRecord = global.loginRecord.slice(0, 10)
@ -103,8 +102,7 @@ const updatePwd = async ({ res, request }) => {
keyObj.pwd = newPwd
await writeKey(keyObj)
let sw = getNotifySwByType('updatePwd')
if (sw) sendEmailToConfList(`登录信息修改提醒, 新用户名: ${ newLoginName }`)
asyncSendNotice('updatePwd', 'EasyNode用户密码修改提醒', `原用户名:${ user }<br/>更新用户名: ${ newLoginName }`)
res.success({ data: true, msg: 'success' })
}

View File

@ -1,27 +1,34 @@
const nodemailer = require('nodemailer')
const axios = require('axios')
const { getNotifySwByType, readNotifyConfig } = require('../utils')
module.exports.sctTest = function ({ sendKey }) {
// eslint-disable-next-line no-async-promise-executor
function sendServerChan(sendKey, title, content) {
if (!sendKey) return consola.error('发送server酱通知失败, sendKey 为空')
return new Promise((async (resolve, reject) => {
consola.info('server酱通知测试: ', sendKey)
try {
let { data } = await axios.get(`https://sctapi.ftqq.com/${ sendKey }.send?title=messagetitle`)
consola.info('server酱通知预发送: ', title)
const url = `https://sctapi.ftqq.com/${ sendKey }.send`
const params = new URLSearchParams({ text: title, desp: content })
let { data } = await axios.post(url, params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
resolve(data)
consola.success('测试成功')
consola.info('server酱通知发送成功: ', title)
} catch (error) {
reject(error)
consola.error('测试失败: ', error)
consola.error('server酱通知发送失败: ', error)
}
}))
}
module.exports.emailTest = function (conf) {
// eslint-disable-next-line no-async-promise-executor
function sendEmail({ service, user, pass }, title, content) {
if (!service || !user || !pass) return consola.info('发送通知失败, 邮箱配置信息不完整: ', { service, user, pass })
return new Promise((async (resolve, reject) => {
consola.info('邮箱通知测试: ', conf)
try {
const { service, user, pass } = conf
consola.info('邮箱通知预发送: ', title)
let transporter = nodemailer.createTransport({
service,
auth: {
@ -29,19 +36,52 @@ module.exports.emailTest = function (conf) {
pass
}
})
let info = await transporter.sendMail({
await transporter.sendMail({
from: user,
to: user,
subject: 'EasyNode: 测试邮件通知',
text: '测试邮件',
html: '<b>测试邮件</b>'
subject: title,
// text: '', // 纯文本版本内容如果收件人的邮件客户端不支持HTML显示就会显示这个文本
html: content
})
consola.info('Message sent: %s', info.messageId)
consola.info('邮件通知发送成功: ', title)
resolve()
consola.success('测试成功')
} catch (error) {
reject(error)
consola.error('测试失败: ', error)
consola.error('邮件通知发送失败: ', error)
}
}))
}
// 异步发送通知
async function asyncSendNotice(noticeAction, title, content) {
try {
let sw = await getNotifySwByType(noticeAction) // 获取对应动作的通知开关
if (!sw) return
let notifyConfig = await readNotifyConfig()
let { type } = notifyConfig
if (!type) return consola.error('通知类型不存在: ', type)
content += `<br/>通知发送时间:${ new Date() }`
switch (type) {
case 'sct':
let { sendKey } = notifyConfig['sct']
if (!sendKey) return consola.info('未发送server酱通知, sendKey 为空')
await sendServerChan(sendKey, title, content)
break
case 'email':
let { service, user, pass } = notifyConfig['email']
if (!service || !user || !pass) return consola.info('未发送邮件通知通知, 未配置邮箱: ', { service, user, pass })
await sendEmail({ service, user, pass }, title, content)
break
default:
break
}
} catch (error) {
consola.error('通知发送失败: ', error)
}
}
module.exports = {
asyncSendNotice,
sendServerChan,
sendEmail
}