@leanmcp/auth 0.3.1 → 0.3.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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AuthProviderBase,
3
3
  __name
4
- } from "./chunk-EVD2TRPR.mjs";
4
+ } from "./chunk-ESHQ6BRM.mjs";
5
5
 
6
6
  // src/providers/auth0.ts
7
7
  import axios from "axios";
@@ -86,29 +86,39 @@ function createAuthenticatedMethod(originalMethod, authProvider, options) {
86
86
  }
87
87
  throw new AuthenticationError(`Token verification failed: ${error instanceof Error ? error.message : String(error)}`, "VERIFICATION_FAILED");
88
88
  }
89
+ let user = void 0;
89
90
  if (options.getUser !== false) {
90
91
  try {
91
- const user = await authProvider.getUser(token);
92
- return await authUserStorage.run(user, async () => {
93
- return await originalMethod.apply(this, [
94
- args
95
- ]);
96
- });
92
+ user = await authProvider.getUser(token);
97
93
  } catch (error) {
98
94
  console.warn("Failed to fetch user information:", error);
99
- return await authUserStorage.run(void 0, async () => {
95
+ }
96
+ }
97
+ let userSecrets = {};
98
+ if (options.projectId) {
99
+ try {
100
+ if ("getUserSecrets" in authProvider && typeof authProvider.getUserSecrets === "function") {
101
+ userSecrets = await authProvider.getUserSecrets(token, options.projectId);
102
+ } else {
103
+ console.warn('[Auth] Auth provider does not support user secrets. Only the LeanMCP provider supports @RequireEnv and getEnv(). Use: new AuthProvider("leanmcp", { apiKey: "..." })');
104
+ }
105
+ } catch (error) {
106
+ console.warn("[Auth] Failed to fetch user secrets:", error instanceof Error ? error.message : error);
107
+ }
108
+ }
109
+ return await authUserStorage.run(user, async () => {
110
+ if (options.projectId) {
111
+ const { runWithEnv } = await import("@leanmcp/env-injection");
112
+ return await runWithEnv(userSecrets, async () => {
100
113
  return await originalMethod.apply(this, [
101
114
  args
102
115
  ]);
103
116
  });
104
117
  }
105
- } else {
106
- return await authUserStorage.run(void 0, async () => {
107
- return await originalMethod.apply(this, [
108
- args
109
- ]);
110
- });
111
- }
118
+ return await originalMethod.apply(this, [
119
+ args
120
+ ]);
121
+ });
112
122
  };
113
123
  }
114
124
  __name(createAuthenticatedMethod, "createAuthenticatedMethod");
@@ -165,25 +175,31 @@ var AuthProvider = class extends AuthProviderBase {
165
175
  const finalConfig = config || this.config;
166
176
  switch (this.providerType) {
167
177
  case "cognito": {
168
- const { AuthCognito } = await import("./cognito-I6V5YNYM.mjs");
178
+ const { AuthCognito } = await import("./cognito-5Q5HGYMA.mjs");
169
179
  this.providerInstance = new AuthCognito();
170
180
  await this.providerInstance.init(finalConfig);
171
181
  break;
172
182
  }
173
183
  case "auth0": {
174
- const { AuthAuth0 } = await import("./auth0-54GZT2EI.mjs");
184
+ const { AuthAuth0 } = await import("./auth0-DMNC3QWJ.mjs");
175
185
  this.providerInstance = new AuthAuth0();
176
186
  await this.providerInstance.init(finalConfig);
177
187
  break;
178
188
  }
179
189
  case "clerk": {
180
- const { AuthClerk } = await import("./clerk-FR7ITM33.mjs");
190
+ const { AuthClerk } = await import("./clerk-7PVVTTC7.mjs");
181
191
  this.providerInstance = new AuthClerk();
182
192
  await this.providerInstance.init(finalConfig);
183
193
  break;
184
194
  }
195
+ case "leanmcp": {
196
+ const { AuthLeanmcp } = await import("./leanmcp-X6BD6HOJ.mjs");
197
+ this.providerInstance = new AuthLeanmcp();
198
+ await this.providerInstance.init(finalConfig);
199
+ break;
200
+ }
185
201
  default:
186
- throw new Error(`Unsupported auth provider: ${this.providerType}. Supported providers: cognito`);
202
+ throw new Error(`Unsupported auth provider: ${this.providerType}. Supported providers: cognito, auth0, clerk, leanmcp`);
187
203
  }
188
204
  }
189
205
  /**
@@ -214,6 +230,19 @@ var AuthProvider = class extends AuthProviderBase {
214
230
  return this.providerInstance.getUser(token);
215
231
  }
216
232
  /**
233
+ * Get user secrets for a project (LeanMCP provider only)
234
+ * Other providers will return empty object
235
+ */
236
+ async getUserSecrets(token, projectId) {
237
+ if (!this.providerInstance) {
238
+ throw new Error("AuthProvider not initialized. Call init() first.");
239
+ }
240
+ if ("getUserSecrets" in this.providerInstance && typeof this.providerInstance.getUserSecrets === "function") {
241
+ return this.providerInstance.getUserSecrets(token, projectId);
242
+ }
243
+ return {};
244
+ }
245
+ /**
217
246
  * Get the provider type
218
247
  */
219
248
  getProviderType() {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AuthProviderBase,
3
3
  __name
4
- } from "./chunk-EVD2TRPR.mjs";
4
+ } from "./chunk-ESHQ6BRM.mjs";
5
5
 
6
6
  // src/providers/clerk.ts
7
7
  import axios from "axios";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AuthProviderBase,
3
3
  __name
4
- } from "./chunk-EVD2TRPR.mjs";
4
+ } from "./chunk-ESHQ6BRM.mjs";
5
5
 
6
6
  // src/providers/cognito.ts
7
7
  import { CognitoIdentityProviderClient, InitiateAuthCommand } from "@aws-sdk/client-cognito-identity-provider";
package/dist/index.d.mts CHANGED
@@ -10,6 +10,12 @@ interface AuthenticatedOptions {
10
10
  * @default true
11
11
  */
12
12
  getUser?: boolean;
13
+ /**
14
+ * Project ID for fetching user environment variables.
15
+ * Required when @RequireEnv is used on the method or class.
16
+ * Used to scope user secrets to a specific project.
17
+ */
18
+ projectId?: string;
13
19
  }
14
20
 
15
21
  /**
@@ -161,6 +167,11 @@ declare class AuthProvider extends AuthProviderBase {
161
167
  * Get user information from a token
162
168
  */
163
169
  getUser(token: string): Promise<any>;
170
+ /**
171
+ * Get user secrets for a project (LeanMCP provider only)
172
+ * Other providers will return empty object
173
+ */
174
+ getUserSecrets(token: string, projectId: string): Promise<Record<string, string>>;
164
175
  /**
165
176
  * Get the provider type
166
177
  */
package/dist/index.d.ts CHANGED
@@ -10,6 +10,12 @@ interface AuthenticatedOptions {
10
10
  * @default true
11
11
  */
12
12
  getUser?: boolean;
13
+ /**
14
+ * Project ID for fetching user environment variables.
15
+ * Required when @RequireEnv is used on the method or class.
16
+ * Used to scope user secrets to a specific project.
17
+ */
18
+ projectId?: string;
13
19
  }
14
20
 
15
21
  /**
@@ -161,6 +167,11 @@ declare class AuthProvider extends AuthProviderBase {
161
167
  * Get user information from a token
162
168
  */
163
169
  getUser(token: string): Promise<any>;
170
+ /**
171
+ * Get user secrets for a project (LeanMCP provider only)
172
+ * Other providers will return empty object
173
+ */
174
+ getUserSecrets(token: string, projectId: string): Promise<Record<string, string>>;
164
175
  /**
165
176
  * Get the provider type
166
177
  */
package/dist/index.js CHANGED
@@ -89,29 +89,39 @@ function createAuthenticatedMethod(originalMethod, authProvider, options) {
89
89
  }
90
90
  throw new AuthenticationError(`Token verification failed: ${error instanceof Error ? error.message : String(error)}`, "VERIFICATION_FAILED");
91
91
  }
92
+ let user = void 0;
92
93
  if (options.getUser !== false) {
93
94
  try {
94
- const user = await authProvider.getUser(token);
95
- return await authUserStorage.run(user, async () => {
96
- return await originalMethod.apply(this, [
97
- args
98
- ]);
99
- });
95
+ user = await authProvider.getUser(token);
100
96
  } catch (error) {
101
97
  console.warn("Failed to fetch user information:", error);
102
- return await authUserStorage.run(void 0, async () => {
98
+ }
99
+ }
100
+ let userSecrets = {};
101
+ if (options.projectId) {
102
+ try {
103
+ if ("getUserSecrets" in authProvider && typeof authProvider.getUserSecrets === "function") {
104
+ userSecrets = await authProvider.getUserSecrets(token, options.projectId);
105
+ } else {
106
+ console.warn('[Auth] Auth provider does not support user secrets. Only the LeanMCP provider supports @RequireEnv and getEnv(). Use: new AuthProvider("leanmcp", { apiKey: "..." })');
107
+ }
108
+ } catch (error) {
109
+ console.warn("[Auth] Failed to fetch user secrets:", error instanceof Error ? error.message : error);
110
+ }
111
+ }
112
+ return await authUserStorage.run(user, async () => {
113
+ if (options.projectId) {
114
+ const { runWithEnv } = await import("@leanmcp/env-injection");
115
+ return await runWithEnv(userSecrets, async () => {
103
116
  return await originalMethod.apply(this, [
104
117
  args
105
118
  ]);
106
119
  });
107
120
  }
108
- } else {
109
- return await authUserStorage.run(void 0, async () => {
110
- return await originalMethod.apply(this, [
111
- args
112
- ]);
113
- });
114
- }
121
+ return await originalMethod.apply(this, [
122
+ args
123
+ ]);
124
+ });
115
125
  };
116
126
  }
117
127
  function copyMetadata(source, target) {
@@ -547,6 +557,148 @@ var init_clerk = __esm({
547
557
  }
548
558
  });
549
559
 
560
+ // src/providers/leanmcp.ts
561
+ var leanmcp_exports = {};
562
+ __export(leanmcp_exports, {
563
+ AuthLeanmcp: () => AuthLeanmcp
564
+ });
565
+ var import_axios4, import_jsonwebtoken4, AuthLeanmcp;
566
+ var init_leanmcp = __esm({
567
+ "src/providers/leanmcp.ts"() {
568
+ "use strict";
569
+ import_axios4 = __toESM(require("axios"));
570
+ import_jsonwebtoken4 = __toESM(require("jsonwebtoken"));
571
+ init_index();
572
+ AuthLeanmcp = class extends AuthProviderBase {
573
+ static {
574
+ __name(this, "AuthLeanmcp");
575
+ }
576
+ authUrl = "https://auth.leanmcp.com";
577
+ orchestrationApiUrl = "https://api.leanmcp.com";
578
+ apiKey;
579
+ async init(config) {
580
+ this.authUrl = config?.authUrl || process.env.LEANMCP_AUTH_URL || "https://auth.leanmcp.com";
581
+ this.orchestrationApiUrl = config?.orchestrationApiUrl || process.env.LEANMCP_ORCHESTRATION_API_URL || "https://qaapi.leanmcp.com";
582
+ this.apiKey = config?.apiKey || process.env.LEANMCP_API_KEY;
583
+ }
584
+ async refreshToken(refreshToken) {
585
+ const url = `${this.authUrl}/api/refresh`;
586
+ try {
587
+ const { data } = await import_axios4.default.post(url, {
588
+ refresh_token: refreshToken
589
+ }, {
590
+ headers: {
591
+ "Content-Type": "application/json"
592
+ }
593
+ });
594
+ return data;
595
+ } catch (error) {
596
+ if (import_axios4.default.isAxiosError(error) && error.response) {
597
+ throw new Error(`Failed to refresh token: ${error.response.data.error?.message || error.response.data.error || "Unknown error"}`);
598
+ }
599
+ throw error;
600
+ }
601
+ }
602
+ async verifyToken(token) {
603
+ if (this.apiKey) {
604
+ const url2 = `${this.orchestrationApiUrl}/public/auth/verify-user`;
605
+ try {
606
+ await import_axios4.default.post(url2, {
607
+ token
608
+ }, {
609
+ headers: {
610
+ "Content-Type": "application/json",
611
+ "x-api-key": this.apiKey
612
+ }
613
+ });
614
+ return true;
615
+ } catch (error) {
616
+ console.error("Failed to verify token:", error);
617
+ return false;
618
+ }
619
+ }
620
+ const url = `${this.authUrl}/api/verify`;
621
+ try {
622
+ const { data } = await import_axios4.default.post(url, {
623
+ token
624
+ }, {
625
+ headers: {
626
+ "Content-Type": "application/json"
627
+ }
628
+ });
629
+ return data.valid;
630
+ } catch (error) {
631
+ return false;
632
+ }
633
+ }
634
+ async getUser(token) {
635
+ if (this.apiKey) {
636
+ const url = `${this.orchestrationApiUrl}/public/auth/verify-user`;
637
+ try {
638
+ const { data } = await import_axios4.default.post(url, {
639
+ token
640
+ }, {
641
+ headers: {
642
+ "Content-Type": "application/json",
643
+ "x-api-key": this.apiKey
644
+ }
645
+ });
646
+ return {
647
+ uid: data.uid,
648
+ email: data.email,
649
+ email_verified: data.emailVerified,
650
+ name: data.name,
651
+ picture: data.picture,
652
+ type: "firebase"
653
+ };
654
+ } catch (error) {
655
+ console.error("Failed to verify user token via Orchestration API:", error.response?.data || error.message);
656
+ throw new Error("Invalid user token or API key");
657
+ }
658
+ }
659
+ const decoded = import_jsonwebtoken4.default.decode(token);
660
+ if (!decoded) throw new Error("Invalid ID token");
661
+ return {
662
+ uid: decoded.user_id || decoded.sub,
663
+ email: decoded.email,
664
+ email_verified: decoded.email_verified,
665
+ name: decoded.name || decoded.displayName,
666
+ picture: decoded.picture || decoded.photoURL,
667
+ attributes: decoded,
668
+ type: "jwt"
669
+ };
670
+ }
671
+ /**
672
+ * Fetch user-specific environment variables for a project
673
+ * Uses the user's UID and project ID to retrieve their stored secrets
674
+ *
675
+ * @param token - User's auth token
676
+ * @param projectId - Project ID to scope the secrets
677
+ * @returns Record of environment variables
678
+ */
679
+ async getUserSecrets(token, projectId) {
680
+ if (!this.apiKey) {
681
+ console.warn("[LeanMCP] API key not configured - cannot fetch user secrets. Set LEANMCP_API_KEY environment variable or pass apiKey in config.");
682
+ return {};
683
+ }
684
+ const url = `${this.orchestrationApiUrl}/public/secrets/user/${projectId}`;
685
+ try {
686
+ const { data } = await import_axios4.default.get(url, {
687
+ headers: {
688
+ "Authorization": `Bearer ${token}`,
689
+ "x-api-key": this.apiKey
690
+ }
691
+ });
692
+ return data.secrets || {};
693
+ } catch (error) {
694
+ console.warn("[LeanMCP] Failed to fetch user secrets:", error.response?.status || error.message);
695
+ return {};
696
+ }
697
+ }
698
+ };
699
+ }
700
+ });
701
+
550
702
  // src/index.ts
551
703
  var index_exports = {};
552
704
  __export(index_exports, {
@@ -605,8 +757,14 @@ var init_index = __esm({
605
757
  await this.providerInstance.init(finalConfig);
606
758
  break;
607
759
  }
760
+ case "leanmcp": {
761
+ const { AuthLeanmcp: AuthLeanmcp2 } = await Promise.resolve().then(() => (init_leanmcp(), leanmcp_exports));
762
+ this.providerInstance = new AuthLeanmcp2();
763
+ await this.providerInstance.init(finalConfig);
764
+ break;
765
+ }
608
766
  default:
609
- throw new Error(`Unsupported auth provider: ${this.providerType}. Supported providers: cognito`);
767
+ throw new Error(`Unsupported auth provider: ${this.providerType}. Supported providers: cognito, auth0, clerk, leanmcp`);
610
768
  }
611
769
  }
612
770
  /**
@@ -637,6 +795,19 @@ var init_index = __esm({
637
795
  return this.providerInstance.getUser(token);
638
796
  }
639
797
  /**
798
+ * Get user secrets for a project (LeanMCP provider only)
799
+ * Other providers will return empty object
800
+ */
801
+ async getUserSecrets(token, projectId) {
802
+ if (!this.providerInstance) {
803
+ throw new Error("AuthProvider not initialized. Call init() first.");
804
+ }
805
+ if ("getUserSecrets" in this.providerInstance && typeof this.providerInstance.getUserSecrets === "function") {
806
+ return this.providerInstance.getUserSecrets(token, projectId);
807
+ }
808
+ return {};
809
+ }
810
+ /**
640
811
  * Get the provider type
641
812
  */
642
813
  getProviderType() {
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  getAuthProvider,
7
7
  getAuthUser,
8
8
  isAuthenticationRequired
9
- } from "./chunk-EVD2TRPR.mjs";
9
+ } from "./chunk-ESHQ6BRM.mjs";
10
10
  export {
11
11
  AuthProvider,
12
12
  AuthProviderBase,
@@ -0,0 +1,138 @@
1
+ import {
2
+ AuthProviderBase,
3
+ __name
4
+ } from "./chunk-ESHQ6BRM.mjs";
5
+
6
+ // src/providers/leanmcp.ts
7
+ import axios from "axios";
8
+ import jwt from "jsonwebtoken";
9
+ var AuthLeanmcp = class extends AuthProviderBase {
10
+ static {
11
+ __name(this, "AuthLeanmcp");
12
+ }
13
+ authUrl = "https://auth.leanmcp.com";
14
+ orchestrationApiUrl = "https://api.leanmcp.com";
15
+ apiKey;
16
+ async init(config) {
17
+ this.authUrl = config?.authUrl || process.env.LEANMCP_AUTH_URL || "https://auth.leanmcp.com";
18
+ this.orchestrationApiUrl = config?.orchestrationApiUrl || process.env.LEANMCP_ORCHESTRATION_API_URL || "https://qaapi.leanmcp.com";
19
+ this.apiKey = config?.apiKey || process.env.LEANMCP_API_KEY;
20
+ }
21
+ async refreshToken(refreshToken) {
22
+ const url = `${this.authUrl}/api/refresh`;
23
+ try {
24
+ const { data } = await axios.post(url, {
25
+ refresh_token: refreshToken
26
+ }, {
27
+ headers: {
28
+ "Content-Type": "application/json"
29
+ }
30
+ });
31
+ return data;
32
+ } catch (error) {
33
+ if (axios.isAxiosError(error) && error.response) {
34
+ throw new Error(`Failed to refresh token: ${error.response.data.error?.message || error.response.data.error || "Unknown error"}`);
35
+ }
36
+ throw error;
37
+ }
38
+ }
39
+ async verifyToken(token) {
40
+ if (this.apiKey) {
41
+ const url2 = `${this.orchestrationApiUrl}/public/auth/verify-user`;
42
+ try {
43
+ await axios.post(url2, {
44
+ token
45
+ }, {
46
+ headers: {
47
+ "Content-Type": "application/json",
48
+ "x-api-key": this.apiKey
49
+ }
50
+ });
51
+ return true;
52
+ } catch (error) {
53
+ console.error("Failed to verify token:", error);
54
+ return false;
55
+ }
56
+ }
57
+ const url = `${this.authUrl}/api/verify`;
58
+ try {
59
+ const { data } = await axios.post(url, {
60
+ token
61
+ }, {
62
+ headers: {
63
+ "Content-Type": "application/json"
64
+ }
65
+ });
66
+ return data.valid;
67
+ } catch (error) {
68
+ return false;
69
+ }
70
+ }
71
+ async getUser(token) {
72
+ if (this.apiKey) {
73
+ const url = `${this.orchestrationApiUrl}/public/auth/verify-user`;
74
+ try {
75
+ const { data } = await axios.post(url, {
76
+ token
77
+ }, {
78
+ headers: {
79
+ "Content-Type": "application/json",
80
+ "x-api-key": this.apiKey
81
+ }
82
+ });
83
+ return {
84
+ uid: data.uid,
85
+ email: data.email,
86
+ email_verified: data.emailVerified,
87
+ name: data.name,
88
+ picture: data.picture,
89
+ type: "firebase"
90
+ };
91
+ } catch (error) {
92
+ console.error("Failed to verify user token via Orchestration API:", error.response?.data || error.message);
93
+ throw new Error("Invalid user token or API key");
94
+ }
95
+ }
96
+ const decoded = jwt.decode(token);
97
+ if (!decoded) throw new Error("Invalid ID token");
98
+ return {
99
+ uid: decoded.user_id || decoded.sub,
100
+ email: decoded.email,
101
+ email_verified: decoded.email_verified,
102
+ name: decoded.name || decoded.displayName,
103
+ picture: decoded.picture || decoded.photoURL,
104
+ attributes: decoded,
105
+ type: "jwt"
106
+ };
107
+ }
108
+ /**
109
+ * Fetch user-specific environment variables for a project
110
+ * Uses the user's UID and project ID to retrieve their stored secrets
111
+ *
112
+ * @param token - User's auth token
113
+ * @param projectId - Project ID to scope the secrets
114
+ * @returns Record of environment variables
115
+ */
116
+ async getUserSecrets(token, projectId) {
117
+ if (!this.apiKey) {
118
+ console.warn("[LeanMCP] API key not configured - cannot fetch user secrets. Set LEANMCP_API_KEY environment variable or pass apiKey in config.");
119
+ return {};
120
+ }
121
+ const url = `${this.orchestrationApiUrl}/public/secrets/user/${projectId}`;
122
+ try {
123
+ const { data } = await axios.get(url, {
124
+ headers: {
125
+ "Authorization": `Bearer ${token}`,
126
+ "x-api-key": this.apiKey
127
+ }
128
+ });
129
+ return data.secrets || {};
130
+ } catch (error) {
131
+ console.warn("[LeanMCP] Failed to fetch user secrets:", error.response?.status || error.message);
132
+ return {};
133
+ }
134
+ }
135
+ };
136
+ export {
137
+ AuthLeanmcp
138
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanmcp/auth",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Authentication and identity module supporting multiple providers",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -38,6 +38,7 @@
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@aws-sdk/client-cognito-identity-provider": "^3.0.0",
41
+ "@leanmcp/env-injection": "^0.1.0",
41
42
  "axios": "^1.0.0",
42
43
  "jsonwebtoken": "^9.0.0",
43
44
  "jwk-to-pem": "^2.0.0"
@@ -46,6 +47,9 @@
46
47
  "@aws-sdk/client-cognito-identity-provider": {
47
48
  "optional": true
48
49
  },
50
+ "@leanmcp/env-injection": {
51
+ "optional": true
52
+ },
49
53
  "axios": {
50
54
  "optional": true
51
55
  },
@@ -80,4 +84,4 @@
80
84
  "publishConfig": {
81
85
  "access": "public"
82
86
  }
83
- }
87
+ }