@frontmcp/auth 0.11.1 → 0.11.3

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.
@@ -113,6 +113,10 @@ export declare abstract class AuthorizationBase implements Authorization {
113
113
  * Convert to LLM-safe context (no tokens exposed)
114
114
  */
115
115
  toLLMSafeContext(session: TransportSession): LLMSafeAuthContext;
116
+ /**
117
+ * Check if a base64url segment decodes to a JWT-like header (contains "alg").
118
+ */
119
+ private static isJwtHeader;
116
120
  /**
117
121
  * Validate that no tokens are leaked in data
118
122
  * Throws if JWT pattern detected
@@ -1 +1 @@
1
- {"version":3,"file":"authorization.class.d.ts","sourceRoot":"","sources":["../../src/authorization/authorization.class.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authorization.class.d.ts","sourceRoot":"","sources":["../../src/authorization/authorization.class.ts"],"names":[],"mappings":"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"}
package/esm/index.mjs CHANGED
@@ -2560,8 +2560,8 @@ function deriveTypedUser(claims) {
2560
2560
  }
2561
2561
  function extractBearerToken(header) {
2562
2562
  if (!header) return void 0;
2563
- const m = header.match(/^\s*Bearer\s+(.+)\s*$/i);
2564
- return m ? m[1].trim() : void 0;
2563
+ const m = header.match(/^\s*Bearer\s+(\S+)\s*$/i);
2564
+ return m ? m[1] : void 0;
2565
2565
  }
2566
2566
 
2567
2567
  // libs/auth/src/session/utils/session-crypto.utils.ts
@@ -4471,8 +4471,8 @@ var progressiveAuthStateSchema = z7.object({
4471
4471
  });
4472
4472
 
4473
4473
  // libs/auth/src/authorization/authorization.class.ts
4474
- import { randomUUID as randomUUID10 } from "@frontmcp/utils";
4475
- var AuthorizationBase = class {
4474
+ import { randomUUID as randomUUID10, base64urlDecode as base64urlDecode4 } from "@frontmcp/utils";
4475
+ var AuthorizationBase = class _AuthorizationBase {
4476
4476
  id;
4477
4477
  isAnonymous;
4478
4478
  user;
@@ -4651,14 +4651,52 @@ var AuthorizationBase = class {
4651
4651
  authorizedPromptIds: this.authorizedPromptIds
4652
4652
  };
4653
4653
  }
4654
+ /**
4655
+ * Check if a base64url segment decodes to a JWT-like header (contains "alg").
4656
+ */
4657
+ static isJwtHeader(segment) {
4658
+ try {
4659
+ const bytes = base64urlDecode4(segment);
4660
+ const text = new TextDecoder().decode(bytes);
4661
+ const parsed = JSON.parse(text);
4662
+ return typeof parsed === "object" && parsed !== null && typeof parsed.alg === "string";
4663
+ } catch {
4664
+ return false;
4665
+ }
4666
+ }
4654
4667
  /**
4655
4668
  * Validate that no tokens are leaked in data
4656
4669
  * Throws if JWT pattern detected
4657
4670
  */
4658
4671
  static validateNoTokenLeakage(data) {
4659
4672
  const json = JSON.stringify(data);
4660
- if (/eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/.test(json)) {
4661
- throw new TokenLeakDetectedError("JWT pattern detected in LLM context data");
4673
+ const B64URL = /^[A-Za-z0-9_-]+$/;
4674
+ const MIN_SEG = 2;
4675
+ let dotIdx = json.indexOf(".");
4676
+ while (dotIdx !== -1) {
4677
+ let seg1Start = dotIdx;
4678
+ while (seg1Start > 0 && /[A-Za-z0-9_-]/.test(json[seg1Start - 1])) seg1Start--;
4679
+ const seg1Len = dotIdx - seg1Start;
4680
+ if (seg1Len >= MIN_SEG) {
4681
+ let seg2End = dotIdx + 1;
4682
+ while (seg2End < json.length && /[A-Za-z0-9_-]/.test(json[seg2End])) seg2End++;
4683
+ const seg2Len = seg2End - (dotIdx + 1);
4684
+ if (seg2Len >= MIN_SEG && seg2End < json.length && json[seg2End] === ".") {
4685
+ const dot2 = seg2End;
4686
+ let seg3End = dot2 + 1;
4687
+ while (seg3End < json.length && /[A-Za-z0-9_-]/.test(json[seg3End])) seg3End++;
4688
+ const seg3Len = seg3End - (dot2 + 1);
4689
+ if (seg3Len >= MIN_SEG) {
4690
+ const seg1 = json.substring(seg1Start, dotIdx);
4691
+ const seg2 = json.substring(dotIdx + 1, dot2);
4692
+ const seg3 = json.substring(dot2 + 1, seg3End);
4693
+ if (B64URL.test(seg1) && B64URL.test(seg2) && B64URL.test(seg3) && _AuthorizationBase.isJwtHeader(seg1)) {
4694
+ throw new TokenLeakDetectedError("JWT pattern detected in LLM context data");
4695
+ }
4696
+ }
4697
+ }
4698
+ }
4699
+ dotIdx = json.indexOf(".", dotIdx + 1);
4662
4700
  }
4663
4701
  const sensitiveFields = ["access_token", "refresh_token", "id_token", "tokenEnc", "secretRefId"];
4664
4702
  for (const field of sensitiveFields) {
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/auth",
3
- "version": "0.11.1",
3
+ "version": "0.11.3",
4
4
  "description": "FrontMCP Auth - Authentication, session management, and credential vault",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",
@@ -50,7 +50,7 @@
50
50
  "zod": "^4.0.0",
51
51
  "ioredis": "^5.0.0",
52
52
  "@vercel/kv": "^3.0.0",
53
- "@frontmcp/storage-sqlite": "0.11.1"
53
+ "@frontmcp/storage-sqlite": "0.11.3"
54
54
  },
55
55
  "peerDependenciesMeta": {
56
56
  "ioredis": {
@@ -64,8 +64,8 @@
64
64
  }
65
65
  },
66
66
  "dependencies": {
67
- "@frontmcp/utils": "0.11.1",
68
- "@frontmcp/di": "0.11.1",
67
+ "@frontmcp/utils": "0.11.3",
68
+ "@frontmcp/di": "0.11.3",
69
69
  "jose": "^6.0.0"
70
70
  },
71
71
  "devDependencies": {
package/index.js CHANGED
@@ -2810,8 +2810,8 @@ function deriveTypedUser(claims) {
2810
2810
  }
2811
2811
  function extractBearerToken(header) {
2812
2812
  if (!header) return void 0;
2813
- const m = header.match(/^\s*Bearer\s+(.+)\s*$/i);
2814
- return m ? m[1].trim() : void 0;
2813
+ const m = header.match(/^\s*Bearer\s+(\S+)\s*$/i);
2814
+ return m ? m[1] : void 0;
2815
2815
  }
2816
2816
 
2817
2817
  // libs/auth/src/session/utils/session-crypto.utils.ts
@@ -4722,7 +4722,7 @@ var progressiveAuthStateSchema = import_zod7.z.object({
4722
4722
 
4723
4723
  // libs/auth/src/authorization/authorization.class.ts
4724
4724
  var import_utils27 = require("@frontmcp/utils");
4725
- var AuthorizationBase = class {
4725
+ var AuthorizationBase = class _AuthorizationBase {
4726
4726
  id;
4727
4727
  isAnonymous;
4728
4728
  user;
@@ -4901,14 +4901,52 @@ var AuthorizationBase = class {
4901
4901
  authorizedPromptIds: this.authorizedPromptIds
4902
4902
  };
4903
4903
  }
4904
+ /**
4905
+ * Check if a base64url segment decodes to a JWT-like header (contains "alg").
4906
+ */
4907
+ static isJwtHeader(segment) {
4908
+ try {
4909
+ const bytes = (0, import_utils27.base64urlDecode)(segment);
4910
+ const text = new TextDecoder().decode(bytes);
4911
+ const parsed = JSON.parse(text);
4912
+ return typeof parsed === "object" && parsed !== null && typeof parsed.alg === "string";
4913
+ } catch {
4914
+ return false;
4915
+ }
4916
+ }
4904
4917
  /**
4905
4918
  * Validate that no tokens are leaked in data
4906
4919
  * Throws if JWT pattern detected
4907
4920
  */
4908
4921
  static validateNoTokenLeakage(data) {
4909
4922
  const json = JSON.stringify(data);
4910
- if (/eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/.test(json)) {
4911
- throw new TokenLeakDetectedError("JWT pattern detected in LLM context data");
4923
+ const B64URL = /^[A-Za-z0-9_-]+$/;
4924
+ const MIN_SEG = 2;
4925
+ let dotIdx = json.indexOf(".");
4926
+ while (dotIdx !== -1) {
4927
+ let seg1Start = dotIdx;
4928
+ while (seg1Start > 0 && /[A-Za-z0-9_-]/.test(json[seg1Start - 1])) seg1Start--;
4929
+ const seg1Len = dotIdx - seg1Start;
4930
+ if (seg1Len >= MIN_SEG) {
4931
+ let seg2End = dotIdx + 1;
4932
+ while (seg2End < json.length && /[A-Za-z0-9_-]/.test(json[seg2End])) seg2End++;
4933
+ const seg2Len = seg2End - (dotIdx + 1);
4934
+ if (seg2Len >= MIN_SEG && seg2End < json.length && json[seg2End] === ".") {
4935
+ const dot2 = seg2End;
4936
+ let seg3End = dot2 + 1;
4937
+ while (seg3End < json.length && /[A-Za-z0-9_-]/.test(json[seg3End])) seg3End++;
4938
+ const seg3Len = seg3End - (dot2 + 1);
4939
+ if (seg3Len >= MIN_SEG) {
4940
+ const seg1 = json.substring(seg1Start, dotIdx);
4941
+ const seg2 = json.substring(dotIdx + 1, dot2);
4942
+ const seg3 = json.substring(dot2 + 1, seg3End);
4943
+ if (B64URL.test(seg1) && B64URL.test(seg2) && B64URL.test(seg3) && _AuthorizationBase.isJwtHeader(seg1)) {
4944
+ throw new TokenLeakDetectedError("JWT pattern detected in LLM context data");
4945
+ }
4946
+ }
4947
+ }
4948
+ }
4949
+ dotIdx = json.indexOf(".", dotIdx + 1);
4912
4950
  }
4913
4951
  const sensitiveFields = ["access_token", "refresh_token", "id_token", "tokenEnc", "secretRefId"];
4914
4952
  for (const field of sensitiveFields) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/auth",
3
- "version": "0.11.1",
3
+ "version": "0.11.3",
4
4
  "description": "FrontMCP Auth - Authentication, session management, and credential vault",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",
@@ -50,7 +50,7 @@
50
50
  "zod": "^4.0.0",
51
51
  "ioredis": "^5.0.0",
52
52
  "@vercel/kv": "^3.0.0",
53
- "@frontmcp/storage-sqlite": "0.11.1"
53
+ "@frontmcp/storage-sqlite": "0.11.3"
54
54
  },
55
55
  "peerDependenciesMeta": {
56
56
  "ioredis": {
@@ -64,8 +64,8 @@
64
64
  }
65
65
  },
66
66
  "dependencies": {
67
- "@frontmcp/utils": "0.11.1",
68
- "@frontmcp/di": "0.11.1",
67
+ "@frontmcp/utils": "0.11.3",
68
+ "@frontmcp/di": "0.11.3",
69
69
  "jose": "^6.0.0"
70
70
  },
71
71
  "devDependencies": {