修复快手销毁请求验签

This commit is contained in:
yml2213
2026-07-08 17:36:52 +08:00
parent 5902ac65d3
commit 5f29e73205
2 changed files with 86 additions and 1 deletions
@@ -0,0 +1,65 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import {
buildKuaishouIndustrySignSource,
signKuaishouIndustryPayload,
verifyKuaishouIndustrySignature,
} from './crypto.js'
const TEST_CONFIG = { signSecret: 'test-secret' } as any
test('buildKuaishouIndustrySignSource keeps nested eticket fields for destroy-code payload', () => {
const source = buildKuaishouIndustrySignSource(
{
appkey: 'ks-test',
param: {
oid: '2618901686368642',
reason: 'USER_APPLY_REFUND',
etickets: [
{
code: null,
goodsValue: 3800,
id: 'KSVW9JTD4FZM4VDHKBV',
num: 1,
},
],
},
signMethod: 'MD5',
timestamp: 1783497998539,
version: '1',
},
TEST_CONFIG,
)
assert.match(
source,
/param=\{"etickets":\[\{"code":null,"goodsValue":3800,"id":"KSVW9JTD4FZM4VDHKBV","num":1\}\],"oid":"2618901686368642","reason":"USER_APPLY_REFUND"\}/,
)
assert.doesNotMatch(source, /"etickets":\[\{\}\]/)
})
test('verifyKuaishouIndustrySignature accepts nested object payload signed by the same canonical source', () => {
const payload = {
appkey: 'ks-test',
param: {
oid: '2618901686368642',
reason: 'USER_APPLY_REFUND',
etickets: [
{
code: null,
goodsValue: 3800,
id: 'KSVW9JTD4FZM4VDHKBV',
num: 1,
},
],
},
signMethod: 'MD5',
timestamp: 1783497998539,
version: '1',
}
const sign = signKuaishouIndustryPayload(payload, 'MD5', TEST_CONFIG)
assert.equal(verifyKuaishouIndustrySignature({ ...payload, sign }, TEST_CONFIG), true)
})
@@ -103,8 +103,28 @@ function stringifySignValue(value: unknown) {
}
if (typeof value === 'object') {
return JSON.stringify(value, Object.keys(value as Record<string, unknown>).sort())
return JSON.stringify(normalizeSignJsonValue(value))
}
return String(value)
}
function normalizeSignJsonValue(value: unknown): unknown {
if (Array.isArray(value)) {
return value.map((item) => normalizeSignJsonValue(item))
}
if (value && typeof value === 'object') {
const record = value as Record<string, unknown>
const normalized: Record<string, unknown> = {}
for (const key of Object.keys(record).sort()) {
const current = normalizeSignJsonValue(record[key])
if (current !== undefined) {
normalized[key] = current
}
}
return normalized
}
return value
}