companion-oauth-pkce-stress.test.mjs
85 lines 2.9 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 2 days ago
1 /**
2 * Tier 4 — STRESS: high-volume generation and validation. Asserts no collisions in CSPRNG output,
3 * no accidental "ok" under a flood of hostile inputs, and bounded behavior at scale.
4 */
5 import { describe, it } from 'node:test';
6 import assert from 'node:assert/strict';
7 import crypto from 'node:crypto';
8 import {
9 createPkcePair,
10 createOAuthState,
11 createNonce,
12 computeCodeChallenge,
13 validateAuthorizationResponse,
14 validateTokenResponse,
15 validateRedirectUri,
16 } from '../lib/companion-oauth-pkce.mjs';
17
18 describe('Stress — CSPRNG outputs are unique and correct at volume', () => {
19 it('50k PKCE pairs: all verifiers unique, all challenges correct', () => {
20 const N = 50_000;
21 const verifiers = new Set();
22 for (let i = 0; i < N; i++) {
23 const { codeVerifier, codeChallenge } = createPkcePair();
24 verifiers.add(codeVerifier);
25 if (i % 5000 === 0) {
26 assert.equal(codeChallenge, crypto.createHash('sha256').update(codeVerifier, 'ascii').digest('base64url'));
27 }
28 }
29 assert.equal(verifiers.size, N, 'no verifier collisions');
30 });
31
32 it('100k states + nonces: no collisions', () => {
33 const N = 100_000;
34 const states = new Set();
35 const nonces = new Set();
36 for (let i = 0; i < N; i++) {
37 states.add(createOAuthState());
38 nonces.add(createNonce());
39 }
40 assert.equal(states.size, N);
41 assert.equal(nonces.size, N);
42 });
43 });
44
45 describe('Stress — 100k wrong-state callbacks never admit', () => {
46 it('an exhaustive flood of mismatched states is always rejected', () => {
47 const expected = createOAuthState();
48 let admits = 0;
49 for (let i = 0; i < 100_000; i++) {
50 const r = validateAuthorizationResponse({ params: { code: 'c', state: 'guess-' + i }, expectedState: expected });
51 if (r.ok) admits += 1;
52 }
53 assert.equal(admits, 0);
54 });
55 });
56
57 describe('Stress — hostile token responses never validate', () => {
58 it('50k malformed token responses all fail closed', () => {
59 let oks = 0;
60 for (let i = 0; i < 50_000; i++) {
61 const variants = [
62 { access_token: '', token_type: 'Bearer', expires_in: 60 },
63 { access_token: 'x'.repeat((i % 20000) + 1), token_type: 'Bearer' }, // no expires_in
64 { access_token: 'x', token_type: 'nope', expires_in: 60 },
65 { error: 'e' + i },
66 ];
67 const v = validateTokenResponse(variants[i % variants.length]);
68 if (v.ok) oks += 1;
69 }
70 assert.equal(oks, 0);
71 });
72 });
73
74 describe('Stress — large redirect inputs are bounded and rejected', () => {
75 it('an oversized redirect uri is rejected without error', () => {
76 const huge = 'http://127.0.0.1:49321/' + 'a'.repeat(20000);
77 const r = validateRedirectUri(huge);
78 assert.equal(r.ok, false);
79 });
80 it('many computeCodeChallenge calls stay correct', () => {
81 const v = createPkcePair().codeVerifier;
82 const expected = computeCodeChallenge(v);
83 for (let i = 0; i < 20_000; i++) assert.equal(computeCodeChallenge(v), expected);
84 });
85 });
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 2 days ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 2 days ago