auth-refresh-wiring.test.mjs
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf
mirror: GitHub Phase A durable MCP OAuth (#270)
Human
minor
⚠ breaking
11 days ago
| 1 | /** |
| 2 | * Structural wiring tests — proves the self-hosted Hub actually mounts the persistent-session |
| 3 | * machinery (refresh-token rotation + HttpOnly cookie + real logout). These guard the |
| 4 | * integration points; the behavioral guarantees are covered by refresh-token-core, |
| 5 | * refresh-tokens-store, and auth-session test suites. |
| 6 | */ |
| 7 | |
| 8 | import { test, describe } from 'node:test'; |
| 9 | import assert from 'node:assert/strict'; |
| 10 | import fs from 'node:fs'; |
| 11 | import path from 'node:path'; |
| 12 | import { fileURLToPath } from 'node:url'; |
| 13 | |
| 14 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
| 15 | const ROOT = path.resolve(__dirname, '..'); |
| 16 | |
| 17 | describe('self-hosted Hub wires persistent sessions', () => { |
| 18 | let src; |
| 19 | const load = () => { |
| 20 | if (!src) src = fs.readFileSync(path.join(ROOT, 'hub/server.mjs'), 'utf8'); |
| 21 | return src; |
| 22 | }; |
| 23 | |
| 24 | test('imports cookie-parser and registers it as middleware', () => { |
| 25 | const s = load(); |
| 26 | assert.ok(s.includes("import cookieParser from 'cookie-parser'"), 'must import cookie-parser'); |
| 27 | assert.ok(s.includes('app.use(cookieParser())'), 'must register cookieParser middleware'); |
| 28 | }); |
| 29 | |
| 30 | test('imports the refresh-token store and auth-session helpers', () => { |
| 31 | const s = load(); |
| 32 | assert.ok(s.includes("from './refresh-tokens.mjs'"), 'must import the refresh-token store'); |
| 33 | assert.ok(s.includes("from './auth-session.mjs'"), 'must import auth-session helpers'); |
| 34 | }); |
| 35 | |
| 36 | test('mounts POST /api/v1/auth/refresh and /api/v1/auth/logout', () => { |
| 37 | const s = load(); |
| 38 | assert.ok(/app\.post\(\s*'\/api\/v1\/auth\/refresh'/.test(s), 'must mount POST /auth/refresh'); |
| 39 | assert.ok(/app\.post\(\s*'\/api\/v1\/auth\/logout'/.test(s), 'must mount POST /auth/logout'); |
| 40 | }); |
| 41 | |
| 42 | test('refresh route uses createRefreshHandler with the refresh store', () => { |
| 43 | const s = load(); |
| 44 | const block = s.slice(s.indexOf("'/api/v1/auth/refresh'"), s.indexOf("'/api/v1/auth/refresh'") + 400); |
| 45 | assert.ok(block.includes('createRefreshHandler'), 'refresh route must use createRefreshHandler'); |
| 46 | assert.ok(block.includes('issueAccessToken'), 'refresh route must supply an access-token signer'); |
| 47 | }); |
| 48 | |
| 49 | test('OAuth callback issues a refresh cookie', () => { |
| 50 | const s = load(); |
| 51 | const block = s.slice(s.indexOf('function handleAuthCallback')); |
| 52 | const end = block.indexOf('\n}\n'); |
| 53 | const body = block.slice(0, end > 0 ? end : 1200); |
| 54 | assert.ok(body.includes('issueRefreshCookie'), 'login callback must issue a refresh cookie'); |
| 55 | }); |
| 56 | |
| 57 | test('refresh cookie policy is HttpOnly and path-scoped to the auth endpoints', () => { |
| 58 | const s = load(); |
| 59 | assert.ok(s.includes('refreshCookieOptions'), 'must use refreshCookieOptions for the policy'); |
| 60 | // The policy helper centralizes HttpOnly; assert the auth-session module enforces it. |
| 61 | const sess = fs.readFileSync(path.join(ROOT, 'hub/auth-session.mjs'), 'utf8'); |
| 62 | assert.ok(sess.includes('httpOnly: true'), 'refresh cookie must be HttpOnly'); |
| 63 | assert.ok(sess.includes("REFRESH_COOKIE_PATH = '/api/v1/auth'"), 'cookie must be scoped to /api/v1/auth'); |
| 64 | }); |
| 65 | |
| 66 | test('logout uses createLogoutHandler (server-side revocation)', () => { |
| 67 | const s = load(); |
| 68 | const block = s.slice(s.indexOf("'/api/v1/auth/logout'"), s.indexOf("'/api/v1/auth/logout'") + 300); |
| 69 | assert.ok(block.includes('createLogoutHandler'), 'logout must use createLogoutHandler'); |
| 70 | }); |
| 71 | }); |
File History
3 commits
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf
mirror: GitHub Phase A durable MCP OAuth (#270)
Human
minor
⚠
11 days ago
sha256:d8c648b20a4d53b2673c5c082ee7edfa7b2fc9b11080832da1f38807b6bf940b
fix(7C-L1b): route hosted delegation proposals through cani…
Human
minor
⚠
31 days ago
sha256:2827ba9e7632a4b141c50caf1e8f7d77abbc3515be20e7465f2bccb0ac4edf91
fix: repair endpoint now sets has_active_subscription when …
Human
minor
⚠
51 days ago