This commit is contained in:
parent
bfb4458f0b
commit
4e7805bc76
@ -158,6 +158,16 @@ export function usePage(pageKey = 'base') {
|
||||
if (selectedSection.value === 'base' && ['mysql', 'postgresql'].includes(formConfig.value.database?.type)) {
|
||||
return { label: '数据库密码', description: '只在本次请求内传输,保存后仅保留密文状态。留空表示保持原值。', placeholder: '输入新数据库密码(可选)' }
|
||||
}
|
||||
const pluginSecrets = { telegram_push: 'Telegram Bot Token', wechat_push: '微信 Secret' }
|
||||
const label = pluginSecrets[selectedSection.value]
|
||||
if (label && formConfig.value.plugins?.[selectedSection.value]) {
|
||||
const configured = readFormConfig(loadedText.value).plugins?.[selectedSection.value]?.secretStatus?.configured
|
||||
return {
|
||||
label,
|
||||
description: `${configured ? '已设置' : '未设置'}。保存后加密存储,不回显;留空保持原值。`,
|
||||
placeholder: `输入新的 ${label}(可选)`
|
||||
}
|
||||
}
|
||||
return null
|
||||
})
|
||||
const sensitiveHint = computed(() => secretField.value ? '密码不会回填,修改请使用下方独立输入框,留空保持原值' : '')
|
||||
@ -526,6 +536,9 @@ export function usePage(pageKey = 'base') {
|
||||
if (value && selectedSection.value === 'base' && secretField.value) {
|
||||
secretChanges['database.password'] = { operation: 'replace', value: { plaintext: value } }
|
||||
}
|
||||
if (value && ['telegram_push', 'wechat_push'].includes(selectedSection.value) && secretField.value) {
|
||||
secretChanges[`plugins.${selectedSection.value}.secret`] = { operation: 'replace', value: { plaintext: value } }
|
||||
}
|
||||
const relayPassword = formConfig.value?.relay?.password
|
||||
if (relayPassword && selectedSection.value === 'mail') {
|
||||
secretChanges['relay.password'] = { operation: 'replace', value: { plaintext: relayPassword } }
|
||||
|
||||
@ -1147,6 +1147,76 @@ test('插件读取状态字段不传回严格解析接口,未展示字段和
|
||||
assert.equal(page.formConfig.value.plugins.telegram_push.secretStatus.configured, true)
|
||||
})
|
||||
|
||||
for (const key of ['telegram_push', 'wechat_push']) {
|
||||
test(`${key} 密钥独立提交、留空保留,保存回读与离开后清空`, async () => {
|
||||
let active = { meta: { generation: 1 }, plugins: {
|
||||
telegram_push: { enabled: false, settings: { timeout: 30 }, secretStatus: { configured: false } },
|
||||
wechat_push: { enabled: false, settings: { appId: 'test-only', future: 'preserved' }, secretStatus: { configured: false } }
|
||||
} }
|
||||
const original = structuredClone(active)
|
||||
let pending = null
|
||||
const requests = []
|
||||
const http = {
|
||||
get: async path => ({ errorNo: 0, data: path.endsWith('/status') ? { activeGeneration: active.meta.generation }
|
||||
: path.endsWith('/pending') ? pending : active }),
|
||||
put: async (path, body) => {
|
||||
requests.push({ path, body })
|
||||
pending = { generation: 2, section: 'plugins', sameSession: true, candidateId: 'secret-test', payload: body.payload }
|
||||
return { errorNo: 0, data: pending }
|
||||
},
|
||||
post: async (path, body) => {
|
||||
requests.push({ path, body })
|
||||
if (path.endsWith('/apply')) {
|
||||
active = { ...pending.payload, meta: { generation: 2 } }
|
||||
active.plugins[key].secretStatus = { configured: true }
|
||||
pending = null
|
||||
}
|
||||
return { errorNo: 0, data: { valid: true } }
|
||||
}
|
||||
}
|
||||
const { page, dispose } = fixture(() => {}, key, { http })
|
||||
await page.loadAll()
|
||||
assert.match(page.secretField.value.description, /^未设置/)
|
||||
await page.validateConfig()
|
||||
assert.deepEqual(requests.at(-1).body.secretChanges, {})
|
||||
page.updateSecret(' test-only-plugin-secret ')
|
||||
assert.equal(page.hasChanges.value, true)
|
||||
assert.equal(page.editorText.value.includes('test-only-plugin-secret'), false)
|
||||
await page.validateConfig()
|
||||
assert.equal(requests.at(-1).path, '/api/v1/config/plugins/validate')
|
||||
assert.deepEqual(requests.at(-1).body.secretChanges, {
|
||||
[`plugins.${key}.secret`]: { operation: 'replace', value: { plaintext: ' test-only-plugin-secret ' } }
|
||||
})
|
||||
for (const id of Object.keys(original.plugins)) {
|
||||
assert.deepEqual(requests.at(-1).body.payload.plugins[id].settings, original.plugins[id].settings)
|
||||
assert.equal(requests.at(-1).body.payload.plugins[id].secretStatus, undefined)
|
||||
assert.equal(requests.at(-1).body.payload.plugins[id].enabled, false)
|
||||
}
|
||||
assert.equal(await page.saveConfig(), true)
|
||||
assert.equal(page.secretValue.value, '')
|
||||
const saved = requests.find(item => item.path === '/api/v1/config/plugins')
|
||||
assert.equal(saved.body.secretChanges[`plugins.${key}.secret`].value.plaintext, ' test-only-plugin-secret ')
|
||||
page.updateSecret('blocked-pending-edit')
|
||||
assert.equal(page.secretValue.value, '')
|
||||
assert.equal(await page.applyConfig(), true)
|
||||
assert.equal(page.secretValue.value, '')
|
||||
assert.match(page.secretField.value.description, /^已设置/)
|
||||
await page.validateConfig()
|
||||
assert.deepEqual(requests.at(-1).body.secretChanges, {})
|
||||
page.updateSecret('discard-on-leave')
|
||||
dispose()
|
||||
assert.equal(page.secretValue.value, '')
|
||||
|
||||
const readonly = fixture(() => {}, key, { http, hasCapability: () => false }).page
|
||||
await readonly.loadAll()
|
||||
const previousRequests = requests.length
|
||||
readonly.updateSecret('forbidden')
|
||||
await readonly.saveConfig()
|
||||
assert.equal(readonly.secretValue.value, '')
|
||||
assert.equal(requests.length, previousRequests)
|
||||
})
|
||||
}
|
||||
|
||||
test('SQLite 不显示或发送密码,网络数据库和中继密码留空保留且不裁剪空格', async () => {
|
||||
for (const type of ['sqlite', 'mysql', 'postgresql']) {
|
||||
let request
|
||||
|
||||
Loading…
Reference in New Issue
Block a user