♻️ 重构本地数据库-host模块
This commit is contained in:
parent
a72ab84cee
commit
5724ede172
@ -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 }) {
|
async function getGroupList({ res }) {
|
||||||
let data = await readGroupList()
|
let data = await readGroupList()
|
||||||
@ -41,16 +44,17 @@ const removeGroup = async ({ res, request }) => {
|
|||||||
if (idx === -1) return res.fail({ msg: '分组不存在' })
|
if (idx === -1) return res.fail({ msg: '分组不存在' })
|
||||||
|
|
||||||
// 移除分组将所有该分组下host分配到default中去
|
// 移除分组将所有该分组下host分配到default中去
|
||||||
let hostList = await readHostList()
|
let hostList = await hostListDB.findAsync({})
|
||||||
hostList = hostList?.map((item) => {
|
if (Array.isArray(hostList) && hostList.length > 0) {
|
||||||
if (item.group === groupList[idx]._id) item.group = 'default'
|
for (let item of hostList) {
|
||||||
return item
|
if (item.group === groupList[idx]._id) {
|
||||||
})
|
item.group = 'default'
|
||||||
await writeHostList(hostList)
|
await hostListDB.updateAsync({ _id: item._id }, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
groupList.splice(idx, 1)
|
groupList.splice(idx, 1)
|
||||||
await writeGroupList(groupList)
|
await writeGroupList(groupList)
|
||||||
|
|
||||||
res.success({ data: '移除成功' })
|
res.success({ data: '移除成功' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
const { readHostList, writeHostList } = require('../utils/storage')
|
const { RSADecryptAsync, AESEncryptAsync, AESDecryptAsync } = require('../utils/encrypt')
|
||||||
const { RSADecryptSync, AESEncryptSync, AESDecryptSync } = require('../utils/encrypt')
|
const { HostListDB } = require('../utils/db-class')
|
||||||
|
const hostListDB = new HostListDB().getInstance()
|
||||||
|
|
||||||
async function getHostList({ res }) {
|
async function getHostList({ res }) {
|
||||||
// console.log('get-host-list')
|
// 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))
|
data?.sort((a, b) => Number(b.index || 0) - Number(a.index || 0))
|
||||||
for (const item of data) {
|
for (const item of data) {
|
||||||
try {
|
try {
|
||||||
let { username, port, authType, _id: id, credential } = item
|
let { username, port, authType, _id: id, credential } = item
|
||||||
// console.log('解密凭证title: ', credential)
|
// console.log('解密凭证title: ', credential)
|
||||||
if (credential) credential = await AESDecryptSync(credential)
|
if (credential) credential = await AESDecryptAsync(credential)
|
||||||
const isConfig = Boolean(username && port && (item[authType]))
|
const isConfig = Boolean(username && port && (item[authType]))
|
||||||
Object.assign(item, { id, isConfig, password: '', privateKey: '', credential })
|
Object.assign(item, { id, isConfig, password: '', privateKey: '', credential })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -19,9 +20,7 @@ async function getHostList({ res }) {
|
|||||||
res.success({ data })
|
res.success({ data })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addHost({
|
async function addHost({ res, request }) {
|
||||||
res, request
|
|
||||||
}) {
|
|
||||||
let {
|
let {
|
||||||
body: {
|
body: {
|
||||||
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
|
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
|
||||||
@ -30,21 +29,19 @@ async function addHost({
|
|||||||
} = request
|
} = request
|
||||||
// console.log(request)
|
// console.log(request)
|
||||||
if (!host || !name) return res.fail({ msg: 'missing params: name or host' })
|
if (!host || !name) return res.fail({ msg: 'missing params: name or host' })
|
||||||
let hostList = await readHostList()
|
|
||||||
let record = {
|
let record = {
|
||||||
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
|
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
|
||||||
port: newPort, clientPort, username, authType, password, privateKey, credential, command
|
port: newPort, clientPort, username, authType, password, privateKey, credential, command
|
||||||
}
|
}
|
||||||
if (record[authType]) {
|
if (record[authType]) {
|
||||||
const clearTempKey = await RSADecryptSync(tempKey)
|
const clearTempKey = await RSADecryptAsync(tempKey)
|
||||||
console.log('clearTempKey:', clearTempKey)
|
console.log('clearTempKey:', clearTempKey)
|
||||||
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
|
const clearSSHKey = await AESDecryptAsync(record[authType], clearTempKey)
|
||||||
console.log(`${ authType }原密文: `, clearSSHKey)
|
console.log(`${ authType }原密文: `, clearSSHKey)
|
||||||
record[authType] = await AESEncryptSync(clearSSHKey)
|
record[authType] = await AESEncryptAsync(clearSSHKey)
|
||||||
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
||||||
}
|
}
|
||||||
hostList.push(record)
|
await hostListDB.insertAsync(record)
|
||||||
await writeHostList(hostList)
|
|
||||||
res.success()
|
res.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,78 +57,65 @@ async function updateHost({ res, request }) {
|
|||||||
let isBatch = Array.isArray(hosts)
|
let isBatch = Array.isArray(hosts)
|
||||||
if (isBatch) {
|
if (isBatch) {
|
||||||
if (!hosts.length) return res.fail({ msg: 'hosts为空' })
|
if (!hosts.length) return res.fail({ msg: 'hosts为空' })
|
||||||
let hostList = await readHostList()
|
let hostList = await hostListDB.findAsync({})
|
||||||
let newHostList = []
|
|
||||||
for (let oldRecord of hostList) {
|
for (let oldRecord of hostList) {
|
||||||
let record = hosts.find(item => item.id === oldRecord._id)
|
let target = hosts.find(item => item.id === oldRecord._id)
|
||||||
if (!record) {
|
if (!target) continue
|
||||||
newHostList.push(oldRecord)
|
let { authType } = target
|
||||||
continue
|
|
||||||
}
|
|
||||||
let { authType } = record
|
|
||||||
// 如果存在原认证方式则保存下来
|
// 如果存在原认证方式则保存下来
|
||||||
if (!record[authType] && oldRecord[authType]) {
|
if (!target[authType]) {
|
||||||
record[authType] = oldRecord[authType]
|
target[authType] = oldRecord[authType]
|
||||||
} else {
|
} else {
|
||||||
const clearTempKey = await RSADecryptSync(record.tempKey)
|
const clearTempKey = await RSADecryptAsync(target.tempKey)
|
||||||
// console.log('批量解密tempKey:', clearTempKey)
|
// console.log('批量解密tempKey:', clearTempKey)
|
||||||
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
|
const clearSSHKey = await AESDecryptAsync(target[authType], clearTempKey)
|
||||||
// console.log(`${ authType }原密文: `, clearSSHKey)
|
// console.log(`${ authType }原密文: `, clearSSHKey)
|
||||||
record[authType] = await AESEncryptSync(clearSSHKey)
|
target[authType] = await AESEncryptAsync(clearSSHKey)
|
||||||
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
// console.log(`${ authType }__commonKey加密存储: `, target[authType])
|
||||||
}
|
}
|
||||||
delete oldRecord.monitorData
|
delete target._id
|
||||||
delete record.monitorData
|
delete target.monitorData
|
||||||
newHostList.push(Object.assign(oldRecord, record))
|
delete target.tempKey
|
||||||
|
Object.assign(oldRecord, target)
|
||||||
|
await hostListDB.updateAsync({ _id: oldRecord._id }, oldRecord)
|
||||||
}
|
}
|
||||||
await writeHostList(newHostList)
|
|
||||||
return res.success({ msg: '批量修改成功' })
|
return res.success({ msg: '批量修改成功' })
|
||||||
}
|
}
|
||||||
if (!newHost || !newName || !oldHost) return res.fail({ msg: '参数错误' })
|
if (!newHost || !newName || !oldHost) return res.fail({ msg: '参数错误' })
|
||||||
|
|
||||||
let hostList = await readHostList()
|
let updateRecord = {
|
||||||
if (!hostList.some(({ host }) => host === oldHost)) return res.fail({ msg: `原实例[${ oldHost }]不存在,请尝试添加实例` })
|
|
||||||
|
|
||||||
let record = {
|
|
||||||
name: newName, host: newHost, index, expired, expiredNotify, group, consoleUrl, remark,
|
name: newName, host: newHost, index, expired, expiredNotify, group, consoleUrl, remark,
|
||||||
port, clientPort, username, authType, password, privateKey, credential, command
|
port, clientPort, username, authType, password, privateKey, credential, command
|
||||||
}
|
}
|
||||||
|
|
||||||
let idx = hostList.findIndex(({ _id }) => _id === id)
|
let oldRecord = await hostListDB.findOneAsync({ _id: id })
|
||||||
const oldRecord = hostList[idx]
|
|
||||||
// 如果存在原认证方式则保存下来
|
// 如果存在原认证方式则保存下来
|
||||||
if (!record[authType] && oldRecord[authType]) {
|
if (!updateRecord[authType] && oldRecord[authType]) {
|
||||||
record[authType] = oldRecord[authType]
|
updateRecord[authType] = oldRecord[authType]
|
||||||
} else {
|
} else {
|
||||||
const clearTempKey = await RSADecryptSync(tempKey)
|
const clearTempKey = await RSADecryptAsync(tempKey)
|
||||||
// console.log('clearTempKey:', clearTempKey)
|
// console.log('clearTempKey:', clearTempKey)
|
||||||
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
|
const clearSSHKey = await AESDecryptAsync(updateRecord[authType], clearTempKey)
|
||||||
// console.log(`${ authType }原密文: `, clearSSHKey)
|
// console.log(`${ authType }原密文: `, clearSSHKey)
|
||||||
record[authType] = await AESEncryptSync(clearSSHKey)
|
updateRecord[authType] = await AESEncryptAsync(clearSSHKey)
|
||||||
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
// console.log(`${ authType }__commonKey加密存储: `, updateRecord[authType])
|
||||||
}
|
}
|
||||||
hostList.splice(idx, 1, record)
|
await hostListDB.updateAsync({ _id: oldRecord._id }, updateRecord)
|
||||||
await writeHostList(hostList)
|
res.success({ msg: '修改成功' })
|
||||||
res.success()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeHost({
|
async function removeHost({ res, request }) {
|
||||||
res, request
|
|
||||||
}) {
|
|
||||||
let { body: { ids } } = request
|
let { body: { ids } } = request
|
||||||
let hostList = await readHostList()
|
|
||||||
if (!Array.isArray(ids)) return res.fail({ msg: '参数错误' })
|
if (!Array.isArray(ids)) return res.fail({ msg: '参数错误' })
|
||||||
hostList = hostList.filter(({ _id }) => !ids.includes(_id))
|
const numRemoved = await hostListDB.removeAsync({ _id: { $in: ids } }, { multi: true })
|
||||||
await writeHostList(hostList)
|
// console.log('numRemoved: ', numRemoved)
|
||||||
res.success({ data: '已移除' })
|
res.success({ data: `已移除,数量: ${ numRemoved }` })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importHost({
|
async function importHost({ res, request }) {
|
||||||
res, request
|
|
||||||
}) {
|
|
||||||
let { body: { importHost, isEasyNodeJson = false } } = request
|
let { body: { importHost, isEasyNodeJson = false } } = request
|
||||||
if (!Array.isArray(importHost)) return res.fail({ msg: '参数错误' })
|
if (!Array.isArray(importHost)) return res.fail({ msg: '参数错误' })
|
||||||
let hostList = await readHostList()
|
let hostList = await hostListDB.findAsync({})
|
||||||
// 考虑到批量导入可能会重复太多,先过滤已存在的host:port
|
// 考虑到批量导入可能会重复太多,先过滤已存在的host:port
|
||||||
let hostListSet = new Set(hostList.map(({ host, port }) => `${ host }:${ port }`))
|
let hostListSet = new Set(hostList.map(({ host, port }) => `${ host }:${ port }`))
|
||||||
let newHostList = importHost.filter(({ host, port }) => !hostListSet.has(`${ host }:${ port }`))
|
let newHostList = importHost.filter(({ host, port }) => !hostListSet.has(`${ host }:${ port }`))
|
||||||
@ -157,8 +141,7 @@ async function importHost({
|
|||||||
return Object.assign(item, { ...extraFiels })
|
return Object.assign(item, { ...extraFiels })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
hostList.push(...newHostList)
|
await hostListDB.insertAsync(newHostList)
|
||||||
await writeHostList(hostList)
|
|
||||||
res.success({ data: { len: newHostList.length } })
|
res.success({ data: { len: newHostList.length } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
const { readSSHRecord, writeSSHRecord, readHostList, writeHostList } = require('../utils/storage')
|
const { readSSHRecord, writeSSHRecord } = 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 getSSHList({ res }) {
|
async function getSSHList({ res }) {
|
||||||
// console.log('get-host-list')
|
// console.log('get-host-list')
|
||||||
@ -19,11 +21,11 @@ const addSSH = async ({ res, request }) => {
|
|||||||
let sshRecord = await readSSHRecord()
|
let sshRecord = await readSSHRecord()
|
||||||
if (sshRecord.some(item => item.name === name)) return res.fail({ data: false, msg: '已存在同名凭证' })
|
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)
|
console.log('clearTempKey:', clearTempKey)
|
||||||
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
|
const clearSSHKey = await AESDecryptAsync(record[authType], clearTempKey)
|
||||||
// console.log(`${ authType }原密文: `, clearSSHKey)
|
// console.log(`${ authType }原密文: `, clearSSHKey)
|
||||||
record[authType] = await AESEncryptSync(clearSSHKey)
|
record[authType] = await AESEncryptAsync(clearSSHKey)
|
||||||
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
||||||
|
|
||||||
sshRecord.push({ ...record, date: Date.now() })
|
sshRecord.push({ ...record, date: Date.now() })
|
||||||
@ -46,11 +48,11 @@ const updateSSH = async ({ res, request }) => {
|
|||||||
if (!record[authType] && oldRecord[authType]) {
|
if (!record[authType] && oldRecord[authType]) {
|
||||||
record[authType] = oldRecord[authType]
|
record[authType] = oldRecord[authType]
|
||||||
} else {
|
} else {
|
||||||
const clearTempKey = await RSADecryptSync(tempKey)
|
const clearTempKey = await RSADecryptAsync(tempKey)
|
||||||
console.log('clearTempKey:', clearTempKey)
|
console.log('clearTempKey:', clearTempKey)
|
||||||
const clearSSHKey = await AESDecryptSync(record[authType], clearTempKey)
|
const clearSSHKey = await AESDecryptAsync(record[authType], clearTempKey)
|
||||||
// console.log(`${ authType }原密文: `, clearSSHKey)
|
// console.log(`${ authType }原密文: `, clearSSHKey)
|
||||||
record[authType] = await AESEncryptSync(clearSSHKey)
|
record[authType] = await AESEncryptAsync(clearSSHKey)
|
||||||
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
||||||
}
|
}
|
||||||
record._id = sshRecord[idx]._id
|
record._id = sshRecord[idx]._id
|
||||||
@ -67,12 +69,15 @@ const removeSSH = async ({ res, request }) => {
|
|||||||
if (idx === -1) return res.fail({ msg: '凭证不存在' })
|
if (idx === -1) return res.fail({ msg: '凭证不存在' })
|
||||||
sshRecord.splice(idx, 1)
|
sshRecord.splice(idx, 1)
|
||||||
// 将删除的凭证id从host中删除
|
// 将删除的凭证id从host中删除
|
||||||
let hostList = await readHostList()
|
let hostList = await hostListDB.findAsync({})
|
||||||
hostList = hostList.map(item => {
|
if (Array.isArray(hostList) && hostList.length > 0) {
|
||||||
if (item.credential === id) item.credential = ''
|
for (let item of hostList) {
|
||||||
return item
|
if (item.credential === id) {
|
||||||
})
|
item.credential = ''
|
||||||
await writeHostList(hostList)
|
await hostListDB.updateAsync({ _id: item._id }, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
consola.info('移除凭证:', id)
|
consola.info('移除凭证:', id)
|
||||||
await writeSSHRecord(sshRecord)
|
await writeSSHRecord(sshRecord)
|
||||||
res.success({ data: '移除成功' })
|
res.success({ data: '移除成功' })
|
||||||
@ -81,7 +86,7 @@ const removeSSH = async ({ res, request }) => {
|
|||||||
const getCommand = async ({ res, request }) => {
|
const getCommand = async ({ res, request }) => {
|
||||||
let { hostId } = request.query
|
let { hostId } = request.query
|
||||||
if (!hostId) return res.fail({ data: false, msg: '参数错误' })
|
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)
|
let record = hostInfo?.find(item => item._id === hostId)
|
||||||
consola.info('查询登录后执行的指令:', hostId)
|
consola.info('查询登录后执行的指令:', hostId)
|
||||||
if (!record) return res.fail({ data: false, msg: 'host not found' }) // host不存在
|
if (!record) return res.fail({ data: false, msg: 'host not found' }) // host不存在
|
||||||
|
@ -2,7 +2,7 @@ const jwt = require('jsonwebtoken')
|
|||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
const { asyncSendNotice } = require('../utils/notify')
|
const { asyncSendNotice } = require('../utils/notify')
|
||||||
const { readKey, writeKey, writeLog } = require('../utils/storage')
|
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 { getNetIPInfo } = require('../utils/tools')
|
||||||
|
|
||||||
const getpublicKey = async ({ res }) => {
|
const getpublicKey = async ({ res }) => {
|
||||||
@ -52,7 +52,7 @@ const login = async ({ res, request }) => {
|
|||||||
// 登录流程
|
// 登录流程
|
||||||
try {
|
try {
|
||||||
// console.log('ciphertext', ciphertext)
|
// console.log('ciphertext', ciphertext)
|
||||||
let loginPwd = await RSADecryptSync(ciphertext)
|
let loginPwd = await RSADecryptAsync(ciphertext)
|
||||||
// console.log('Decrypt解密password:', loginPwd)
|
// console.log('Decrypt解密password:', loginPwd)
|
||||||
let { user, pwd } = await readKey()
|
let { user, pwd } = await readKey()
|
||||||
if (loginName === user && loginPwd === 'admin' && pwd === 'admin') {
|
if (loginName === user && loginPwd === 'admin' && pwd === 'admin') {
|
||||||
@ -76,7 +76,7 @@ const beforeLoginHandler = async (clientIp, jwtExpires) => {
|
|||||||
// 生产token
|
// 生产token
|
||||||
let { commonKey } = await readKey()
|
let { commonKey } = await readKey()
|
||||||
let token = jwt.sign({ date: Date.now() }, commonKey, { expiresIn: jwtExpires }) // 生成token
|
let token = jwt.sign({ date: Date.now() }, commonKey, { expiresIn: jwtExpires }) // 生成token
|
||||||
token = await AESEncryptSync(token) // 对称加密token后再传输给前端
|
token = await AESEncryptAsync(token) // 对称加密token后再传输给前端
|
||||||
|
|
||||||
// 记录客户端登录IP(用于判断是否异地且只保留最近10条)
|
// 记录客户端登录IP(用于判断是否异地且只保留最近10条)
|
||||||
const clientIPInfo = await getNetIPInfo(clientIp)
|
const clientIPInfo = await getNetIPInfo(clientIp)
|
||||||
@ -92,13 +92,13 @@ const beforeLoginHandler = async (clientIp, jwtExpires) => {
|
|||||||
|
|
||||||
const updatePwd = async ({ res, request }) => {
|
const updatePwd = async ({ res, request }) => {
|
||||||
let { body: { oldLoginName, oldPwd, newLoginName, newPwd } } = request
|
let { body: { oldLoginName, oldPwd, newLoginName, newPwd } } = request
|
||||||
let rsaOldPwd = await RSADecryptSync(oldPwd)
|
let rsaOldPwd = await RSADecryptAsync(oldPwd)
|
||||||
oldPwd = rsaOldPwd === 'admin' ? 'admin' : SHA1Encrypt(rsaOldPwd)
|
oldPwd = rsaOldPwd === 'admin' ? 'admin' : SHA1Encrypt(rsaOldPwd)
|
||||||
let keyObj = await readKey()
|
let keyObj = await readKey()
|
||||||
let { user, pwd } = keyObj
|
let { user, pwd } = keyObj
|
||||||
if (oldLoginName !== user || oldPwd !== pwd) return res.fail({ data: false, msg: '原用户名或密码校验失败' })
|
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.user = newLoginName
|
||||||
keyObj.pwd = newPwd
|
keyObj.pwd = newPwd
|
||||||
await writeKey(keyObj)
|
await writeKey(keyObj)
|
||||||
|
@ -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**
|
|
||||||
|
|
||||||
> 批量指令记录
|
|
@ -1,7 +1,7 @@
|
|||||||
const NodeRSA = require('node-rsa')
|
const NodeRSA = require('node-rsa')
|
||||||
const { readKey, writeKey } = require('./utils/storage')
|
const { readKey, writeKey } = require('./utils/storage')
|
||||||
const { randomStr } = require('./utils/tools')
|
const { randomStr } = require('./utils/tools')
|
||||||
const { AESEncryptSync } = require('./utils/encrypt')
|
const { AESEncryptAsync } = require('./utils/encrypt')
|
||||||
|
|
||||||
// 初始化公私钥, 供登录、保存ssh密钥/密码等加解密
|
// 初始化公私钥, 供登录、保存ssh密钥/密码等加解密
|
||||||
async function initRsa() {
|
async function initRsa() {
|
||||||
@ -11,7 +11,7 @@ async function initRsa() {
|
|||||||
key.setOptions({ encryptionScheme: 'pkcs1', environment: 'browser' })
|
key.setOptions({ encryptionScheme: 'pkcs1', environment: 'browser' })
|
||||||
let privateKey = key.exportKey('pkcs1-private-pem')
|
let privateKey = key.exportKey('pkcs1-private-pem')
|
||||||
let publicKey = key.exportKey('pkcs8-public-pem')
|
let publicKey = key.exportKey('pkcs8-public-pem')
|
||||||
keyObj.privateKey = await AESEncryptSync(privateKey) // 加密私钥
|
keyObj.privateKey = await AESEncryptAsync(privateKey) // 加密私钥
|
||||||
keyObj.publicKey = publicKey // 公开公钥
|
keyObj.publicKey = publicKey // 公开公钥
|
||||||
await writeKey(keyObj)
|
await writeKey(keyObj)
|
||||||
consola.info('Task: 已生成新的非对称加密公私钥')
|
consola.info('Task: 已生成新的非对称加密公私钥')
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
const schedule = require('node-schedule')
|
const schedule = require('node-schedule')
|
||||||
const { asyncSendNotice } = require('../utils/notify')
|
const { asyncSendNotice } = require('../utils/notify')
|
||||||
const { readHostList } = require('../utils/storage')
|
|
||||||
const { formatTimestamp } = require('../utils/tools')
|
const { formatTimestamp } = require('../utils/tools')
|
||||||
|
const { HostListDB } = require('../utils/db-class')
|
||||||
|
const hostListDB = new HostListDB().getInstance()
|
||||||
|
|
||||||
const expiredNotifyJob = async () => {
|
const expiredNotifyJob = async () => {
|
||||||
consola.info('=====开始检测服务器到期时间=====', new Date())
|
consola.info('=====开始检测服务器到期时间=====', new Date())
|
||||||
const hostList = await readHostList()
|
const hostList = await hostListDB.findAsync({})
|
||||||
for (const item of hostList) {
|
for (const item of hostList) {
|
||||||
if(!item.expiredNotify) continue
|
if (!item.expiredNotify) continue
|
||||||
const { host, name, expired, consoleUrl } = item
|
const { host, name, expired, consoleUrl } = item
|
||||||
const restDay = Number(((expired - Date.now()) / (1000 * 60 * 60 * 24)).toFixed(1))
|
const restDay = Number(((expired - Date.now()) / (1000 * 60 * 60 * 24)).toFixed(1))
|
||||||
console.log(Date.now(), restDay)
|
console.log(Date.now(), restDay)
|
||||||
let title = '服务器到期提醒'
|
let title = '服务器到期提醒'
|
||||||
let content = `别名: ${ name }\nIP: ${ host }\n到期时间:${ formatTimestamp(expired, 'week') }\n控制台: ${ consoleUrl || '未填写' }`
|
let content = `别名: ${ name }\nIP: ${ host }\n到期时间:${ formatTimestamp(expired, 'week') }\n控制台: ${ consoleUrl || '未填写' }`
|
||||||
if(0 <= restDay && restDay <= 1) {
|
if (0 <= restDay && restDay <= 1) {
|
||||||
let temp = '有服务器将在一天后到期,请关注\n'
|
let temp = '有服务器将在一天后到期,请关注\n'
|
||||||
asyncSendNotice('host_expired', title, temp + content)
|
asyncSendNotice('host_expired', title, temp + content)
|
||||||
}else if(3 <= restDay && restDay < 4) {
|
} else if (3 <= restDay && restDay < 4) {
|
||||||
let temp = '有服务器将在三天后到期,请关注\n'
|
let temp = '有服务器将在三天后到期,请关注\n'
|
||||||
asyncSendNotice('host_expired', title, temp + content)
|
asyncSendNotice('host_expired', title, temp + content)
|
||||||
}else if(7 <= restDay && restDay < 8) {
|
} else if (7 <= restDay && restDay < 8) {
|
||||||
let temp = '有服务器将在七天后到期,请关注\n'
|
let temp = '有服务器将在七天后到期,请关注\n'
|
||||||
asyncSendNotice('host_expired', title, temp + content)
|
asyncSendNotice('host_expired', title, temp + content)
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
const { Server: ServerIO } = require('socket.io')
|
const { Server: ServerIO } = require('socket.io')
|
||||||
const { io: ClientIO } = require('socket.io-client')
|
const { io: ClientIO } = require('socket.io-client')
|
||||||
const { readHostList } = require('../utils/storage')
|
|
||||||
const { defaultClientPort } = require('../config')
|
const { defaultClientPort } = require('../config')
|
||||||
const { verifyAuthSync } = require('../utils/verify-auth')
|
const { verifyAuthSync } = require('../utils/verify-auth')
|
||||||
const { isAllowedIp } = require('../utils/tools')
|
const { isAllowedIp } = require('../utils/tools')
|
||||||
|
const { HostListDB } = require('../utils/db-class')
|
||||||
|
const hostListDB = new HostListDB().getInstance()
|
||||||
|
|
||||||
let clientSockets = []
|
let clientSockets = []
|
||||||
let clientsData = {}
|
let clientsData = {}
|
||||||
|
|
||||||
async function getClientsInfo(clientSockets) {
|
async function getClientsInfo(clientSockets) {
|
||||||
let hostList = await readHostList()
|
let hostList = await hostListDB.findAsync({})
|
||||||
clientSockets.forEach((clientItem) => {
|
clientSockets.forEach((clientItem) => {
|
||||||
// 被删除的客户端断开连接
|
// 被删除的客户端断开连接
|
||||||
if (!hostList.some(item => item.host === clientItem.host)) clientItem.close && clientItem.close()
|
if (!hostList.some(item => item.host === clientItem.host)) clientItem.close && clientItem.close()
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
const { Server } = require('socket.io')
|
const { Server } = require('socket.io')
|
||||||
const { Client: SSHClient } = require('ssh2')
|
const { Client: SSHClient } = require('ssh2')
|
||||||
const { asyncSendNotice } = require('../utils/notify')
|
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 { verifyAuthSync } = require('../utils/verify-auth')
|
||||||
const { shellThrottle } = require('../utils/tools')
|
const { shellThrottle } = require('../utils/tools')
|
||||||
const { AESDecryptSync } = require('../utils/encrypt')
|
const { AESDecryptAsync } = require('../utils/encrypt')
|
||||||
const { isAllowedIp } = require('../utils/tools')
|
const { isAllowedIp } = require('../utils/tools')
|
||||||
|
const { HostListDB } = require('../utils/db-class')
|
||||||
|
const hostListDB = new HostListDB().getInstance()
|
||||||
|
|
||||||
const execStatusEnum = {
|
const execStatusEnum = {
|
||||||
connecting: '连接中',
|
connecting: '连接中',
|
||||||
@ -129,7 +131,7 @@ module.exports = (httpServer) => {
|
|||||||
console.log('hostIds:', hostIds)
|
console.log('hostIds:', hostIds)
|
||||||
// console.log('token:', token)
|
// console.log('token:', token)
|
||||||
console.log('command:', command)
|
console.log('command:', command)
|
||||||
const hostList = await readHostList()
|
const hostList = await hostListDB.findAsync({})
|
||||||
const targetHostsInfo = hostList.filter(item => hostIds.some(id => item._id === id)) || {}
|
const targetHostsInfo = hostList.filter(item => hostIds.some(id => item._id === id)) || {}
|
||||||
// console.log('targetHostsInfo:', targetHostsInfo)
|
// console.log('targetHostsInfo:', targetHostsInfo)
|
||||||
if (!targetHostsInfo.length) return socket.emit('create_fail', `未找到【${ hostIds }】服务器信息`)
|
if (!targetHostsInfo.length) return socket.emit('create_fail', `未找到【${ hostIds }】服务器信息`)
|
||||||
@ -145,13 +147,13 @@ module.exports = (httpServer) => {
|
|||||||
execResult.push(curRes)
|
execResult.push(curRes)
|
||||||
try {
|
try {
|
||||||
if (authType === 'credential') {
|
if (authType === 'credential') {
|
||||||
let credentialId = await AESDecryptSync(hostInfo['credential'])
|
let credentialId = await AESDecryptAsync(hostInfo['credential'])
|
||||||
const sshRecordList = await readSSHRecord()
|
const sshRecordList = await readSSHRecord()
|
||||||
const sshRecord = sshRecordList.find(item => item._id === credentialId)
|
const sshRecord = sshRecordList.find(item => item._id === credentialId)
|
||||||
authInfo.authType = sshRecord.authType
|
authInfo.authType = sshRecord.authType
|
||||||
authInfo[authInfo.authType] = await AESDecryptSync(sshRecord[authInfo.authType])
|
authInfo[authInfo.authType] = await AESDecryptAsync(sshRecord[authInfo.authType])
|
||||||
} else {
|
} else {
|
||||||
authInfo[authType] = await AESDecryptSync(hostInfo[authType])
|
authInfo[authType] = await AESDecryptAsync(hostInfo[authType])
|
||||||
}
|
}
|
||||||
consola.info('准备连接终端执行一次性指令:', host)
|
consola.info('准备连接终端执行一次性指令:', host)
|
||||||
consola.log('连接信息', { username, port, authType })
|
consola.log('连接信息', { username, port, authType })
|
||||||
|
@ -5,9 +5,11 @@ const CryptoJS = require('crypto-js')
|
|||||||
const { Server } = require('socket.io')
|
const { Server } = require('socket.io')
|
||||||
const { sftpCacheDir } = require('../config')
|
const { sftpCacheDir } = require('../config')
|
||||||
const { verifyAuthSync } = require('../utils/verify-auth')
|
const { verifyAuthSync } = require('../utils/verify-auth')
|
||||||
const { AESDecryptSync } = require('../utils/encrypt')
|
const { AESDecryptAsync } = require('../utils/encrypt')
|
||||||
const { readSSHRecord, readHostList } = require('../utils/storage')
|
const { readSSHRecord } = require('../utils/storage')
|
||||||
const { isAllowedIp } = require('../utils/tools')
|
const { isAllowedIp } = require('../utils/tools')
|
||||||
|
const { HostListDB } = require('../utils/db-class')
|
||||||
|
const hostListDB = new HostListDB().getInstance()
|
||||||
|
|
||||||
// 读取切片
|
// 读取切片
|
||||||
const pipeStream = (path, writeStream) => {
|
const pipeStream = (path, writeStream) => {
|
||||||
@ -230,7 +232,7 @@ module.exports = (httpServer) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const hostList = await readHostList()
|
const hostList = await hostListDB.findAsync({})
|
||||||
const targetHostInfo = hostList.find(item => item.host === ip) || {}
|
const targetHostInfo = hostList.find(item => item.host === ip) || {}
|
||||||
let { authType, host, port, username } = targetHostInfo
|
let { authType, host, port, username } = targetHostInfo
|
||||||
if (!host) return socket.emit('create_fail', `查找【${ ip }】凭证信息失败`)
|
if (!host) return socket.emit('create_fail', `查找【${ ip }】凭证信息失败`)
|
||||||
@ -238,16 +240,16 @@ module.exports = (httpServer) => {
|
|||||||
|
|
||||||
// 解密放到try里面,防止报错【commonKey必须配对, 否则需要重新添加服务器密钥】
|
// 解密放到try里面,防止报错【commonKey必须配对, 否则需要重新添加服务器密钥】
|
||||||
if (authType === 'credential') {
|
if (authType === 'credential') {
|
||||||
let credentialId = await AESDecryptSync(targetHostInfo[authType])
|
let credentialId = await AESDecryptAsync(targetHostInfo[authType])
|
||||||
const sshRecordList = await readSSHRecord()
|
const sshRecordList = await readSSHRecord()
|
||||||
const sshRecord = sshRecordList.find(item => item._id === credentialId)
|
const sshRecord = sshRecordList.find(item => item._id === credentialId)
|
||||||
authInfo.authType = sshRecord.authType
|
authInfo.authType = sshRecord.authType
|
||||||
authInfo[authInfo.authType] = await AESDecryptSync(sshRecord[authInfo.authType])
|
authInfo[authInfo.authType] = await AESDecryptAsync(sshRecord[authInfo.authType])
|
||||||
} else {
|
} else {
|
||||||
authInfo[authType] = await AESDecryptSync(targetHostInfo[authType])
|
authInfo[authType] = await AESDecryptAsync(targetHostInfo[authType])
|
||||||
}
|
}
|
||||||
consola.info('准备连接Sftp面板:', host)
|
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 })
|
consola.log('连接信息', { username, port, authType })
|
||||||
sftpClient
|
sftpClient
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
const { Server } = require('socket.io')
|
const { Server } = require('socket.io')
|
||||||
const { Client: SSHClient } = require('ssh2')
|
const { Client: SSHClient } = require('ssh2')
|
||||||
const { verifyAuthSync } = require('../utils/verify-auth')
|
const { verifyAuthSync } = require('../utils/verify-auth')
|
||||||
const { AESDecryptSync } = require('../utils/encrypt')
|
const { AESDecryptAsync } = require('../utils/encrypt')
|
||||||
const { readSSHRecord, readHostList } = require('../utils/storage')
|
const { readSSHRecord } = require('../utils/storage')
|
||||||
const { asyncSendNotice } = require('../utils/notify')
|
const { asyncSendNotice } = require('../utils/notify')
|
||||||
const { isAllowedIp, ping } = require('../utils/tools')
|
const { isAllowedIp, ping } = require('../utils/tools')
|
||||||
|
const { HostListDB } = require('../utils/db-class')
|
||||||
|
const hostListDB = new HostListDB().getInstance()
|
||||||
|
|
||||||
function createInteractiveShell(socket, sshClient) {
|
function createInteractiveShell(socket, sshClient) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
@ -51,7 +53,7 @@ function createInteractiveShell(socket, sshClient) {
|
|||||||
async function createTerminal(hostId, socket, sshClient) {
|
async function createTerminal(hostId, socket, sshClient) {
|
||||||
// eslint-disable-next-line no-async-promise-executor
|
// eslint-disable-next-line no-async-promise-executor
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const hostList = await readHostList()
|
const hostList = await hostListDB.findAsync({})
|
||||||
const targetHostInfo = hostList.find(item => item._id === hostId) || {}
|
const targetHostInfo = hostList.find(item => item._id === hostId) || {}
|
||||||
let { authType, host, port, username, name } = targetHostInfo
|
let { authType, host, port, username, name } = targetHostInfo
|
||||||
if (!host) return socket.emit('create_fail', `查找hostId【${ hostId }】凭证信息失败`)
|
if (!host) return socket.emit('create_fail', `查找hostId【${ hostId }】凭证信息失败`)
|
||||||
@ -60,16 +62,16 @@ async function createTerminal(hostId, socket, sshClient) {
|
|||||||
try {
|
try {
|
||||||
// 解密放到try里面,防止报错【commonKey必须配对, 否则需要重新添加服务器密钥】
|
// 解密放到try里面,防止报错【commonKey必须配对, 否则需要重新添加服务器密钥】
|
||||||
if (authType === 'credential') {
|
if (authType === 'credential') {
|
||||||
let credentialId = await AESDecryptSync(targetHostInfo[authType])
|
let credentialId = await AESDecryptAsync(targetHostInfo[authType])
|
||||||
const sshRecordList = await readSSHRecord()
|
const sshRecordList = await readSSHRecord()
|
||||||
const sshRecord = sshRecordList.find(item => item._id === credentialId)
|
const sshRecord = sshRecordList.find(item => item._id === credentialId)
|
||||||
authInfo.authType = sshRecord.authType
|
authInfo.authType = sshRecord.authType
|
||||||
authInfo[authInfo.authType] = await AESDecryptSync(sshRecord[authInfo.authType])
|
authInfo[authInfo.authType] = await AESDecryptAsync(sshRecord[authInfo.authType])
|
||||||
} else {
|
} else {
|
||||||
authInfo[authType] = await AESDecryptSync(targetHostInfo[authType])
|
authInfo[authType] = await AESDecryptAsync(targetHostInfo[authType])
|
||||||
}
|
}
|
||||||
consola.info('准备连接终端:', host)
|
consola.info('准备连接终端:', host)
|
||||||
// targetHostInfo[targetHostInfo.authType] = await AESDecryptSync(targetHostInfo[targetHostInfo.authType])
|
// targetHostInfo[targetHostInfo.authType] = await AESDecryptAsync(targetHostInfo[targetHostInfo.authType])
|
||||||
consola.log('连接信息', { username, port, authType })
|
consola.log('连接信息', { username, port, authType })
|
||||||
sshClient
|
sshClient
|
||||||
.on('ready', async() => {
|
.on('ready', async() => {
|
||||||
|
@ -15,6 +15,7 @@ module.exports.KeyDB = class KeyDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!KeyDB.instance) {
|
if (!KeyDB.instance) {
|
||||||
KeyDB.instance = new Datastore({ filename: keyDBPath, autoload: true })
|
KeyDB.instance = new Datastore({ filename: keyDBPath, autoload: true })
|
||||||
|
KeyDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -26,6 +27,7 @@ module.exports.HostListDB = class HostListDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!HostListDB.instance) {
|
if (!HostListDB.instance) {
|
||||||
HostListDB.instance = new Datastore({ filename: hostListDBPath, autoload: true })
|
HostListDB.instance = new Datastore({ filename: hostListDBPath, autoload: true })
|
||||||
|
HostListDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -37,6 +39,7 @@ module.exports.SshRecordDB = class SshRecordDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!SshRecordDB.instance) {
|
if (!SshRecordDB.instance) {
|
||||||
SshRecordDB.instance = new Datastore({ filename: credentialsDBPath, autoload: true })
|
SshRecordDB.instance = new Datastore({ filename: credentialsDBPath, autoload: true })
|
||||||
|
SshRecordDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -48,6 +51,8 @@ module.exports.NotifyDB = class NotifyDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!NotifyDB.instance) {
|
if (!NotifyDB.instance) {
|
||||||
NotifyDB.instance = new Datastore({ filename: notifyDBPath, autoload: true })
|
NotifyDB.instance = new Datastore({ filename: notifyDBPath, autoload: true })
|
||||||
|
NotifyDB.instance.setAutocompactionInterval(5000)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -59,6 +64,7 @@ module.exports.NotifyConfigDB = class NotifyConfigDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!NotifyConfigDB.instance) {
|
if (!NotifyConfigDB.instance) {
|
||||||
NotifyConfigDB.instance = new Datastore({ filename: notifyConfigDBPath, autoload: true })
|
NotifyConfigDB.instance = new Datastore({ filename: notifyConfigDBPath, autoload: true })
|
||||||
|
NotifyConfigDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -70,6 +76,7 @@ module.exports.GroupDB = class GroupDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!GroupDB.instance) {
|
if (!GroupDB.instance) {
|
||||||
GroupDB.instance = new Datastore({ filename: groupConfDBPath, autoload: true })
|
GroupDB.instance = new Datastore({ filename: groupConfDBPath, autoload: true })
|
||||||
|
GroupDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -81,6 +88,7 @@ module.exports.ScriptsDB = class ScriptsDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!ScriptsDB.instance) {
|
if (!ScriptsDB.instance) {
|
||||||
ScriptsDB.instance = new Datastore({ filename: scriptsDBPath, autoload: true })
|
ScriptsDB.instance = new Datastore({ filename: scriptsDBPath, autoload: true })
|
||||||
|
ScriptsDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -92,6 +100,7 @@ module.exports.OnekeyDB = class OnekeyDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!OnekeyDB.instance) {
|
if (!OnekeyDB.instance) {
|
||||||
OnekeyDB.instance = new Datastore({ filename: onekeyDBPath, autoload: true })
|
OnekeyDB.instance = new Datastore({ filename: onekeyDBPath, autoload: true })
|
||||||
|
OnekeyDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
@ -103,6 +112,7 @@ module.exports.LogDB = class LogDB {
|
|||||||
constructor() {
|
constructor() {
|
||||||
if (!LogDB.instance) {
|
if (!LogDB.instance) {
|
||||||
LogDB.instance = new Datastore({ filename: logDBPath, autoload: true })
|
LogDB.instance = new Datastore({ filename: logDBPath, autoload: true })
|
||||||
|
LogDB.instance.setAutocompactionInterval(5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInstance() {
|
getInstance() {
|
||||||
|
@ -4,10 +4,10 @@ const NodeRSA = require('node-rsa')
|
|||||||
const { readKey } = require('./storage.js')
|
const { readKey } = require('./storage.js')
|
||||||
|
|
||||||
// rsa非对称 私钥解密
|
// rsa非对称 私钥解密
|
||||||
const RSADecryptSync = async (ciphertext) => {
|
const RSADecryptAsync = async (ciphertext) => {
|
||||||
if (!ciphertext) return
|
if (!ciphertext) return
|
||||||
let { privateKey } = await readKey()
|
let { privateKey } = await readKey()
|
||||||
privateKey = await AESDecryptSync(privateKey) // 先解密私钥
|
privateKey = await AESDecryptAsync(privateKey) // 先解密私钥
|
||||||
const rsakey = new NodeRSA(privateKey)
|
const rsakey = new NodeRSA(privateKey)
|
||||||
rsakey.setOptions({ encryptionScheme: 'pkcs1', environment: 'browser' }) // Must Set It When Frontend Use jsencrypt
|
rsakey.setOptions({ encryptionScheme: 'pkcs1', environment: 'browser' }) // Must Set It When Frontend Use jsencrypt
|
||||||
const plaintext = rsakey.decrypt(ciphertext, 'utf8')
|
const plaintext = rsakey.decrypt(ciphertext, 'utf8')
|
||||||
@ -15,16 +15,16 @@ const RSADecryptSync = async (ciphertext) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// aes对称 加密(default commonKey)
|
// aes对称 加密(default commonKey)
|
||||||
const AESEncryptSync = async (text, key) => {
|
const AESEncryptAsync = async (text, key) => {
|
||||||
if(!text) return
|
if (!text) return
|
||||||
let { commonKey } = await readKey()
|
let { commonKey } = await readKey()
|
||||||
let ciphertext = CryptoJS.AES.encrypt(text, key || commonKey).toString()
|
let ciphertext = CryptoJS.AES.encrypt(text, key || commonKey).toString()
|
||||||
return ciphertext
|
return ciphertext
|
||||||
}
|
}
|
||||||
|
|
||||||
// aes对称 解密(default commonKey)
|
// aes对称 解密(default commonKey)
|
||||||
const AESDecryptSync = async (ciphertext, key) => {
|
const AESDecryptAsync = async (ciphertext, key) => {
|
||||||
if(!ciphertext) return
|
if (!ciphertext) return
|
||||||
let { commonKey } = await readKey()
|
let { commonKey } = await readKey()
|
||||||
let bytes = CryptoJS.AES.decrypt(ciphertext, key || commonKey)
|
let bytes = CryptoJS.AES.decrypt(ciphertext, key || commonKey)
|
||||||
let originalText = bytes.toString(CryptoJS.enc.Utf8)
|
let originalText = bytes.toString(CryptoJS.enc.Utf8)
|
||||||
@ -37,8 +37,8 @@ const SHA1Encrypt = (clearText) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
RSADecryptSync,
|
RSADecryptAsync,
|
||||||
AESEncryptSync,
|
AESEncryptAsync,
|
||||||
AESDecryptSync,
|
AESDecryptAsync,
|
||||||
SHA1Encrypt
|
SHA1Encrypt
|
||||||
}
|
}
|
@ -64,43 +64,43 @@ const writeSSHRecord = async (record = []) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const readHostList = async () => {
|
// const readHostList = async () => {
|
||||||
return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
const hostListDB = new HostListDB().getInstance()
|
// const hostListDB = new HostListDB().getInstance()
|
||||||
hostListDB.find({}, (err, docs) => {
|
// hostListDB.find({}, (err, docs) => {
|
||||||
if (err) {
|
// if (err) {
|
||||||
consola.error('读取host-list-db错误:', err)
|
// consola.error('读取host-list-db错误:', err)
|
||||||
reject(err)
|
// reject(err)
|
||||||
} else {
|
// } else {
|
||||||
resolve(docs)
|
// resolve(docs)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
const writeHostList = async (record = []) => {
|
// const writeHostList = async (record = []) => {
|
||||||
return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
const hostListDB = new HostListDB().getInstance()
|
// const hostListDB = new HostListDB().getInstance()
|
||||||
hostListDB.remove({}, { multi: true }, (err) => {
|
// hostListDB.remove({}, { multi: true }, (err) => {
|
||||||
if (err) {
|
// if (err) {
|
||||||
consola.error('清空HostList出错:', err)
|
// consola.error('清空HostList出错:', err)
|
||||||
reject(err)
|
// reject(err)
|
||||||
} else {
|
// } else {
|
||||||
hostListDB.compactDatafile()
|
// hostListDB.compactDatafile()
|
||||||
// 插入新的数据列表
|
// // 插入新的数据列表
|
||||||
hostListDB.insert(record, (err, newDocs) => {
|
// hostListDB.insert(record, (err, newDocs) => {
|
||||||
if (err) {
|
// if (err) {
|
||||||
consola.error('写入新的HostList出错:', err)
|
// consola.error('写入新的HostList出错:', err)
|
||||||
reject(err)
|
// reject(err)
|
||||||
} else {
|
// } else {
|
||||||
hostListDB.compactDatafile()
|
// hostListDB.compactDatafile()
|
||||||
resolve(newDocs)
|
// resolve(newDocs)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
const readNotifyConfig = async () => {
|
const readNotifyConfig = async () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -329,7 +329,7 @@ const writeLog = async (records = {}) => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
readSSHRecord, writeSSHRecord,
|
readSSHRecord, writeSSHRecord,
|
||||||
readHostList, writeHostList,
|
// readHostList, writeHostList,
|
||||||
readKey, writeKey,
|
readKey, writeKey,
|
||||||
readNotifyList, writeNotifyList,
|
readNotifyList, writeNotifyList,
|
||||||
readNotifyConfig, writeNotifyConfig, getNotifySwByType,
|
readNotifyConfig, writeNotifyConfig, getNotifySwByType,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
const { AESDecryptSync } = require('./encrypt')
|
const { AESDecryptAsync } = require('./encrypt')
|
||||||
const { readKey } = require('./storage')
|
const { readKey } = require('./storage')
|
||||||
const jwt = require('jsonwebtoken')
|
const jwt = require('jsonwebtoken')
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ const enumLoginCode = {
|
|||||||
const verifyAuthSync = async (token, clientIp) => {
|
const verifyAuthSync = async (token, clientIp) => {
|
||||||
consola.info('verifyAuthSync IP:', clientIp)
|
consola.info('verifyAuthSync IP:', clientIp)
|
||||||
try {
|
try {
|
||||||
token = await AESDecryptSync(token) // 先aes解密
|
token = await AESDecryptAsync(token) // 先aes解密
|
||||||
const { commonKey } = await readKey()
|
const { commonKey } = await readKey()
|
||||||
const { exp } = jwt.verify(token, commonKey)
|
const { exp } = jwt.verify(token, commonKey)
|
||||||
if (Date.now() > (exp * 1000)) return { code: -1, msg: 'token expires' } // 过期
|
if (Date.now() > (exp * 1000)) return { code: -1, msg: 'token expires' } // 过期
|
||||||
|
@ -356,7 +356,7 @@ const setDefaultData = () => {
|
|||||||
|
|
||||||
const setBatchDefaultData = () => {
|
const setBatchDefaultData = () => {
|
||||||
if (!isBatchModify.value) return
|
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 () => {
|
const handleOpen = async () => {
|
||||||
setDefaultData()
|
setDefaultData()
|
||||||
@ -416,7 +416,7 @@ const handleSave = () => {
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
let updateFileData = Object.fromEntries(Object.entries(formData).filter(([key, value]) => Boolean(value))) // 剔除掉未更改的值
|
let updateFileData = Object.fromEntries(Object.entries(formData).filter(([key, value]) => Boolean(value))) // 剔除掉未更改的值
|
||||||
if (Object.keys(updateFileData).length === 0) return $message.warning('没有任何修改')
|
if (Object.keys(updateFileData).length === 0) return $message.warning('没有任何修改')
|
||||||
// console.log(updateFileData)
|
console.log(updateFileData)
|
||||||
let newHosts = batchHosts.value
|
let newHosts = batchHosts.value
|
||||||
.map(item => ({ ...item, ...updateFileData }))
|
.map(item => ({ ...item, ...updateFileData }))
|
||||||
.map(item => {
|
.map(item => {
|
||||||
|
@ -168,7 +168,6 @@ let handleBatchOnekey = async () => {
|
|||||||
let handleBatchExport = () => {
|
let handleBatchExport = () => {
|
||||||
collectSelectHost()
|
collectSelectHost()
|
||||||
if (!selectHosts.value.length) return $message.warning('请选择要批量操作的实例')
|
if (!selectHosts.value.length) return $message.warning('请选择要批量操作的实例')
|
||||||
console.log(selectHosts.value)
|
|
||||||
let exportData = JSON.parse(JSON.stringify(selectHosts.value))
|
let exportData = JSON.parse(JSON.stringify(selectHosts.value))
|
||||||
exportData = exportData.map(item => {
|
exportData = exportData.map(item => {
|
||||||
delete item.monitorData
|
delete item.monitorData
|
||||||
|
Loading…
x
Reference in New Issue
Block a user