Lines 5-45javascript
5 * fronts the MCP control plane) instead of doing a raw Supabase session login.
6 * This yields SCOPED access tokens (`mcp:read` / `mcp:write`) — not the full
7 * Supabase god-token — so a leaked CLI credential can only do what the CLI was
8 * granted, and grants are independently revocable server-side (MNE-805/806).
10 * Two interactive flows, both standards-based:
11 * - Authorization Code + PKCE with a loopback redirect (the `wrangler login`
12 * pattern): open the browser to /authorize, catch the redirect on a
13 * localhost listener, exchange code+verifier at /token.
14 * - RFC 8628 Device Authorization Grant (`--no-browser` / headless): POST
15 * /device_authorization, print the user_code + verification_uri, poll
16 * /token honoring `authorization_pending` and `slow_down`.
18 * Everything is driven off RFC 8414 discovery
19 * (/.well-known/oauth-authorization-server) — endpoint paths are NOT hardcoded.
20 * The public client_id is obtained via RFC 7591 Dynamic Client Registration and
21 * cached, so there is no client secret to embed (the AS advertises
22 * token_endpoint_auth_method "none" — public clients only).
24import * as http from "node:http";
25import * as crypto from "node:crypto";
26import { execFile } from "node:child_process";
27import { getApiUrl } from "./config.js";
HighChild Process
Package source references child process execution.
dist/lib/oauth.jsView on unpkg · L25 28// The scopes the CLI requests. The AS currently advertises mcp:read + mcp:write
29// (scopes_supported in discovery); we request both so a single login covers the
30// full command surface. If discovery ever narrows what's available we intersect
31// against scopes_supported before asking, so we never request an unknown scope.
32const REQUESTED_SCOPES = ["mcp:read", "mcp:write"];
33const CLIENT_NAME = "Mnemom CLI";
34const DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
35// Loopback login waits at most this long for the browser round-trip before
36// giving up and freeing the port.
37const LOOPBACK_TIMEOUT_MS = 5 * 60 * 1000;
38// Cadence for the "…still waiting for you to finish signing in" heartbeat that
39// both interactive login poll loops emit, so a multi-minute browser sign-in
40// doesn't read as a hung CLI (matches the card-write retry tick in try-me).
41const LOGIN_HEARTBEAT_MS = 15 * 1000;
42// Refresh-token retry policy (R6 / MNE-7394). A transient AS 5xx or a dropped
43// network connection during refresh must be retried with bounded exponential
44// backoff rather than collapsed into the re-login signal — a one-second AS
45// hiccup or a flaky Wi-Fi moment must not invalidate a valid, long-lived