97 lines
3.2 KiB
JavaScript
97 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const crypto = require('node:crypto');
|
|
const test = require('node:test');
|
|
|
|
const {
|
|
CREDENTIAL_VALIDITY_MS,
|
|
DEFAULT_ENDPOINT_URL,
|
|
buildAlibaba1688SignedHeaders,
|
|
extractAkKeys,
|
|
getAlibaba1688GatewayError,
|
|
getCredentialValidity,
|
|
stripSecretFields,
|
|
} = require('../src/services/alibaba1688ImageSearchSettings');
|
|
|
|
test('extractAkKeys decodes the dedicated 1688 credential format', () => {
|
|
const secret = 's'.repeat(32);
|
|
const akId = 'dedicated-1688-access-id';
|
|
const encoded = Buffer.from(`${secret}${akId}`, 'utf8').toString('base64url');
|
|
|
|
assert.deepEqual(extractAkKeys(encoded), { secret, akId });
|
|
});
|
|
|
|
test('buildAlibaba1688SignedHeaders creates the required gateway headers', () => {
|
|
const secret = 'x'.repeat(32);
|
|
const akId = 'image-search-access-id';
|
|
const ak = Buffer.from(`${secret}${akId}`, 'utf8').toString('base64url');
|
|
const body = JSON.stringify({ imageUrl: 'https://example.com/product.jpg', pageSize: 10 });
|
|
const headers = buildAlibaba1688SignedHeaders({
|
|
method: 'POST',
|
|
uri: '/api/find_product/1.0.0',
|
|
body,
|
|
ak,
|
|
});
|
|
|
|
assert.equal(headers['Content-Type'], 'application/json');
|
|
assert.equal(headers['x-csk-ak'], akId);
|
|
assert.equal(headers['x-csk-version'], '1.7.0');
|
|
assert.equal(headers['x-csk-content-md5'], crypto.createHash('md5').update(body, 'utf8').digest('base64'));
|
|
assert.match(headers['x-csk-time'], /^\d+$/);
|
|
assert.match(headers['x-csk-nonce'], /^[a-f0-9]{8}$/);
|
|
assert.ok(headers['x-csk-sign']);
|
|
});
|
|
|
|
test('legacy 1688 secrets are removed from general configuration', () => {
|
|
assert.deepEqual(stripSecretFields({
|
|
endpointUrl: DEFAULT_ENDPOINT_URL,
|
|
timeoutMs: 45000,
|
|
ak: 'legacy-ak',
|
|
apiKey: 'legacy-api-key',
|
|
api_key: 'legacy-api-key-2',
|
|
}), {
|
|
endpointUrl: DEFAULT_ENDPOINT_URL,
|
|
timeoutMs: 45000,
|
|
});
|
|
});
|
|
|
|
test('1688 gateway business responses reject disabled credentials', () => {
|
|
assert.equal(getAlibaba1688GatewayError({
|
|
success: false,
|
|
code: 'AccessKeyDisabled',
|
|
msgInfo: 'AccessKey已被禁用',
|
|
httpCode: 200,
|
|
}), 'AccessKey已被禁用');
|
|
assert.equal(getAlibaba1688GatewayError({
|
|
success: true,
|
|
code: 'SUCCESS',
|
|
msgInfo: '成功',
|
|
httpCode: 200,
|
|
}), '');
|
|
});
|
|
|
|
test('tracked 1688 credentials expose a seven-day countdown without rounding away time', () => {
|
|
const now = Date.parse('2026-09-11T01:00:00.000Z');
|
|
const validity = getCredentialValidity({
|
|
ak: 'configured-ak',
|
|
credentialUpdatedAt: new Date(now).toISOString(),
|
|
credentialExpiresAt: new Date(now + CREDENTIAL_VALIDITY_MS).toISOString(),
|
|
}, now);
|
|
|
|
assert.equal(validity.status, 'active');
|
|
assert.equal(validity.tracked, true);
|
|
assert.equal(validity.validityDays, 7);
|
|
assert.equal(validity.remainingDays, 7);
|
|
assert.equal(validity.percentRemaining, 100);
|
|
});
|
|
|
|
test('legacy 1688 credentials remain explicitly untracked instead of inventing an expiry date', () => {
|
|
const validity = getCredentialValidity({ ak: 'legacy-ak' }, Date.parse('2026-09-11T01:00:00.000Z'));
|
|
|
|
assert.equal(validity.status, 'untracked');
|
|
assert.equal(validity.tracked, false);
|
|
assert.equal(validity.expiresAt, null);
|
|
assert.equal(validity.remainingDays, null);
|
|
});
|