Files
sub2apipay/src/__tests__/lib/order/code-gen.test.ts
erio 4ce3484179 fix: 全面安全审计修复 — 支付验签、IDOR、竞态、token过期等
- H1: 支付宝响应验签 (verifyResponseSign + bracket-matching 提取签名内容)
- H2/H3: EasyPay queryOrder 从 GET 改 POST,PKEY 不再暴露于 URL
- H5: users/[id] IDOR 修复,校验当前用户只能查询自身信息
- H6: 限额校验移入 prisma.$transaction() 防止 TOCTOU 竞态
- C1: access_token 增加 24h 过期、userId 绑定、派生密钥分离
- M1: EasyPay 回调增加 pid 校验防跨商户注入
- M4: 充值码增加 crypto.randomBytes 随机后缀
- M5: 过期订单批量处理增加 BATCH_SIZE 限制
- M6: 退款失败增加 [CRITICAL] 日志和余额补偿标记
- M7: admin channels PUT 增加 Zod schema 校验
- M8: admin subscriptions 分页参数增加上限
- M9: orders src_url 限制 HTTP/HTTPS 协议
- L1: 微信支付回调时间戳 NaN 检查
- L9: WXPAY_API_V3_KEY 长度校验
2026-03-14 04:36:33 +08:00

32 lines
1.1 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { generateRechargeCode } from '@/lib/order/code-gen';
describe('generateRechargeCode', () => {
it('should generate code with s2p_ prefix and random suffix', () => {
const code = generateRechargeCode('cm1234567890');
expect(code.startsWith('s2p_')).toBe(true);
expect(code.length).toBeLessThanOrEqual(32);
// 包含 orderId 部分和 8 字符随机后缀
expect(code.length).toBeGreaterThan(12);
});
it('should truncate long order IDs to fit 32 chars', () => {
const longId = 'a'.repeat(50);
const code = generateRechargeCode(longId);
expect(code.length).toBeLessThanOrEqual(32);
expect(code.startsWith('s2p_')).toBe(true);
});
it('should generate different codes for same orderId (randomness)', () => {
const code1 = generateRechargeCode('order-001');
const code2 = generateRechargeCode('order-001');
expect(code1).not.toBe(code2);
});
it('should handle empty string', () => {
const code = generateRechargeCode('');
expect(code.startsWith('s2p_')).toBe(true);
expect(code.length).toBeLessThanOrEqual(32);
});
});