♻️ 重构本地数据库-host模块

This commit is contained in:
chaos-zhu 2024-10-22 00:48:26 +08:00
parent a72ab84cee
commit 5724ede172
17 changed files with 178 additions and 219 deletions

View File

@ -1,4 +1,7 @@
const { readGroupList, writeGroupList, readHostList, writeHostList } = require('../utils/storage')
const { readGroupList, writeGroupList } = require('../utils/storage')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
async function getGroupList({ res }) {
let data = await readGroupList()
@ -41,16 +44,17 @@ const removeGroup = async ({ res, request }) => {
if (idx === -1) return res.fail({ msg: '分组不存在' })
// 移除分组将所有该分组下host分配到default中去
let hostList = await readHostList()
hostList = hostList?.map((item) => {
if (item.group === groupList[idx]._id) item.group = 'default'
return item
})
await writeHostList(hostList)
let hostList = await hostListDB.findAsync({})
if (Array.isArray(hostList) && hostList.length > 0) {
for (let item of hostList) {
if (item.group === groupList[idx]._id) {
item.group = 'default'
await hostListDB.updateAsync({ _id: item._id }, item)
}
}
}
groupList.splice(idx, 1)
await writeGroupList(groupList)
res.success({ data: '移除成功' })
}

View File

@ -1,15 +1,16 @@
const { readHostList, writeHostList } = require('../utils/storage')
const { RSADecryptSync, AESEncryptSync, AESDecryptSync } = require('../utils/encrypt')
const { RSADecryptAsync, AESEncryptAsync, AESDecryptAsync } = require('../utils/encrypt')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
async function getHostList({ res }) {
// console.log('get-host-list')
let data = await readHostList()
let data = await hostListDB.findAsync({})
data?.sort((a, b) => Number(b.index || 0) - Number(a.index || 0))
for (const item of data) {
try {
let { username, port, authType, _id: id, credential } = item
// console.log('解密凭证title: ', credential)
if (credential) credential = await AESDecryptSync(credential)
if (credential) credential = await AESDecryptAsync(credential)
const isConfig = Boolean(username && port && (item[authType]))
Object.assign(item, { id, isConfig, password: '', privateKey: '', credential })
} catch (error) {
@ -19,9 +20,7 @@ async function getHostList({ res }) {
res.success({ data })
}
async function addHost({
res, request
}) {
async function addHost({ res, request }) {
let {
body: {
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
@ -30,21 +29,19 @@ async function addHost({
} = request
// console.log(request)
if (!host || !name) return res.fail({ msg: 'missing params: name or host' })
let hostList = await readHostList()
let record = {
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
port: newPort, clientPort, username, authType, password, privateKey, credential, command
}
if (record[authType]) {
const clearTempKey = await RSADecryptSync(tempKey)
const clearTempKey = await RSADecryptAsync(tempKey)
console.log('clearTempKey:', clearTempKey)
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
const clearSSHKey = await AESDecryptAsync(record[authType], clearTempKey)
console.log(`${ authType }原密文: `, clearSSHKey)
record[authType] = await AESEncryptSync(clearSSHKey)
record[authType] = await AESEncryptAsync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
}
hostList.push(record)
await writeHostList(hostList)
await hostListDB.insertAsync(record)
res.success()
}
@ -60,78 +57,65 @@ async function updateHost({ res, request }) {
let isBatch = Array.isArray(hosts)
if (isBatch) {
if (!hosts.length) return res.fail({ msg: 'hosts为空' })
let hostList = await readHostList()
let newHostList = []
let hostList = await hostListDB.findAsync({})
for (let oldRecord of hostList) {
let record = hosts.find(item => item.id === oldRecord._id)
if (!record) {
newHostList.push(oldRecord)
continue
}
let { authType } = record
let target = hosts.find(item => item.id === oldRecord._id)
if (!target) continue
let { authType } = target
// 如果存在原认证方式则保存下来
if (!record[authType] && oldRecord[authType]) {
record[authType] = oldRecord[authType]
if (!target[authType]) {
target[authType] = oldRecord[authType]
} else {
const clearTempKey = await RSADecryptSync(record.tempKey)
const clearTempKey = await RSADecryptAsync(target.tempKey)
// console.log('批量解密tempKey:', clearTempKey)
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
const clearSSHKey = await AESDecryptAsync(target[authType], clearTempKey)
// console.log(`${ authType }原密文: `, clearSSHKey)
record[authType] = await AESEncryptSync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
target[authType] = await AESEncryptAsync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, target[authType])
}
delete oldRecord.monitorData
delete record.monitorData
newHostList.push(Object.assign(oldRecord, record))
delete target._id
delete target.monitorData
delete target.tempKey
Object.assign(oldRecord, target)
await hostListDB.updateAsync({ _id: oldRecord._id }, oldRecord)
}
await writeHostList(newHostList)
return res.success({ msg: '批量修改成功' })
}
if (!newHost || !newName || !oldHost) return res.fail({ msg: '参数错误' })
let hostList = await readHostList()
if (!hostList.some(({ host }) => host === oldHost)) return res.fail({ msg: `原实例[${ oldHost }]不存在,请尝试添加实例` })
let record = {
let updateRecord = {
name: newName, host: newHost, index, expired, expiredNotify, group, consoleUrl, remark,
port, clientPort, username, authType, password, privateKey, credential, command
}
let idx = hostList.findIndex(({ _id }) => _id === id)
const oldRecord = hostList[idx]
let oldRecord = await hostListDB.findOneAsync({ _id: id })
// 如果存在原认证方式则保存下来
if (!record[authType] && oldRecord[authType]) {
record[authType] = oldRecord[authType]
if (!updateRecord[authType] && oldRecord[authType]) {
updateRecord[authType] = oldRecord[authType]
} else {
const clearTempKey = await RSADecryptSync(tempKey)
const clearTempKey = await RSADecryptAsync(tempKey)
// console.log('clearTempKey:', clearTempKey)
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
const clearSSHKey = await AESDecryptAsync(updateRecord[authType], clearTempKey)
// console.log(`${ authType }原密文: `, clearSSHKey)
record[authType] = await AESEncryptSync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
updateRecord[authType] = await AESEncryptAsync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, updateRecord[authType])
}
hostList.splice(idx, 1, record)
await writeHostList(hostList)
res.success()
await hostListDB.updateAsync({ _id: oldRecord._id }, updateRecord)
res.success({ msg: '修改成功' })
}
async function removeHost({
res, request
}) {
async function removeHost({ res, request }) {
let { body: { ids } } = request
let hostList = await readHostList()
if (!Array.isArray(ids)) return res.fail({ msg: '参数错误' })
hostList = hostList.filter(({ _id }) => !ids.includes(_id))
await writeHostList(hostList)
res.success({ data: '已移除' })
const numRemoved = await hostListDB.removeAsync({ _id: { $in: ids } }, { multi: true })
// console.log('numRemoved: ', numRemoved)
res.success({ data: `已移除,数量: ${ numRemoved }` })
}
async function importHost({
res, request
}) {
async function importHost({ res, request }) {
let { body: { importHost, isEasyNodeJson = false } } = request
if (!Array.isArray(importHost)) return res.fail({ msg: '参数错误' })
let hostList = await readHostList()
let hostList = await hostListDB.findAsync({})
// 考虑到批量导入可能会重复太多,先过滤已存在的host:port
let hostListSet = new Set(hostList.map(({ host, port }) => `${ host }:${ port }`))
let newHostList = importHost.filter(({ host, port }) => !hostListSet.has(`${ host }:${ port }`))
@ -157,8 +141,7 @@ async function importHost({
return Object.assign(item, { ...extraFiels })
})
}
hostList.push(...newHostList)
await writeHostList(hostList)
await hostListDB.insertAsync(newHostList)
res.success({ data: { len: newHostList.length } })
}

View File

@ -1,5 +1,7 @@
const { readSSHRecord, writeSSHRecord, readHostList, writeHostList } = require('../utils/storage')
const { RSADecryptSync, AESEncryptSync, AESDecryptSync } = require('../utils/encrypt')
const { readSSHRecord, writeSSHRecord } = require('../utils/storage')
const { RSADecryptAsync, AESEncryptAsync, AESDecryptAsync } = require('../utils/encrypt')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
async function getSSHList({ res }) {
// console.log('get-host-list')
@ -19,11 +21,11 @@ const addSSH = async ({ res, request }) => {
let sshRecord = await readSSHRecord()
if (sshRecord.some(item => item.name === name)) return res.fail({ data: false, msg: '已存在同名凭证' })
const clearTempKey = await RSADecryptSync(tempKey)
const clearTempKey = await RSADecryptAsync(tempKey)
console.log('clearTempKey:', clearTempKey)
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
const clearSSHKey = await AESDecryptAsync(record[authType], clearTempKey)
// console.log(`${ authType }原密文: `, clearSSHKey)
record[authType] = await AESEncryptSync(clearSSHKey)
record[authType] = await AESEncryptAsync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
sshRecord.push({ ...record, date: Date.now() })
@ -46,11 +48,11 @@ const updateSSH = async ({ res, request }) => {
if (!record[authType] && oldRecord[authType]) {
record[authType] = oldRecord[authType]
} else {
const clearTempKey = await RSADecryptSync(tempKey)
const clearTempKey = await RSADecryptAsync(tempKey)
console.log('clearTempKey:', clearTempKey)
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
const clearSSHKey = await AESDecryptAsync(record[authType], clearTempKey)
// console.log(`${ authType }原密文: `, clearSSHKey)
record[authType] = await AESEncryptSync(clearSSHKey)
record[authType] = await AESEncryptAsync(clearSSHKey)
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
}
record._id = sshRecord[idx]._id
@ -67,12 +69,15 @@ const removeSSH = async ({ res, request }) => {
if (idx === -1) return res.fail({ msg: '凭证不存在' })
sshRecord.splice(idx, 1)
// 将删除的凭证id从host中删除
let hostList = await readHostList()
hostList = hostList.map(item => {
if (item.credential === id) item.credential = ''
return item
})
await writeHostList(hostList)
let hostList = await hostListDB.findAsync({})
if (Array.isArray(hostList) && hostList.length > 0) {
for (let item of hostList) {
if (item.credential === id) {
item.credential = ''
await hostListDB.updateAsync({ _id: item._id }, item)
}
}
}
consola.info('移除凭证:', id)
await writeSSHRecord(sshRecord)
res.success({ data: '移除成功' })
@ -81,7 +86,7 @@ const removeSSH = async ({ res, request }) => {
const getCommand = async ({ res, request }) => {
let { hostId } = request.query
if (!hostId) return res.fail({ data: false, msg: '参数错误' })
let hostInfo = await readHostList()
let hostInfo = await hostListDB.findAsync({})
let record = hostInfo?.find(item => item._id === hostId)
consola.info('查询登录后执行的指令:', hostId)
if (!record) return res.fail({ data: false, msg: 'host not found' }) // host不存在

View File

@ -2,7 +2,7 @@ const jwt = require('jsonwebtoken')
const axios = require('axios')
const { asyncSendNotice } = require('../utils/notify')
const { readKey, writeKey, writeLog } = require('../utils/storage')
const { RSADecryptSync, AESEncryptSync, SHA1Encrypt } = require('../utils/encrypt')
const { RSADecryptAsync, AESEncryptAsync, SHA1Encrypt } = require('../utils/encrypt')
const { getNetIPInfo } = require('../utils/tools')
const getpublicKey = async ({ res }) => {
@ -52,7 +52,7 @@ const login = async ({ res, request }) => {
// 登录流程
try {
// console.log('ciphertext', ciphertext)
let loginPwd = await RSADecryptSync(ciphertext)
let loginPwd = await RSADecryptAsync(ciphertext)
// console.log('Decrypt解密password:', loginPwd)
let { user, pwd } = await readKey()
if (loginName === user && loginPwd === 'admin' && pwd === 'admin') {
@ -76,7 +76,7 @@ const beforeLoginHandler = async (clientIp, jwtExpires) => {
// 生产token
let { commonKey } = await readKey()
let token = jwt.sign({ date: Date.now() }, commonKey, { expiresIn: jwtExpires }) // 生成token
token = await AESEncryptSync(token) // 对称加密token后再传输给前端
token = await AESEncryptAsync(token) // 对称加密token后再传输给前端
// 记录客户端登录IP(用于判断是否异地且只保留最近10条)
const clientIPInfo = await getNetIPInfo(clientIp)
@ -92,13 +92,13 @@ const beforeLoginHandler = async (clientIp, jwtExpires) => {
const updatePwd = async ({ res, request }) => {
let { body: { oldLoginName, oldPwd, newLoginName, newPwd } } = request
let rsaOldPwd = await RSADecryptSync(oldPwd)
let rsaOldPwd = await RSADecryptAsync(oldPwd)
oldPwd = rsaOldPwd === 'admin' ? 'admin' : SHA1Encrypt(rsaOldPwd)
let keyObj = await readKey()
let { user, pwd } = keyObj
if (oldLoginName !== user || oldPwd !== pwd) return res.fail({ data: false, msg: '原用户名或密码校验失败' })
// 旧密钥校验通过,加密保存新密码
newPwd = await RSADecryptSync(newPwd) === 'admin' ? 'admin' : SHA1Encrypt(await RSADecryptSync(newPwd))
newPwd = await RSADecryptAsync(newPwd) === 'admin' ? 'admin' : SHA1Encrypt(await RSADecryptAsync(newPwd))
keyObj.user = newLoginName
keyObj.pwd = newPwd
await writeKey(keyObj)

View File

@ -1,50 +0,0 @@
db目录初始化后自动生成
**host.db**
> 存储服务器基本信息
**key.db**
> 用于加密的密钥相关
**credentials.db**
> ssh密钥记录(加密存储)
**email.db**
> 邮件配置
- port: 587 --> secure: false
```db
// Gmail调试不通过, 暂缓
{
"name": "Google邮箱",
"target": "google",
"host": "smtp.gmail.com",
"port": 465,
"secure": true,
"tls": {
"rejectUnauthorized": false
}
}
```
**notify.db**
> 通知配置
**group.db**
> 服务器分组配置
**scripts.db**
> 脚本库
**onekey.db**
> 批量指令记录

View File

@ -1,7 +1,7 @@
const NodeRSA = require('node-rsa')
const { readKey, writeKey } = require('./utils/storage')
const { randomStr } = require('./utils/tools')
const { AESEncryptSync } = require('./utils/encrypt')
const { AESEncryptAsync } = require('./utils/encrypt')
// 初始化公私钥, 供登录、保存ssh密钥/密码等加解密
async function initRsa() {
@ -11,7 +11,7 @@ async function initRsa() {
key.setOptions({ encryptionScheme: 'pkcs1', environment: 'browser' })
let privateKey = key.exportKey('pkcs1-private-pem')
let publicKey = key.exportKey('pkcs8-public-pem')
keyObj.privateKey = await AESEncryptSync(privateKey) // 加密私钥
keyObj.privateKey = await AESEncryptAsync(privateKey) // 加密私钥
keyObj.publicKey = publicKey // 公开公钥
await writeKey(keyObj)
consola.info('Task: 已生成新的非对称加密公私钥')

View File

@ -1,11 +1,12 @@
const schedule = require('node-schedule')
const { asyncSendNotice } = require('../utils/notify')
const { readHostList } = require('../utils/storage')
const { formatTimestamp } = require('../utils/tools')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
const expiredNotifyJob = async () => {
consola.info('=====开始检测服务器到期时间=====', new Date())
const hostList = await readHostList()
const hostList = await hostListDB.findAsync({})
for (const item of hostList) {
if (!item.expiredNotify) continue
const { host, name, expired, consoleUrl } = item

View File

@ -1,15 +1,16 @@
const { Server: ServerIO } = require('socket.io')
const { io: ClientIO } = require('socket.io-client')
const { readHostList } = require('../utils/storage')
const { defaultClientPort } = require('../config')
const { verifyAuthSync } = require('../utils/verify-auth')
const { isAllowedIp } = require('../utils/tools')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
let clientSockets = []
let clientsData = {}
async function getClientsInfo(clientSockets) {
let hostList = await readHostList()
let hostList = await hostListDB.findAsync({})
clientSockets.forEach((clientItem) => {
// 被删除的客户端断开连接
if (!hostList.some(item => item.host === clientItem.host)) clientItem.close && clientItem.close()

View File

@ -1,11 +1,13 @@
const { Server } = require('socket.io')
const { Client: SSHClient } = require('ssh2')
const { asyncSendNotice } = require('../utils/notify')
const { readSSHRecord, readHostList, writeOneKeyRecord } = require('../utils/storage')
const { readSSHRecord, writeOneKeyRecord } = require('../utils/storage')
const { verifyAuthSync } = require('../utils/verify-auth')
const { shellThrottle } = require('../utils/tools')
const { AESDecryptSync } = require('../utils/encrypt')
const { AESDecryptAsync } = require('../utils/encrypt')
const { isAllowedIp } = require('../utils/tools')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
const execStatusEnum = {
connecting: '连接中',
@ -129,7 +131,7 @@ module.exports = (httpServer) => {
console.log('hostIds:', hostIds)
// console.log('token:', token)
console.log('command:', command)
const hostList = await readHostList()
const hostList = await hostListDB.findAsync({})
const targetHostsInfo = hostList.filter(item => hostIds.some(id => item._id === id)) || {}
// console.log('targetHostsInfo:', targetHostsInfo)
if (!targetHostsInfo.length) return socket.emit('create_fail', `未找到【${ hostIds }】服务器信息`)
@ -145,13 +147,13 @@ module.exports = (httpServer) => {
execResult.push(curRes)
try {
if (authType === 'credential') {
let credentialId = await AESDecryptSync(hostInfo['credential'])
let credentialId = await AESDecryptAsync(hostInfo['credential'])
const sshRecordList = await readSSHRecord()
const sshRecord = sshRecordList.find(item => item._id === credentialId)
authInfo.authType = sshRecord.authType
authInfo[authInfo.authType] = await AESDecryptSync(sshRecord[authInfo.authType])
authInfo[authInfo.authType] = await AESDecryptAsync(sshRecord[authInfo.authType])
} else {
authInfo[authType] = await AESDecryptSync(hostInfo[authType])
authInfo[authType] = await AESDecryptAsync(hostInfo[authType])
}
consola.info('准备连接终端执行一次性指令:', host)
consola.log('连接信息', { username, port, authType })

View File

@ -5,9 +5,11 @@ const CryptoJS = require('crypto-js')
const { Server } = require('socket.io')
const { sftpCacheDir } = require('../config')
const { verifyAuthSync } = require('../utils/verify-auth')
const { AESDecryptSync } = require('../utils/encrypt')
const { readSSHRecord, readHostList } = require('../utils/storage')
const { AESDecryptAsync } = require('../utils/encrypt')
const { readSSHRecord } = require('../utils/storage')
const { isAllowedIp } = require('../utils/tools')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
// 读取切片
const pipeStream = (path, writeStream) => {
@ -230,7 +232,7 @@ module.exports = (httpServer) => {
return
}
const hostList = await readHostList()
const hostList = await hostListDB.findAsync({})
const targetHostInfo = hostList.find(item => item.host === ip) || {}
let { authType, host, port, username } = targetHostInfo
if (!host) return socket.emit('create_fail', `查找【${ ip }】凭证信息失败`)
@ -238,16 +240,16 @@ module.exports = (httpServer) => {
// 解密放到try里面防止报错【commonKey必须配对, 否则需要重新添加服务器密钥】
if (authType === 'credential') {
let credentialId = await AESDecryptSync(targetHostInfo[authType])
let credentialId = await AESDecryptAsync(targetHostInfo[authType])
const sshRecordList = await readSSHRecord()
const sshRecord = sshRecordList.find(item => item._id === credentialId)
authInfo.authType = sshRecord.authType
authInfo[authInfo.authType] = await AESDecryptSync(sshRecord[authInfo.authType])
authInfo[authInfo.authType] = await AESDecryptAsync(sshRecord[authInfo.authType])
} else {
authInfo[authType] = await AESDecryptSync(targetHostInfo[authType])
authInfo[authType] = await AESDecryptAsync(targetHostInfo[authType])
}
consola.info('准备连接Sftp面板', host)
targetHostInfo[targetHostInfo.authType] = await AESDecryptSync(targetHostInfo[targetHostInfo.authType])
targetHostInfo[targetHostInfo.authType] = await AESDecryptAsync(targetHostInfo[targetHostInfo.authType])
consola.log('连接信息', { username, port, authType })
sftpClient

View File

@ -1,10 +1,12 @@
const { Server } = require('socket.io')
const { Client: SSHClient } = require('ssh2')
const { verifyAuthSync } = require('../utils/verify-auth')
const { AESDecryptSync } = require('../utils/encrypt')
const { readSSHRecord, readHostList } = require('../utils/storage')
const { AESDecryptAsync } = require('../utils/encrypt')
const { readSSHRecord } = require('../utils/storage')
const { asyncSendNotice } = require('../utils/notify')
const { isAllowedIp, ping } = require('../utils/tools')
const { HostListDB } = require('../utils/db-class')
const hostListDB = new HostListDB().getInstance()
function createInteractiveShell(socket, sshClient) {
return new Promise((resolve) => {
@ -51,7 +53,7 @@ function createInteractiveShell(socket, sshClient) {
async function createTerminal(hostId, socket, sshClient) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve) => {
const hostList = await readHostList()
const hostList = await hostListDB.findAsync({})
const targetHostInfo = hostList.find(item => item._id === hostId) || {}
let { authType, host, port, username, name } = targetHostInfo
if (!host) return socket.emit('create_fail', `查找hostId【${ hostId }】凭证信息失败`)
@ -60,16 +62,16 @@ async function createTerminal(hostId, socket, sshClient) {
try {
// 解密放到try里面防止报错【commonKey必须配对, 否则需要重新添加服务器密钥】
if (authType === 'credential') {
let credentialId = await AESDecryptSync(targetHostInfo[authType])
let credentialId = await AESDecryptAsync(targetHostInfo[authType])
const sshRecordList = await readSSHRecord()
const sshRecord = sshRecordList.find(item => item._id === credentialId)
authInfo.authType = sshRecord.authType
authInfo[authInfo.authType] = await AESDecryptSync(sshRecord[authInfo.authType])
authInfo[authInfo.authType] = await AESDecryptAsync(sshRecord[authInfo.authType])
} else {
authInfo[authType] = await AESDecryptSync(targetHostInfo[authType])
authInfo[authType] = await AESDecryptAsync(targetHostInfo[authType])
}
consola.info('准备连接终端:', host)
// targetHostInfo[targetHostInfo.authType] = await AESDecryptSync(targetHostInfo[targetHostInfo.authType])
// targetHostInfo[targetHostInfo.authType] = await AESDecryptAsync(targetHostInfo[targetHostInfo.authType])
consola.log('连接信息', { username, port, authType })
sshClient
.on('ready', async() => {

View File

@ -15,6 +15,7 @@ module.exports.KeyDB = class KeyDB {
constructor() {
if (!KeyDB.instance) {
KeyDB.instance = new Datastore({ filename: keyDBPath, autoload: true })
KeyDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -26,6 +27,7 @@ module.exports.HostListDB = class HostListDB {
constructor() {
if (!HostListDB.instance) {
HostListDB.instance = new Datastore({ filename: hostListDBPath, autoload: true })
HostListDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -37,6 +39,7 @@ module.exports.SshRecordDB = class SshRecordDB {
constructor() {
if (!SshRecordDB.instance) {
SshRecordDB.instance = new Datastore({ filename: credentialsDBPath, autoload: true })
SshRecordDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -48,6 +51,8 @@ module.exports.NotifyDB = class NotifyDB {
constructor() {
if (!NotifyDB.instance) {
NotifyDB.instance = new Datastore({ filename: notifyDBPath, autoload: true })
NotifyDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -59,6 +64,7 @@ module.exports.NotifyConfigDB = class NotifyConfigDB {
constructor() {
if (!NotifyConfigDB.instance) {
NotifyConfigDB.instance = new Datastore({ filename: notifyConfigDBPath, autoload: true })
NotifyConfigDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -70,6 +76,7 @@ module.exports.GroupDB = class GroupDB {
constructor() {
if (!GroupDB.instance) {
GroupDB.instance = new Datastore({ filename: groupConfDBPath, autoload: true })
GroupDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -81,6 +88,7 @@ module.exports.ScriptsDB = class ScriptsDB {
constructor() {
if (!ScriptsDB.instance) {
ScriptsDB.instance = new Datastore({ filename: scriptsDBPath, autoload: true })
ScriptsDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -92,6 +100,7 @@ module.exports.OnekeyDB = class OnekeyDB {
constructor() {
if (!OnekeyDB.instance) {
OnekeyDB.instance = new Datastore({ filename: onekeyDBPath, autoload: true })
OnekeyDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {
@ -103,6 +112,7 @@ module.exports.LogDB = class LogDB {
constructor() {
if (!LogDB.instance) {
LogDB.instance = new Datastore({ filename: logDBPath, autoload: true })
LogDB.instance.setAutocompactionInterval(5000)
}
}
getInstance() {

View File

@ -4,10 +4,10 @@ const NodeRSA = require('node-rsa')
const { readKey } = require('./storage.js')
// rsa非对称 私钥解密
const RSADecryptSync = async (ciphertext) => {
const RSADecryptAsync = async (ciphertext) => {
if (!ciphertext) return
let { privateKey } = await readKey()
privateKey = await AESDecryptSync(privateKey) // 先解密私钥
privateKey = await AESDecryptAsync(privateKey) // 先解密私钥
const rsakey = new NodeRSA(privateKey)
rsakey.setOptions({ encryptionScheme: 'pkcs1', environment: 'browser' }) // Must Set It When Frontend Use jsencrypt
const plaintext = rsakey.decrypt(ciphertext, 'utf8')
@ -15,7 +15,7 @@ const RSADecryptSync = async (ciphertext) => {
}
// aes对称 加密(default commonKey)
const AESEncryptSync = async (text, key) => {
const AESEncryptAsync = async (text, key) => {
if (!text) return
let { commonKey } = await readKey()
let ciphertext = CryptoJS.AES.encrypt(text, key || commonKey).toString()
@ -23,7 +23,7 @@ const AESEncryptSync = async (text, key) => {
}
// aes对称 解密(default commonKey)
const AESDecryptSync = async (ciphertext, key) => {
const AESDecryptAsync = async (ciphertext, key) => {
if (!ciphertext) return
let { commonKey } = await readKey()
let bytes = CryptoJS.AES.decrypt(ciphertext, key || commonKey)
@ -37,8 +37,8 @@ const SHA1Encrypt = (clearText) => {
}
module.exports = {
RSADecryptSync,
AESEncryptSync,
AESDecryptSync,
RSADecryptAsync,
AESEncryptAsync,
AESDecryptAsync,
SHA1Encrypt
}

View File

@ -64,43 +64,43 @@ const writeSSHRecord = async (record = []) => {
})
}
const readHostList = async () => {
return new Promise((resolve, reject) => {
const hostListDB = new HostListDB().getInstance()
hostListDB.find({}, (err, docs) => {
if (err) {
consola.error('读取host-list-db错误:', err)
reject(err)
} else {
resolve(docs)
}
})
})
}
// const readHostList = async () => {
// return new Promise((resolve, reject) => {
// const hostListDB = new HostListDB().getInstance()
// hostListDB.find({}, (err, docs) => {
// if (err) {
// consola.error('读取host-list-db错误:', err)
// reject(err)
// } else {
// resolve(docs)
// }
// })
// })
// }
const writeHostList = async (record = []) => {
return new Promise((resolve, reject) => {
const hostListDB = new HostListDB().getInstance()
hostListDB.remove({}, { multi: true }, (err) => {
if (err) {
consola.error('清空HostList出错:', err)
reject(err)
} else {
hostListDB.compactDatafile()
// 插入新的数据列表
hostListDB.insert(record, (err, newDocs) => {
if (err) {
consola.error('写入新的HostList出错:', err)
reject(err)
} else {
hostListDB.compactDatafile()
resolve(newDocs)
}
})
}
})
})
}
// const writeHostList = async (record = []) => {
// return new Promise((resolve, reject) => {
// const hostListDB = new HostListDB().getInstance()
// hostListDB.remove({}, { multi: true }, (err) => {
// if (err) {
// consola.error('清空HostList出错:', err)
// reject(err)
// } else {
// hostListDB.compactDatafile()
// // 插入新的数据列表
// hostListDB.insert(record, (err, newDocs) => {
// if (err) {
// consola.error('写入新的HostList出错:', err)
// reject(err)
// } else {
// hostListDB.compactDatafile()
// resolve(newDocs)
// }
// })
// }
// })
// })
// }
const readNotifyConfig = async () => {
return new Promise((resolve, reject) => {
@ -329,7 +329,7 @@ const writeLog = async (records = {}) => {
module.exports = {
readSSHRecord, writeSSHRecord,
readHostList, writeHostList,
// readHostList, writeHostList,
readKey, writeKey,
readNotifyList, writeNotifyList,
readNotifyConfig, writeNotifyConfig, getNotifySwByType,

View File

@ -1,5 +1,5 @@
const { AESDecryptSync } = require('./encrypt')
const { AESDecryptAsync } = require('./encrypt')
const { readKey } = require('./storage')
const jwt = require('jsonwebtoken')
@ -13,7 +13,7 @@ const enumLoginCode = {
const verifyAuthSync = async (token, clientIp) => {
consola.info('verifyAuthSync IP', clientIp)
try {
token = await AESDecryptSync(token) // 先aes解密
token = await AESDecryptAsync(token) // 先aes解密
const { commonKey } = await readKey()
const { exp } = jwt.verify(token, commonKey)
if (Date.now() > (exp * 1000)) return { code: -1, msg: 'token expires' } // 过期

View File

@ -356,7 +356,7 @@ const setDefaultData = () => {
const setBatchDefaultData = () => {
if (!isBatchModify.value) return
Object.assign(hostForm.value, { ...formField }, { group: '', port: '', username: '', authType: '' })
Object.assign(hostForm.value, { ...formField }, { group: '', port: '', username: '', authType: '', clientPort: '' })
}
const handleOpen = async () => {
setDefaultData()
@ -416,7 +416,7 @@ const handleSave = () => {
// eslint-disable-next-line
let updateFileData = Object.fromEntries(Object.entries(formData).filter(([key, value]) => Boolean(value))) //
if (Object.keys(updateFileData).length === 0) return $message.warning('没有任何修改')
// console.log(updateFileData)
console.log(updateFileData)
let newHosts = batchHosts.value
.map(item => ({ ...item, ...updateFileData }))
.map(item => {

View File

@ -168,7 +168,6 @@ let handleBatchOnekey = async () => {
let handleBatchExport = () => {
collectSelectHost()
if (!selectHosts.value.length) return $message.warning('请选择要批量操作的实例')
console.log(selectHosts.value)
let exportData = JSON.parse(JSON.stringify(selectHosts.value))
exportData = exportData.map(item => {
delete item.monitorData