@frontmcp/plugin-approval 1.8.1 → 1.8.2

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.
@@ -10,14 +10,12 @@ export interface ApprovalIdentity {
10
10
  /** Key for user-scoped approvals, when the call has an authenticated principal. */
11
11
  userId: string | undefined;
12
12
  }
13
- type ApprovalCallerContext = Pick<FrontMcpContext, 'sessionId' | 'authInfo'>;
13
+ type ApprovalCallerContext = Pick<FrontMcpContext, 'verifiedSessionId' | 'authInfo'>;
14
14
  /**
15
15
  * The session and user that a call's approvals are read from and granted to.
16
16
  *
17
- * The stateless transport gives every request the same session id, so keying session
18
- * approvals on it let one caller's approval admit every other stateless caller. A stateless
19
- * call is keyed by its authenticated principal instead, and a call with neither a session nor
20
- * a principal gets a key of its own that no other call can match.
17
+ * Only a verified session keys session approvals; a stateless call (shared or per-request session
18
+ * id) is keyed by its principal, and a call with neither gets a key no other call can match.
21
19
  */
22
20
  export declare function resolveApprovalIdentity(ctx: ApprovalCallerContext | undefined): ApprovalIdentity;
23
21
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"approval.identity.d.ts","sourceRoot":"","sources":["../src/approval.identity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAG3E,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,KAAK,qBAAqB,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC;AAM7E;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,qBAAqB,GAAG,SAAS,GAAG,gBAAgB,CAWhG"}
1
+ {"version":3,"file":"approval.identity.d.ts","sourceRoot":"","sources":["../src/approval.identity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,KAAK,qBAAqB,GAAG,IAAI,CAAC,eAAe,EAAE,mBAAmB,GAAG,UAAU,CAAC,CAAC;AAMrF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,qBAAqB,GAAG,SAAS,GAAG,gBAAgB,CAWhG"}
package/esm/index.mjs CHANGED
@@ -26,7 +26,6 @@ import {
26
26
  } from "@frontmcp/sdk";
27
27
 
28
28
  // plugins/plugin-approval/src/approval.identity.ts
29
- import { STATELESS_SESSION_ID } from "@frontmcp/sdk";
30
29
  import { randomUUID } from "@frontmcp/utils";
31
30
  function nonEmptyString(value) {
32
31
  return typeof value === "string" && value.length > 0 ? value : void 0;
@@ -34,8 +33,8 @@ function nonEmptyString(value) {
34
33
  function resolveApprovalIdentity(ctx) {
35
34
  const extra = ctx?.authInfo?.extra;
36
35
  const userId = nonEmptyString(extra?.["userId"]) ?? nonEmptyString(extra?.["sub"]) ?? nonEmptyString(ctx?.authInfo?.clientId);
37
- const sessionId = nonEmptyString(ctx?.sessionId);
38
- if (sessionId && sessionId !== STATELESS_SESSION_ID) {
36
+ const sessionId = nonEmptyString(ctx?.verifiedSessionId);
37
+ if (sessionId) {
39
38
  return { sessionId, userId };
40
39
  }
41
40
  return { sessionId: userId ? `stateless-user:${userId}` : `unidentified:${randomUUID()}`, userId };
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-approval",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Approval plugin for FrontMCP - tool authorization workflow with PKCE webhook security",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -49,13 +49,13 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@frontmcp/sdk": "1.8.1",
53
- "@frontmcp/utils": "1.8.1",
52
+ "@frontmcp/sdk": "1.8.2",
53
+ "@frontmcp/utils": "1.8.2",
54
54
  "ioredis": "^5.8.0",
55
55
  "reflect-metadata": "^0.2.2"
56
56
  },
57
57
  "peerDependencies": {
58
- "@frontmcp/lazy-zod": "1.8.1",
58
+ "@frontmcp/lazy-zod": "1.8.2",
59
59
  "@vercel/kv": "^2.0.0 || ^3.0.0"
60
60
  },
61
61
  "peerDependenciesMeta": {
package/index.js CHANGED
@@ -76,10 +76,9 @@ __export(index_exports, {
76
76
  module.exports = __toCommonJS(index_exports);
77
77
 
78
78
  // plugins/plugin-approval/src/approval.plugin.ts
79
- var import_sdk6 = require("@frontmcp/sdk");
79
+ var import_sdk5 = require("@frontmcp/sdk");
80
80
 
81
81
  // plugins/plugin-approval/src/approval.identity.ts
82
- var import_sdk = require("@frontmcp/sdk");
83
82
  var import_utils = require("@frontmcp/utils");
84
83
  function nonEmptyString(value) {
85
84
  return typeof value === "string" && value.length > 0 ? value : void 0;
@@ -87,8 +86,8 @@ function nonEmptyString(value) {
87
86
  function resolveApprovalIdentity(ctx) {
88
87
  const extra = ctx?.authInfo?.extra;
89
88
  const userId = nonEmptyString(extra?.["userId"]) ?? nonEmptyString(extra?.["sub"]) ?? nonEmptyString(ctx?.authInfo?.clientId);
90
- const sessionId = nonEmptyString(ctx?.sessionId);
91
- if (sessionId && sessionId !== import_sdk.STATELESS_SESSION_ID) {
89
+ const sessionId = nonEmptyString(ctx?.verifiedSessionId);
90
+ if (sessionId) {
92
91
  return { sessionId, userId };
93
92
  }
94
93
  return { sessionId: userId ? `stateless-user:${userId}` : `unidentified:${(0, import_utils.randomUUID)()}`, userId };
@@ -106,7 +105,7 @@ var ChallengeServiceToken = /* @__PURE__ */ Symbol.for(
106
105
  );
107
106
 
108
107
  // plugins/plugin-approval/src/hooks/approval-check.hook.ts
109
- var import_sdk2 = require("@frontmcp/sdk");
108
+ var import_sdk = require("@frontmcp/sdk");
110
109
 
111
110
  // plugins/plugin-approval/src/approval/types.ts
112
111
  var ApprovalScope = /* @__PURE__ */ ((ApprovalScope2) => {
@@ -473,7 +472,7 @@ var ChallengeValidationError = class extends ApprovalError {
473
472
 
474
473
  // plugins/plugin-approval/src/hooks/approval-check.hook.ts
475
474
  var passedApprovalStores = /* @__PURE__ */ new WeakMap();
476
- var ApprovalCheckPlugin = class extends import_sdk2.DynamicPlugin {
475
+ var ApprovalCheckPlugin = class extends import_sdk.DynamicPlugin {
477
476
  async checkApproval(flowCtx) {
478
477
  const { tool, toolContext } = flowCtx.state;
479
478
  if (!tool || !toolContext) return;
@@ -579,17 +578,17 @@ var ApprovalCheckPlugin = class extends import_sdk2.DynamicPlugin {
579
578
  }
580
579
  };
581
580
  __decorateClass([
582
- import_sdk2.ToolHook.Will("execute", { priority: 100 })
581
+ import_sdk.ToolHook.Will("execute", { priority: 100 })
583
582
  ], ApprovalCheckPlugin.prototype, "checkApproval", 1);
584
583
  ApprovalCheckPlugin = __decorateClass([
585
- (0, import_sdk2.Plugin)({
584
+ (0, import_sdk.Plugin)({
586
585
  name: "approval:check",
587
586
  description: "Checks tool approval state before execution"
588
587
  })
589
588
  ], ApprovalCheckPlugin);
590
589
 
591
590
  // plugins/plugin-approval/src/services/approval.service.ts
592
- var import_sdk3 = require("@frontmcp/sdk");
591
+ var import_sdk2 = require("@frontmcp/sdk");
593
592
  var ApprovalService = class {
594
593
  constructor(store, sessionId, userId) {
595
594
  this.store = store;
@@ -731,10 +730,10 @@ var ApprovalService = class {
731
730
  }
732
731
  };
733
732
  ApprovalService = __decorateClass([
734
- (0, import_sdk3.Provider)({
733
+ (0, import_sdk2.Provider)({
735
734
  name: "provider:approval:service",
736
735
  description: "Service for managing tool approvals",
737
- scope: import_sdk3.ProviderScope.CONTEXT
736
+ scope: import_sdk2.ProviderScope.CONTEXT
738
737
  })
739
738
  ], ApprovalService);
740
739
  function createApprovalService(store, sessionId, userId) {
@@ -742,7 +741,7 @@ function createApprovalService(store, sessionId, userId) {
742
741
  }
743
742
 
744
743
  // plugins/plugin-approval/src/services/challenge.service.ts
745
- var import_sdk4 = require("@frontmcp/sdk");
744
+ var import_sdk3 = require("@frontmcp/sdk");
746
745
  var import_utils2 = require("@frontmcp/utils");
747
746
  var ChallengeService = class {
748
747
  storage;
@@ -876,10 +875,10 @@ var ChallengeService = class {
876
875
  }
877
876
  };
878
877
  ChallengeService = __decorateClass([
879
- (0, import_sdk4.Provider)({
878
+ (0, import_sdk3.Provider)({
880
879
  name: "provider:approval:challenge-service",
881
880
  description: "PKCE challenge service for webhook approval flows",
882
- scope: import_sdk4.ProviderScope.GLOBAL
881
+ scope: import_sdk3.ProviderScope.GLOBAL
883
882
  })
884
883
  ], ChallengeService);
885
884
  function generatePkcePairFromVerifier(codeVerifier) {
@@ -897,7 +896,7 @@ function createMemoryChallengeService(options = {}) {
897
896
  }
898
897
 
899
898
  // plugins/plugin-approval/src/stores/approval-storage.store.ts
900
- var import_sdk5 = require("@frontmcp/sdk");
899
+ var import_sdk4 = require("@frontmcp/sdk");
901
900
  var import_utils3 = require("@frontmcp/utils");
902
901
  function escapePattern(str) {
903
902
  return str.replace(/[*?[\]\\]/g, "\\$&");
@@ -1146,10 +1145,10 @@ var ApprovalStorageStore = class {
1146
1145
  }
1147
1146
  };
1148
1147
  ApprovalStorageStore = __decorateClass([
1149
- (0, import_sdk5.Provider)({
1148
+ (0, import_sdk4.Provider)({
1150
1149
  name: "provider:approval:store:storage",
1151
1150
  description: "Storage-backed approval store (supports Memory, Redis, Vercel KV, Upstash)",
1152
- scope: import_sdk5.ProviderScope.GLOBAL
1151
+ scope: import_sdk4.ProviderScope.GLOBAL
1153
1152
  })
1154
1153
  ], ApprovalStorageStore);
1155
1154
  function createApprovalMemoryStore(options = {}) {
@@ -1161,7 +1160,7 @@ function createApprovalMemoryStore(options = {}) {
1161
1160
  }
1162
1161
 
1163
1162
  // plugins/plugin-approval/src/approval.plugin.ts
1164
- var ApprovalPlugin = class extends import_sdk6.DynamicPlugin {
1163
+ var ApprovalPlugin = class extends import_sdk5.DynamicPlugin {
1165
1164
  options;
1166
1165
  constructor(options = {}) {
1167
1166
  super();
@@ -1222,8 +1221,8 @@ __publicField(ApprovalPlugin, "dynamicProviders", (options) => {
1222
1221
  providers.push({
1223
1222
  name: "approval:service",
1224
1223
  provide: ApprovalServiceToken,
1225
- scope: import_sdk6.ProviderScope.CONTEXT,
1226
- inject: () => [ApprovalStoreToken, import_sdk6.FRONTMCP_CONTEXT],
1224
+ scope: import_sdk5.ProviderScope.CONTEXT,
1225
+ inject: () => [ApprovalStoreToken, import_sdk5.FRONTMCP_CONTEXT],
1227
1226
  useFactory: (store, ctx) => {
1228
1227
  const { sessionId, userId } = resolveApprovalIdentity(ctx);
1229
1228
  return createApprovalService(store, sessionId, userId);
@@ -1232,7 +1231,7 @@ __publicField(ApprovalPlugin, "dynamicProviders", (options) => {
1232
1231
  return providers;
1233
1232
  });
1234
1233
  ApprovalPlugin = __decorateClass([
1235
- (0, import_sdk6.Plugin)({
1234
+ (0, import_sdk5.Plugin)({
1236
1235
  name: "approval",
1237
1236
  description: "Tool authorization workflow with PKCE webhook security",
1238
1237
  plugins: [ApprovalCheckPlugin],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-approval",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Approval plugin for FrontMCP - tool authorization workflow with PKCE webhook security",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -49,13 +49,13 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@frontmcp/sdk": "1.8.1",
53
- "@frontmcp/utils": "1.8.1",
52
+ "@frontmcp/sdk": "1.8.2",
53
+ "@frontmcp/utils": "1.8.2",
54
54
  "ioredis": "^5.8.0",
55
55
  "reflect-metadata": "^0.2.2"
56
56
  },
57
57
  "peerDependencies": {
58
- "@frontmcp/lazy-zod": "1.8.1",
58
+ "@frontmcp/lazy-zod": "1.8.2",
59
59
  "@vercel/kv": "^2.0.0 || ^3.0.0"
60
60
  },
61
61
  "peerDependenciesMeta": {