mirror of
https://github.com/hanzoai/extension.git
synced 2026-10-31 21:57:06 +00:00
Five surfaces (browser, office, vscode, cli, mcp) each hand-rolled the SAME
IAM OAuth2+PKCE flow — and one drifted and broke: vscode built
hanzo.id/oauth/authorize and iam.hanzo.ai/oauth/token, both MISSING the
/v1/iam prefix (a 404 — the same class of bug as the browser login fix),
plus it POSTed JSON where IAM requires form-urlencoded and sent a
client_secret on a public PKCE client. That is the opposite of one way.
Decomplected into ONE core — packages/auth (@hanzo/auth):
- config.ts canonical HIP-0111 endpoints (authorize/token/userinfo ALL
carry /v1/iam) + the one-client-per-surface registry
(hanzo-browser/office/vscode/cli). URL assembly lives once.
- pkce.ts the one PKCE (S256), platform-CSPRNG + WebCrypto.
- oauth.ts buildAuthorizeURL / exchangeCode / refreshTokens / userinfo —
pure fetch, form-encoded per RFC 6749.
- flow.ts login / getValidToken (transparent refresh) / logout /
currentUser, written ONCE against TokenStore + Opener. A
surface supplies only those two thin adapters — no surface
re-implements the flow.
23 tests: the drift guard (every path has /v1/iam), client registry, PKCE
RFC-7636 vector, wire shapes, and the full flow with fake adapters.
Migrate office onto it: roamingSettings TokenStore + Dialog-API Opener;
delete office's duplicate pkce.ts + IAM config (now the core's). API-key
path kept. 22 tests; the core bundles into the task pane.
Fix vscode standalone-auth: all three endpoints → ${host}/v1/iam/oauth/*,
token calls form-urlencoded, OIDC scopes, drop the secret on the public
PKCE client. Compiles clean.
CI now gates @hanzo/auth. Browser/mcp/tools already use canonical paths;
migrating them to import the core is the tracked next step (each needs its
own bundler wiring) — the ONE way now exists and has two consumers.
15 lines
331 B
JSON
15 lines
331 B
JSON
{
|
|
"compilerOptions": {
|
|
"target": "ES2020",
|
|
"module": "ESNext",
|
|
"moduleResolution": "bundler",
|
|
"lib": ["ES2020", "DOM"],
|
|
"strict": true,
|
|
"noEmit": true,
|
|
"esModuleInterop": true,
|
|
"skipLibCheck": true,
|
|
"forceConsistentCasingInFileNames": true
|
|
},
|
|
"include": ["src/**/*.ts", "tests/**/*.ts"]
|
|
}
|