@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.
- package/CHANGELOG.md +6 -0
- package/dist/auth/AuthProviderFactory.d.ts +71 -0
- package/dist/auth/AuthProviderFactory.js +111 -0
- package/dist/auth/AuthProviderRegistry.d.ts +33 -0
- package/dist/auth/AuthProviderRegistry.js +190 -0
- package/dist/auth/RequestContext.d.ts +23 -0
- package/dist/auth/RequestContext.js +78 -0
- package/dist/auth/authContext.d.ts +198 -0
- package/dist/auth/authContext.js +314 -0
- package/dist/auth/errors.d.ts +63 -0
- package/dist/auth/errors.js +39 -0
- package/dist/auth/index.d.ts +20 -8
- package/dist/auth/index.js +35 -7
- package/dist/auth/middleware/AuthMiddleware.d.ts +181 -0
- package/dist/auth/middleware/AuthMiddleware.js +519 -0
- package/dist/auth/middleware/rateLimitByUser.d.ts +282 -0
- package/dist/auth/middleware/rateLimitByUser.js +554 -0
- package/dist/auth/providers/BaseAuthProvider.d.ts +259 -0
- package/dist/auth/providers/BaseAuthProvider.js +723 -0
- package/dist/auth/providers/CognitoProvider.d.ts +61 -0
- package/dist/auth/providers/CognitoProvider.js +304 -0
- package/dist/auth/providers/KeycloakProvider.d.ts +61 -0
- package/dist/auth/providers/KeycloakProvider.js +393 -0
- package/dist/auth/providers/auth0.d.ts +59 -0
- package/dist/auth/providers/auth0.js +274 -0
- package/dist/auth/providers/betterAuth.d.ts +51 -0
- package/dist/auth/providers/betterAuth.js +182 -0
- package/dist/auth/providers/clerk.d.ts +65 -0
- package/dist/auth/providers/clerk.js +317 -0
- package/dist/auth/providers/custom.d.ts +64 -0
- package/dist/auth/providers/custom.js +112 -0
- package/dist/auth/providers/firebase.d.ts +63 -0
- package/dist/auth/providers/firebase.js +226 -0
- package/dist/auth/providers/jwt.d.ts +68 -0
- package/dist/auth/providers/jwt.js +212 -0
- package/dist/auth/providers/oauth2.d.ts +73 -0
- package/dist/auth/providers/oauth2.js +303 -0
- package/dist/auth/providers/supabase.d.ts +63 -0
- package/dist/auth/providers/supabase.js +259 -0
- package/dist/auth/providers/workos.d.ts +61 -0
- package/dist/auth/providers/workos.js +284 -0
- package/dist/auth/serverBridge.d.ts +14 -0
- package/dist/auth/serverBridge.js +25 -0
- package/dist/auth/sessionManager.d.ts +142 -0
- package/dist/auth/sessionManager.js +437 -0
- package/dist/cli/commands/authProviders.d.ts +43 -0
- package/dist/cli/commands/authProviders.js +399 -0
- package/dist/cli/factories/authCommandFactory.d.ts +23 -5
- package/dist/cli/factories/authCommandFactory.js +108 -5
- package/dist/cli/parser.js +1 -1
- package/dist/client/auth/AuthProviderFactory.js +111 -0
- package/dist/client/auth/AuthProviderRegistry.js +190 -0
- package/dist/client/auth/RequestContext.js +78 -0
- package/dist/client/auth/accountPool.js +178 -0
- package/dist/client/auth/authContext.js +314 -0
- package/dist/client/auth/errors.js +39 -0
- package/dist/client/auth/index.js +61 -0
- package/dist/client/auth/middleware/AuthMiddleware.js +519 -0
- package/dist/client/auth/middleware/rateLimitByUser.js +554 -0
- package/dist/client/auth/providers/BaseAuthProvider.js +723 -0
- package/dist/client/auth/providers/CognitoProvider.js +304 -0
- package/dist/client/auth/providers/KeycloakProvider.js +393 -0
- package/dist/client/auth/providers/auth0.js +274 -0
- package/dist/client/auth/providers/betterAuth.js +182 -0
- package/dist/client/auth/providers/clerk.js +317 -0
- package/dist/client/auth/providers/custom.js +112 -0
- package/dist/client/auth/providers/firebase.js +226 -0
- package/dist/client/auth/providers/jwt.js +212 -0
- package/dist/client/auth/providers/oauth2.js +303 -0
- package/dist/client/auth/providers/supabase.js +259 -0
- package/dist/client/auth/providers/workos.js +284 -0
- package/dist/client/auth/serverBridge.js +25 -0
- package/dist/client/auth/sessionManager.js +437 -0
- package/dist/client/core/infrastructure/baseRegistry.js +5 -1
- package/dist/client/index.js +25 -0
- package/dist/client/mcp/toolRegistry.js +11 -1
- package/dist/client/neurolink.js +218 -0
- package/dist/client/rag/ChunkerRegistry.js +2 -2
- package/dist/client/rag/metadata/MetadataExtractorRegistry.js +2 -2
- package/dist/client/rag/reranker/RerankerRegistry.js +2 -2
- package/dist/client/server/routes/agentRoutes.js +20 -2
- package/dist/client/types/authTypes.js +2 -1
- package/dist/core/infrastructure/baseRegistry.d.ts +3 -1
- package/dist/core/infrastructure/baseRegistry.js +5 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +25 -0
- package/dist/lib/auth/AuthProviderFactory.d.ts +71 -0
- package/dist/lib/auth/AuthProviderFactory.js +112 -0
- package/dist/lib/auth/AuthProviderRegistry.d.ts +33 -0
- package/dist/lib/auth/AuthProviderRegistry.js +191 -0
- package/dist/lib/auth/RequestContext.d.ts +23 -0
- package/dist/lib/auth/RequestContext.js +79 -0
- package/dist/lib/auth/authContext.d.ts +198 -0
- package/dist/lib/auth/authContext.js +315 -0
- package/dist/lib/auth/errors.d.ts +63 -0
- package/dist/lib/auth/errors.js +40 -0
- package/dist/lib/auth/index.d.ts +20 -8
- package/dist/lib/auth/index.js +35 -7
- package/dist/lib/auth/middleware/AuthMiddleware.d.ts +181 -0
- package/dist/lib/auth/middleware/AuthMiddleware.js +520 -0
- package/dist/lib/auth/middleware/rateLimitByUser.d.ts +282 -0
- package/dist/lib/auth/middleware/rateLimitByUser.js +555 -0
- package/dist/lib/auth/providers/BaseAuthProvider.d.ts +259 -0
- package/dist/lib/auth/providers/BaseAuthProvider.js +724 -0
- package/dist/lib/auth/providers/CognitoProvider.d.ts +61 -0
- package/dist/lib/auth/providers/CognitoProvider.js +305 -0
- package/dist/lib/auth/providers/KeycloakProvider.d.ts +61 -0
- package/dist/lib/auth/providers/KeycloakProvider.js +394 -0
- package/dist/lib/auth/providers/auth0.d.ts +59 -0
- package/dist/lib/auth/providers/auth0.js +275 -0
- package/dist/lib/auth/providers/betterAuth.d.ts +51 -0
- package/dist/lib/auth/providers/betterAuth.js +183 -0
- package/dist/lib/auth/providers/clerk.d.ts +65 -0
- package/dist/lib/auth/providers/clerk.js +318 -0
- package/dist/lib/auth/providers/custom.d.ts +64 -0
- package/dist/lib/auth/providers/custom.js +113 -0
- package/dist/lib/auth/providers/firebase.d.ts +63 -0
- package/dist/lib/auth/providers/firebase.js +227 -0
- package/dist/lib/auth/providers/jwt.d.ts +68 -0
- package/dist/lib/auth/providers/jwt.js +213 -0
- package/dist/lib/auth/providers/oauth2.d.ts +73 -0
- package/dist/lib/auth/providers/oauth2.js +304 -0
- package/dist/lib/auth/providers/supabase.d.ts +63 -0
- package/dist/lib/auth/providers/supabase.js +260 -0
- package/dist/lib/auth/providers/workos.d.ts +61 -0
- package/dist/lib/auth/providers/workos.js +285 -0
- package/dist/lib/auth/serverBridge.d.ts +14 -0
- package/dist/lib/auth/serverBridge.js +26 -0
- package/dist/lib/auth/sessionManager.d.ts +142 -0
- package/dist/lib/auth/sessionManager.js +438 -0
- package/dist/lib/core/infrastructure/baseRegistry.d.ts +3 -1
- package/dist/lib/core/infrastructure/baseRegistry.js +5 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +25 -0
- package/dist/lib/mcp/toolRegistry.js +11 -1
- package/dist/lib/neurolink.d.ts +42 -1
- package/dist/lib/neurolink.js +218 -0
- package/dist/lib/rag/ChunkerRegistry.js +2 -2
- package/dist/lib/rag/metadata/MetadataExtractorRegistry.js +2 -2
- package/dist/lib/rag/reranker/RerankerRegistry.js +2 -2
- package/dist/lib/server/routes/agentRoutes.js +20 -2
- package/dist/lib/types/authTypes.d.ts +937 -1
- package/dist/lib/types/authTypes.js +2 -1
- package/dist/lib/types/configTypes.d.ts +46 -0
- package/dist/lib/types/generateTypes.d.ts +6 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/streamTypes.d.ts +6 -0
- package/dist/mcp/toolRegistry.js +11 -1
- package/dist/neurolink.d.ts +42 -1
- package/dist/neurolink.js +218 -0
- package/dist/rag/ChunkerRegistry.js +2 -2
- package/dist/rag/metadata/MetadataExtractorRegistry.js +2 -2
- package/dist/rag/reranker/RerankerRegistry.js +2 -2
- package/dist/server/routes/agentRoutes.js +20 -2
- package/dist/types/authTypes.d.ts +937 -1
- package/dist/types/authTypes.js +2 -1
- package/dist/types/configTypes.d.ts +46 -0
- package/dist/types/generateTypes.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/streamTypes.d.ts +6 -0
- package/package.json +2 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type { AuthUser, AuthSession, AuthenticatedContext, AuthProviderType, AuthRequestContext } from "../types/authTypes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Run a function with authentication context
|
|
4
|
+
*
|
|
5
|
+
* Sets up async local storage so getAuthContext() can be called
|
|
6
|
+
* from anywhere within the callback's execution.
|
|
7
|
+
*
|
|
8
|
+
* @param context - The authenticated context
|
|
9
|
+
* @param callback - Function to run with context available
|
|
10
|
+
* @returns Result of the callback
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* await runWithAuthContext(authContext, async () => {
|
|
15
|
+
* // Inside here, getAuthContext() returns the context
|
|
16
|
+
* const user = getCurrentUser();
|
|
17
|
+
* await processRequest();
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function runWithAuthContext<T>(context: AuthenticatedContext, callback: () => T | Promise<T>): T | Promise<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Get the current authentication context
|
|
24
|
+
*
|
|
25
|
+
* Returns the authenticated context for the current request,
|
|
26
|
+
* or undefined if no context is set.
|
|
27
|
+
*
|
|
28
|
+
* @returns Current auth context or undefined
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const context = getAuthContext();
|
|
33
|
+
* if (context) {
|
|
34
|
+
* console.log("Current user:", context.user.email);
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function getAuthContext(): AuthenticatedContext | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Get the current authenticated user
|
|
41
|
+
*
|
|
42
|
+
* Convenience function to get just the user from context.
|
|
43
|
+
*
|
|
44
|
+
* @returns Current user or undefined
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const user = getCurrentUser();
|
|
49
|
+
* if (user) {
|
|
50
|
+
* console.log("Hello,", user.name);
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function getCurrentUser(): AuthUser | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Get the current session
|
|
57
|
+
*
|
|
58
|
+
* Convenience function to get just the session from context.
|
|
59
|
+
*
|
|
60
|
+
* @returns Current session or undefined
|
|
61
|
+
*/
|
|
62
|
+
export declare function getCurrentSession(): AuthSession | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Check if the current request is authenticated
|
|
65
|
+
*
|
|
66
|
+
* @returns True if authenticated, false otherwise
|
|
67
|
+
*/
|
|
68
|
+
export declare function isAuthenticated(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Require authentication
|
|
71
|
+
*
|
|
72
|
+
* Throws if no auth context is available.
|
|
73
|
+
*
|
|
74
|
+
* @returns The authenticated context
|
|
75
|
+
* @throws Error if not authenticated
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const context = requireAuth();
|
|
80
|
+
* // Safe to use context.user here
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function requireAuth(): AuthenticatedContext;
|
|
84
|
+
/**
|
|
85
|
+
* Require a specific user
|
|
86
|
+
*
|
|
87
|
+
* Throws if no auth context or user doesn't match.
|
|
88
|
+
*
|
|
89
|
+
* @param userId - Expected user ID
|
|
90
|
+
* @returns The authenticated context
|
|
91
|
+
* @throws Error if not authenticated or wrong user
|
|
92
|
+
*/
|
|
93
|
+
export declare function requireUser(userId: string): AuthenticatedContext;
|
|
94
|
+
/**
|
|
95
|
+
* Check if current user has a permission
|
|
96
|
+
*
|
|
97
|
+
* @param permission - Permission to check
|
|
98
|
+
* @returns True if user has permission
|
|
99
|
+
*/
|
|
100
|
+
export declare function hasPermission(permission: string): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Check if current user has a role
|
|
103
|
+
*
|
|
104
|
+
* @param role - Role to check
|
|
105
|
+
* @returns True if user has role
|
|
106
|
+
*/
|
|
107
|
+
export declare function hasRole(role: string): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Check if current user has any of the roles
|
|
110
|
+
*
|
|
111
|
+
* @param roles - Roles to check (any of)
|
|
112
|
+
* @returns True if user has at least one role
|
|
113
|
+
*/
|
|
114
|
+
export declare function hasAnyRole(roles: string[]): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Check if current user has all permissions
|
|
117
|
+
*
|
|
118
|
+
* @param permissions - Permissions to check (all of)
|
|
119
|
+
* @returns True if user has all permissions
|
|
120
|
+
*/
|
|
121
|
+
export declare function hasAllPermissions(permissions: string[]): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Require a permission
|
|
124
|
+
*
|
|
125
|
+
* Throws if user doesn't have the permission.
|
|
126
|
+
*
|
|
127
|
+
* @param permission - Required permission
|
|
128
|
+
* @throws Error if user lacks permission
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* requirePermission("admin:write");
|
|
133
|
+
* // Safe to proceed with admin write operation
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export declare function requirePermission(permission: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Require a role
|
|
139
|
+
*
|
|
140
|
+
* Throws if user doesn't have the role.
|
|
141
|
+
*
|
|
142
|
+
* @param role - Required role
|
|
143
|
+
* @throws Error if user lacks role
|
|
144
|
+
*/
|
|
145
|
+
export declare function requireRole(role: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* Create an authenticated context
|
|
148
|
+
*
|
|
149
|
+
* Helper to build an AuthenticatedContext object.
|
|
150
|
+
*
|
|
151
|
+
* @param user - The authenticated user
|
|
152
|
+
* @param session - The user's session
|
|
153
|
+
* @param request - The original request context
|
|
154
|
+
* @param provider - The auth provider type
|
|
155
|
+
* @returns Complete authenticated context
|
|
156
|
+
*/
|
|
157
|
+
export declare function createAuthenticatedContext(user: AuthUser, session: AuthSession, request: AuthRequestContext, provider: AuthProviderType): AuthenticatedContext;
|
|
158
|
+
/**
|
|
159
|
+
* Context holder for non-async-local-storage environments
|
|
160
|
+
*
|
|
161
|
+
* Use this when async local storage is not available.
|
|
162
|
+
*/
|
|
163
|
+
export declare class AuthContextHolder {
|
|
164
|
+
private context;
|
|
165
|
+
/**
|
|
166
|
+
* Set the auth context
|
|
167
|
+
*/
|
|
168
|
+
set(context: AuthenticatedContext): void;
|
|
169
|
+
/**
|
|
170
|
+
* Get the auth context
|
|
171
|
+
*/
|
|
172
|
+
get(): AuthenticatedContext | undefined;
|
|
173
|
+
/**
|
|
174
|
+
* Clear the auth context
|
|
175
|
+
*/
|
|
176
|
+
clear(): void;
|
|
177
|
+
/**
|
|
178
|
+
* Get the current user
|
|
179
|
+
*/
|
|
180
|
+
getUser(): AuthUser | undefined;
|
|
181
|
+
/**
|
|
182
|
+
* Get the current session
|
|
183
|
+
*/
|
|
184
|
+
getSession(): AuthSession | undefined;
|
|
185
|
+
/**
|
|
186
|
+
* Check if authenticated
|
|
187
|
+
*/
|
|
188
|
+
isAuthenticated(): boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Check if user has permission
|
|
191
|
+
*/
|
|
192
|
+
hasPermission(permission: string): boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Check if user has role
|
|
195
|
+
*/
|
|
196
|
+
hasRole(role: string): boolean;
|
|
197
|
+
}
|
|
198
|
+
export declare const globalAuthContext: AuthContextHolder;
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
// src/lib/auth/authContext.ts
|
|
2
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
3
|
+
import { AuthError } from "./errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Async local storage for auth context
|
|
6
|
+
*
|
|
7
|
+
* Enables access to authentication context throughout the request lifecycle
|
|
8
|
+
* without explicitly passing it through every function call.
|
|
9
|
+
*/
|
|
10
|
+
const authContextStorage = new AsyncLocalStorage();
|
|
11
|
+
/**
|
|
12
|
+
* Run a function with authentication context
|
|
13
|
+
*
|
|
14
|
+
* Sets up async local storage so getAuthContext() can be called
|
|
15
|
+
* from anywhere within the callback's execution.
|
|
16
|
+
*
|
|
17
|
+
* @param context - The authenticated context
|
|
18
|
+
* @param callback - Function to run with context available
|
|
19
|
+
* @returns Result of the callback
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* await runWithAuthContext(authContext, async () => {
|
|
24
|
+
* // Inside here, getAuthContext() returns the context
|
|
25
|
+
* const user = getCurrentUser();
|
|
26
|
+
* await processRequest();
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function runWithAuthContext(context, callback) {
|
|
31
|
+
return authContextStorage.run(context, callback);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the current authentication context
|
|
35
|
+
*
|
|
36
|
+
* Returns the authenticated context for the current request,
|
|
37
|
+
* or undefined if no context is set.
|
|
38
|
+
*
|
|
39
|
+
* @returns Current auth context or undefined
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const context = getAuthContext();
|
|
44
|
+
* if (context) {
|
|
45
|
+
* console.log("Current user:", context.user.email);
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function getAuthContext() {
|
|
50
|
+
return authContextStorage.getStore() ?? globalAuthContext.get();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the current authenticated user
|
|
54
|
+
*
|
|
55
|
+
* Convenience function to get just the user from context.
|
|
56
|
+
*
|
|
57
|
+
* @returns Current user or undefined
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const user = getCurrentUser();
|
|
62
|
+
* if (user) {
|
|
63
|
+
* console.log("Hello,", user.name);
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export function getCurrentUser() {
|
|
68
|
+
return (authContextStorage.getStore() ?? globalAuthContext.get())?.user;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the current session
|
|
72
|
+
*
|
|
73
|
+
* Convenience function to get just the session from context.
|
|
74
|
+
*
|
|
75
|
+
* @returns Current session or undefined
|
|
76
|
+
*/
|
|
77
|
+
export function getCurrentSession() {
|
|
78
|
+
return (authContextStorage.getStore() ?? globalAuthContext.get())?.session;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if the current request is authenticated
|
|
82
|
+
*
|
|
83
|
+
* @returns True if authenticated, false otherwise
|
|
84
|
+
*/
|
|
85
|
+
export function isAuthenticated() {
|
|
86
|
+
return (authContextStorage.getStore() !== undefined ||
|
|
87
|
+
globalAuthContext.isAuthenticated());
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Require authentication
|
|
91
|
+
*
|
|
92
|
+
* Throws if no auth context is available.
|
|
93
|
+
*
|
|
94
|
+
* @returns The authenticated context
|
|
95
|
+
* @throws Error if not authenticated
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const context = requireAuth();
|
|
100
|
+
* // Safe to use context.user here
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export function requireAuth() {
|
|
104
|
+
const context = getAuthContext();
|
|
105
|
+
if (!context) {
|
|
106
|
+
throw AuthError.create("MISSING_TOKEN", "Authentication required");
|
|
107
|
+
}
|
|
108
|
+
return context;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Require a specific user
|
|
112
|
+
*
|
|
113
|
+
* Throws if no auth context or user doesn't match.
|
|
114
|
+
*
|
|
115
|
+
* @param userId - Expected user ID
|
|
116
|
+
* @returns The authenticated context
|
|
117
|
+
* @throws Error if not authenticated or wrong user
|
|
118
|
+
*/
|
|
119
|
+
export function requireUser(userId) {
|
|
120
|
+
const context = requireAuth();
|
|
121
|
+
if (context.user.id !== userId) {
|
|
122
|
+
throw AuthError.create("ACCESS_DENIED", "User mismatch");
|
|
123
|
+
}
|
|
124
|
+
return context;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check if current user has a permission
|
|
128
|
+
*
|
|
129
|
+
* @param permission - Permission to check
|
|
130
|
+
* @returns True if user has permission
|
|
131
|
+
*/
|
|
132
|
+
export function hasPermission(permission) {
|
|
133
|
+
const user = getCurrentUser();
|
|
134
|
+
if (!user) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
// Check direct permission
|
|
138
|
+
if (user.permissions.includes(permission)) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
// Check wildcard
|
|
142
|
+
if (user.permissions.includes("*")) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
// Check permission hierarchy
|
|
146
|
+
const parts = permission.split(":");
|
|
147
|
+
for (let i = parts.length - 1; i > 0; i--) {
|
|
148
|
+
const wildcardPerm = [...parts.slice(0, i), "*"].join(":");
|
|
149
|
+
if (user.permissions.includes(wildcardPerm)) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if current user has a role
|
|
157
|
+
*
|
|
158
|
+
* @param role - Role to check
|
|
159
|
+
* @returns True if user has role
|
|
160
|
+
*/
|
|
161
|
+
export function hasRole(role) {
|
|
162
|
+
const user = getCurrentUser();
|
|
163
|
+
return user?.roles.includes(role) ?? false;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Check if current user has any of the roles
|
|
167
|
+
*
|
|
168
|
+
* @param roles - Roles to check (any of)
|
|
169
|
+
* @returns True if user has at least one role
|
|
170
|
+
*/
|
|
171
|
+
export function hasAnyRole(roles) {
|
|
172
|
+
const user = getCurrentUser();
|
|
173
|
+
if (!user) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
return roles.some((role) => user.roles.includes(role));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if current user has all permissions
|
|
180
|
+
*
|
|
181
|
+
* @param permissions - Permissions to check (all of)
|
|
182
|
+
* @returns True if user has all permissions
|
|
183
|
+
*/
|
|
184
|
+
export function hasAllPermissions(permissions) {
|
|
185
|
+
return permissions.every((perm) => hasPermission(perm));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Require a permission
|
|
189
|
+
*
|
|
190
|
+
* Throws if user doesn't have the permission.
|
|
191
|
+
*
|
|
192
|
+
* @param permission - Required permission
|
|
193
|
+
* @throws Error if user lacks permission
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* requirePermission("admin:write");
|
|
198
|
+
* // Safe to proceed with admin write operation
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export function requirePermission(permission) {
|
|
202
|
+
if (!hasPermission(permission)) {
|
|
203
|
+
throw AuthError.create("INSUFFICIENT_PERMISSIONS", `Permission denied: ${permission}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Require a role
|
|
208
|
+
*
|
|
209
|
+
* Throws if user doesn't have the role.
|
|
210
|
+
*
|
|
211
|
+
* @param role - Required role
|
|
212
|
+
* @throws Error if user lacks role
|
|
213
|
+
*/
|
|
214
|
+
export function requireRole(role) {
|
|
215
|
+
if (!hasRole(role)) {
|
|
216
|
+
throw AuthError.create("INSUFFICIENT_ROLES", `Role required: ${role}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create an authenticated context
|
|
221
|
+
*
|
|
222
|
+
* Helper to build an AuthenticatedContext object.
|
|
223
|
+
*
|
|
224
|
+
* @param user - The authenticated user
|
|
225
|
+
* @param session - The user's session
|
|
226
|
+
* @param request - The original request context
|
|
227
|
+
* @param provider - The auth provider type
|
|
228
|
+
* @returns Complete authenticated context
|
|
229
|
+
*/
|
|
230
|
+
export function createAuthenticatedContext(user, session, request, provider) {
|
|
231
|
+
return {
|
|
232
|
+
...request,
|
|
233
|
+
user,
|
|
234
|
+
session,
|
|
235
|
+
request,
|
|
236
|
+
authenticatedAt: new Date(),
|
|
237
|
+
provider,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Context holder for non-async-local-storage environments
|
|
242
|
+
*
|
|
243
|
+
* Use this when async local storage is not available.
|
|
244
|
+
*/
|
|
245
|
+
export class AuthContextHolder {
|
|
246
|
+
context;
|
|
247
|
+
/**
|
|
248
|
+
* Set the auth context
|
|
249
|
+
*/
|
|
250
|
+
set(context) {
|
|
251
|
+
this.context = context;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get the auth context
|
|
255
|
+
*/
|
|
256
|
+
get() {
|
|
257
|
+
return this.context;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Clear the auth context
|
|
261
|
+
*/
|
|
262
|
+
clear() {
|
|
263
|
+
this.context = undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get the current user
|
|
267
|
+
*/
|
|
268
|
+
getUser() {
|
|
269
|
+
return this.context?.user;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get the current session
|
|
273
|
+
*/
|
|
274
|
+
getSession() {
|
|
275
|
+
return this.context?.session;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Check if authenticated
|
|
279
|
+
*/
|
|
280
|
+
isAuthenticated() {
|
|
281
|
+
return this.context !== undefined;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Check if user has permission
|
|
285
|
+
*/
|
|
286
|
+
hasPermission(permission) {
|
|
287
|
+
const user = this.context?.user;
|
|
288
|
+
if (!user) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
if (user.permissions.includes(permission) ||
|
|
292
|
+
user.permissions.includes("*")) {
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
// Check hierarchy
|
|
296
|
+
const parts = permission.split(":");
|
|
297
|
+
for (let i = parts.length - 1; i > 0; i--) {
|
|
298
|
+
const wildcardPerm = [...parts.slice(0, i), "*"].join(":");
|
|
299
|
+
if (user.permissions.includes(wildcardPerm)) {
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Check if user has role
|
|
307
|
+
*/
|
|
308
|
+
hasRole(role) {
|
|
309
|
+
return this.context?.user.roles.includes(role) ?? false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Internal: global context holder for non-async environments.
|
|
313
|
+
// Exported for use by neurolink.ts; not part of the public API contract.
|
|
314
|
+
export const globalAuthContext = new AuthContextHolder();
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare const AuthErrorCodes: {
|
|
2
|
+
readonly INVALID_TOKEN: "AUTH-001";
|
|
3
|
+
readonly EXPIRED_TOKEN: "AUTH-002";
|
|
4
|
+
readonly MISSING_TOKEN: "AUTH-003";
|
|
5
|
+
readonly TOKEN_DECODE_FAILED: "AUTH-004";
|
|
6
|
+
readonly INVALID_SIGNATURE: "AUTH-005";
|
|
7
|
+
readonly SESSION_NOT_FOUND: "AUTH-010";
|
|
8
|
+
readonly SESSION_EXPIRED: "AUTH-011";
|
|
9
|
+
readonly SESSION_REVOKED: "AUTH-012";
|
|
10
|
+
readonly INSUFFICIENT_PERMISSIONS: "AUTH-020";
|
|
11
|
+
readonly INSUFFICIENT_ROLES: "AUTH-021";
|
|
12
|
+
readonly ACCESS_DENIED: "AUTH-022";
|
|
13
|
+
readonly USER_NOT_FOUND: "AUTH-030";
|
|
14
|
+
readonly USER_DISABLED: "AUTH-031";
|
|
15
|
+
readonly EMAIL_NOT_VERIFIED: "AUTH-032";
|
|
16
|
+
readonly MFA_REQUIRED: "AUTH-033";
|
|
17
|
+
readonly PROVIDER_ERROR: "AUTH-040";
|
|
18
|
+
readonly PROVIDER_NOT_FOUND: "AUTH-041";
|
|
19
|
+
readonly PROVIDER_INIT_FAILED: "AUTH-042";
|
|
20
|
+
readonly CONFIGURATION_ERROR: "AUTH-043";
|
|
21
|
+
readonly CREATION_FAILED: "AUTH-050";
|
|
22
|
+
readonly REGISTRATION_FAILED: "AUTH-051";
|
|
23
|
+
readonly DUPLICATE_REGISTRATION: "AUTH-052";
|
|
24
|
+
readonly MIDDLEWARE_ERROR: "AUTH-060";
|
|
25
|
+
readonly RATE_LIMITED: "AUTH-061";
|
|
26
|
+
readonly JWKS_FETCH_FAILED: "AUTH-070";
|
|
27
|
+
readonly JWKS_KEY_NOT_FOUND: "AUTH-071";
|
|
28
|
+
};
|
|
29
|
+
export declare const AuthError: {
|
|
30
|
+
codes: {
|
|
31
|
+
readonly INVALID_TOKEN: "AUTH-001";
|
|
32
|
+
readonly EXPIRED_TOKEN: "AUTH-002";
|
|
33
|
+
readonly MISSING_TOKEN: "AUTH-003";
|
|
34
|
+
readonly TOKEN_DECODE_FAILED: "AUTH-004";
|
|
35
|
+
readonly INVALID_SIGNATURE: "AUTH-005";
|
|
36
|
+
readonly SESSION_NOT_FOUND: "AUTH-010";
|
|
37
|
+
readonly SESSION_EXPIRED: "AUTH-011";
|
|
38
|
+
readonly SESSION_REVOKED: "AUTH-012";
|
|
39
|
+
readonly INSUFFICIENT_PERMISSIONS: "AUTH-020";
|
|
40
|
+
readonly INSUFFICIENT_ROLES: "AUTH-021";
|
|
41
|
+
readonly ACCESS_DENIED: "AUTH-022";
|
|
42
|
+
readonly USER_NOT_FOUND: "AUTH-030";
|
|
43
|
+
readonly USER_DISABLED: "AUTH-031";
|
|
44
|
+
readonly EMAIL_NOT_VERIFIED: "AUTH-032";
|
|
45
|
+
readonly MFA_REQUIRED: "AUTH-033";
|
|
46
|
+
readonly PROVIDER_ERROR: "AUTH-040";
|
|
47
|
+
readonly PROVIDER_NOT_FOUND: "AUTH-041";
|
|
48
|
+
readonly PROVIDER_INIT_FAILED: "AUTH-042";
|
|
49
|
+
readonly CONFIGURATION_ERROR: "AUTH-043";
|
|
50
|
+
readonly CREATION_FAILED: "AUTH-050";
|
|
51
|
+
readonly REGISTRATION_FAILED: "AUTH-051";
|
|
52
|
+
readonly DUPLICATE_REGISTRATION: "AUTH-052";
|
|
53
|
+
readonly MIDDLEWARE_ERROR: "AUTH-060";
|
|
54
|
+
readonly RATE_LIMITED: "AUTH-061";
|
|
55
|
+
readonly JWKS_FETCH_FAILED: "AUTH-070";
|
|
56
|
+
readonly JWKS_KEY_NOT_FOUND: "AUTH-071";
|
|
57
|
+
};
|
|
58
|
+
create: (code: "SESSION_NOT_FOUND" | "INVALID_TOKEN" | "EXPIRED_TOKEN" | "MISSING_TOKEN" | "TOKEN_DECODE_FAILED" | "INVALID_SIGNATURE" | "SESSION_EXPIRED" | "SESSION_REVOKED" | "INSUFFICIENT_PERMISSIONS" | "INSUFFICIENT_ROLES" | "ACCESS_DENIED" | "USER_NOT_FOUND" | "USER_DISABLED" | "EMAIL_NOT_VERIFIED" | "MFA_REQUIRED" | "PROVIDER_ERROR" | "PROVIDER_NOT_FOUND" | "PROVIDER_INIT_FAILED" | "CONFIGURATION_ERROR" | "CREATION_FAILED" | "REGISTRATION_FAILED" | "DUPLICATE_REGISTRATION" | "MIDDLEWARE_ERROR" | "RATE_LIMITED" | "JWKS_FETCH_FAILED" | "JWKS_KEY_NOT_FOUND", message: string, options?: {
|
|
59
|
+
retryable?: boolean;
|
|
60
|
+
details?: Record<string, unknown>;
|
|
61
|
+
cause?: Error;
|
|
62
|
+
} | undefined) => import("../core/infrastructure/baseError.js").NeuroLinkFeatureError;
|
|
63
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// src/lib/auth/errors.ts — Unified auth error codes (Phase 1 of auth error redesign)
|
|
2
|
+
import { createErrorFactory } from "../core/infrastructure/baseError.js";
|
|
3
|
+
export const AuthErrorCodes = {
|
|
4
|
+
// Token errors
|
|
5
|
+
INVALID_TOKEN: "AUTH-001",
|
|
6
|
+
EXPIRED_TOKEN: "AUTH-002",
|
|
7
|
+
MISSING_TOKEN: "AUTH-003",
|
|
8
|
+
TOKEN_DECODE_FAILED: "AUTH-004",
|
|
9
|
+
INVALID_SIGNATURE: "AUTH-005",
|
|
10
|
+
// Session errors
|
|
11
|
+
SESSION_NOT_FOUND: "AUTH-010",
|
|
12
|
+
SESSION_EXPIRED: "AUTH-011",
|
|
13
|
+
SESSION_REVOKED: "AUTH-012",
|
|
14
|
+
// Authorization errors
|
|
15
|
+
INSUFFICIENT_PERMISSIONS: "AUTH-020",
|
|
16
|
+
INSUFFICIENT_ROLES: "AUTH-021",
|
|
17
|
+
ACCESS_DENIED: "AUTH-022",
|
|
18
|
+
// User errors
|
|
19
|
+
USER_NOT_FOUND: "AUTH-030",
|
|
20
|
+
USER_DISABLED: "AUTH-031",
|
|
21
|
+
EMAIL_NOT_VERIFIED: "AUTH-032",
|
|
22
|
+
MFA_REQUIRED: "AUTH-033",
|
|
23
|
+
// Provider errors
|
|
24
|
+
PROVIDER_ERROR: "AUTH-040",
|
|
25
|
+
PROVIDER_NOT_FOUND: "AUTH-041",
|
|
26
|
+
PROVIDER_INIT_FAILED: "AUTH-042",
|
|
27
|
+
CONFIGURATION_ERROR: "AUTH-043",
|
|
28
|
+
// Factory/Registry errors
|
|
29
|
+
CREATION_FAILED: "AUTH-050",
|
|
30
|
+
REGISTRATION_FAILED: "AUTH-051",
|
|
31
|
+
DUPLICATE_REGISTRATION: "AUTH-052",
|
|
32
|
+
// Middleware errors
|
|
33
|
+
MIDDLEWARE_ERROR: "AUTH-060",
|
|
34
|
+
RATE_LIMITED: "AUTH-061",
|
|
35
|
+
// JWKS errors
|
|
36
|
+
JWKS_FETCH_FAILED: "AUTH-070",
|
|
37
|
+
JWKS_KEY_NOT_FOUND: "AUTH-071",
|
|
38
|
+
};
|
|
39
|
+
export const AuthError = createErrorFactory("Auth", AuthErrorCodes);
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NeuroLink Authentication Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
4
|
+
* Exports the full multi-provider authentication system including:
|
|
5
|
+
* - Anthropic OAuth 2.0 flow (PKCE, token storage, callback server)
|
|
6
|
+
* - Multi-provider auth (Auth0, Clerk, Firebase, Supabase, Cognito,
|
|
7
|
+
* Keycloak, Better Auth, WorkOS, JWT, OAuth2, Custom)
|
|
8
|
+
* - AuthProviderFactory / AuthProviderRegistry for lazy-loaded provider creation
|
|
9
|
+
* - Auth middleware (token extraction, RBAC, rate limiting)
|
|
10
|
+
* - Session management (memory, Redis)
|
|
11
|
+
* - Auth context (AsyncLocalStorage-based request scoping)
|
|
11
12
|
*/
|
|
12
13
|
export { ANTHROPIC_OAUTH_BASE_URL, DEFAULT_SCOPES, DEFAULT_REDIRECT_URI, DEFAULT_CALLBACK_PORT, } from "./anthropicOAuth.js";
|
|
13
14
|
export { AnthropicOAuth } from "./anthropicOAuth.js";
|
|
14
15
|
export { OAuthError, OAuthConfigurationError, OAuthTokenExchangeError, OAuthTokenRefreshError, OAuthTokenValidationError, OAuthTokenRevocationError, OAuthCallbackServerError, } from "../types/errors.js";
|
|
15
16
|
export { createAnthropicOAuth, createAnthropicOAuthConfig, hasAnthropicOAuthCredentials, startCallbackServer, stopCallbackServer, performOAuthFlow, } from "./anthropicOAuth.js";
|
|
16
|
-
export type { OAuthTokenResponse, OAuthFlowTokens, OAuthFlowTokens as OAuthTokens, TokenValidationResult, AnthropicOAuthConfig, PKCEParams, CallbackResult, } from "../types/index.js";
|
|
17
|
+
export type { OAuthTokenResponse, OAuthFlowTokens, OAuthFlowTokens as OAuthTokens, TokenValidationResult as OAuthTokenValidationResult, AnthropicOAuthConfig, PKCEParams, CallbackResult, } from "../types/index.js";
|
|
17
18
|
export { TokenStore, tokenStore, defaultTokenStore } from "./tokenStore.js";
|
|
18
19
|
export { TokenStoreError } from "../types/errors.js";
|
|
19
20
|
export type { StoredOAuthTokens, TokenRefresher } from "../types/authTypes.js";
|
|
20
21
|
export type { NeuroLinkAuthOptions, AuthStatus } from "../types/index.js";
|
|
21
22
|
export { AccountPool } from "./accountPool.js";
|
|
22
23
|
export type { ProxyAccount, AccountPoolConfig } from "../types/index.js";
|
|
24
|
+
export { AuthProviderFactory, createAuthProvider, } from "./AuthProviderFactory.js";
|
|
25
|
+
export { AuthProviderRegistry } from "./AuthProviderRegistry.js";
|
|
26
|
+
export { AuthError, AuthErrorCodes } from "./errors.js";
|
|
27
|
+
export { AuthProviderError, BaseAuthProvider, InMemorySessionStorage, } from "./providers/BaseAuthProvider.js";
|
|
28
|
+
export { AuthMiddlewareError, AuthMiddlewareErrorCodes, createAuthMiddleware, createExpressAuthMiddleware, createProtectedMiddleware, createRBACMiddleware, createRequestContext, type ExpressMiddleware, extractToken, type MiddlewareHandler, type MiddlewareResult, type NextFunction, } from "./middleware/AuthMiddleware.js";
|
|
29
|
+
export { createAuthenticatedRateLimitMiddleware, createRateLimitByUserMiddleware, createRateLimitStorage, MemoryRateLimitStorage, type RateLimitConfig, type RateLimitMiddlewareResult, type RateLimitResult, type RateLimitStorage, RedisRateLimitStorage, UserRateLimiter, } from "./middleware/rateLimitByUser.js";
|
|
30
|
+
export { createSessionStorage, MemorySessionStorage, RedisSessionStorage, SessionManager, type SessionManagerStorage as SessionStorageInterface, } from "./sessionManager.js";
|
|
31
|
+
export { AuthContextHolder, createAuthenticatedContext, getAuthContext, getCurrentSession, getCurrentUser, globalAuthContext, hasAllPermissions, hasAnyRole, hasPermission, hasRole, isAuthenticated, requireAuth, requirePermission, requireRole, requireUser, runWithAuthContext, } from "./authContext.js";
|
|
32
|
+
export { RequestContext, NEUROLINK_RESOURCE_ID_KEY, NEUROLINK_THREAD_ID_KEY, } from "./RequestContext.js";
|
|
33
|
+
export type { Auth0Config, AuthCacheConfig, AuthErrorInfo as AuthErrorType, AuthErrorCode, AuthEventData, AuthEventHandler, AuthEventType, AuthenticatedContext, AuthMiddlewareConfig, AuthorizationResult, AuthProviderConfig, AuthProviderFactoryFn, AuthProviderHealthCheck, AuthProviderRegistration, AuthProviderType, AuthRequestContext, AuthSession, AuthUser, BaseAuthProviderConfig, BetterAuthConfig, ClerkConfig, CognitoConfig, CustomAuthConfig, FirebaseConfig, JWK, JWKS, JWTConfig, KeycloakConfig, MastraAuthProvider, OAuth2Config, RBACConfig, RBACMiddlewareConfig, SessionConfig, SessionStorage, SessionValidationResult, SupabaseConfig, TokenClaims, TokenExtractionConfig, TokenValidationConfig, TokenValidationResult as AuthTokenValidationResult, WorkOSConfig, } from "../types/authTypes.js";
|
|
34
|
+
export { createAuthValidatorFromProvider } from "./serverBridge.js";
|