修复快手appSecret意外修改问题

This commit is contained in:
yml2213
2026-09-13 10:42:32 +08:00
parent 1cf790d6ab
commit 447d501f7b
3 changed files with 324 additions and 49 deletions
@@ -0,0 +1,80 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import { isMaskedSecretValue, resolveSecretPatch } from './kuaishou-industry-service.js'
import type { KuaishouIndustrySourceConfig } from '../../platforms/kuaishou-industry/source-config-service.js'
test('isMaskedSecretValue correctly identifies masked values and prevents overwrite', () => {
assert.equal(isMaskedSecretValue(''), true)
assert.equal(isMaskedSecretValue(' '), true)
assert.equal(isMaskedSecretValue('SK_ATD******XXrqmD'), true)
assert.equal(isMaskedSecretValue('29a8f2****79a2'), true)
assert.equal(isMaskedSecretValue('abc***xyz'), true)
assert.equal(isMaskedSecretValue('real_secret_key_12345678'), false)
assert.equal(isMaskedSecretValue('abcdef12****5678', 'abcdef12345678'), true)
})
test('resolveSecretPatch preserves current secrets when input is empty or masked', () => {
const current: KuaishouIndustrySourceConfig = {
enabled: true,
baseUrl: 'https://openapi.kwaixiaodian.com',
authBaseUrl: 'https://open.kwaixiaodian.com',
redirectUri: 'https://ks.khhao.com/oauth',
scopes: 'merchant_item',
authState: 'default',
appKey: '1088715114',
appSecret: 'real_kuaishou_secret_value_12345',
signSecret: 'real_sign_secret_67890',
messageSecret: 'real_message_secret_abcde',
accessToken: '',
refreshToken: '',
accessTokenExpiresAt: '',
refreshTokenExpiresAt: '',
openId: '',
grantedScopes: '',
sellerId: '',
provider: '',
platform: '',
shopId: '',
shopName: '',
version: '1',
shops: [],
lastRefreshedAt: '',
lastRefreshError: '',
}
// 1. Payload with empty string secrets (default when page loads and user doesn't edit)
const emptyPatch = resolveSecretPatch(
{
appSecret: '',
signSecret: '',
messageSecret: '',
},
current,
)
assert.equal(emptyPatch.appSecret, 'real_kuaishou_secret_value_12345')
assert.equal(emptyPatch.signSecret, 'real_sign_secret_67890')
assert.equal(emptyPatch.messageSecret, 'real_message_secret_abcde')
// 2. Payload with masked string (e.g. browser autofill of placeholder or masked token)
const maskedPatch = resolveSecretPatch(
{
appSecret: 'SK_ATD******XXrqmD',
signSecret: 'real_s****7890',
},
current,
)
assert.equal(maskedPatch.appSecret, 'real_kuaishou_secret_value_12345')
assert.equal(maskedPatch.signSecret, 'real_sign_secret_67890')
// 3. Payload with genuinely new secret
const validPatch = resolveSecretPatch(
{
appSecret: 'new_valid_app_secret_value_99999',
},
current,
)
assert.equal(validPatch.appSecret, 'new_valid_app_secret_value_99999')
assert.equal(validPatch.signSecret, 'real_sign_secret_67890')
assert.equal(validPatch.messageSecret, 'real_message_secret_abcde')
})
@@ -213,14 +213,31 @@ function normalizeScopeText(value: unknown): string {
.join(',')
}
function resolveSecretPatch(
export function isMaskedSecretValue(value: unknown, currentSecret = ''): boolean {
const text = String(value || '').trim()
if (!text) {
return true
}
if (text.includes('****') || text.includes('***')) {
return true
}
if (currentSecret && text === maskSecret(currentSecret)) {
return true
}
return false
}
export function resolveSecretPatch(
payload: JsonObject,
current: KuaishouIndustrySourceConfig,
): Partial<KuaishouIndustrySourceConfig> {
const patch: Partial<KuaishouIndustrySourceConfig> = {}
for (const field of SECRET_FIELDS) {
const text = String(payload[field] || '').trim()
patch[field] = text || current[field]
patch[field] = !text || isMaskedSecretValue(text, current[field]) ? current[field] : text
}
return patch
@@ -352,7 +369,7 @@ function resolveShopSecretPatch(
function readSecretString(payload: JsonObject, field: string, fallback: string): string {
const text = String(payload[field] || '').trim()
return text || fallback
return !text || isMaskedSecretValue(text, fallback) ? fallback : text
}
function resolveAccessTokenStatus(