@lifeaitools/clauth 1.5.26 → 1.5.28

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.
@@ -2934,38 +2934,14 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
2934
2934
  return res.end();
2935
2935
  }
2936
2936
 
2937
- // ── OAuth Discovery (RFC 9728 + RFC 8414) ──────────────
2938
- // claude.ai probes these for ALL remote MCP connections.
2939
- // resource MUST match the connector URL configured in claude.ai.
2940
- // /.well-known/oauth-protected-resource/gws resource=/gws
2941
- // /.well-known/oauth-protected-resource/sse → resource=/sse
2942
- // /.well-known/oauth-protected-resource → resource=/sse (default)
2943
- if (reqPath.startsWith("/.well-known/oauth-protected-resource")) {
2944
- const base = oauthBase();
2945
- const suffix = reqPath.replace("/.well-known/oauth-protected-resource", "").replace(/^\//, "");
2946
- const resourcePath = suffix && ["/gws", "/clauth", "/mcp", "/sse"].includes("/" + suffix) ? "/" + suffix : "/clauth";
2947
- res.writeHead(200, { "Content-Type": "application/json", ...CORS });
2948
- return res.end(JSON.stringify({
2949
- resource: `${base}${resourcePath}`,
2950
- authorization_servers: [base],
2951
- scopes_supported: ["mcp:tools"],
2952
- bearer_methods_supported: ["header"],
2953
- }));
2954
- }
2955
-
2956
- if (reqPath === "/.well-known/oauth-authorization-server") {
2957
- const base = oauthBase();
2958
- res.writeHead(200, { "Content-Type": "application/json", ...CORS });
2959
- return res.end(JSON.stringify({
2960
- issuer: base,
2961
- authorization_endpoint: `${base}/authorize`,
2962
- token_endpoint: `${base}/token`,
2963
- registration_endpoint: `${base}/register`,
2964
- response_types_supported: ["code"],
2965
- grant_types_supported: ["authorization_code", "client_credentials"],
2966
- code_challenge_methods_supported: ["S256"],
2967
- scopes_supported: ["mcp:tools"],
2968
- }));
2937
+ // ── OAuth Discovery 404 well-known only ──────────────
2938
+ // claude.ai ignores metadata endpoints and constructs /register, /authorize,
2939
+ // /token from the domain root (issue #82). Keep well-known as 404 so claude.ai
2940
+ // uses the fallback paths. OAuth endpoints below are live.
2941
+ if (reqPath.startsWith("/.well-known/oauth-protected-resource") ||
2942
+ reqPath === "/.well-known/oauth-authorization-server") {
2943
+ res.writeHead(404, { "Content-Type": "application/json", ...CORS });
2944
+ return res.end(JSON.stringify({ error: "not_found" }));
2969
2945
  }
2970
2946
 
2971
2947
  // ── Dynamic Client Registration (RFC 7591) ──────────────
@@ -2998,7 +2974,6 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
2998
2974
  const redirectUri = url.searchParams.get("redirect_uri");
2999
2975
  const state = url.searchParams.get("state");
3000
2976
  const codeChallenge = url.searchParams.get("code_challenge");
3001
- const codeChallengeMethod = url.searchParams.get("code_challenge_method");
3002
2977
 
3003
2978
  if (!clientId || !redirectUri) {
3004
2979
  res.writeHead(400, { "Content-Type": "text/plain", ...CORS });
@@ -3008,7 +2983,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3008
2983
  const code = crypto.randomBytes(32).toString("hex");
3009
2984
  oauthCodes.set(code, {
3010
2985
  client_id: clientId, redirect_uri: redirectUri,
3011
- code_challenge: codeChallenge, code_challenge_method: codeChallengeMethod,
2986
+ code_challenge: codeChallenge,
3012
2987
  expires: Date.now() + 300_000,
3013
2988
  });
3014
2989
 
@@ -3016,7 +2991,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3016
2991
  redirect.searchParams.set("code", code);
3017
2992
  if (state) redirect.searchParams.set("state", state);
3018
2993
 
3019
- const logMsg = `[${new Date().toISOString()}] OAuth: authorize → code issued for ${clientId}, redirecting to ${redirect.origin}\n`;
2994
+ const logMsg = `[${new Date().toISOString()}] OAuth: authorize → code for ${clientId}, redirect to ${redirect.origin}\n`;
3020
2995
  try { fs.appendFileSync(LOG_FILE, logMsg); } catch {}
3021
2996
  res.writeHead(302, { Location: redirect.toString(), ...CORS });
3022
2997
  return res.end();
@@ -3038,23 +3013,6 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3038
3013
  return res.end(JSON.stringify({ error: "invalid_request" }));
3039
3014
  }
3040
3015
 
3041
- // client_credentials grant — skip authorize/redirect, just issue token from client_id+secret
3042
- if (body.grant_type === "client_credentials") {
3043
- const cid = body.client_id;
3044
- const csec = body.client_secret;
3045
- if (cid === OAUTH_CLIENT_ID && csec === OAUTH_CLIENT_SECRET) {
3046
- const accessToken = crypto.randomBytes(32).toString("hex");
3047
- oauthTokens.add(accessToken);
3048
- saveTokens(oauthTokens);
3049
- const logMsg = `[${new Date().toISOString()}] OAuth: client_credentials token issued for ${cid.slice(0,8)}… (token=${accessToken.slice(0,8)}…)\n`;
3050
- try { fs.appendFileSync(LOG_FILE, logMsg); } catch {}
3051
- res.writeHead(200, { "Content-Type": "application/json", ...CORS });
3052
- return res.end(JSON.stringify({ access_token: accessToken, token_type: "Bearer", expires_in: 86400, scope: "mcp:tools" }));
3053
- }
3054
- res.writeHead(401, { "Content-Type": "application/json", ...CORS });
3055
- return res.end(JSON.stringify({ error: "invalid_client" }));
3056
- }
3057
-
3058
3016
  if (body.grant_type !== "authorization_code") {
3059
3017
  res.writeHead(400, { "Content-Type": "application/json", ...CORS });
3060
3018
  return res.end(JSON.stringify({ error: "unsupported_grant_type" }));
@@ -3073,7 +3031,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3073
3031
  if (computed !== stored.code_challenge) {
3074
3032
  oauthCodes.delete(body.code);
3075
3033
  res.writeHead(400, { "Content-Type": "application/json", ...CORS });
3076
- return res.end(JSON.stringify({ error: "invalid_grant", error_description: "PKCE verification failed" }));
3034
+ return res.end(JSON.stringify({ error: "invalid_grant", error_description: "PKCE failed" }));
3077
3035
  }
3078
3036
  }
3079
3037
 
@@ -3082,10 +3040,10 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3082
3040
  oauthTokens.add(accessToken);
3083
3041
  saveTokens(oauthTokens);
3084
3042
 
3085
- const logMsg = `[${new Date().toISOString()}] OAuth: token issued for client ${stored.client_id} (token=${accessToken.slice(0,8)}…)\n`;
3043
+ const logMsg = `[${new Date().toISOString()}] OAuth: token issued for ${stored.client_id} (token=${accessToken.slice(0,8)}…)\n`;
3086
3044
  try { fs.appendFileSync(LOG_FILE, logMsg); } catch {}
3087
3045
  res.writeHead(200, { "Content-Type": "application/json", ...CORS });
3088
- return res.end(JSON.stringify({ access_token: accessToken, token_type: "Bearer", expires_in: 86400 }));
3046
+ return res.end(JSON.stringify({ access_token: accessToken, token_type: "Bearer", scope: "mcp:tools", expires_in: 86400 }));
3089
3047
  }
3090
3048
 
3091
3049
  // ── MCP path helpers ──
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.5.26",
3
+ "version": "1.5.28",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {