@nestr/mcp 0.1.52 → 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.
@@ -0,0 +1,174 @@
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 { Redis } from "ioredis";
13
+ import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";
14
+ // Key prefixes
15
+ const PREFIX = {
16
+ client: "oauth:client:",
17
+ clientCount: "oauth:client:count",
18
+ pending: "oauth:pending:",
19
+ pkce: "oauth:pkce:",
20
+ session: "oauth:session:",
21
+ };
22
+ // TTLs in seconds
23
+ const PENDING_AUTH_TTL = 300; // 5 minutes
24
+ const PKCE_TTL = 300; // 5 minutes
25
+ const CLIENT_TTL = 86400; // 24 hours (clients re-register on reconnect)
26
+ const SESSION_REFRESH_TTL = 30 * 86400; // 30 days for sessions with refresh tokens
27
+ // Encryption constants
28
+ const ALGORITHM = "aes-256-gcm";
29
+ const IV_LENGTH = 16;
30
+ function getEncryptionKey() {
31
+ if (!process.env.OAUTH_ENCRYPTION_KEY)
32
+ return null;
33
+ const key = Buffer.from(process.env.OAUTH_ENCRYPTION_KEY, "base64");
34
+ if (key.length !== 32) {
35
+ throw new Error("OAUTH_ENCRYPTION_KEY must be 32 bytes (256 bits) base64-encoded");
36
+ }
37
+ return key;
38
+ }
39
+ function encrypt(data, key) {
40
+ const iv = randomBytes(IV_LENGTH);
41
+ const cipher = createCipheriv(ALGORITHM, key, iv);
42
+ let encrypted = cipher.update(data, "utf8", "base64");
43
+ encrypted += cipher.final("base64");
44
+ const authTag = cipher.getAuthTag();
45
+ return `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
46
+ }
47
+ function decrypt(encryptedData, key) {
48
+ const parts = encryptedData.split(":");
49
+ if (parts.length !== 3)
50
+ throw new Error("Invalid encrypted data format");
51
+ const iv = Buffer.from(parts[0], "base64");
52
+ const authTag = Buffer.from(parts[1], "base64");
53
+ const data = parts[2];
54
+ const decipher = createDecipheriv(ALGORITHM, key, iv);
55
+ decipher.setAuthTag(authTag);
56
+ let decrypted = decipher.update(data, "base64", "utf8");
57
+ decrypted += decipher.final("utf8");
58
+ return decrypted;
59
+ }
60
+ class RedisStore {
61
+ redis;
62
+ encryptionKey;
63
+ constructor(redis) {
64
+ this.redis = redis;
65
+ this.encryptionKey = getEncryptionKey();
66
+ }
67
+ // ---- Helpers ----
68
+ serialize(data) {
69
+ const json = JSON.stringify(data);
70
+ if (this.encryptionKey)
71
+ return encrypt(json, this.encryptionKey);
72
+ return json;
73
+ }
74
+ deserialize(raw) {
75
+ if (this.encryptionKey) {
76
+ const json = decrypt(raw, this.encryptionKey);
77
+ return JSON.parse(json);
78
+ }
79
+ return JSON.parse(raw);
80
+ }
81
+ // ---- Clients ----
82
+ async registerClient(client) {
83
+ const key = PREFIX.client + client.client_id;
84
+ // Only increment the counter for genuinely new clients (SET NX returns 1 if key didn't exist).
85
+ // Without this, the counter drifts upward as clients re-register and eventually blocks
86
+ // all registrations when it hits MAX_REGISTERED_CLIENTS.
87
+ const isNew = await this.redis.set(key, this.serialize(client), "EX", CLIENT_TTL, "GET");
88
+ if (isNew === null) {
89
+ await this.redis.incr(PREFIX.clientCount);
90
+ }
91
+ console.log(`Registered OAuth client: ${client.client_id}`);
92
+ }
93
+ async getClient(clientId) {
94
+ const raw = await this.redis.get(PREFIX.client + clientId);
95
+ if (!raw)
96
+ return undefined;
97
+ return this.deserialize(raw);
98
+ }
99
+ async getClientCount() {
100
+ const count = await this.redis.get(PREFIX.clientCount);
101
+ return count ? parseInt(count, 10) : 0;
102
+ }
103
+ async clientExists(clientId) {
104
+ return (await this.redis.exists(PREFIX.client + clientId)) === 1;
105
+ }
106
+ // ---- Pending Auth ----
107
+ async storePendingAuth(pending) {
108
+ await this.redis.set(PREFIX.pending + pending.state, this.serialize(pending), "EX", PENDING_AUTH_TTL);
109
+ }
110
+ async consumePendingAuth(state) {
111
+ const raw = await this.redis.getdel(PREFIX.pending + state);
112
+ if (!raw)
113
+ return undefined;
114
+ return this.deserialize(raw);
115
+ }
116
+ // ---- PKCE Codes ----
117
+ async storePkceForCode(code, codeChallenge, codeChallengeMethod) {
118
+ const data = { codeChallenge, codeChallengeMethod, createdAt: Date.now() };
119
+ await this.redis.set(PREFIX.pkce + code, this.serialize(data), "EX", PKCE_TTL);
120
+ }
121
+ async consumePkceForCode(code) {
122
+ const raw = await this.redis.getdel(PREFIX.pkce + code);
123
+ if (!raw)
124
+ return undefined;
125
+ return this.deserialize(raw);
126
+ }
127
+ // ---- Sessions ----
128
+ sessionTtl(session) {
129
+ if (session.refreshToken)
130
+ return SESSION_REFRESH_TTL;
131
+ // TTL = time until expiry (minimum 60s to avoid immediate deletion)
132
+ const ttl = Math.max(60, Math.ceil((session.expiresAt - Date.now()) / 1000));
133
+ return ttl;
134
+ }
135
+ async storeSession(sessionId, session) {
136
+ await this.redis.set(PREFIX.session + sessionId, this.serialize(session), "EX", this.sessionTtl(session));
137
+ }
138
+ async getSession(sessionId) {
139
+ const raw = await this.redis.get(PREFIX.session + sessionId);
140
+ if (!raw)
141
+ return undefined;
142
+ return this.deserialize(raw);
143
+ }
144
+ async updateSession(sessionId, session) {
145
+ // Unconditional SET — the EXISTS + SET pattern has a TOCTOU race across pods.
146
+ // If the session was deleted between the two calls, this would silently re-create it.
147
+ // Matching FileStore behavior: just overwrite.
148
+ await this.redis.set(PREFIX.session + sessionId, this.serialize(session), "EX", this.sessionTtl(session));
149
+ }
150
+ async removeSession(sessionId) {
151
+ await this.redis.del(PREFIX.session + sessionId);
152
+ }
153
+ // ---- Lifecycle ----
154
+ async close() {
155
+ await this.redis.quit();
156
+ }
157
+ }
158
+ /**
159
+ * Create a Redis-backed OAuthStore instance.
160
+ */
161
+ export async function createRedisStore(redisUrl) {
162
+ const redis = new Redis(redisUrl, {
163
+ maxRetriesPerRequest: 3,
164
+ retryStrategy(times) {
165
+ // Exponential backoff: 50ms, 100ms, 200ms, ... capped at 2s
166
+ return Math.min(times * 50, 2000);
167
+ },
168
+ });
169
+ // Verify connection
170
+ await redis.ping();
171
+ console.log("Redis connected for OAuth storage");
172
+ return new RedisStore(redis);
173
+ }
174
+ //# sourceMappingURL=redis-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-store.js","sourceRoot":"","sources":["../../src/oauth/redis-store.ts"],"names":[],"mappings":"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"}
@@ -1,111 +1,36 @@
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
- /**
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
- * Register a new OAuth client
51
- */
52
- export declare function registerClient(client: RegisteredClient): void;
53
- /**
54
- * Get a registered client by ID
55
- */
56
- export declare function getClient(clientId: string): RegisteredClient | undefined;
57
- /**
58
- * Check if a client ID exists
59
- */
60
- export declare function clientExists(clientId: string): boolean;
61
- /**
62
- * Validate client credentials
63
- */
64
- export declare function validateClientCredentials(clientId: string, clientSecret?: string): boolean;
65
- /**
66
- * Validate redirect URI for a client
67
- */
68
- export declare function validateRedirectUri(clientId: string, redirectUri: string): boolean;
69
- /**
70
- * Store a pending auth request
71
- */
72
- export declare function storePendingAuth(pending: PendingAuthWithPKCE): void;
73
- /**
74
- * Get and remove a pending auth request
75
- */
76
- export declare function consumePendingAuth(state: string): PendingAuthWithPKCE | undefined;
77
- /**
78
- * Cleanup expired pending auth requests
79
- */
80
- export declare function cleanupExpiredPendingAuth(): void;
81
- interface PkceForCodeData {
82
- codeChallenge: string;
83
- codeChallengeMethod: string;
84
- createdAt: number;
85
- }
86
- export declare function storePkceForCode(code: string, codeChallenge: string, codeChallengeMethod: string): void;
87
- export declare function consumePkceForCode(code: string): PkceForCodeData | undefined;
88
- /**
89
- * Store an OAuth session
90
- */
91
- export declare function storeSession(sessionId: string, session: StoredOAuthSession): void;
92
- /**
93
- * Get an OAuth session by ID
94
- */
95
- export declare function getSession(sessionId: string): StoredOAuthSession | undefined;
96
- /**
97
- * Update an existing OAuth session (e.g., after token refresh)
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.
98
9
  */
99
- export declare function updateSession(sessionId: string, session: StoredOAuthSession): void;
10
+ import { getStore } from "./store.js";
11
+ export type { RegisteredClient, PendingAuthWithPKCE, StoredOAuthSession, PkceForCodeData, } from "./store.js";
100
12
  /**
101
- * Remove an OAuth session
13
+ * Constant-time string comparison to prevent timing attacks on secrets.
14
+ * Standalone utility — not part of the store interface.
102
15
  */
103
- export declare function removeSession(sessionId: string): void;
16
+ export declare function constantTimeCompare(a: string, b: string): boolean;
104
17
  /**
105
- * Cleanup expired OAuth sessions
106
- * Sessions are considered expired if their expiresAt time has passed
107
- * and they have no refresh token
18
+ * Validate redirect URI against a registered client's allowed URIs.
19
+ * Accepts the client object directly to avoid an extra async lookup.
108
20
  */
109
- export declare function cleanupExpiredSessions(): void;
110
- export {};
21
+ export declare function validateRedirectUri(client: {
22
+ redirect_uris: string[];
23
+ }, redirectUri: string): boolean;
24
+ export declare function registerClient(...args: Parameters<ReturnType<typeof getStore>["registerClient"]>): Promise<void>;
25
+ export declare function getClient(...args: Parameters<ReturnType<typeof getStore>["getClient"]>): Promise<import("./store.js").RegisteredClient | undefined>;
26
+ export declare function getClientCount(): Promise<number>;
27
+ export declare function clientExists(...args: Parameters<ReturnType<typeof getStore>["clientExists"]>): Promise<boolean>;
28
+ export declare function storePendingAuth(...args: Parameters<ReturnType<typeof getStore>["storePendingAuth"]>): Promise<void>;
29
+ export declare function consumePendingAuth(...args: Parameters<ReturnType<typeof getStore>["consumePendingAuth"]>): Promise<import("./store.js").PendingAuthWithPKCE | undefined>;
30
+ export declare function storePkceForCode(...args: Parameters<ReturnType<typeof getStore>["storePkceForCode"]>): Promise<void>;
31
+ export declare function consumePkceForCode(...args: Parameters<ReturnType<typeof getStore>["consumePkceForCode"]>): Promise<import("./store.js").PkceForCodeData | undefined>;
32
+ export declare function storeSession(...args: Parameters<ReturnType<typeof getStore>["storeSession"]>): Promise<void>;
33
+ export declare function getSession(...args: Parameters<ReturnType<typeof getStore>["getSession"]>): Promise<import("./store.js").StoredOAuthSession | undefined>;
34
+ export declare function updateSession(...args: Parameters<ReturnType<typeof getStore>["updateSession"]>): Promise<void>;
35
+ export declare function removeSession(...args: Parameters<ReturnType<typeof getStore>["removeSession"]>): Promise<void>;
111
36
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/oauth/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/oauth/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKjE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE;IAAE,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,EACnC,WAAW,EAAE,MAAM,GAClB,OAAO,CAwBT;AAKD,wBAAsB,cAAc,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC,iBAEtG;AAED,wBAAsB,SAAS,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,8DAE5F;AAED,wBAAsB,cAAc,oBAEnC;AAED,wBAAsB,YAAY,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC,oBAElG;AAED,wBAAsB,gBAAgB,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,kBAAkB,CAAC,CAAC,iBAE1G;AAED,wBAAsB,kBAAkB,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,oBAAoB,CAAC,CAAC,iEAE9G;AAED,wBAAsB,gBAAgB,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,kBAAkB,CAAC,CAAC,iBAE1G;AAED,wBAAsB,kBAAkB,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,oBAAoB,CAAC,CAAC,6DAE9G;AAED,wBAAsB,YAAY,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC,iBAElG;AAED,wBAAsB,UAAU,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,gEAE9F;AAED,wBAAsB,aAAa,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,iBAEpG;AAED,wBAAsB,aAAa,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,iBAEpG"}