/** * MWT decode tests — round-trip + cross-language pin against Python create_mwt. */ import { describe, test, expect } from 'bun:test' import { createHmac } from 'crypto' import { decodeMwt, decodeJwtBearer, identityFromMwt } from '../src' function b64url(buf: Buffer | string): string { return Buffer.from(buf).toString('base64url') } /** Mint an HS256 MWT with node crypto, mirroring Python create_mwt. */ function mint(payload: Record, secret: string, kid = 'v1'): string { const header = b64url(JSON.stringify({ alg: 'HS256', kid, typ: 'JWT' })) const body = b64url(JSON.stringify(payload)) const sig = createHmac('sha256', secret).update(`${header}.${body}`).digest('base64url') return `${header}.${body}.${sig}` } const SECRET = 'round-trip-secret' const now = Math.floor(Date.now() / 1000) function basePayload(overrides: Record = {}) { return { sub: '7', staff: true, super: false, pkey: 'abc123', aud: 'mizan', iat: now, nbf: now, exp: now + 300, ...overrides, } } describe('MWT round-trip', () => { test('valid token decodes', () => { const token = mint(basePayload(), SECRET) const p = decodeMwt(token, SECRET) expect(p).not.toBeNull() expect(p!.sub).toBe('7') expect(p!.staff).toBe(true) expect(p!.super).toBe(false) expect(p!.pkey).toBe('abc123') expect(p!.kid).toBe('v1') expect(p!.aud).toBe('mizan') }) test('identityFromMwt maps claims', () => { const token = mint(basePayload({ sub: '99', staff: false, super: true }), SECRET) const p = decodeMwt(token, SECRET)! expect(identityFromMwt(p)).toEqual({ isAuthenticated: true, isStaff: false, isSuperuser: true, id: 99, }) }) test('decodeJwtBearer strips Bearer prefix', () => { const token = mint(basePayload(), SECRET) const p = decodeJwtBearer(`Bearer ${token}`, SECRET) expect(p).not.toBeNull() expect(p!.sub).toBe('7') }) test('null on tampered signature', () => { const token = mint(basePayload(), SECRET) const tampered = token.slice(0, -2) + (token.endsWith('AA') ? 'BB' : 'AA') expect(decodeMwt(tampered, SECRET)).toBeNull() }) test('null on wrong secret', () => { const token = mint(basePayload(), SECRET) expect(decodeMwt(token, 'other-secret')).toBeNull() }) test('null on expired exp', () => { const token = mint(basePayload({ exp: now - 10 }), SECRET) expect(decodeMwt(token, SECRET)).toBeNull() }) test('null on future nbf', () => { const token = mint(basePayload({ nbf: now + 1000 }), SECRET) expect(decodeMwt(token, SECRET)).toBeNull() }) test('null on wrong aud', () => { const token = mint(basePayload({ aud: 'other' }), SECRET) expect(decodeMwt(token, SECRET)).toBeNull() }) test('null on malformed token', () => { expect(decodeMwt('not.a.jwt', SECRET)).toBeNull() expect(decodeMwt('onlyonepart', SECRET)).toBeNull() expect(decodeMwt('', SECRET)).toBeNull() }) }) describe('MWT cross-language pin (Python create_mwt)', () => { const TOKEN = 'eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJzdWIiOiI0MiIsInN0YWZmIjp0cnVlLCJzdXBlciI6ZmFsc2UsInBrZXkiOiIwZTk5OGE5ZmYxNjkwNDYzN2EwM2QyZWEwZmJkYmY5NzQyOTdhOWQxYTVkMjViOGQ0Mjk0ZmE4ODIxMTVlNDU3IiwiYXVkIjoibWl6YW4iLCJpYXQiOjE3MDAwMDAwMDAsIm5iZiI6MTcwMDAwMDAwMCwiZXhwIjo0MTAyNDQ0ODAwfQ._V92JXiLSLXoyuSwbNvvJjwzgmczmC7dvX34kVSLIa8' const PIN_SECRET = 'pin-test-secret-mwt' test('decodes the Python-minted token', () => { const p = decodeMwt(TOKEN, PIN_SECRET) expect(p).not.toBeNull() expect(p!.sub).toBe('42') expect(p!.staff).toBe(true) expect(p!.super).toBe(false) expect(p!.pkey).toBe('0e998a9ff16904637a03d2ea0fbdbf974297a9d1a5d25b8d4294fa882115e457') expect(p!.kid).toBe('v1') expect(p!.aud).toBe('mizan') }) test('identity from Python-minted token', () => { const p = decodeMwt(TOKEN, PIN_SECRET)! expect(identityFromMwt(p)).toEqual({ isAuthenticated: true, isStaff: true, isSuperuser: false, id: 42, }) }) })