import { describe, expect, it } from 'vitest'; import { TICKET_TTL_MS, createTicketIssuer } from '../ticket.ts'; const issuer = createTicketIssuer(Buffer.alloc(32, 7)); const t0 = new Date('2026-08-25T09:00:00Z'); describe('60 秒票据', () => { it('签出来能验回 sub;形状 v1...;到期时刻 = 签发 + 60s', () => { const { ticket, expiresAt } = issuer.issue('sub-1', t0); expect(ticket.split('.')).toHaveLength(4); expect(ticket.startsWith('v1.')).toBe(true); expect(expiresAt.getTime() - t0.getTime()).toBe(TICKET_TTL_MS); expect(issuer.verify(ticket, new Date(t0.getTime() + 30_000))).toEqual({ staffId: 'sub-1' }); }); it('到期即拒(61 秒后)', () => { const { ticket } = issuer.issue('sub-1', t0); expect(issuer.verify(ticket, new Date(t0.getTime() + TICKET_TTL_MS + 1000))).toBeUndefined(); }); it('改一个字就拒:mac / sub / exp', () => { const { ticket } = issuer.issue('sub-1', t0); const [v, id, exp, mac] = ticket.split('.') as [string, string, string, string]; expect(issuer.verify(`${v}.${id}.${exp}.${mac.slice(0, -1)}${mac.endsWith('A') ? 'B' : 'A'}`, t0)).toBeUndefined(); expect(issuer.verify(`${v}.${Buffer.from('sub-2').toString('base64url')}.${exp}.${mac}`, t0)).toBeUndefined(); expect(issuer.verify(`${v}.${id}.${Number(exp) + 600}.${mac}`, t0)).toBeUndefined(); }); it('别的密钥签的不认', () => { const other = createTicketIssuer(Buffer.alloc(32, 8)); expect(issuer.verify(other.issue('sub-1', t0).ticket, t0)).toBeUndefined(); }); it('垃圾输入不抛只拒', () => { expect(issuer.verify('', t0)).toBeUndefined(); expect(issuer.verify('v2.a.b.c', t0)).toBeUndefined(); expect(issuer.verify('a.b', t0)).toBeUndefined(); expect(issuer.verify('v1...', t0)).toBeUndefined(); }); });