@nestr/mcp 0.1.53 → 0.1.54
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/build/http.d.ts.map +1 -1
- package/build/http.js +83 -41
- package/build/http.js.map +1 -1
- package/build/oauth/file-store.d.ts +14 -0
- package/build/oauth/file-store.d.ts.map +1 -0
- package/build/oauth/file-store.js +366 -0
- package/build/oauth/file-store.js.map +1 -0
- package/build/oauth/flow.d.ts +13 -13
- package/build/oauth/flow.d.ts.map +1 -1
- package/build/oauth/flow.js +21 -19
- package/build/oauth/flow.js.map +1 -1
- package/build/oauth/redis-store.d.ts +17 -0
- package/build/oauth/redis-store.d.ts.map +1 -0
- package/build/oauth/redis-store.js +174 -0
- package/build/oauth/redis-store.js.map +1 -0
- package/build/oauth/storage.d.ts +25 -109
- package/build/oauth/storage.d.ts.map +1 -1
- package/build/oauth/storage.js +39 -491
- package/build/oauth/storage.js.map +1 -1
- package/build/oauth/store.d.ts +80 -0
- package/build/oauth/store.d.ts.map +1 -0
- package/build/oauth/store.js +37 -0
- package/build/oauth/store.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based OAuthStore Implementation
|
|
3
|
+
*
|
|
4
|
+
* Stores OAuth state as JSON files on disk with in-memory caching.
|
|
5
|
+
* Used for local development and stdio mode (npx @nestr/mcp).
|
|
6
|
+
*
|
|
7
|
+
* For multi-pod production deployments, use RedisStore (REDIS_URL).
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";
|
|
12
|
+
// Storage directory - use /data in production (mounted volume), fallback to local .data
|
|
13
|
+
const STORAGE_DIR = process.env.OAUTH_STORAGE_DIR ||
|
|
14
|
+
(process.env.NODE_ENV === "production" ? "/data" : ".data");
|
|
15
|
+
const CLIENTS_FILE = join(STORAGE_DIR, "oauth-clients.json");
|
|
16
|
+
const PENDING_AUTH_FILE = join(STORAGE_DIR, "pending-auth.json");
|
|
17
|
+
const PKCE_FOR_CODE_FILE = join(STORAGE_DIR, "pkce-codes.json");
|
|
18
|
+
const SESSIONS_FILE_ENCRYPTED = join(STORAGE_DIR, "oauth-sessions.enc");
|
|
19
|
+
const SESSIONS_FILE_PLAINTEXT = join(STORAGE_DIR, "oauth-sessions.json");
|
|
20
|
+
// Encryption constants
|
|
21
|
+
const ALGORITHM = "aes-256-gcm";
|
|
22
|
+
const IV_LENGTH = 16;
|
|
23
|
+
// TTL constants
|
|
24
|
+
const PENDING_AUTH_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
25
|
+
const PKCE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
26
|
+
// ============ Encryption helpers ============
|
|
27
|
+
function getEncryptionKey() {
|
|
28
|
+
if (!process.env.OAUTH_ENCRYPTION_KEY)
|
|
29
|
+
return null;
|
|
30
|
+
const key = Buffer.from(process.env.OAUTH_ENCRYPTION_KEY, "base64");
|
|
31
|
+
if (key.length !== 32) {
|
|
32
|
+
throw new Error("OAUTH_ENCRYPTION_KEY must be 32 bytes (256 bits) base64-encoded");
|
|
33
|
+
}
|
|
34
|
+
return key;
|
|
35
|
+
}
|
|
36
|
+
function encrypt(data, key) {
|
|
37
|
+
const iv = randomBytes(IV_LENGTH);
|
|
38
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
39
|
+
let encrypted = cipher.update(data, "utf8", "base64");
|
|
40
|
+
encrypted += cipher.final("base64");
|
|
41
|
+
const authTag = cipher.getAuthTag();
|
|
42
|
+
return `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
|
|
43
|
+
}
|
|
44
|
+
function decrypt(encryptedData, key) {
|
|
45
|
+
const parts = encryptedData.split(":");
|
|
46
|
+
if (parts.length !== 3)
|
|
47
|
+
throw new Error("Invalid encrypted data format");
|
|
48
|
+
const iv = Buffer.from(parts[0], "base64");
|
|
49
|
+
const authTag = Buffer.from(parts[1], "base64");
|
|
50
|
+
const data = parts[2];
|
|
51
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
52
|
+
decipher.setAuthTag(authTag);
|
|
53
|
+
let decrypted = decipher.update(data, "base64", "utf8");
|
|
54
|
+
decrypted += decipher.final("utf8");
|
|
55
|
+
return decrypted;
|
|
56
|
+
}
|
|
57
|
+
// ============ File I/O helpers ============
|
|
58
|
+
function ensureStorageDir() {
|
|
59
|
+
if (!existsSync(STORAGE_DIR)) {
|
|
60
|
+
mkdirSync(STORAGE_DIR, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function loadJsonFile(filePath) {
|
|
64
|
+
if (!existsSync(filePath))
|
|
65
|
+
return {};
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error(`Failed to load ${filePath}:`, error);
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function saveJsonFile(filePath, data) {
|
|
75
|
+
ensureStorageDir();
|
|
76
|
+
try {
|
|
77
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error(`Failed to save ${filePath}:`, error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// ============ FileStore implementation ============
|
|
84
|
+
class FileStore {
|
|
85
|
+
clientsCache = null;
|
|
86
|
+
pendingAuthCache = null;
|
|
87
|
+
pkceForCodeCache = null;
|
|
88
|
+
sessionsCache = null;
|
|
89
|
+
cleanupInterval;
|
|
90
|
+
constructor() {
|
|
91
|
+
ensureStorageDir();
|
|
92
|
+
// Run cleanup every minute
|
|
93
|
+
this.cleanupInterval = setInterval(() => {
|
|
94
|
+
this.cleanupExpiredPendingAuth();
|
|
95
|
+
this.cleanupExpiredSessions();
|
|
96
|
+
}, 60000);
|
|
97
|
+
}
|
|
98
|
+
// ---- Clients ----
|
|
99
|
+
loadClients() {
|
|
100
|
+
if (this.clientsCache)
|
|
101
|
+
return this.clientsCache;
|
|
102
|
+
this.clientsCache = new Map();
|
|
103
|
+
const data = loadJsonFile(CLIENTS_FILE);
|
|
104
|
+
for (const [id, client] of Object.entries(data)) {
|
|
105
|
+
this.clientsCache.set(id, client);
|
|
106
|
+
}
|
|
107
|
+
if (this.clientsCache.size > 0) {
|
|
108
|
+
console.log(`Loaded ${this.clientsCache.size} registered OAuth clients`);
|
|
109
|
+
}
|
|
110
|
+
return this.clientsCache;
|
|
111
|
+
}
|
|
112
|
+
saveClients() {
|
|
113
|
+
if (!this.clientsCache)
|
|
114
|
+
return;
|
|
115
|
+
const data = {};
|
|
116
|
+
for (const [id, client] of this.clientsCache)
|
|
117
|
+
data[id] = client;
|
|
118
|
+
saveJsonFile(CLIENTS_FILE, data);
|
|
119
|
+
}
|
|
120
|
+
async registerClient(client) {
|
|
121
|
+
const clients = this.loadClients();
|
|
122
|
+
clients.set(client.client_id, client);
|
|
123
|
+
this.saveClients();
|
|
124
|
+
console.log(`Registered OAuth client: ${client.client_id}`);
|
|
125
|
+
}
|
|
126
|
+
async getClient(clientId) {
|
|
127
|
+
return this.loadClients().get(clientId);
|
|
128
|
+
}
|
|
129
|
+
async getClientCount() {
|
|
130
|
+
return this.loadClients().size;
|
|
131
|
+
}
|
|
132
|
+
async clientExists(clientId) {
|
|
133
|
+
return this.loadClients().has(clientId);
|
|
134
|
+
}
|
|
135
|
+
// ---- Pending Auth ----
|
|
136
|
+
loadPendingAuth() {
|
|
137
|
+
if (this.pendingAuthCache)
|
|
138
|
+
return this.pendingAuthCache;
|
|
139
|
+
this.pendingAuthCache = new Map();
|
|
140
|
+
const data = loadJsonFile(PENDING_AUTH_FILE);
|
|
141
|
+
const now = Date.now();
|
|
142
|
+
for (const [state, pending] of Object.entries(data)) {
|
|
143
|
+
if (now - pending.createdAt < PENDING_AUTH_TTL_MS) {
|
|
144
|
+
this.pendingAuthCache.set(state, pending);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return this.pendingAuthCache;
|
|
148
|
+
}
|
|
149
|
+
savePendingAuth() {
|
|
150
|
+
if (!this.pendingAuthCache)
|
|
151
|
+
return;
|
|
152
|
+
const data = {};
|
|
153
|
+
for (const [state, pending] of this.pendingAuthCache)
|
|
154
|
+
data[state] = pending;
|
|
155
|
+
saveJsonFile(PENDING_AUTH_FILE, data);
|
|
156
|
+
}
|
|
157
|
+
async storePendingAuth(pending) {
|
|
158
|
+
const cache = this.loadPendingAuth();
|
|
159
|
+
cache.set(pending.state, pending);
|
|
160
|
+
this.savePendingAuth();
|
|
161
|
+
}
|
|
162
|
+
async consumePendingAuth(state) {
|
|
163
|
+
const cache = this.loadPendingAuth();
|
|
164
|
+
const pending = cache.get(state);
|
|
165
|
+
if (!pending)
|
|
166
|
+
return undefined;
|
|
167
|
+
if (Date.now() - pending.createdAt > PENDING_AUTH_TTL_MS) {
|
|
168
|
+
cache.delete(state);
|
|
169
|
+
this.savePendingAuth();
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
cache.delete(state);
|
|
173
|
+
this.savePendingAuth();
|
|
174
|
+
return pending;
|
|
175
|
+
}
|
|
176
|
+
cleanupExpiredPendingAuth() {
|
|
177
|
+
const cache = this.loadPendingAuth();
|
|
178
|
+
const now = Date.now();
|
|
179
|
+
let cleaned = 0;
|
|
180
|
+
for (const [state, pending] of cache) {
|
|
181
|
+
if (now - pending.createdAt > PENDING_AUTH_TTL_MS) {
|
|
182
|
+
cache.delete(state);
|
|
183
|
+
cleaned++;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (cleaned > 0)
|
|
187
|
+
this.savePendingAuth();
|
|
188
|
+
}
|
|
189
|
+
// ---- PKCE Codes ----
|
|
190
|
+
loadPkceForCode() {
|
|
191
|
+
if (this.pkceForCodeCache)
|
|
192
|
+
return this.pkceForCodeCache;
|
|
193
|
+
this.pkceForCodeCache = new Map();
|
|
194
|
+
const data = loadJsonFile(PKCE_FOR_CODE_FILE);
|
|
195
|
+
const now = Date.now();
|
|
196
|
+
for (const [code, pkce] of Object.entries(data)) {
|
|
197
|
+
if (now - pkce.createdAt < PKCE_TTL_MS) {
|
|
198
|
+
this.pkceForCodeCache.set(code, pkce);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return this.pkceForCodeCache;
|
|
202
|
+
}
|
|
203
|
+
savePkceForCode() {
|
|
204
|
+
if (!this.pkceForCodeCache)
|
|
205
|
+
return;
|
|
206
|
+
const data = {};
|
|
207
|
+
for (const [code, pkce] of this.pkceForCodeCache)
|
|
208
|
+
data[code] = pkce;
|
|
209
|
+
saveJsonFile(PKCE_FOR_CODE_FILE, data);
|
|
210
|
+
}
|
|
211
|
+
async storePkceForCode(code, codeChallenge, codeChallengeMethod) {
|
|
212
|
+
const cache = this.loadPkceForCode();
|
|
213
|
+
cache.set(code, { codeChallenge, codeChallengeMethod, createdAt: Date.now() });
|
|
214
|
+
this.savePkceForCode();
|
|
215
|
+
}
|
|
216
|
+
async consumePkceForCode(code) {
|
|
217
|
+
const cache = this.loadPkceForCode();
|
|
218
|
+
const pkce = cache.get(code);
|
|
219
|
+
if (!pkce)
|
|
220
|
+
return undefined;
|
|
221
|
+
if (Date.now() - pkce.createdAt > PKCE_TTL_MS) {
|
|
222
|
+
cache.delete(code);
|
|
223
|
+
this.savePkceForCode();
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
cache.delete(code);
|
|
227
|
+
this.savePkceForCode();
|
|
228
|
+
return pkce;
|
|
229
|
+
}
|
|
230
|
+
// ---- Sessions ----
|
|
231
|
+
migrateToEncrypted(key) {
|
|
232
|
+
if (!existsSync(SESSIONS_FILE_PLAINTEXT))
|
|
233
|
+
return null;
|
|
234
|
+
try {
|
|
235
|
+
const data = JSON.parse(readFileSync(SESSIONS_FILE_PLAINTEXT, "utf-8"));
|
|
236
|
+
const sessions = new Map();
|
|
237
|
+
for (const [id, session] of Object.entries(data)) {
|
|
238
|
+
sessions.set(id, session);
|
|
239
|
+
}
|
|
240
|
+
console.log(`Migrating ${sessions.size} OAuth sessions from plaintext to encrypted storage`);
|
|
241
|
+
const plaintext = JSON.stringify(data);
|
|
242
|
+
const encrypted = encrypt(plaintext, key);
|
|
243
|
+
writeFileSync(SESSIONS_FILE_ENCRYPTED, encrypted, { mode: 0o600 });
|
|
244
|
+
unlinkSync(SESSIONS_FILE_PLAINTEXT);
|
|
245
|
+
console.log("Migration complete - plaintext sessions file removed");
|
|
246
|
+
return sessions;
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.error("Failed to migrate sessions to encrypted:", error);
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
loadSessions() {
|
|
254
|
+
if (this.sessionsCache)
|
|
255
|
+
return this.sessionsCache;
|
|
256
|
+
ensureStorageDir();
|
|
257
|
+
this.sessionsCache = new Map();
|
|
258
|
+
const encryptionKey = getEncryptionKey();
|
|
259
|
+
if (encryptionKey) {
|
|
260
|
+
if (existsSync(SESSIONS_FILE_ENCRYPTED)) {
|
|
261
|
+
try {
|
|
262
|
+
const encryptedData = readFileSync(SESSIONS_FILE_ENCRYPTED, "utf-8");
|
|
263
|
+
const decrypted = decrypt(encryptedData, encryptionKey);
|
|
264
|
+
const data = JSON.parse(decrypted);
|
|
265
|
+
for (const [id, session] of Object.entries(data)) {
|
|
266
|
+
this.sessionsCache.set(id, session);
|
|
267
|
+
}
|
|
268
|
+
console.log(`Loaded ${this.sessionsCache.size} OAuth sessions (encrypted)`);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
console.error("Failed to load encrypted OAuth sessions (starting fresh):", error);
|
|
272
|
+
this.sessionsCache = new Map();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
const migrated = this.migrateToEncrypted(encryptionKey);
|
|
277
|
+
if (migrated)
|
|
278
|
+
this.sessionsCache = migrated;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
if (existsSync(SESSIONS_FILE_PLAINTEXT)) {
|
|
283
|
+
try {
|
|
284
|
+
const data = JSON.parse(readFileSync(SESSIONS_FILE_PLAINTEXT, "utf-8"));
|
|
285
|
+
for (const [id, session] of Object.entries(data)) {
|
|
286
|
+
this.sessionsCache.set(id, session);
|
|
287
|
+
}
|
|
288
|
+
console.log(`Loaded ${this.sessionsCache.size} OAuth sessions`);
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.error("Failed to load OAuth sessions:", error);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return this.sessionsCache;
|
|
296
|
+
}
|
|
297
|
+
saveSessions() {
|
|
298
|
+
if (!this.sessionsCache)
|
|
299
|
+
return;
|
|
300
|
+
ensureStorageDir();
|
|
301
|
+
const data = {};
|
|
302
|
+
for (const [id, session] of this.sessionsCache)
|
|
303
|
+
data[id] = session;
|
|
304
|
+
const encryptionKey = getEncryptionKey();
|
|
305
|
+
try {
|
|
306
|
+
if (encryptionKey) {
|
|
307
|
+
const plaintext = JSON.stringify(data);
|
|
308
|
+
const encrypted = encrypt(plaintext, encryptionKey);
|
|
309
|
+
writeFileSync(SESSIONS_FILE_ENCRYPTED, encrypted, { mode: 0o600 });
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
writeFileSync(SESSIONS_FILE_PLAINTEXT, JSON.stringify(data, null, 2));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
console.error("Failed to save OAuth sessions:", error);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
async storeSession(sessionId, session) {
|
|
320
|
+
const cache = this.loadSessions();
|
|
321
|
+
cache.set(sessionId, session);
|
|
322
|
+
this.saveSessions();
|
|
323
|
+
}
|
|
324
|
+
async getSession(sessionId) {
|
|
325
|
+
return this.loadSessions().get(sessionId);
|
|
326
|
+
}
|
|
327
|
+
async updateSession(sessionId, session) {
|
|
328
|
+
const cache = this.loadSessions();
|
|
329
|
+
if (cache.has(sessionId)) {
|
|
330
|
+
cache.set(sessionId, session);
|
|
331
|
+
this.saveSessions();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
async removeSession(sessionId) {
|
|
335
|
+
const cache = this.loadSessions();
|
|
336
|
+
if (cache.delete(sessionId)) {
|
|
337
|
+
this.saveSessions();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
cleanupExpiredSessions() {
|
|
341
|
+
const cache = this.loadSessions();
|
|
342
|
+
const now = Date.now();
|
|
343
|
+
let cleaned = 0;
|
|
344
|
+
for (const [sessionId, session] of cache) {
|
|
345
|
+
if (now >= session.expiresAt && !session.refreshToken) {
|
|
346
|
+
cache.delete(sessionId);
|
|
347
|
+
cleaned++;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (cleaned > 0) {
|
|
351
|
+
this.saveSessions();
|
|
352
|
+
console.log(`Cleaned up ${cleaned} expired OAuth sessions`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// ---- Lifecycle ----
|
|
356
|
+
async close() {
|
|
357
|
+
clearInterval(this.cleanupInterval);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Create a file-based OAuthStore instance.
|
|
362
|
+
*/
|
|
363
|
+
export function createFileStore() {
|
|
364
|
+
return new FileStore();
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=file-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-store.js","sourceRoot":"","sources":["../../src/oauth/file-store.ts"],"names":[],"mappings":"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"}
|
package/build/oauth/flow.d.ts
CHANGED
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
* - We proxy to Nestr WITHOUT PKCE (Nestr doesn't support it)
|
|
11
11
|
* - This provides PKCE security from the MCP client's perspective
|
|
12
12
|
*/
|
|
13
|
-
import { type PendingAuthWithPKCE, type StoredOAuthSession } from "./
|
|
13
|
+
import { type PendingAuthWithPKCE, type StoredOAuthSession } from "./store.js";
|
|
14
14
|
/**
|
|
15
15
|
* Pending OAuth authorization request
|
|
16
|
-
* @deprecated Use PendingAuthWithPKCE from
|
|
16
|
+
* @deprecated Use PendingAuthWithPKCE from store.ts
|
|
17
17
|
*/
|
|
18
18
|
export interface PendingAuth {
|
|
19
19
|
state: string;
|
|
@@ -33,7 +33,7 @@ export interface TokenResponse {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Stored OAuth session after successful authentication
|
|
36
|
-
* @deprecated Use StoredOAuthSession from
|
|
36
|
+
* @deprecated Use StoredOAuthSession from store.ts
|
|
37
37
|
*/
|
|
38
38
|
export type OAuthSession = StoredOAuthSession;
|
|
39
39
|
/**
|
|
@@ -69,18 +69,18 @@ export interface AuthorizationRequestParams {
|
|
|
69
69
|
* Supports PKCE: We store the code_challenge and verify it when the client
|
|
70
70
|
* exchanges the code. Nestr doesn't support PKCE, so we handle it in our proxy.
|
|
71
71
|
*/
|
|
72
|
-
export declare function createAuthorizationRequest(redirectUri: string, finalRedirect?: string): {
|
|
72
|
+
export declare function createAuthorizationRequest(redirectUri: string, finalRedirect?: string): Promise<{
|
|
73
73
|
authUrl: string;
|
|
74
74
|
state: string;
|
|
75
|
-
}
|
|
76
|
-
export declare function createAuthorizationRequest(params: AuthorizationRequestParams): {
|
|
75
|
+
}>;
|
|
76
|
+
export declare function createAuthorizationRequest(params: AuthorizationRequestParams): Promise<{
|
|
77
77
|
authUrl: string;
|
|
78
78
|
state: string;
|
|
79
|
-
}
|
|
79
|
+
}>;
|
|
80
80
|
/**
|
|
81
81
|
* Get and remove a pending auth request
|
|
82
82
|
*/
|
|
83
|
-
export declare function getPendingAuth(state: string): PendingAuthWithPKCE | undefined
|
|
83
|
+
export declare function getPendingAuth(state: string): Promise<PendingAuthWithPKCE | undefined>;
|
|
84
84
|
/**
|
|
85
85
|
* Verify PKCE code_verifier against stored code_challenge
|
|
86
86
|
*
|
|
@@ -99,18 +99,18 @@ export declare function exchangeCodeForTokens(code: string, redirectUri: string)
|
|
|
99
99
|
*/
|
|
100
100
|
export declare function refreshAccessToken(refreshToken: string): Promise<TokenResponse>;
|
|
101
101
|
/**
|
|
102
|
-
* Store an OAuth session (persisted to
|
|
102
|
+
* Store an OAuth session (persisted to store)
|
|
103
103
|
* @param sessionId - The session identifier (used as key for token lookup)
|
|
104
104
|
* @param tokens - The OAuth token response from Nestr
|
|
105
105
|
* @param userId - Optional Nestr user ID for analytics (GA4 user_id)
|
|
106
106
|
*/
|
|
107
|
-
export declare function storeOAuthSession(sessionId: string, tokens: TokenResponse, userId?: string): void
|
|
107
|
+
export declare function storeOAuthSession(sessionId: string, tokens: TokenResponse, userId?: string): Promise<void>;
|
|
108
108
|
/**
|
|
109
|
-
* Get an OAuth session, refreshing if needed
|
|
109
|
+
* Get an OAuth session, refreshing if needed
|
|
110
110
|
*/
|
|
111
111
|
export declare function getOAuthSession(sessionId: string): Promise<OAuthSession | undefined>;
|
|
112
112
|
/**
|
|
113
|
-
* Remove an OAuth session
|
|
113
|
+
* Remove an OAuth session
|
|
114
114
|
*/
|
|
115
|
-
export declare function removeOAuthSession(sessionId: string): void
|
|
115
|
+
export declare function removeOAuthSession(sessionId: string): Promise<void>;
|
|
116
116
|
//# sourceMappingURL=flow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,
|
|
1
|
+
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAElB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAY9C;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC/C,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAkF/C;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAE5F;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,MAAe,GACtB,OAAO,CAST;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC,CAiCxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CA+BxB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CA6BnC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE"}
|
package/build/oauth/flow.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { randomBytes, createHash } from "node:crypto";
|
|
14
14
|
import { getOAuthConfig } from "./config.js";
|
|
15
|
-
import {
|
|
15
|
+
import { getStore, } from "./store.js";
|
|
16
16
|
// Buffer time before token expiration to trigger refresh (60 seconds)
|
|
17
17
|
const TOKEN_EXPIRY_BUFFER_MS = 60 * 1000;
|
|
18
18
|
/**
|
|
@@ -39,16 +39,17 @@ export function generateCodeChallenge(verifier) {
|
|
|
39
39
|
export function generateState() {
|
|
40
40
|
return generateRandomString(32);
|
|
41
41
|
}
|
|
42
|
-
export function createAuthorizationRequest(redirectUriOrParams, finalRedirect) {
|
|
42
|
+
export async function createAuthorizationRequest(redirectUriOrParams, finalRedirect) {
|
|
43
43
|
const config = getOAuthConfig();
|
|
44
|
+
const store = getStore();
|
|
44
45
|
// Handle legacy signature (redirectUri, finalRedirect)
|
|
45
46
|
if (typeof redirectUriOrParams === "string") {
|
|
46
47
|
if (!config.clientId) {
|
|
47
48
|
throw new Error("NESTR_OAUTH_CLIENT_ID environment variable is required for OAuth flow");
|
|
48
49
|
}
|
|
49
50
|
const state = generateState();
|
|
50
|
-
// Store pending auth
|
|
51
|
-
|
|
51
|
+
// Store pending auth
|
|
52
|
+
await store.storePendingAuth({
|
|
52
53
|
state,
|
|
53
54
|
redirectUri: redirectUriOrParams,
|
|
54
55
|
clientId: config.clientId,
|
|
@@ -70,7 +71,7 @@ export function createAuthorizationRequest(redirectUriOrParams, finalRedirect) {
|
|
|
70
71
|
const state = params.state || generateState();
|
|
71
72
|
// Store pending auth with PKCE info
|
|
72
73
|
// redirectUri here is the MCP CLIENT's redirect_uri (where we redirect with the code)
|
|
73
|
-
|
|
74
|
+
await store.storePendingAuth({
|
|
74
75
|
state,
|
|
75
76
|
redirectUri: params.redirectUri, // MCP client's callback URL
|
|
76
77
|
clientId: params.clientId,
|
|
@@ -105,8 +106,8 @@ export function createAuthorizationRequest(redirectUriOrParams, finalRedirect) {
|
|
|
105
106
|
/**
|
|
106
107
|
* Get and remove a pending auth request
|
|
107
108
|
*/
|
|
108
|
-
export function getPendingAuth(state) {
|
|
109
|
-
return
|
|
109
|
+
export async function getPendingAuth(state) {
|
|
110
|
+
return getStore().consumePendingAuth(state);
|
|
110
111
|
}
|
|
111
112
|
/**
|
|
112
113
|
* Verify PKCE code_verifier against stored code_challenge
|
|
@@ -186,13 +187,13 @@ export async function refreshAccessToken(refreshToken) {
|
|
|
186
187
|
return response.json();
|
|
187
188
|
}
|
|
188
189
|
/**
|
|
189
|
-
* Store an OAuth session (persisted to
|
|
190
|
+
* Store an OAuth session (persisted to store)
|
|
190
191
|
* @param sessionId - The session identifier (used as key for token lookup)
|
|
191
192
|
* @param tokens - The OAuth token response from Nestr
|
|
192
193
|
* @param userId - Optional Nestr user ID for analytics (GA4 user_id)
|
|
193
194
|
*/
|
|
194
|
-
export function storeOAuthSession(sessionId, tokens, userId) {
|
|
195
|
-
storeSession(sessionId, {
|
|
195
|
+
export async function storeOAuthSession(sessionId, tokens, userId) {
|
|
196
|
+
await getStore().storeSession(sessionId, {
|
|
196
197
|
accessToken: tokens.access_token,
|
|
197
198
|
refreshToken: tokens.refresh_token,
|
|
198
199
|
expiresAt: Date.now() + tokens.expires_in * 1000,
|
|
@@ -201,10 +202,11 @@ export function storeOAuthSession(sessionId, tokens, userId) {
|
|
|
201
202
|
});
|
|
202
203
|
}
|
|
203
204
|
/**
|
|
204
|
-
* Get an OAuth session, refreshing if needed
|
|
205
|
+
* Get an OAuth session, refreshing if needed
|
|
205
206
|
*/
|
|
206
207
|
export async function getOAuthSession(sessionId) {
|
|
207
|
-
const
|
|
208
|
+
const store = getStore();
|
|
209
|
+
const session = await store.getSession(sessionId);
|
|
208
210
|
if (!session) {
|
|
209
211
|
return undefined;
|
|
210
212
|
}
|
|
@@ -214,27 +216,27 @@ export async function getOAuthSession(sessionId) {
|
|
|
214
216
|
if (session.refreshToken) {
|
|
215
217
|
try {
|
|
216
218
|
const tokens = await refreshAccessToken(session.refreshToken);
|
|
217
|
-
storeOAuthSession(sessionId, tokens);
|
|
218
|
-
return getSession(sessionId);
|
|
219
|
+
await storeOAuthSession(sessionId, tokens);
|
|
220
|
+
return await store.getSession(sessionId);
|
|
219
221
|
}
|
|
220
222
|
catch {
|
|
221
223
|
// Refresh failed, remove session
|
|
222
|
-
removeSession(sessionId);
|
|
224
|
+
await store.removeSession(sessionId);
|
|
223
225
|
return undefined;
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
else {
|
|
227
229
|
// No refresh token, session expired
|
|
228
|
-
removeSession(sessionId);
|
|
230
|
+
await store.removeSession(sessionId);
|
|
229
231
|
return undefined;
|
|
230
232
|
}
|
|
231
233
|
}
|
|
232
234
|
return session;
|
|
233
235
|
}
|
|
234
236
|
/**
|
|
235
|
-
* Remove an OAuth session
|
|
237
|
+
* Remove an OAuth session
|
|
236
238
|
*/
|
|
237
|
-
export function removeOAuthSession(sessionId) {
|
|
238
|
-
removeSession(sessionId);
|
|
239
|
+
export async function removeOAuthSession(sessionId) {
|
|
240
|
+
await getStore().removeSession(sessionId);
|
|
239
241
|
}
|
|
240
242
|
//# sourceMappingURL=flow.js.map
|
package/build/oauth/flow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/oauth/flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redis-backed OAuthStore Implementation
|
|
3
|
+
*
|
|
4
|
+
* Uses Redis for shared state across multiple pods.
|
|
5
|
+
* Activated when REDIS_URL environment variable is set.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Native TTL for automatic expiry (no cleanup timers needed)
|
|
9
|
+
* - Atomic GETDEL for consume-once operations (pending auth, PKCE)
|
|
10
|
+
* - Optional AES-256-GCM encryption for session values (OAUTH_ENCRYPTION_KEY)
|
|
11
|
+
*/
|
|
12
|
+
import type { OAuthStore } from "./store.js";
|
|
13
|
+
/**
|
|
14
|
+
* Create a Redis-backed OAuthStore instance.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createRedisStore(redisUrl: string): Promise<OAuthStore>;
|
|
17
|
+
//# sourceMappingURL=redis-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-store.d.ts","sourceRoot":"","sources":["../../src/oauth/redis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,YAAY,CAAC;AAyLpB;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAc5E"}
|