import { createSign, generateKeyPairSync } from 'node:crypto'; import { describe, expect, it } from 'vitest'; import { verifySsv } from '../src/quest/ad_ssv.js'; /** AdMob SSV 서명 검증(fn-ad-ssv) — 에뮬레이터 없이 도는 순수 검증. */ describe('AdMob SSV 서명 검증', () => { const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'prime256v1' }); const keys = new Map([['42', publicKey.export({ type: 'spki', format: 'pem' }) as string]]); const sign = (message: string) => createSign('sha256').update(message).sign(privateKey) .toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); const message = 'ad_network=5450213213286189855&ad_unit=1234&custom_data=tx1&reward_amount=1' + '&reward_item=Reward×tamp=1507770365237823&transaction_id=abc&user_id=u1'; it('서명이 맞으면 파라미터를 돌려준다', () => { const params = verifySsv(`${message}&signature=${sign(message)}&key_id=42`, keys); expect(params?.get('user_id')).toBe('u1'); expect(params?.get('custom_data')).toBe('tx1'); }); it('값을 바꾸거나 모르는 키 · 서명 없음이면 거부한다', () => { const sig = sign(message); expect(verifySsv(`${message.replace('u1', 'u2')}&signature=${sig}&key_id=42`, keys)).toBeNull(); expect(verifySsv(`${message}&signature=${sig}&key_id=7`, keys)).toBeNull(); expect(verifySsv(message, keys)).toBeNull(); }); });