@lifeaitools/clauth 1.5.20 → 1.5.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2506,8 +2506,9 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
2506
2506
  const oauthClients = new Map(); // client_id → { client_secret, redirect_uris, client_name }
2507
2507
  const oauthCodes = new Map(); // code → { client_id, redirect_uri, code_challenge, expires }
2508
2508
 
2509
- // Persist tokens to disk so daemon restarts don't invalidate claude.ai sessions
2509
+ // Persist tokens + credentials to disk so daemon restarts don't invalidate sessions
2510
2510
  const TOKENS_FILE = path.join(os.tmpdir(), "clauth-oauth-tokens.json");
2511
+ const CREDS_FILE = path.join(os.tmpdir(), "clauth-oauth-creds.json");
2511
2512
  function loadTokens() {
2512
2513
  try { return new Set(JSON.parse(fs.readFileSync(TOKENS_FILE, "utf8"))); } catch { return new Set(); }
2513
2514
  }
@@ -2516,9 +2517,22 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
2516
2517
  }
2517
2518
  const oauthTokens = loadTokens(); // active access tokens — persisted across restarts
2518
2519
 
2519
- // Pre-generate a stable client for claude.ai (shown at startup)
2520
- const OAUTH_CLIENT_ID = crypto.randomBytes(16).toString("hex");
2521
- const OAUTH_CLIENT_SECRET = crypto.randomBytes(32).toString("hex");
2520
+ // Stable client credentials persist across restarts so claude.ai custom setup works
2521
+ function loadOrCreateCreds() {
2522
+ try {
2523
+ const saved = JSON.parse(fs.readFileSync(CREDS_FILE, "utf8"));
2524
+ if (saved.client_id && saved.client_secret) return saved;
2525
+ } catch {}
2526
+ const creds = {
2527
+ client_id: crypto.randomBytes(16).toString("hex"),
2528
+ client_secret: crypto.randomBytes(32).toString("hex"),
2529
+ };
2530
+ try { fs.writeFileSync(CREDS_FILE, JSON.stringify(creds)); } catch {}
2531
+ return creds;
2532
+ }
2533
+ const stableCreds = loadOrCreateCreds();
2534
+ const OAUTH_CLIENT_ID = stableCreds.client_id;
2535
+ const OAUTH_CLIENT_SECRET = stableCreds.client_secret;
2522
2536
  oauthClients.set(OAUTH_CLIENT_ID, {
2523
2537
  client_id: OAUTH_CLIENT_ID, client_secret: OAUTH_CLIENT_SECRET,
2524
2538
  client_name: "claude.ai", redirect_uris: ["https://claude.ai/api/mcp/auth_callback"],
@@ -2880,12 +2894,17 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
2880
2894
 
2881
2895
  // ── OAuth Discovery (RFC 9728 + RFC 8414) ──────────────
2882
2896
  // claude.ai probes these for ALL remote MCP connections.
2883
- // resource MUST match the connector URL configured in claude.ai (/sse).
2897
+ // resource MUST match the connector URL configured in claude.ai.
2898
+ // /.well-known/oauth-protected-resource/gws → resource=/gws
2899
+ // /.well-known/oauth-protected-resource/sse → resource=/sse
2900
+ // /.well-known/oauth-protected-resource → resource=/sse (default)
2884
2901
  if (reqPath.startsWith("/.well-known/oauth-protected-resource")) {
2885
2902
  const base = oauthBase();
2903
+ const suffix = reqPath.replace("/.well-known/oauth-protected-resource", "").replace(/^\//, "");
2904
+ const resourcePath = suffix && ["/gws", "/clauth", "/mcp", "/sse"].includes("/" + suffix) ? "/" + suffix : "/sse";
2886
2905
  res.writeHead(200, { "Content-Type": "application/json", ...CORS });
2887
2906
  return res.end(JSON.stringify({
2888
- resource: `${base}/sse`,
2907
+ resource: `${base}${resourcePath}`,
2889
2908
  authorization_servers: [base],
2890
2909
  scopes_supported: ["mcp:tools"],
2891
2910
  bearer_methods_supported: ["header"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.5.20",
3
+ "version": "1.5.22",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {