修复快手appSecret意外修改问题
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user