import { constantTimeEqual, normalizeStripeTier, tierFromStripeSubscriptionPrice, verifyStripeSignature, } from './index.ts' function assert(condition: boolean, message: string): asserts condition { if (!condition) throw new Error(message) } async function stripeHeader(payload: string, secret: string, timestamp: number): Promise { const key = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'], ) const signature = await crypto.subtle.sign( 'HMAC', key, new TextEncoder().encode(`${timestamp}.${payload}`), ) const hex = Array.from(new Uint8Array(signature)) .map((part) => part.toString(16).padStart(2, '0')) .join('') return `t=${timestamp},v1=${hex}` } Deno.test('Stripe signature verifies exact payload and rejects tampering', async () => { const now = 1_800_000_000 const payload = JSON.stringify({ id: 'evt_test', type: 'customer.subscription.updated' }) const header = await stripeHeader(payload, 'whsec_test', now) assert(await verifyStripeSignature(payload, header, 'whsec_test', 300, now * 1000), 'valid signature') assert( !(await verifyStripeSignature(`${payload} `, header, 'whsec_test', 300, now * 1000)), 'payload mutation must fail', ) assert( !(await verifyStripeSignature(payload, header, 'different', 300, now * 1000)), 'wrong secret must fail', ) }) Deno.test('Stripe signature rejects stale and ambiguous timestamp headers', async () => { const timestamp = 1_800_000_000 const payload = '{}' const header = await stripeHeader(payload, 'whsec_test', timestamp) assert( !(await verifyStripeSignature(payload, header, 'whsec_test', 300, (timestamp + 301) * 1000)), 'stale signature must fail', ) assert( !(await verifyStripeSignature(payload, `${header},t=${timestamp}`, 'whsec_test', 300, timestamp * 1000)), 'multiple timestamp fields must fail', ) }) Deno.test('Stripe tier is derived from the exact configured subscription price', () => { const prices = { pro: 'price_pro', pro_plus: 'price_pro_plus' } assert(tierFromStripeSubscriptionPrice({ items: { data: [{ price: { id: 'price_pro' } }] }, }, prices) === 'pro', 'pro price must map to pro') assert(tierFromStripeSubscriptionPrice({ items: { data: [{ price: { id: 'price_pro_plus' } }] }, }, prices) === 'pro_plus', 'pro plus price must map to pro_plus') assert(tierFromStripeSubscriptionPrice({ items: { data: [{ price: { id: 'price_attacker' } }] }, }, prices) === null, 'unknown price must fail closed') assert(tierFromStripeSubscriptionPrice({ items: { data: [{ price: { id: 'price_pro' } }, { price: { id: 'price_pro_plus' } }] }, }, prices) === null, 'ambiguous multi-price subscription must fail closed') assert(normalizeStripeTier('team') === 'pro_plus', 'legacy team alias maps only to pro_plus') assert(normalizeStripeTier('enterprise') === null, 'unknown metadata tier must fail') }) Deno.test('constant-time comparator rejects length and value mismatch', () => { assert(constantTimeEqual('abc', 'abc'), 'equal strings') assert(!constantTimeEqual('abc', 'abd'), 'different strings') assert(!constantTimeEqual('abc', 'ab'), 'different lengths') })