@juspay/neurolink 9.31.2 → 9.32.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.
Files changed (161) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/auth/AuthProviderFactory.d.ts +71 -0
  3. package/dist/auth/AuthProviderFactory.js +111 -0
  4. package/dist/auth/AuthProviderRegistry.d.ts +33 -0
  5. package/dist/auth/AuthProviderRegistry.js +190 -0
  6. package/dist/auth/RequestContext.d.ts +23 -0
  7. package/dist/auth/RequestContext.js +78 -0
  8. package/dist/auth/authContext.d.ts +198 -0
  9. package/dist/auth/authContext.js +314 -0
  10. package/dist/auth/errors.d.ts +63 -0
  11. package/dist/auth/errors.js +39 -0
  12. package/dist/auth/index.d.ts +20 -8
  13. package/dist/auth/index.js +35 -7
  14. package/dist/auth/middleware/AuthMiddleware.d.ts +181 -0
  15. package/dist/auth/middleware/AuthMiddleware.js +519 -0
  16. package/dist/auth/middleware/rateLimitByUser.d.ts +282 -0
  17. package/dist/auth/middleware/rateLimitByUser.js +554 -0
  18. package/dist/auth/providers/BaseAuthProvider.d.ts +259 -0
  19. package/dist/auth/providers/BaseAuthProvider.js +723 -0
  20. package/dist/auth/providers/CognitoProvider.d.ts +61 -0
  21. package/dist/auth/providers/CognitoProvider.js +304 -0
  22. package/dist/auth/providers/KeycloakProvider.d.ts +61 -0
  23. package/dist/auth/providers/KeycloakProvider.js +393 -0
  24. package/dist/auth/providers/auth0.d.ts +59 -0
  25. package/dist/auth/providers/auth0.js +274 -0
  26. package/dist/auth/providers/betterAuth.d.ts +51 -0
  27. package/dist/auth/providers/betterAuth.js +182 -0
  28. package/dist/auth/providers/clerk.d.ts +65 -0
  29. package/dist/auth/providers/clerk.js +317 -0
  30. package/dist/auth/providers/custom.d.ts +64 -0
  31. package/dist/auth/providers/custom.js +112 -0
  32. package/dist/auth/providers/firebase.d.ts +63 -0
  33. package/dist/auth/providers/firebase.js +226 -0
  34. package/dist/auth/providers/jwt.d.ts +68 -0
  35. package/dist/auth/providers/jwt.js +212 -0
  36. package/dist/auth/providers/oauth2.d.ts +73 -0
  37. package/dist/auth/providers/oauth2.js +303 -0
  38. package/dist/auth/providers/supabase.d.ts +63 -0
  39. package/dist/auth/providers/supabase.js +259 -0
  40. package/dist/auth/providers/workos.d.ts +61 -0
  41. package/dist/auth/providers/workos.js +284 -0
  42. package/dist/auth/serverBridge.d.ts +14 -0
  43. package/dist/auth/serverBridge.js +25 -0
  44. package/dist/auth/sessionManager.d.ts +142 -0
  45. package/dist/auth/sessionManager.js +437 -0
  46. package/dist/cli/commands/authProviders.d.ts +43 -0
  47. package/dist/cli/commands/authProviders.js +399 -0
  48. package/dist/cli/factories/authCommandFactory.d.ts +23 -5
  49. package/dist/cli/factories/authCommandFactory.js +108 -5
  50. package/dist/cli/parser.js +1 -1
  51. package/dist/client/auth/AuthProviderFactory.js +111 -0
  52. package/dist/client/auth/AuthProviderRegistry.js +190 -0
  53. package/dist/client/auth/RequestContext.js +78 -0
  54. package/dist/client/auth/accountPool.js +178 -0
  55. package/dist/client/auth/authContext.js +314 -0
  56. package/dist/client/auth/errors.js +39 -0
  57. package/dist/client/auth/index.js +61 -0
  58. package/dist/client/auth/middleware/AuthMiddleware.js +519 -0
  59. package/dist/client/auth/middleware/rateLimitByUser.js +554 -0
  60. package/dist/client/auth/providers/BaseAuthProvider.js +723 -0
  61. package/dist/client/auth/providers/CognitoProvider.js +304 -0
  62. package/dist/client/auth/providers/KeycloakProvider.js +393 -0
  63. package/dist/client/auth/providers/auth0.js +274 -0
  64. package/dist/client/auth/providers/betterAuth.js +182 -0
  65. package/dist/client/auth/providers/clerk.js +317 -0
  66. package/dist/client/auth/providers/custom.js +112 -0
  67. package/dist/client/auth/providers/firebase.js +226 -0
  68. package/dist/client/auth/providers/jwt.js +212 -0
  69. package/dist/client/auth/providers/oauth2.js +303 -0
  70. package/dist/client/auth/providers/supabase.js +259 -0
  71. package/dist/client/auth/providers/workos.js +284 -0
  72. package/dist/client/auth/serverBridge.js +25 -0
  73. package/dist/client/auth/sessionManager.js +437 -0
  74. package/dist/client/core/infrastructure/baseRegistry.js +5 -1
  75. package/dist/client/index.js +25 -0
  76. package/dist/client/mcp/toolRegistry.js +11 -1
  77. package/dist/client/neurolink.js +218 -0
  78. package/dist/client/rag/ChunkerRegistry.js +2 -2
  79. package/dist/client/rag/metadata/MetadataExtractorRegistry.js +2 -2
  80. package/dist/client/rag/reranker/RerankerRegistry.js +2 -2
  81. package/dist/client/server/routes/agentRoutes.js +20 -2
  82. package/dist/client/types/authTypes.js +2 -1
  83. package/dist/core/infrastructure/baseRegistry.d.ts +3 -1
  84. package/dist/core/infrastructure/baseRegistry.js +5 -1
  85. package/dist/index.d.ts +1 -0
  86. package/dist/index.js +25 -0
  87. package/dist/lib/auth/AuthProviderFactory.d.ts +71 -0
  88. package/dist/lib/auth/AuthProviderFactory.js +112 -0
  89. package/dist/lib/auth/AuthProviderRegistry.d.ts +33 -0
  90. package/dist/lib/auth/AuthProviderRegistry.js +191 -0
  91. package/dist/lib/auth/RequestContext.d.ts +23 -0
  92. package/dist/lib/auth/RequestContext.js +79 -0
  93. package/dist/lib/auth/authContext.d.ts +198 -0
  94. package/dist/lib/auth/authContext.js +315 -0
  95. package/dist/lib/auth/errors.d.ts +63 -0
  96. package/dist/lib/auth/errors.js +40 -0
  97. package/dist/lib/auth/index.d.ts +20 -8
  98. package/dist/lib/auth/index.js +35 -7
  99. package/dist/lib/auth/middleware/AuthMiddleware.d.ts +181 -0
  100. package/dist/lib/auth/middleware/AuthMiddleware.js +520 -0
  101. package/dist/lib/auth/middleware/rateLimitByUser.d.ts +282 -0
  102. package/dist/lib/auth/middleware/rateLimitByUser.js +555 -0
  103. package/dist/lib/auth/providers/BaseAuthProvider.d.ts +259 -0
  104. package/dist/lib/auth/providers/BaseAuthProvider.js +724 -0
  105. package/dist/lib/auth/providers/CognitoProvider.d.ts +61 -0
  106. package/dist/lib/auth/providers/CognitoProvider.js +305 -0
  107. package/dist/lib/auth/providers/KeycloakProvider.d.ts +61 -0
  108. package/dist/lib/auth/providers/KeycloakProvider.js +394 -0
  109. package/dist/lib/auth/providers/auth0.d.ts +59 -0
  110. package/dist/lib/auth/providers/auth0.js +275 -0
  111. package/dist/lib/auth/providers/betterAuth.d.ts +51 -0
  112. package/dist/lib/auth/providers/betterAuth.js +183 -0
  113. package/dist/lib/auth/providers/clerk.d.ts +65 -0
  114. package/dist/lib/auth/providers/clerk.js +318 -0
  115. package/dist/lib/auth/providers/custom.d.ts +64 -0
  116. package/dist/lib/auth/providers/custom.js +113 -0
  117. package/dist/lib/auth/providers/firebase.d.ts +63 -0
  118. package/dist/lib/auth/providers/firebase.js +227 -0
  119. package/dist/lib/auth/providers/jwt.d.ts +68 -0
  120. package/dist/lib/auth/providers/jwt.js +213 -0
  121. package/dist/lib/auth/providers/oauth2.d.ts +73 -0
  122. package/dist/lib/auth/providers/oauth2.js +304 -0
  123. package/dist/lib/auth/providers/supabase.d.ts +63 -0
  124. package/dist/lib/auth/providers/supabase.js +260 -0
  125. package/dist/lib/auth/providers/workos.d.ts +61 -0
  126. package/dist/lib/auth/providers/workos.js +285 -0
  127. package/dist/lib/auth/serverBridge.d.ts +14 -0
  128. package/dist/lib/auth/serverBridge.js +26 -0
  129. package/dist/lib/auth/sessionManager.d.ts +142 -0
  130. package/dist/lib/auth/sessionManager.js +438 -0
  131. package/dist/lib/core/infrastructure/baseRegistry.d.ts +3 -1
  132. package/dist/lib/core/infrastructure/baseRegistry.js +5 -1
  133. package/dist/lib/index.d.ts +1 -0
  134. package/dist/lib/index.js +25 -0
  135. package/dist/lib/mcp/toolRegistry.js +11 -1
  136. package/dist/lib/neurolink.d.ts +42 -1
  137. package/dist/lib/neurolink.js +218 -0
  138. package/dist/lib/rag/ChunkerRegistry.js +2 -2
  139. package/dist/lib/rag/metadata/MetadataExtractorRegistry.js +2 -2
  140. package/dist/lib/rag/reranker/RerankerRegistry.js +2 -2
  141. package/dist/lib/server/routes/agentRoutes.js +20 -2
  142. package/dist/lib/types/authTypes.d.ts +937 -1
  143. package/dist/lib/types/authTypes.js +2 -1
  144. package/dist/lib/types/configTypes.d.ts +46 -0
  145. package/dist/lib/types/generateTypes.d.ts +6 -0
  146. package/dist/lib/types/index.d.ts +1 -0
  147. package/dist/lib/types/streamTypes.d.ts +6 -0
  148. package/dist/mcp/toolRegistry.js +11 -1
  149. package/dist/neurolink.d.ts +42 -1
  150. package/dist/neurolink.js +218 -0
  151. package/dist/rag/ChunkerRegistry.js +2 -2
  152. package/dist/rag/metadata/MetadataExtractorRegistry.js +2 -2
  153. package/dist/rag/reranker/RerankerRegistry.js +2 -2
  154. package/dist/server/routes/agentRoutes.js +20 -2
  155. package/dist/types/authTypes.d.ts +937 -1
  156. package/dist/types/authTypes.js +2 -1
  157. package/dist/types/configTypes.d.ts +46 -0
  158. package/dist/types/generateTypes.d.ts +6 -0
  159. package/dist/types/index.d.ts +1 -0
  160. package/dist/types/streamTypes.d.ts +6 -0
  161. package/package.json +2 -1
@@ -0,0 +1,275 @@
1
+ // src/lib/auth/providers/auth0.ts
2
+ import { BaseAuthProvider } from "./BaseAuthProvider.js";
3
+ import { AuthError } from "../errors.js";
4
+ import { logger } from "../../utils/logger.js";
5
+ import { createProxyFetch } from "../../proxy/proxyFetch.js";
6
+ import * as jose from "jose";
7
+ /**
8
+ * Auth0 Authentication Provider
9
+ *
10
+ * Supports JWT validation with JWKS for Auth0-issued tokens.
11
+ * Uses jose library for JWT verification against Auth0's JWKS endpoint.
12
+ *
13
+ * Features:
14
+ * - JWT validation with JWKS
15
+ * - User profile fetching (requires Management API token)
16
+ * - Role and permission extraction from token claims
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const auth0 = new Auth0Provider({
21
+ * type: "auth0",
22
+ * domain: "your-tenant.auth0.com",
23
+ * clientId: "your-client-id",
24
+ * audience: "https://your-api.example.com"
25
+ * });
26
+ *
27
+ * const result = await auth0.authenticateToken(bearerToken);
28
+ * if (result.valid) {
29
+ * console.log("Authenticated user:", result.user);
30
+ * }
31
+ * ```
32
+ */
33
+ export class Auth0Provider extends BaseAuthProvider {
34
+ type = "auth0";
35
+ domain;
36
+ clientId;
37
+ audience;
38
+ rolesNamespace;
39
+ permissionsNamespace;
40
+ jwks = null;
41
+ constructor(config) {
42
+ super(config);
43
+ if (!config.domain) {
44
+ throw AuthError.create("CONFIGURATION_ERROR", "Auth0 domain is required", { details: { missingFields: ["domain"] } });
45
+ }
46
+ if (!config.clientId) {
47
+ throw AuthError.create("CONFIGURATION_ERROR", "Auth0 clientId is required", { details: { missingFields: ["clientId"] } });
48
+ }
49
+ this.domain = config.domain;
50
+ this.clientId = config.clientId;
51
+ this.audience = config.audience;
52
+ // Allow custom namespaces for roles/permissions claims.
53
+ // If no namespace is configured, fall back to standard "roles" / "permissions" claims.
54
+ this.rolesNamespace = config.options?.rolesNamespace;
55
+ this.permissionsNamespace = config.options?.permissionsNamespace;
56
+ }
57
+ /**
58
+ * Initialize JWKS for JWT verification
59
+ */
60
+ async initialize() {
61
+ try {
62
+ const jwksUrl = new URL(`https://${this.domain}/.well-known/jwks.json`);
63
+ this.jwks = jose.createRemoteJWKSet(jwksUrl);
64
+ logger.debug(`Auth0 provider initialized for domain: ${this.domain}`);
65
+ }
66
+ catch (error) {
67
+ throw AuthError.create("PROVIDER_INIT_FAILED", "Failed to initialize Auth0 JWKS", { cause: error instanceof Error ? error : new Error(String(error)) });
68
+ }
69
+ }
70
+ /**
71
+ * Validate Auth0 JWT token
72
+ */
73
+ async authenticateToken(token, _context) {
74
+ if (!this.jwks) {
75
+ await this.initialize();
76
+ }
77
+ try {
78
+ if (!this.jwks) {
79
+ return {
80
+ valid: false,
81
+ error: "Auth0 JWKS not initialized",
82
+ };
83
+ }
84
+ const { payload } = await jose.jwtVerify(token, this.jwks, {
85
+ issuer: `https://${this.domain}/`,
86
+ audience: this.audience,
87
+ });
88
+ const auth0Payload = payload;
89
+ // Validate audience / authorized party against clientId
90
+ if (this.audience) {
91
+ const aud = auth0Payload.aud;
92
+ const audArray = Array.isArray(aud) ? aud : [aud];
93
+ if (!audArray.includes(this.audience)) {
94
+ return {
95
+ valid: false,
96
+ error: `Token audience does not match expected audience: ${this.audience}`,
97
+ };
98
+ }
99
+ }
100
+ if (this.clientId) {
101
+ const aud = auth0Payload.aud;
102
+ const azp = payload.azp;
103
+ const audArray = Array.isArray(aud) ? aud : [aud];
104
+ if (azp) {
105
+ if (azp !== this.clientId) {
106
+ return {
107
+ valid: false,
108
+ error: `Token azp claim "${azp}" does not match clientId "${this.clientId}"`,
109
+ };
110
+ }
111
+ }
112
+ else if (!audArray.includes(this.clientId)) {
113
+ return {
114
+ valid: false,
115
+ error: `Token audience does not include clientId "${this.clientId}"`,
116
+ };
117
+ }
118
+ }
119
+ // Extract roles: use custom namespace if configured, otherwise standard "roles" claim
120
+ const rolesKey = this.rolesNamespace ?? "roles";
121
+ const permissionsKey = this.permissionsNamespace ?? "permissions";
122
+ const roles = payload[rolesKey] || auth0Payload.roles || [];
123
+ const permissions = payload[permissionsKey] || auth0Payload.permissions || [];
124
+ // Extract user information from token
125
+ const user = {
126
+ id: auth0Payload.sub,
127
+ email: auth0Payload.email,
128
+ name: auth0Payload.name,
129
+ picture: auth0Payload.picture,
130
+ emailVerified: auth0Payload.email_verified,
131
+ roles,
132
+ permissions,
133
+ metadata: {
134
+ iss: auth0Payload.iss,
135
+ aud: auth0Payload.aud,
136
+ },
137
+ };
138
+ return {
139
+ valid: true,
140
+ payload: payload,
141
+ user,
142
+ expiresAt: new Date(auth0Payload.exp * 1000),
143
+ tokenType: "jwt",
144
+ };
145
+ }
146
+ catch (error) {
147
+ const message = error instanceof Error ? error.message : String(error);
148
+ logger.warn("Auth0 token validation failed:", message);
149
+ return {
150
+ valid: false,
151
+ error: message,
152
+ };
153
+ }
154
+ }
155
+ /**
156
+ * Fetch user profile from Auth0 Management API
157
+ * Note: Requires AUTH0_MANAGEMENT_TOKEN environment variable
158
+ */
159
+ async getUser(userId) {
160
+ const managementToken = process.env.AUTH0_MANAGEMENT_TOKEN;
161
+ if (!managementToken) {
162
+ logger.warn("AUTH0_MANAGEMENT_TOKEN not set, cannot fetch user profile");
163
+ return null;
164
+ }
165
+ try {
166
+ const proxyFetch = createProxyFetch();
167
+ const response = await proxyFetch(`https://${this.domain}/api/v2/users/${encodeURIComponent(userId)}`, {
168
+ headers: {
169
+ Authorization: `Bearer ${managementToken}`,
170
+ },
171
+ });
172
+ if (!response.ok) {
173
+ if (response.status === 404) {
174
+ return null;
175
+ }
176
+ throw AuthError.create("PROVIDER_ERROR", `Auth0 API returned ${response.status}`, { details: { statusCode: response.status } });
177
+ }
178
+ const data = (await response.json());
179
+ return {
180
+ id: data.user_id,
181
+ email: data.email,
182
+ name: data.name,
183
+ picture: data.picture,
184
+ emailVerified: data.email_verified,
185
+ roles: data.app_metadata?.roles ||
186
+ [],
187
+ permissions: data.app_metadata
188
+ ?.permissions || [],
189
+ createdAt: data.created_at
190
+ ? new Date(data.created_at)
191
+ : undefined,
192
+ lastLoginAt: data.last_login
193
+ ? new Date(data.last_login)
194
+ : undefined,
195
+ metadata: data.user_metadata,
196
+ };
197
+ }
198
+ catch (error) {
199
+ logger.error("Failed to fetch Auth0 user:", error);
200
+ throw error;
201
+ }
202
+ }
203
+ /**
204
+ * Get user by email from Auth0 Management API
205
+ */
206
+ async getUserByEmail(email) {
207
+ const managementToken = process.env.AUTH0_MANAGEMENT_TOKEN;
208
+ if (!managementToken) {
209
+ logger.warn("AUTH0_MANAGEMENT_TOKEN not set, cannot fetch user by email");
210
+ return null;
211
+ }
212
+ try {
213
+ const proxyFetch = createProxyFetch();
214
+ const response = await proxyFetch(`https://${this.domain}/api/v2/users-by-email?email=${encodeURIComponent(email)}`, {
215
+ headers: {
216
+ Authorization: `Bearer ${managementToken}`,
217
+ },
218
+ });
219
+ if (!response.ok) {
220
+ throw AuthError.create("PROVIDER_ERROR", `Auth0 API returned ${response.status}`, { details: { statusCode: response.status } });
221
+ }
222
+ const users = (await response.json());
223
+ if (users.length === 0) {
224
+ return null;
225
+ }
226
+ const data = users[0];
227
+ return {
228
+ id: data.user_id,
229
+ email: data.email,
230
+ name: data.name,
231
+ picture: data.picture,
232
+ emailVerified: data.email_verified,
233
+ roles: data.app_metadata?.roles ||
234
+ [],
235
+ permissions: data.app_metadata
236
+ ?.permissions || [],
237
+ createdAt: data.created_at
238
+ ? new Date(data.created_at)
239
+ : undefined,
240
+ lastLoginAt: data.last_login
241
+ ? new Date(data.last_login)
242
+ : undefined,
243
+ metadata: data.user_metadata,
244
+ };
245
+ }
246
+ catch (error) {
247
+ logger.error("Failed to fetch Auth0 user by email:", error);
248
+ throw error;
249
+ }
250
+ }
251
+ /**
252
+ * Health check
253
+ */
254
+ async healthCheck() {
255
+ try {
256
+ const proxyFetch = createProxyFetch();
257
+ const response = await proxyFetch(`https://${this.domain}/.well-known/openid-configuration`);
258
+ return {
259
+ healthy: response.ok,
260
+ providerConnected: response.ok,
261
+ sessionStorageHealthy: true,
262
+ error: response.ok ? undefined : `HTTP ${response.status}`,
263
+ };
264
+ }
265
+ catch (error) {
266
+ return {
267
+ healthy: false,
268
+ providerConnected: false,
269
+ sessionStorageHealthy: true,
270
+ error: error instanceof Error ? error.message : String(error),
271
+ };
272
+ }
273
+ }
274
+ }
275
+ //# sourceMappingURL=auth0.js.map
@@ -0,0 +1,51 @@
1
+ import type { AuthProviderConfig, BetterAuthConfig, TokenValidationResult, AuthRequestContext, AuthHealthCheck } from "../../types/authTypes.js";
2
+ import { BaseAuthProvider } from "./BaseAuthProvider.js";
3
+ /**
4
+ * Better Auth Provider
5
+ *
6
+ * Supports Better Auth, a self-hosted open-source authentication solution.
7
+ * Validates session tokens and JWTs issued by Better Auth server.
8
+ *
9
+ * Features:
10
+ * - JWT validation using HMAC secret
11
+ * - Session validation via Better Auth API
12
+ * - Social provider support (GitHub, Google, Discord)
13
+ * - Session management (inherited from BaseAuthProvider)
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const betterAuth = new BetterAuthProvider({
18
+ * type: "better-auth",
19
+ * secret: "your-better-auth-secret",
20
+ * baseUrl: "https://your-app.com"
21
+ * });
22
+ *
23
+ * const result = await betterAuth.authenticateToken(sessionToken);
24
+ * if (result.valid) {
25
+ * console.log("Authenticated user:", result.user);
26
+ * }
27
+ * ```
28
+ */
29
+ export declare class BetterAuthProvider extends BaseAuthProvider {
30
+ readonly type: "better-auth";
31
+ private secret;
32
+ private baseUrl;
33
+ private secretKey;
34
+ constructor(config: AuthProviderConfig & BetterAuthConfig);
35
+ /**
36
+ * Validate Better Auth token (session or JWT)
37
+ */
38
+ authenticateToken(token: string, _context?: AuthRequestContext): Promise<TokenValidationResult>;
39
+ /**
40
+ * Validate JWT using the secret
41
+ */
42
+ private validateJWT;
43
+ /**
44
+ * Validate session via Better Auth API
45
+ */
46
+ private validateSessionViaAPI;
47
+ /**
48
+ * Health check
49
+ */
50
+ healthCheck(): Promise<AuthHealthCheck>;
51
+ }
@@ -0,0 +1,183 @@
1
+ // src/lib/auth/providers/betterAuth.ts
2
+ import { createProxyFetch } from "../../proxy/proxyFetch.js";
3
+ import { AuthError } from "../errors.js";
4
+ import * as jose from "jose";
5
+ import { BaseAuthProvider } from "./BaseAuthProvider.js";
6
+ /**
7
+ * Better Auth Provider
8
+ *
9
+ * Supports Better Auth, a self-hosted open-source authentication solution.
10
+ * Validates session tokens and JWTs issued by Better Auth server.
11
+ *
12
+ * Features:
13
+ * - JWT validation using HMAC secret
14
+ * - Session validation via Better Auth API
15
+ * - Social provider support (GitHub, Google, Discord)
16
+ * - Session management (inherited from BaseAuthProvider)
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const betterAuth = new BetterAuthProvider({
21
+ * type: "better-auth",
22
+ * secret: "your-better-auth-secret",
23
+ * baseUrl: "https://your-app.com"
24
+ * });
25
+ *
26
+ * const result = await betterAuth.authenticateToken(sessionToken);
27
+ * if (result.valid) {
28
+ * console.log("Authenticated user:", result.user);
29
+ * }
30
+ * ```
31
+ */
32
+ export class BetterAuthProvider extends BaseAuthProvider {
33
+ type = "better-auth";
34
+ secret;
35
+ baseUrl;
36
+ secretKey;
37
+ constructor(config) {
38
+ super(config);
39
+ if (!config.secret) {
40
+ throw AuthError.create("CONFIGURATION_ERROR", "Better Auth secret is required", { details: { provider: "better-auth", missingFields: ["secret"] } });
41
+ }
42
+ if (!config.baseUrl) {
43
+ throw AuthError.create("CONFIGURATION_ERROR", "Better Auth baseUrl is required", { details: { provider: "better-auth", missingFields: ["baseUrl"] } });
44
+ }
45
+ this.secret = config.secret;
46
+ this.baseUrl = config.baseUrl.replace(/\/$/, ""); // Remove trailing slash
47
+ this.secretKey = new TextEncoder().encode(this.secret);
48
+ }
49
+ /**
50
+ * Validate Better Auth token (session or JWT)
51
+ */
52
+ async authenticateToken(token, _context) {
53
+ // Try JWT validation first (if it looks like a JWT)
54
+ if (token.includes(".") && token.split(".").length === 3) {
55
+ const jwtResult = await this.validateJWT(token);
56
+ if (jwtResult.valid) {
57
+ return jwtResult;
58
+ }
59
+ }
60
+ // Fall back to session validation via API
61
+ return this.validateSessionViaAPI(token);
62
+ }
63
+ /**
64
+ * Validate JWT using the secret
65
+ */
66
+ async validateJWT(token) {
67
+ try {
68
+ const { payload } = await jose.jwtVerify(token, this.secretKey);
69
+ if (!payload.sub) {
70
+ return {
71
+ valid: false,
72
+ error: "Token missing required 'sub' claim",
73
+ };
74
+ }
75
+ const user = {
76
+ id: payload.sub,
77
+ email: payload.email,
78
+ name: payload.name,
79
+ picture: payload.picture,
80
+ emailVerified: payload.email_verified,
81
+ roles: payload.roles || [],
82
+ permissions: payload.permissions || [],
83
+ metadata: payload.metadata,
84
+ };
85
+ return {
86
+ valid: true,
87
+ payload: payload,
88
+ user,
89
+ expiresAt: payload.exp ? new Date(payload.exp * 1000) : undefined,
90
+ tokenType: "jwt",
91
+ };
92
+ }
93
+ catch (error) {
94
+ return {
95
+ valid: false,
96
+ error: error instanceof Error ? error.message : String(error),
97
+ };
98
+ }
99
+ }
100
+ /**
101
+ * Validate session via Better Auth API
102
+ */
103
+ async validateSessionViaAPI(sessionToken) {
104
+ try {
105
+ const proxyFetch = createProxyFetch();
106
+ const response = await proxyFetch(`${this.baseUrl}/api/auth/session`, {
107
+ headers: {
108
+ Cookie: `better-auth.session_token=${sessionToken}`,
109
+ },
110
+ signal: AbortSignal.timeout(5000),
111
+ });
112
+ if (!response.ok) {
113
+ return {
114
+ valid: false,
115
+ error: `Session validation failed: HTTP ${response.status}`,
116
+ };
117
+ }
118
+ const session = (await response.json());
119
+ if (!session.user) {
120
+ return {
121
+ valid: false,
122
+ error: "Invalid session",
123
+ };
124
+ }
125
+ const user = {
126
+ id: session.user.id,
127
+ email: session.user.email,
128
+ name: session.user.name,
129
+ picture: session.user.image,
130
+ emailVerified: session.user.emailVerified,
131
+ roles: session.user.roles || [],
132
+ permissions: session.user.permissions || [],
133
+ createdAt: session.user.createdAt
134
+ ? new Date(session.user.createdAt)
135
+ : undefined,
136
+ metadata: session.user,
137
+ };
138
+ return {
139
+ valid: true,
140
+ payload: session,
141
+ user,
142
+ expiresAt: session.session?.expiresAt
143
+ ? new Date(session.session.expiresAt)
144
+ : undefined,
145
+ tokenType: "session",
146
+ };
147
+ }
148
+ catch (error) {
149
+ return {
150
+ valid: false,
151
+ error: error instanceof Error ? error.message : String(error),
152
+ };
153
+ }
154
+ }
155
+ /**
156
+ * Health check
157
+ */
158
+ async healthCheck() {
159
+ try {
160
+ const proxyFetch = createProxyFetch();
161
+ // Better Auth typically exposes session endpoint that we can check
162
+ const response = await proxyFetch(`${this.baseUrl}/api/auth/session`, {
163
+ signal: AbortSignal.timeout(5000),
164
+ });
165
+ // Even a 401 means the endpoint is working
166
+ const isReachable = response.status < 500;
167
+ return {
168
+ healthy: isReachable,
169
+ providerConnected: isReachable,
170
+ sessionStorageHealthy: true,
171
+ };
172
+ }
173
+ catch (error) {
174
+ return {
175
+ healthy: false,
176
+ providerConnected: false,
177
+ sessionStorageHealthy: true,
178
+ error: error instanceof Error ? error.message : String(error),
179
+ };
180
+ }
181
+ }
182
+ }
183
+ //# sourceMappingURL=betterAuth.js.map
@@ -0,0 +1,65 @@
1
+ import { BaseAuthProvider } from "./BaseAuthProvider.js";
2
+ import type { AuthProviderConfig, ClerkConfig, AuthUser, TokenValidationResult, AuthRequestContext, AuthHealthCheck, AuthProviderType } from "../../types/authTypes.js";
3
+ /**
4
+ * Clerk Authentication Provider
5
+ *
6
+ * Supports Clerk's session-based and JWT authentication.
7
+ * Can validate both JWT tokens and session tokens via Clerk API.
8
+ *
9
+ * Features:
10
+ * - JWT validation using Clerk's JWKS
11
+ * - Session token validation via Clerk API
12
+ * - User profile fetching
13
+ * - Organization support for multi-tenant apps
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const clerk = new ClerkProvider({
18
+ * type: "clerk",
19
+ * publishableKey: "pk_test_...",
20
+ * secretKey: "sk_test_..."
21
+ * });
22
+ *
23
+ * const result = await clerk.authenticateToken(sessionToken);
24
+ * if (result.valid) {
25
+ * console.log("Authenticated user:", result.user);
26
+ * }
27
+ * ```
28
+ */
29
+ export declare class ClerkProvider extends BaseAuthProvider {
30
+ readonly type: AuthProviderType;
31
+ private secretKey;
32
+ private jwtKey?;
33
+ private publishableKey?;
34
+ private jwks;
35
+ private localKey;
36
+ constructor(config: AuthProviderConfig & ClerkConfig);
37
+ /**
38
+ * Initialize Clerk JWKS
39
+ */
40
+ initialize(): Promise<void>;
41
+ /**
42
+ * Validate Clerk session token or JWT
43
+ */
44
+ authenticateToken(token: string, _context?: AuthRequestContext): Promise<TokenValidationResult>;
45
+ /**
46
+ * Validate JWT using local jwtKey (if configured) or JWKS
47
+ */
48
+ private validateJWT;
49
+ /**
50
+ * Validate session token via Clerk API
51
+ */
52
+ private validateSessionToken;
53
+ /**
54
+ * Get user by ID from Clerk API
55
+ */
56
+ getUser(userId: string): Promise<AuthUser | null>;
57
+ /**
58
+ * Get user by email from Clerk API
59
+ */
60
+ getUserByEmail(email: string): Promise<AuthUser | null>;
61
+ /**
62
+ * Health check
63
+ */
64
+ healthCheck(): Promise<AuthHealthCheck>;
65
+ }