45 lines
2.3 KiB
JavaScript
45 lines
2.3 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { admissionNoticeCode, resolveDocumentVerificationSecret, safeCodeEqual, scoreReportCode } from '../src/security/document-verification.mjs';
|
|
|
|
const secret = 'test-document-verification-secret-32-characters';
|
|
const exam = { id: 'exam_1' };
|
|
const registration = { id: 'registration_1', userId: 'candidate_1' };
|
|
const results = [
|
|
{ subjectId: 'math', score: 118, publishedAt: '2026-07-20T08:00:00.000Z' },
|
|
{ subjectId: 'chinese', score: 112, publishedAt: '2026-07-20T08:00:00.000Z' }
|
|
];
|
|
|
|
const scoreCode = scoreReportCode(secret, registration, exam, results);
|
|
const reorderedCode = scoreReportCode(secret, registration, exam, [...results].reverse());
|
|
const changedScoreCode = scoreReportCode(secret, registration, exam, [{ ...results[0], score: 119 }, results[1]]);
|
|
|
|
assert.match(scoreCode, /^SR-[A-F0-9]{24}$/);
|
|
assert.equal(scoreCode, reorderedCode, '科目返回顺序不应改变同一成绩单的防伪码');
|
|
assert.notEqual(scoreCode, changedScoreCode, '成绩变化必须使旧防伪码失效');
|
|
assert.equal(safeCodeEqual(scoreCode, scoreCode.toLowerCase()), true);
|
|
assert.equal(safeCodeEqual(scoreCode, `${scoreCode}0`), false);
|
|
|
|
const placement = {
|
|
id: 'placement_1', userId: 'candidate_1', schoolId: 'school_1',
|
|
payload: { categoryCode: 'general', noticeNumber: 'AD01-EX-2026-000001' }, updatedAt: '2026-07-21T08:00:00.000Z'
|
|
};
|
|
const noticeCode = admissionNoticeCode(secret, placement, exam);
|
|
const movedSchoolCode = admissionNoticeCode(secret, { ...placement, schoolId: 'school_2' }, exam);
|
|
const changedNumberCode = admissionNoticeCode(secret, { ...placement, payload: { ...placement.payload, noticeNumber: 'AD01-EX-2026-000002' } }, exam);
|
|
|
|
assert.match(noticeCode, /^AN-[A-F0-9]{24}$/);
|
|
assert.notEqual(noticeCode, movedSchoolCode, '录取学校变化必须使旧通知书防伪码失效');
|
|
assert.notEqual(noticeCode, changedNumberCode, '录取通知书编号变化必须使旧防伪码失效');
|
|
|
|
assert.throws(
|
|
() => resolveDocumentVerificationSecret({ NODE_ENV: 'production', DOCUMENT_VERIFICATION_SECRET: 'too-short' }),
|
|
/至少 32 个字符/,
|
|
'生产环境不得静默使用弱密钥或开发回退值'
|
|
);
|
|
assert.equal(
|
|
resolveDocumentVerificationSecret({ NODE_ENV: 'production', DOCUMENT_VERIFICATION_SECRET: secret }),
|
|
secret
|
|
);
|
|
|
|
console.log('✓ 文书防伪码稳定性、篡改失效与安全比较测试通过');
|