@leanmcp/auth 0.3.1 → 0.4.0
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.
- package/README.md +148 -661
- package/dist/{auth0-54GZT2EI.mjs → auth0-UTD4QBG6.mjs} +4 -2
- package/dist/chunk-LPEX4YW6.mjs +13 -0
- package/dist/{chunk-EVD2TRPR.mjs → chunk-P4HFKA5R.mjs} +50 -21
- package/dist/chunk-RGCCBQWG.mjs +113 -0
- package/dist/chunk-ZOPKMOPV.mjs +53 -0
- package/dist/{clerk-FR7ITM33.mjs → clerk-3SDKGD6C.mjs} +4 -2
- package/dist/client/index.d.mts +499 -0
- package/dist/client/index.d.ts +499 -0
- package/dist/client/index.js +1039 -0
- package/dist/client/index.mjs +869 -0
- package/dist/{cognito-I6V5YNYM.mjs → cognito-QQT7LK2Y.mjs} +4 -2
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +186 -15
- package/dist/index.mjs +2 -1
- package/dist/leanmcp-Y7TXNSTD.mjs +140 -0
- package/dist/proxy/index.d.mts +376 -0
- package/dist/proxy/index.d.ts +376 -0
- package/dist/proxy/index.js +536 -0
- package/dist/proxy/index.mjs +480 -0
- package/dist/server/index.d.mts +496 -0
- package/dist/server/index.d.ts +496 -0
- package/dist/server/index.js +882 -0
- package/dist/server/index.mjs +847 -0
- package/dist/storage/index.d.mts +181 -0
- package/dist/storage/index.d.ts +181 -0
- package/dist/storage/index.js +499 -0
- package/dist/storage/index.mjs +372 -0
- package/dist/types-DMpGN530.d.mts +122 -0
- package/dist/types-DMpGN530.d.ts +122 -0
- package/package.json +45 -8
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
__name,
|
|
12
|
+
__require
|
|
13
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
__name
|
|
3
|
+
} from "./chunk-LPEX4YW6.mjs";
|
|
3
4
|
|
|
4
5
|
// src/index.ts
|
|
5
6
|
import "reflect-metadata";
|
|
@@ -86,29 +87,39 @@ function createAuthenticatedMethod(originalMethod, authProvider, options) {
|
|
|
86
87
|
}
|
|
87
88
|
throw new AuthenticationError(`Token verification failed: ${error instanceof Error ? error.message : String(error)}`, "VERIFICATION_FAILED");
|
|
88
89
|
}
|
|
90
|
+
let user = void 0;
|
|
89
91
|
if (options.getUser !== false) {
|
|
90
92
|
try {
|
|
91
|
-
|
|
92
|
-
return await authUserStorage.run(user, async () => {
|
|
93
|
-
return await originalMethod.apply(this, [
|
|
94
|
-
args
|
|
95
|
-
]);
|
|
96
|
-
});
|
|
93
|
+
user = await authProvider.getUser(token);
|
|
97
94
|
} catch (error) {
|
|
98
95
|
console.warn("Failed to fetch user information:", error);
|
|
99
|
-
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
let userSecrets = {};
|
|
99
|
+
if (options.projectId) {
|
|
100
|
+
try {
|
|
101
|
+
if ("getUserSecrets" in authProvider && typeof authProvider.getUserSecrets === "function") {
|
|
102
|
+
userSecrets = await authProvider.getUserSecrets(token, options.projectId);
|
|
103
|
+
} else {
|
|
104
|
+
console.warn('[Auth] Auth provider does not support user secrets. Only the LeanMCP provider supports @RequireEnv and getEnv(). Use: new AuthProvider("leanmcp", { apiKey: "..." })');
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.warn("[Auth] Failed to fetch user secrets:", error instanceof Error ? error.message : error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return await authUserStorage.run(user, async () => {
|
|
111
|
+
if (options.projectId) {
|
|
112
|
+
const { runWithEnv } = await import("@leanmcp/env-injection");
|
|
113
|
+
return await runWithEnv(userSecrets, async () => {
|
|
100
114
|
return await originalMethod.apply(this, [
|
|
101
115
|
args
|
|
102
116
|
]);
|
|
103
117
|
});
|
|
104
118
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
]);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
119
|
+
return await originalMethod.apply(this, [
|
|
120
|
+
args
|
|
121
|
+
]);
|
|
122
|
+
});
|
|
112
123
|
};
|
|
113
124
|
}
|
|
114
125
|
__name(createAuthenticatedMethod, "createAuthenticatedMethod");
|
|
@@ -165,25 +176,31 @@ var AuthProvider = class extends AuthProviderBase {
|
|
|
165
176
|
const finalConfig = config || this.config;
|
|
166
177
|
switch (this.providerType) {
|
|
167
178
|
case "cognito": {
|
|
168
|
-
const { AuthCognito } = await import("./cognito-
|
|
179
|
+
const { AuthCognito } = await import("./cognito-QQT7LK2Y.mjs");
|
|
169
180
|
this.providerInstance = new AuthCognito();
|
|
170
181
|
await this.providerInstance.init(finalConfig);
|
|
171
182
|
break;
|
|
172
183
|
}
|
|
173
184
|
case "auth0": {
|
|
174
|
-
const { AuthAuth0 } = await import("./auth0-
|
|
185
|
+
const { AuthAuth0 } = await import("./auth0-UTD4QBG6.mjs");
|
|
175
186
|
this.providerInstance = new AuthAuth0();
|
|
176
187
|
await this.providerInstance.init(finalConfig);
|
|
177
188
|
break;
|
|
178
189
|
}
|
|
179
190
|
case "clerk": {
|
|
180
|
-
const { AuthClerk } = await import("./clerk-
|
|
191
|
+
const { AuthClerk } = await import("./clerk-3SDKGD6C.mjs");
|
|
181
192
|
this.providerInstance = new AuthClerk();
|
|
182
193
|
await this.providerInstance.init(finalConfig);
|
|
183
194
|
break;
|
|
184
195
|
}
|
|
196
|
+
case "leanmcp": {
|
|
197
|
+
const { AuthLeanmcp } = await import("./leanmcp-Y7TXNSTD.mjs");
|
|
198
|
+
this.providerInstance = new AuthLeanmcp();
|
|
199
|
+
await this.providerInstance.init(finalConfig);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
185
202
|
default:
|
|
186
|
-
throw new Error(`Unsupported auth provider: ${this.providerType}. Supported providers: cognito`);
|
|
203
|
+
throw new Error(`Unsupported auth provider: ${this.providerType}. Supported providers: cognito, auth0, clerk, leanmcp`);
|
|
187
204
|
}
|
|
188
205
|
}
|
|
189
206
|
/**
|
|
@@ -214,6 +231,19 @@ var AuthProvider = class extends AuthProviderBase {
|
|
|
214
231
|
return this.providerInstance.getUser(token);
|
|
215
232
|
}
|
|
216
233
|
/**
|
|
234
|
+
* Get user secrets for a project (LeanMCP provider only)
|
|
235
|
+
* Other providers will return empty object
|
|
236
|
+
*/
|
|
237
|
+
async getUserSecrets(token, projectId) {
|
|
238
|
+
if (!this.providerInstance) {
|
|
239
|
+
throw new Error("AuthProvider not initialized. Call init() first.");
|
|
240
|
+
}
|
|
241
|
+
if ("getUserSecrets" in this.providerInstance && typeof this.providerInstance.getUserSecrets === "function") {
|
|
242
|
+
return this.providerInstance.getUserSecrets(token, projectId);
|
|
243
|
+
}
|
|
244
|
+
return {};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
217
247
|
* Get the provider type
|
|
218
248
|
*/
|
|
219
249
|
getProviderType() {
|
|
@@ -222,7 +252,6 @@ var AuthProvider = class extends AuthProviderBase {
|
|
|
222
252
|
};
|
|
223
253
|
|
|
224
254
|
export {
|
|
225
|
-
__name,
|
|
226
255
|
getAuthUser,
|
|
227
256
|
AuthenticationError,
|
|
228
257
|
Authenticated,
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__name
|
|
3
|
+
} from "./chunk-LPEX4YW6.mjs";
|
|
4
|
+
|
|
5
|
+
// src/storage/types.ts
|
|
6
|
+
function isTokenExpired(tokens, bufferSeconds = 60) {
|
|
7
|
+
if (!tokens.expires_at && !tokens.expires_in) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const expiresAt = tokens.expires_at ?? Date.now() / 1e3 + (tokens.expires_in ?? 0);
|
|
11
|
+
const now = Date.now() / 1e3;
|
|
12
|
+
return expiresAt <= now + bufferSeconds;
|
|
13
|
+
}
|
|
14
|
+
__name(isTokenExpired, "isTokenExpired");
|
|
15
|
+
function withExpiresAt(tokens) {
|
|
16
|
+
if (tokens.expires_at || !tokens.expires_in) {
|
|
17
|
+
return tokens;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
...tokens,
|
|
21
|
+
expires_at: Math.floor(Date.now() / 1e3) + tokens.expires_in
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
__name(withExpiresAt, "withExpiresAt");
|
|
25
|
+
|
|
26
|
+
// src/storage/memory.ts
|
|
27
|
+
var MemoryStorage = class {
|
|
28
|
+
static {
|
|
29
|
+
__name(this, "MemoryStorage");
|
|
30
|
+
}
|
|
31
|
+
tokens = /* @__PURE__ */ new Map();
|
|
32
|
+
clients = /* @__PURE__ */ new Map();
|
|
33
|
+
/**
|
|
34
|
+
* Normalize server URL for consistent key lookup
|
|
35
|
+
*/
|
|
36
|
+
normalizeUrl(serverUrl) {
|
|
37
|
+
return serverUrl.replace(/\/+$/, "").toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if an entry is expired
|
|
41
|
+
*/
|
|
42
|
+
isExpired(entry) {
|
|
43
|
+
if (!entry) return true;
|
|
44
|
+
if (!entry.expiresAt) return false;
|
|
45
|
+
return Date.now() / 1e3 >= entry.expiresAt;
|
|
46
|
+
}
|
|
47
|
+
async getTokens(serverUrl) {
|
|
48
|
+
const key = this.normalizeUrl(serverUrl);
|
|
49
|
+
const entry = this.tokens.get(key);
|
|
50
|
+
if (this.isExpired(entry)) {
|
|
51
|
+
this.tokens.delete(key);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return entry?.value ?? null;
|
|
55
|
+
}
|
|
56
|
+
async setTokens(serverUrl, tokens) {
|
|
57
|
+
const key = this.normalizeUrl(serverUrl);
|
|
58
|
+
const enrichedTokens = withExpiresAt(tokens);
|
|
59
|
+
this.tokens.set(key, {
|
|
60
|
+
value: enrichedTokens,
|
|
61
|
+
expiresAt: enrichedTokens.expires_at
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async clearTokens(serverUrl) {
|
|
65
|
+
const key = this.normalizeUrl(serverUrl);
|
|
66
|
+
this.tokens.delete(key);
|
|
67
|
+
}
|
|
68
|
+
async getClientInfo(serverUrl) {
|
|
69
|
+
const key = this.normalizeUrl(serverUrl);
|
|
70
|
+
const entry = this.clients.get(key);
|
|
71
|
+
if (this.isExpired(entry)) {
|
|
72
|
+
this.clients.delete(key);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
return entry?.value ?? null;
|
|
76
|
+
}
|
|
77
|
+
async setClientInfo(serverUrl, info) {
|
|
78
|
+
const key = this.normalizeUrl(serverUrl);
|
|
79
|
+
this.clients.set(key, {
|
|
80
|
+
value: info,
|
|
81
|
+
expiresAt: info.client_secret_expires_at
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async clearClientInfo(serverUrl) {
|
|
85
|
+
const key = this.normalizeUrl(serverUrl);
|
|
86
|
+
this.clients.delete(key);
|
|
87
|
+
}
|
|
88
|
+
async clearAll() {
|
|
89
|
+
this.tokens.clear();
|
|
90
|
+
this.clients.clear();
|
|
91
|
+
}
|
|
92
|
+
async getAllSessions() {
|
|
93
|
+
const sessions = [];
|
|
94
|
+
for (const [url, entry] of this.tokens.entries()) {
|
|
95
|
+
if (!this.isExpired(entry)) {
|
|
96
|
+
sessions.push({
|
|
97
|
+
serverUrl: url,
|
|
98
|
+
tokens: entry.value,
|
|
99
|
+
clientInfo: this.clients.get(url)?.value,
|
|
100
|
+
createdAt: Date.now(),
|
|
101
|
+
updatedAt: Date.now()
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return sessions;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export {
|
|
110
|
+
isTokenExpired,
|
|
111
|
+
withExpiresAt,
|
|
112
|
+
MemoryStorage
|
|
113
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__name
|
|
3
|
+
} from "./chunk-LPEX4YW6.mjs";
|
|
4
|
+
|
|
5
|
+
// src/client/pkce.ts
|
|
6
|
+
import { createHash, randomBytes } from "crypto";
|
|
7
|
+
function generateCodeVerifier(length = 64) {
|
|
8
|
+
if (length < 43 || length > 128) {
|
|
9
|
+
throw new Error("PKCE code verifier must be between 43-128 characters");
|
|
10
|
+
}
|
|
11
|
+
const bytesNeeded = Math.ceil(length * 0.75);
|
|
12
|
+
const randomBuffer = randomBytes(bytesNeeded);
|
|
13
|
+
return randomBuffer.toString("base64url").slice(0, length);
|
|
14
|
+
}
|
|
15
|
+
__name(generateCodeVerifier, "generateCodeVerifier");
|
|
16
|
+
function generateCodeChallenge(verifier) {
|
|
17
|
+
return createHash("sha256").update(verifier, "utf8").digest("base64url");
|
|
18
|
+
}
|
|
19
|
+
__name(generateCodeChallenge, "generateCodeChallenge");
|
|
20
|
+
function generatePKCE(verifierLength = 64) {
|
|
21
|
+
const verifier = generateCodeVerifier(verifierLength);
|
|
22
|
+
const challenge = generateCodeChallenge(verifier);
|
|
23
|
+
return {
|
|
24
|
+
verifier,
|
|
25
|
+
challenge,
|
|
26
|
+
method: "S256"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
__name(generatePKCE, "generatePKCE");
|
|
30
|
+
function verifyPKCE(verifier, challenge, method = "S256") {
|
|
31
|
+
if (method === "plain") {
|
|
32
|
+
return verifier === challenge;
|
|
33
|
+
}
|
|
34
|
+
const expectedChallenge = generateCodeChallenge(verifier);
|
|
35
|
+
return expectedChallenge === challenge;
|
|
36
|
+
}
|
|
37
|
+
__name(verifyPKCE, "verifyPKCE");
|
|
38
|
+
function isValidCodeVerifier(verifier) {
|
|
39
|
+
if (verifier.length < 43 || verifier.length > 128) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const validPattern = /^[A-Za-z0-9\-._~]+$/;
|
|
43
|
+
return validPattern.test(verifier);
|
|
44
|
+
}
|
|
45
|
+
__name(isValidCodeVerifier, "isValidCodeVerifier");
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
generateCodeVerifier,
|
|
49
|
+
generateCodeChallenge,
|
|
50
|
+
generatePKCE,
|
|
51
|
+
verifyPKCE,
|
|
52
|
+
isValidCodeVerifier
|
|
53
|
+
};
|