mirror of
https://github.com/Kuingsmile/PicList.git
synced 2025-01-23 06:38:13 -05:00
✨ Feature(custom): upload api now return encrypted full result
This commit is contained in:
parent
10ec712496
commit
018971509a
@ -204,6 +204,7 @@ SETTINGS_SET_SERVER_KEY: Set Auth Key
|
|||||||
SETTINGS_TIP_PLACEHOLDER_HOST: Default:127.0.0.1
|
SETTINGS_TIP_PLACEHOLDER_HOST: Default:127.0.0.1
|
||||||
SETTINGS_TIP_PLACEHOLDER_PORT: Default:36677
|
SETTINGS_TIP_PLACEHOLDER_PORT: Default:36677
|
||||||
SETTINGS_TIP_PLACEHOLDER_KEY: This key is used to avoid malicious requests, through urlParams '?key=xxx' to pass
|
SETTINGS_TIP_PLACEHOLDER_KEY: This key is used to avoid malicious requests, through urlParams '?key=xxx' to pass
|
||||||
|
SETTINGS_SET_SERVER_AES_KEY: Set AES Key for server response
|
||||||
SETTINGS_LOG_LEVEL_ALL: All
|
SETTINGS_LOG_LEVEL_ALL: All
|
||||||
SETTINGS_LOG_LEVEL_SUCCESS: Success
|
SETTINGS_LOG_LEVEL_SUCCESS: Success
|
||||||
SETTINGS_LOG_LEVEL_ERROR: Error
|
SETTINGS_LOG_LEVEL_ERROR: Error
|
||||||
|
@ -206,6 +206,7 @@ SETTINGS_SET_SERVER_KEY: 设置鉴权密钥
|
|||||||
SETTINGS_TIP_PLACEHOLDER_HOST: 推荐默认地址:127.0.0.1
|
SETTINGS_TIP_PLACEHOLDER_HOST: 推荐默认地址:127.0.0.1
|
||||||
SETTINGS_TIP_PLACEHOLDER_PORT: 推荐默认端口:36677
|
SETTINGS_TIP_PLACEHOLDER_PORT: 推荐默认端口:36677
|
||||||
SETTINGS_TIP_PLACEHOLDER_KEY: 用于接口鉴权, 通过url参数添加'?key=xxx'
|
SETTINGS_TIP_PLACEHOLDER_KEY: 用于接口鉴权, 通过url参数添加'?key=xxx'
|
||||||
|
SETTINGS_SET_SERVER_AES_KEY: 设置接口数据加密密钥
|
||||||
SETTINGS_LOG_LEVEL_ALL: 全部-All
|
SETTINGS_LOG_LEVEL_ALL: 全部-All
|
||||||
SETTINGS_LOG_LEVEL_SUCCESS: 成功-Success
|
SETTINGS_LOG_LEVEL_SUCCESS: 成功-Success
|
||||||
SETTINGS_LOG_LEVEL_ERROR: 错误-Error
|
SETTINGS_LOG_LEVEL_ERROR: 错误-Error
|
||||||
|
@ -204,6 +204,7 @@ SETTINGS_SET_SERVER_KEY: 設定鑒權密鑰
|
|||||||
SETTINGS_TIP_PLACEHOLDER_HOST: 推薦預設地址:127.0.0.1
|
SETTINGS_TIP_PLACEHOLDER_HOST: 推薦預設地址:127.0.0.1
|
||||||
SETTINGS_TIP_PLACEHOLDER_PORT: 推薦預設端口:36677
|
SETTINGS_TIP_PLACEHOLDER_PORT: 推薦預設端口:36677
|
||||||
SETTINGS_TIP_PLACEHOLDER_KEY: 用於接口鑒權, 通過url參數添加'?key=xxx'
|
SETTINGS_TIP_PLACEHOLDER_KEY: 用於接口鑒權, 通過url參數添加'?key=xxx'
|
||||||
|
SETTINGS_SET_SERVER_AES_KEY: 設定AES加密密鑰
|
||||||
SETTINGS_LOG_LEVEL_ALL: 全部-All
|
SETTINGS_LOG_LEVEL_ALL: 全部-All
|
||||||
SETTINGS_LOG_LEVEL_SUCCESS: 成功-Success
|
SETTINGS_LOG_LEVEL_SUCCESS: 成功-Success
|
||||||
SETTINGS_LOG_LEVEL_ERROR: 錯誤-Error
|
SETTINGS_LOG_LEVEL_ERROR: 錯誤-Error
|
||||||
|
@ -11,6 +11,7 @@ import picgo from '@core/picgo'
|
|||||||
import { changeCurrentUploader } from '../utils/handleUploaderConfig'
|
import { changeCurrentUploader } from '../utils/handleUploaderConfig'
|
||||||
import { app } from 'electron'
|
import { app } from 'electron'
|
||||||
import fs from 'fs-extra'
|
import fs from 'fs-extra'
|
||||||
|
import { AESHelper } from '../utils/aesHelper'
|
||||||
|
|
||||||
const appPath = app.getPath('userData')
|
const appPath = app.getPath('userData')
|
||||||
const serverTempDir = path.join(appPath, 'serverTemp')
|
const serverTempDir = path.join(appPath, 'serverTemp')
|
||||||
@ -76,12 +77,18 @@ router.post('/upload', async ({
|
|||||||
const fullResult = result.fullResult
|
const fullResult = result.fullResult
|
||||||
logger.info('[PicList Server] upload result:', res)
|
logger.info('[PicList Server] upload result:', res)
|
||||||
if (res) {
|
if (res) {
|
||||||
|
const treatedFullResult = {
|
||||||
|
isAESEncrypted: 1,
|
||||||
|
AESEncryptedData: new AESHelper().encrypt(JSON.stringify(fullResult)),
|
||||||
|
...fullResult
|
||||||
|
}
|
||||||
|
delete treatedFullResult.config
|
||||||
handleResponse({
|
handleResponse({
|
||||||
response,
|
response,
|
||||||
body: {
|
body: {
|
||||||
success: true,
|
success: true,
|
||||||
result: [res],
|
result: [res],
|
||||||
fullResult: [fullResult]
|
fullResult: [treatedFullResult]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -107,7 +114,13 @@ router.post('/upload', async ({
|
|||||||
return item.url
|
return item.url
|
||||||
})
|
})
|
||||||
const fullResult = result.map((item: any) => {
|
const fullResult = result.map((item: any) => {
|
||||||
return item.fullResult
|
const treatedItem = {
|
||||||
|
isAESEncrypted: 1,
|
||||||
|
AESEncryptedData: new AESHelper().encrypt(JSON.stringify(item.fullResult)),
|
||||||
|
...item.fullResult
|
||||||
|
}
|
||||||
|
delete treatedItem.config
|
||||||
|
return treatedItem
|
||||||
})
|
})
|
||||||
logger.info('[PicList Server] upload result', res.join(' ; '))
|
logger.info('[PicList Server] upload result', res.join(' ; '))
|
||||||
if (res.length) {
|
if (res.length) {
|
||||||
@ -163,7 +176,17 @@ router.post('/delete', async ({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result = await deleteChoosedFiles(list)
|
// 区分是否是aes加密的数据,如果不是直接传入list,如果是,解密后再传入
|
||||||
|
const treatList = list.map(item => {
|
||||||
|
if (item.isAESEncrypted) {
|
||||||
|
const aesHelper = new AESHelper()
|
||||||
|
const data = aesHelper.decrypt(item.AESEncryptedData)
|
||||||
|
return JSON.parse(data)
|
||||||
|
} else {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const result = await deleteChoosedFiles(treatList)
|
||||||
const successCount = result.filter(item => item).length
|
const successCount = result.filter(item => item).length
|
||||||
const failCount = result.filter(item => !item).length
|
const failCount = result.filter(item => !item).length
|
||||||
if (successCount) {
|
if (successCount) {
|
||||||
|
39
src/main/utils/aesHelper.ts
Normal file
39
src/main/utils/aesHelper.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import crypto from 'crypto'
|
||||||
|
import picgo from '@core/picgo'
|
||||||
|
|
||||||
|
function getDerivedKey (): Buffer {
|
||||||
|
const userPassword = picgo.getConfig<string>('settings.aesPassword') || 'PicList-aesPassword'
|
||||||
|
const fixedSalt = Buffer.from('a8b3c4d2e4f5098712345678feedc0de', 'hex')
|
||||||
|
const fixedIterations = 100000
|
||||||
|
const keyLength = 32
|
||||||
|
return crypto.pbkdf2Sync(userPassword, fixedSalt, fixedIterations, keyLength, 'sha512')
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AESHelper {
|
||||||
|
key: Buffer
|
||||||
|
constructor () {
|
||||||
|
this.key = getDerivedKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypt (plainText: string) {
|
||||||
|
const iv = crypto.randomBytes(16)
|
||||||
|
const cipher = crypto.createCipheriv('aes-256-cbc', this.key, iv)
|
||||||
|
let encrypted = cipher.update(plainText, 'utf8', 'hex')
|
||||||
|
encrypted += cipher.final('hex')
|
||||||
|
const encryptedData = `${iv.toString('hex')}:${encrypted}`
|
||||||
|
return encryptedData
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypt (encryptedData: string) {
|
||||||
|
const parts = encryptedData.split(':')
|
||||||
|
if (parts.length !== 2) {
|
||||||
|
return '{}'
|
||||||
|
}
|
||||||
|
const iv = Buffer.from(parts[0], 'hex')
|
||||||
|
const encryptedText = parts[1]
|
||||||
|
const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, iv)
|
||||||
|
let decrypted = decipher.update(encryptedText, 'hex', 'utf8')
|
||||||
|
decrypted += decipher.final('utf8')
|
||||||
|
return decrypted
|
||||||
|
}
|
||||||
|
}
|
@ -598,6 +598,18 @@
|
|||||||
{{ $T('SETTINGS_CLICK_TO_SET') }}
|
{{ $T('SETTINGS_CLICK_TO_SET') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$T('SETTINGS_SET_SERVER_AES_KEY')"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model.trim="form.aesPassword"
|
||||||
|
type="input"
|
||||||
|
:placeholder="$T('SETTINGS_SET_SERVER_AES_KEY')"
|
||||||
|
size="small"
|
||||||
|
style="width: 50%"
|
||||||
|
@change="handleAesPasswordChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -1702,7 +1714,8 @@ const form = reactive<ISettingForm>({
|
|||||||
yourlsDomain: '',
|
yourlsDomain: '',
|
||||||
yourlsSignature: '',
|
yourlsSignature: '',
|
||||||
deleteLocalFile: false,
|
deleteLocalFile: false,
|
||||||
serverKey: ''
|
serverKey: '',
|
||||||
|
aesPassword: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const languageList = i18nManager.languageList.map(item => ({
|
const languageList = i18nManager.languageList.map(item => ({
|
||||||
@ -1860,6 +1873,7 @@ async function initData () {
|
|||||||
form.yourlsSignature = settings.yourlsSignature || ''
|
form.yourlsSignature = settings.yourlsSignature || ''
|
||||||
form.deleteLocalFile = settings.deleteLocalFile || false
|
form.deleteLocalFile = settings.deleteLocalFile || false
|
||||||
form.serverKey = settings.serverKey || ''
|
form.serverKey = settings.serverKey || ''
|
||||||
|
form.aesPassword = settings.aesPassword || 'PicList-aesPassword'
|
||||||
currentLanguage.value = settings.language ?? 'zh-CN'
|
currentLanguage.value = settings.language ?? 'zh-CN'
|
||||||
currentStartMode.value = settings.startMode || 'quiet'
|
currentStartMode.value = settings.startMode || 'quiet'
|
||||||
customLink.value = settings.customLink || '![$fileName]($url)'
|
customLink.value = settings.customLink || '![$fileName]($url)'
|
||||||
@ -2210,6 +2224,10 @@ function handleYourlsSignatureChange (val: string) {
|
|||||||
saveConfig('settings.yourlsSignature', val)
|
saveConfig('settings.yourlsSignature', val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleAesPasswordChange (val: string) {
|
||||||
|
saveConfig('settings.aesPassword', val || 'PicList-aesPassword')
|
||||||
|
}
|
||||||
|
|
||||||
function confirmLogLevelSetting () {
|
function confirmLogLevelSetting () {
|
||||||
if (form.logLevel.length === 0) {
|
if (form.logLevel.length === 0) {
|
||||||
return $message.error($T('TIPS_PLEASE_CHOOSE_LOG_LEVEL'))
|
return $message.error($T('TIPS_PLEASE_CHOOSE_LOG_LEVEL'))
|
||||||
|
1
src/universal/types/i18n.d.ts
vendored
1
src/universal/types/i18n.d.ts
vendored
@ -199,6 +199,7 @@ interface ILocales {
|
|||||||
SETTINGS_TIP_PLACEHOLDER_HOST: string
|
SETTINGS_TIP_PLACEHOLDER_HOST: string
|
||||||
SETTINGS_TIP_PLACEHOLDER_PORT: string
|
SETTINGS_TIP_PLACEHOLDER_PORT: string
|
||||||
SETTINGS_TIP_PLACEHOLDER_KEY: string
|
SETTINGS_TIP_PLACEHOLDER_KEY: string
|
||||||
|
SETTINGS_SET_SERVER_AES_KEY: string
|
||||||
SETTINGS_LOG_LEVEL_ALL: string
|
SETTINGS_LOG_LEVEL_ALL: string
|
||||||
SETTINGS_LOG_LEVEL_SUCCESS: string
|
SETTINGS_LOG_LEVEL_SUCCESS: string
|
||||||
SETTINGS_LOG_LEVEL_ERROR: string
|
SETTINGS_LOG_LEVEL_ERROR: string
|
||||||
|
3
src/universal/types/view.d.ts
vendored
3
src/universal/types/view.d.ts
vendored
@ -28,7 +28,8 @@ interface ISettingForm {
|
|||||||
yourlsDomain: string,
|
yourlsDomain: string,
|
||||||
yourlsSignature: string,
|
yourlsSignature: string,
|
||||||
deleteLocalFile: boolean,
|
deleteLocalFile: boolean,
|
||||||
serverKey: string
|
serverKey: string,
|
||||||
|
aesPassword: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IShortKeyMap {
|
interface IShortKeyMap {
|
||||||
|
Loading…
Reference in New Issue
Block a user