@nestr/mcp 0.1.53 → 0.1.55

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,238 +1,33 @@
1
1
  /**
2
- * Persistent Storage for OAuth Data
2
+ * Backward-compatibility re-exports from the OAuthStore abstraction.
3
3
  *
4
- * Stores registered OAuth clients and pending auth requests to disk.
5
- * Uses a simple JSON file-based storage that persists across restarts.
6
- * OAuth sessions are encrypted at rest using AES-256-GCM.
7
- */
8
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
9
- import { join } from "node:path";
10
- import { randomBytes, createCipheriv, createDecipheriv, timingSafeEqual } from "node:crypto";
11
- // Storage directory - use /data in production (mounted volume), fallback to local .data
12
- const STORAGE_DIR = process.env.OAUTH_STORAGE_DIR ||
13
- (process.env.NODE_ENV === "production" ? "/data" : ".data");
14
- const CLIENTS_FILE = join(STORAGE_DIR, "oauth-clients.json");
15
- const PENDING_AUTH_FILE = join(STORAGE_DIR, "pending-auth.json");
16
- const SESSIONS_FILE_ENCRYPTED = join(STORAGE_DIR, "oauth-sessions.enc");
17
- const SESSIONS_FILE_PLAINTEXT = join(STORAGE_DIR, "oauth-sessions.json");
18
- // Encryption constants
19
- const ALGORITHM = "aes-256-gcm";
20
- const IV_LENGTH = 16;
21
- /**
22
- * Check if encryption is enabled (OAUTH_ENCRYPTION_KEY env var is set)
23
- */
24
- function isEncryptionEnabled() {
25
- return !!process.env.OAUTH_ENCRYPTION_KEY;
26
- }
27
- /**
28
- * Get the encryption key from environment variable.
29
- * Returns null if not set.
30
- */
31
- function getEncryptionKey() {
32
- if (!process.env.OAUTH_ENCRYPTION_KEY) {
33
- return null;
34
- }
35
- const key = Buffer.from(process.env.OAUTH_ENCRYPTION_KEY, "base64");
36
- if (key.length !== 32) {
37
- throw new Error("OAUTH_ENCRYPTION_KEY must be 32 bytes (256 bits) base64-encoded");
38
- }
39
- return key;
40
- }
41
- /**
42
- * Encrypt data using AES-256-GCM
43
- */
44
- function encrypt(data, key) {
45
- const iv = randomBytes(IV_LENGTH);
46
- const cipher = createCipheriv(ALGORITHM, key, iv);
47
- let encrypted = cipher.update(data, "utf8", "base64");
48
- encrypted += cipher.final("base64");
49
- const authTag = cipher.getAuthTag();
50
- // Format: iv:authTag:encryptedData (all base64)
51
- return `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
52
- }
53
- /**
54
- * Decrypt data using AES-256-GCM
4
+ * All types and the store singleton are canonical in store.ts.
5
+ * This file provides synchronous-looking wrappers that delegate to the
6
+ * initialized store for callers that haven't migrated yet.
7
+ *
8
+ * TODO: Remove this file once all callers import from store.ts directly.
55
9
  */
56
- function decrypt(encryptedData, key) {
57
- const parts = encryptedData.split(":");
58
- if (parts.length !== 3) {
59
- throw new Error("Invalid encrypted data format");
60
- }
61
- const iv = Buffer.from(parts[0], "base64");
62
- const authTag = Buffer.from(parts[1], "base64");
63
- const data = parts[2];
64
- const decipher = createDecipheriv(ALGORITHM, key, iv);
65
- decipher.setAuthTag(authTag);
66
- let decrypted = decipher.update(data, "base64", "utf8");
67
- decrypted += decipher.final("utf8");
68
- return decrypted;
69
- }
10
+ import { timingSafeEqual } from "node:crypto";
11
+ import { getStore } from "./store.js";
70
12
  /**
71
13
  * Constant-time string comparison to prevent timing attacks on secrets.
72
- * Uses crypto.timingSafeEqual under the hood.
14
+ * Standalone utility not part of the store interface.
73
15
  */
74
16
  export function constantTimeCompare(a, b) {
75
17
  const bufA = Buffer.from(a);
76
18
  const bufB = Buffer.from(b);
77
- if (bufA.length !== bufB.length) {
19
+ if (bufA.length !== bufB.length)
78
20
  return false;
79
- }
80
21
  return timingSafeEqual(bufA, bufB);
81
22
  }
82
- // In-memory cache backed by disk
83
- let clientsCache = null;
84
- let pendingAuthCache = null;
85
- let sessionsCache = null;
86
23
  /**
87
- * Ensure storage directory exists
24
+ * Validate redirect URI against a registered client's allowed URIs.
25
+ * Accepts the client object directly to avoid an extra async lookup.
88
26
  */
89
- function ensureStorageDir() {
90
- if (!existsSync(STORAGE_DIR)) {
91
- mkdirSync(STORAGE_DIR, { recursive: true });
92
- }
93
- }
94
- /**
95
- * Load registered clients from disk
96
- */
97
- function loadClients() {
98
- if (clientsCache)
99
- return clientsCache;
100
- ensureStorageDir();
101
- clientsCache = new Map();
102
- if (existsSync(CLIENTS_FILE)) {
103
- try {
104
- const data = JSON.parse(readFileSync(CLIENTS_FILE, "utf-8"));
105
- for (const [id, client] of Object.entries(data)) {
106
- clientsCache.set(id, client);
107
- }
108
- console.log(`Loaded ${clientsCache.size} registered OAuth clients`);
109
- }
110
- catch (error) {
111
- console.error("Failed to load OAuth clients:", error);
112
- }
113
- }
114
- return clientsCache;
115
- }
116
- /**
117
- * Save registered clients to disk
118
- */
119
- function saveClients() {
120
- if (!clientsCache)
121
- return;
122
- ensureStorageDir();
123
- const data = {};
124
- for (const [id, client] of clientsCache) {
125
- data[id] = client;
126
- }
127
- try {
128
- writeFileSync(CLIENTS_FILE, JSON.stringify(data, null, 2));
129
- }
130
- catch (error) {
131
- console.error("Failed to save OAuth clients:", error);
132
- }
133
- }
134
- /**
135
- * Load pending auth requests from disk
136
- */
137
- function loadPendingAuth() {
138
- if (pendingAuthCache)
139
- return pendingAuthCache;
140
- ensureStorageDir();
141
- pendingAuthCache = new Map();
142
- if (existsSync(PENDING_AUTH_FILE)) {
143
- try {
144
- const data = JSON.parse(readFileSync(PENDING_AUTH_FILE, "utf-8"));
145
- const now = Date.now();
146
- const TTL = 5 * 60 * 1000; // 5 minutes
147
- for (const [state, pending] of Object.entries(data)) {
148
- const p = pending;
149
- // Only load non-expired entries
150
- if (now - p.createdAt < TTL) {
151
- pendingAuthCache.set(state, p);
152
- }
153
- }
154
- }
155
- catch (error) {
156
- console.error("Failed to load pending auth:", error);
157
- }
158
- }
159
- return pendingAuthCache;
160
- }
161
- /**
162
- * Save pending auth requests to disk
163
- */
164
- function savePendingAuth() {
165
- if (!pendingAuthCache)
166
- return;
167
- ensureStorageDir();
168
- const data = {};
169
- for (const [state, pending] of pendingAuthCache) {
170
- data[state] = pending;
171
- }
172
- try {
173
- writeFileSync(PENDING_AUTH_FILE, JSON.stringify(data, null, 2));
174
- }
175
- catch (error) {
176
- console.error("Failed to save pending auth:", error);
177
- }
178
- }
179
- // ============ Client Registration ============
180
- /**
181
- * Register a new OAuth client
182
- */
183
- export function registerClient(client) {
184
- const clients = loadClients();
185
- clients.set(client.client_id, client);
186
- saveClients();
187
- console.log(`Registered OAuth client: ${client.client_id}`);
188
- }
189
- /**
190
- * Get a registered client by ID
191
- */
192
- export function getClient(clientId) {
193
- const clients = loadClients();
194
- return clients.get(clientId);
195
- }
196
- /**
197
- * Get the total number of registered clients
198
- */
199
- export function getClientCount() {
200
- return loadClients().size;
201
- }
202
- /**
203
- * Check if a client ID exists
204
- */
205
- export function clientExists(clientId) {
206
- const clients = loadClients();
207
- return clients.has(clientId);
208
- }
209
- /**
210
- * Validate client credentials
211
- */
212
- export function validateClientCredentials(clientId, clientSecret) {
213
- const client = getClient(clientId);
214
- if (!client)
215
- return false;
216
- // If client has no secret (public client), accept
217
- if (!client.client_secret)
218
- return true;
219
- // Otherwise validate secret using constant-time comparison
220
- return constantTimeCompare(client.client_secret, clientSecret || "");
221
- }
222
- /**
223
- * Validate redirect URI for a client
224
- */
225
- export function validateRedirectUri(clientId, redirectUri) {
226
- const client = getClient(clientId);
227
- if (!client)
228
- return false;
27
+ export function validateRedirectUri(client, redirectUri) {
229
28
  return client.redirect_uris.some((uri) => {
230
- // Exact match or localhost with any port
231
29
  if (uri === redirectUri)
232
30
  return true;
233
- // Handle localhost wildcards (common for CLI tools)
234
- // Per RFC 8252, localhost redirects should use http: and we treat
235
- // localhost and 127.0.0.1 as equivalent.
236
31
  try {
237
32
  const registered = new URL(uri);
238
33
  const requested = new URL(redirectUri);
@@ -251,289 +46,42 @@ export function validateRedirectUri(clientId, redirectUri) {
251
46
  return false;
252
47
  });
253
48
  }
254
- // ============ Pending Auth with PKCE ============
255
- /**
256
- * Store a pending auth request
257
- */
258
- export function storePendingAuth(pending) {
259
- const cache = loadPendingAuth();
260
- cache.set(pending.state, pending);
261
- savePendingAuth();
262
- }
263
- /**
264
- * Get and remove a pending auth request
265
- */
266
- export function consumePendingAuth(state) {
267
- const cache = loadPendingAuth();
268
- const pending = cache.get(state);
269
- if (!pending)
270
- return undefined;
271
- // Check if expired (5 minutes)
272
- if (Date.now() - pending.createdAt > 5 * 60 * 1000) {
273
- cache.delete(state);
274
- savePendingAuth();
275
- return undefined;
276
- }
277
- // Remove from cache (one-time use)
278
- cache.delete(state);
279
- savePendingAuth();
280
- return pending;
281
- }
282
- /**
283
- * Cleanup expired pending auth requests
284
- */
285
- export function cleanupExpiredPendingAuth() {
286
- const cache = loadPendingAuth();
287
- const now = Date.now();
288
- const TTL = 5 * 60 * 1000;
289
- let cleaned = 0;
290
- for (const [state, pending] of cache) {
291
- if (now - pending.createdAt > TTL) {
292
- cache.delete(state);
293
- cleaned++;
294
- }
295
- }
296
- if (cleaned > 0) {
297
- savePendingAuth();
298
- }
299
- }
300
- // ============ PKCE Code Storage ============
301
- // Stores PKCE challenges indexed by authorization code for token exchange verification
302
- const PKCE_FOR_CODE_FILE = join(STORAGE_DIR, "pkce-codes.json");
303
- let pkceForCodeCache = null;
304
- function loadPkceForCode() {
305
- if (pkceForCodeCache)
306
- return pkceForCodeCache;
307
- ensureStorageDir();
308
- pkceForCodeCache = new Map();
309
- if (existsSync(PKCE_FOR_CODE_FILE)) {
310
- try {
311
- const data = JSON.parse(readFileSync(PKCE_FOR_CODE_FILE, "utf-8"));
312
- const now = Date.now();
313
- const TTL = 5 * 60 * 1000;
314
- for (const [code, pkce] of Object.entries(data)) {
315
- const p = pkce;
316
- if (now - p.createdAt < TTL) {
317
- pkceForCodeCache.set(code, p);
318
- }
319
- }
320
- }
321
- catch {
322
- pkceForCodeCache = new Map();
323
- }
324
- }
325
- return pkceForCodeCache;
49
+ // ============ Async store delegates ============
50
+ // These are used by callers that haven't migrated to the store interface yet.
51
+ export async function registerClient(...args) {
52
+ return getStore().registerClient(...args);
326
53
  }
327
- function savePkceForCode() {
328
- if (!pkceForCodeCache)
329
- return;
330
- ensureStorageDir();
331
- const data = {};
332
- for (const [code, pkce] of pkceForCodeCache) {
333
- data[code] = pkce;
334
- }
335
- try {
336
- writeFileSync(PKCE_FOR_CODE_FILE, JSON.stringify(data, null, 2));
337
- }
338
- catch (error) {
339
- console.error("Failed to save PKCE codes:", error);
340
- }
54
+ export async function getClient(...args) {
55
+ return getStore().getClient(...args);
341
56
  }
342
- export function storePkceForCode(code, codeChallenge, codeChallengeMethod) {
343
- const cache = loadPkceForCode();
344
- cache.set(code, {
345
- codeChallenge,
346
- codeChallengeMethod,
347
- createdAt: Date.now(),
348
- });
349
- savePkceForCode();
57
+ export async function getClientCount() {
58
+ return getStore().getClientCount();
350
59
  }
351
- export function consumePkceForCode(code) {
352
- const cache = loadPkceForCode();
353
- const pkce = cache.get(code);
354
- if (!pkce)
355
- return undefined;
356
- if (Date.now() - pkce.createdAt > 5 * 60 * 1000) {
357
- cache.delete(code);
358
- savePkceForCode();
359
- return undefined;
360
- }
361
- cache.delete(code);
362
- savePkceForCode();
363
- return pkce;
60
+ export async function clientExists(...args) {
61
+ return getStore().clientExists(...args);
364
62
  }
365
- // ============ OAuth Sessions ============
366
- // Uses plaintext storage by default, encrypted storage when OAUTH_ENCRYPTION_KEY is set
367
- /**
368
- * Migrate plaintext sessions to encrypted format when encryption key is added
369
- */
370
- function migrateToEncrypted(key) {
371
- if (!existsSync(SESSIONS_FILE_PLAINTEXT)) {
372
- return null;
373
- }
374
- try {
375
- const data = JSON.parse(readFileSync(SESSIONS_FILE_PLAINTEXT, "utf-8"));
376
- const sessions = new Map();
377
- for (const [id, session] of Object.entries(data)) {
378
- sessions.set(id, session);
379
- }
380
- console.log(`Migrating ${sessions.size} OAuth sessions from plaintext to encrypted storage`);
381
- // Save encrypted version
382
- const plaintext = JSON.stringify(data);
383
- const encrypted = encrypt(plaintext, key);
384
- writeFileSync(SESSIONS_FILE_ENCRYPTED, encrypted, { mode: 0o600 });
385
- // Remove plaintext file
386
- unlinkSync(SESSIONS_FILE_PLAINTEXT);
387
- console.log("Migration complete - plaintext sessions file removed");
388
- return sessions;
389
- }
390
- catch (error) {
391
- console.error("Failed to migrate sessions to encrypted:", error);
392
- return null;
393
- }
63
+ export async function storePendingAuth(...args) {
64
+ return getStore().storePendingAuth(...args);
394
65
  }
395
- /**
396
- * Load OAuth sessions from disk
397
- * - If OAUTH_ENCRYPTION_KEY is set: uses encrypted storage, migrates plaintext if exists
398
- * - Otherwise: uses plaintext storage
399
- */
400
- function loadSessions() {
401
- if (sessionsCache)
402
- return sessionsCache;
403
- ensureStorageDir();
404
- sessionsCache = new Map();
405
- const encryptionKey = getEncryptionKey();
406
- if (encryptionKey) {
407
- // Encryption enabled - use encrypted storage
408
- if (existsSync(SESSIONS_FILE_ENCRYPTED)) {
409
- try {
410
- const encryptedData = readFileSync(SESSIONS_FILE_ENCRYPTED, "utf-8");
411
- const decrypted = decrypt(encryptedData, encryptionKey);
412
- const data = JSON.parse(decrypted);
413
- for (const [id, session] of Object.entries(data)) {
414
- sessionsCache.set(id, session);
415
- }
416
- console.log(`Loaded ${sessionsCache.size} OAuth sessions (encrypted)`);
417
- }
418
- catch (error) {
419
- console.error("Failed to load encrypted OAuth sessions (starting fresh):", error);
420
- sessionsCache = new Map();
421
- }
422
- }
423
- else {
424
- // Try migrating from plaintext
425
- const migrated = migrateToEncrypted(encryptionKey);
426
- if (migrated) {
427
- sessionsCache = migrated;
428
- }
429
- }
430
- }
431
- else {
432
- // No encryption - use plaintext storage
433
- if (existsSync(SESSIONS_FILE_PLAINTEXT)) {
434
- try {
435
- const data = JSON.parse(readFileSync(SESSIONS_FILE_PLAINTEXT, "utf-8"));
436
- for (const [id, session] of Object.entries(data)) {
437
- sessionsCache.set(id, session);
438
- }
439
- console.log(`Loaded ${sessionsCache.size} OAuth sessions`);
440
- }
441
- catch (error) {
442
- console.error("Failed to load OAuth sessions:", error);
443
- }
444
- }
445
- }
446
- return sessionsCache;
66
+ export async function consumePendingAuth(...args) {
67
+ return getStore().consumePendingAuth(...args);
447
68
  }
448
- /**
449
- * Save OAuth sessions to disk
450
- * - If OAUTH_ENCRYPTION_KEY is set: saves encrypted
451
- * - Otherwise: saves plaintext
452
- */
453
- function saveSessions() {
454
- if (!sessionsCache)
455
- return;
456
- ensureStorageDir();
457
- const data = {};
458
- for (const [id, session] of sessionsCache) {
459
- data[id] = session;
460
- }
461
- const encryptionKey = getEncryptionKey();
462
- try {
463
- if (encryptionKey) {
464
- // Save encrypted
465
- const plaintext = JSON.stringify(data);
466
- const encrypted = encrypt(plaintext, encryptionKey);
467
- writeFileSync(SESSIONS_FILE_ENCRYPTED, encrypted, { mode: 0o600 });
468
- }
469
- else {
470
- // Save plaintext
471
- writeFileSync(SESSIONS_FILE_PLAINTEXT, JSON.stringify(data, null, 2));
472
- }
473
- }
474
- catch (error) {
475
- console.error("Failed to save OAuth sessions:", error);
476
- }
69
+ export async function storePkceForCode(...args) {
70
+ return getStore().storePkceForCode(...args);
477
71
  }
478
- /**
479
- * Store an OAuth session
480
- */
481
- export function storeSession(sessionId, session) {
482
- const cache = loadSessions();
483
- cache.set(sessionId, session);
484
- saveSessions();
72
+ export async function consumePkceForCode(...args) {
73
+ return getStore().consumePkceForCode(...args);
485
74
  }
486
- /**
487
- * Get an OAuth session by ID
488
- */
489
- export function getSession(sessionId) {
490
- const cache = loadSessions();
491
- return cache.get(sessionId);
75
+ export async function storeSession(...args) {
76
+ return getStore().storeSession(...args);
492
77
  }
493
- /**
494
- * Update an existing OAuth session (e.g., after token refresh)
495
- */
496
- export function updateSession(sessionId, session) {
497
- const cache = loadSessions();
498
- if (cache.has(sessionId)) {
499
- cache.set(sessionId, session);
500
- saveSessions();
501
- }
78
+ export async function getSession(...args) {
79
+ return getStore().getSession(...args);
502
80
  }
503
- /**
504
- * Remove an OAuth session
505
- */
506
- export function removeSession(sessionId) {
507
- const cache = loadSessions();
508
- if (cache.delete(sessionId)) {
509
- saveSessions();
510
- }
81
+ export async function updateSession(...args) {
82
+ return getStore().updateSession(...args);
511
83
  }
512
- /**
513
- * Cleanup expired OAuth sessions
514
- * Sessions are considered expired if their expiresAt time has passed
515
- * and they have no refresh token
516
- */
517
- export function cleanupExpiredSessions() {
518
- const cache = loadSessions();
519
- const now = Date.now();
520
- let cleaned = 0;
521
- for (const [sessionId, session] of cache) {
522
- // Only remove if expired AND no refresh token
523
- // Sessions with refresh tokens can be renewed
524
- if (now >= session.expiresAt && !session.refreshToken) {
525
- cache.delete(sessionId);
526
- cleaned++;
527
- }
528
- }
529
- if (cleaned > 0) {
530
- saveSessions();
531
- console.log(`Cleaned up ${cleaned} expired OAuth sessions`);
532
- }
84
+ export async function removeSession(...args) {
85
+ return getStore().removeSession(...args);
533
86
  }
534
- // Run cleanup every minute
535
- setInterval(() => {
536
- cleanupExpiredPendingAuth();
537
- cleanupExpiredSessions();
538
- }, 60000);
539
87
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/oauth/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/oauth/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * OAuthStore Interface
3
+ *
4
+ * Abstraction layer for OAuth state storage. Two implementations:
5
+ * - FileStore (default): JSON files on disk, for local dev and stdio mode
6
+ * - RedisStore: Redis-backed, for multi-pod production deployment (REDIS_URL)
7
+ */
8
+ /**
9
+ * Registered OAuth Client (RFC 7591)
10
+ */
11
+ export interface RegisteredClient {
12
+ client_id: string;
13
+ client_secret?: string;
14
+ client_name?: string;
15
+ redirect_uris: string[];
16
+ grant_types: string[];
17
+ response_types: string[];
18
+ token_endpoint_auth_method: string;
19
+ scope?: string;
20
+ registered_at: number;
21
+ }
22
+ /**
23
+ * Pending OAuth authorization with PKCE
24
+ */
25
+ export interface PendingAuthWithPKCE {
26
+ state: string;
27
+ redirectUri: string;
28
+ clientId: string;
29
+ codeChallenge?: string;
30
+ codeChallengeMethod?: string;
31
+ createdAt: number;
32
+ scope?: string;
33
+ /** Identifier for the MCP client (e.g., "claude-code", "cursor") for token metadata */
34
+ clientConsumer?: string;
35
+ /** GA4 client_id for cross-domain analytics tracking */
36
+ gaClientId?: string;
37
+ }
38
+ /**
39
+ * Stored OAuth session after successful authentication
40
+ */
41
+ export interface StoredOAuthSession {
42
+ accessToken: string;
43
+ refreshToken?: string;
44
+ expiresAt: number;
45
+ scope?: string;
46
+ /** Nestr user ID for analytics (GA4 user_id) */
47
+ userId?: string;
48
+ }
49
+ /**
50
+ * PKCE challenge data indexed by authorization code
51
+ */
52
+ export interface PkceForCodeData {
53
+ codeChallenge: string;
54
+ codeChallengeMethod: string;
55
+ createdAt: number;
56
+ }
57
+ export interface OAuthStore {
58
+ registerClient(client: RegisteredClient): Promise<void>;
59
+ getClient(clientId: string): Promise<RegisteredClient | undefined>;
60
+ getClientCount(): Promise<number>;
61
+ clientExists(clientId: string): Promise<boolean>;
62
+ storePendingAuth(pending: PendingAuthWithPKCE): Promise<void>;
63
+ consumePendingAuth(state: string): Promise<PendingAuthWithPKCE | undefined>;
64
+ storePkceForCode(code: string, codeChallenge: string, codeChallengeMethod: string): Promise<void>;
65
+ consumePkceForCode(code: string): Promise<PkceForCodeData | undefined>;
66
+ storeSession(sessionId: string, session: StoredOAuthSession): Promise<void>;
67
+ getSession(sessionId: string): Promise<StoredOAuthSession | undefined>;
68
+ updateSession(sessionId: string, session: StoredOAuthSession): Promise<void>;
69
+ removeSession(sessionId: string): Promise<void>;
70
+ close(): Promise<void>;
71
+ }
72
+ /**
73
+ * Initialize the global store. Must be called once at startup (before handling requests).
74
+ */
75
+ export declare function initStore(): Promise<OAuthStore>;
76
+ /**
77
+ * Get the initialized store. Throws if initStore() hasn't been called.
78
+ */
79
+ export declare function getStore(): OAuthStore;
80
+ //# sourceMappingURL=store.d.ts.map