@vunexa/lixa 0.1.6-alpha.7 → 0.1.6-alpha.9
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/README.md +1 -2
- package/README.template.md +1 -2
- package/dist/dao/session-cache.d.ts +2 -1
- package/dist/dao/session-cache.d.ts.map +1 -1
- package/dist/dao/state-cache.d.ts +4 -0
- package/dist/dao/state-cache.d.ts.map +1 -1
- package/dist/dao/types.d.ts +21 -75
- package/dist/dao/types.d.ts.map +1 -1
- package/dist/errors.d.ts +90 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/export-types/index.d.ts +439 -95
- package/dist/express.d.ts +103 -0
- package/dist/express.d.ts.map +1 -0
- package/dist/index.cjs +509 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +408 -96
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +483 -128
- package/dist/index.js.map +1 -1
- package/dist/lixa.d.ts +25 -21
- package/dist/lixa.d.ts.map +1 -1
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cookies.d.ts +142 -0
- package/dist/utils/cookies.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -123,6 +123,61 @@ export declare enum AccountLinkingStrategy {
|
|
|
123
123
|
ISOLATED = "ISOLATED"
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Thrown when unlinking an account violates security constraints (e.g. unlinking the only login provider).
|
|
128
|
+
*
|
|
129
|
+
* @public
|
|
130
|
+
*/
|
|
131
|
+
export declare class AccountUnlinkError extends LixaError {
|
|
132
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Generates an expired session cookie payload to clear the session on logout.
|
|
137
|
+
*
|
|
138
|
+
* @param options - Optional overrides for cookie name or attributes
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const cookie = clearSessionCookie();
|
|
143
|
+
* res.setHeader("Set-Cookie", cookie.header);
|
|
144
|
+
* // or with Express:
|
|
145
|
+
* res.clearCookie(cookie.name, cookie.options);
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @public
|
|
149
|
+
*/
|
|
150
|
+
export declare function clearSessionCookie(options?: CookieOptions): CookiePayload;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Clears the session cookie on an Express response.
|
|
154
|
+
*
|
|
155
|
+
* @param res - Express response object
|
|
156
|
+
* @param options - Optional cookie attribute overrides
|
|
157
|
+
*
|
|
158
|
+
* @public
|
|
159
|
+
*/
|
|
160
|
+
export declare function clearSessionCookieOnResponse(res: ExpressLikeResponse, options?: CookieOptions): void;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Generates an expired OAuth state cookie payload to clean up the state cookie after callback.
|
|
164
|
+
*
|
|
165
|
+
* @param options - Optional overrides for cookie attributes
|
|
166
|
+
*
|
|
167
|
+
* @public
|
|
168
|
+
*/
|
|
169
|
+
export declare function clearStateCookie(options?: CookieOptions): CookiePayload;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Clears the OAuth CSRF state cookie on an Express response.
|
|
173
|
+
*
|
|
174
|
+
* @param res - Express response object
|
|
175
|
+
* @param options - Optional cookie attribute overrides
|
|
176
|
+
*
|
|
177
|
+
* @public
|
|
178
|
+
*/
|
|
179
|
+
export declare function clearStateCookieOnResponse(res: ExpressLikeResponse, options?: CookieOptions): void;
|
|
180
|
+
|
|
126
181
|
/**
|
|
127
182
|
* Type representing the keys of configured providers
|
|
128
183
|
*/
|
|
@@ -151,6 +206,112 @@ export declare interface ConnectedResource {
|
|
|
151
206
|
connectedAt: number;
|
|
152
207
|
}
|
|
153
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Sensible default cookie configuration options.
|
|
211
|
+
* Follows RFC 6265bis and OAuth 2.0 security best practices.
|
|
212
|
+
*
|
|
213
|
+
* @public
|
|
214
|
+
*/
|
|
215
|
+
export declare interface CookieOptions {
|
|
216
|
+
/**
|
|
217
|
+
* Cookie name.
|
|
218
|
+
* @default 'lixa_session'
|
|
219
|
+
*/
|
|
220
|
+
name?: string | undefined;
|
|
221
|
+
/**
|
|
222
|
+
* Cookie path.
|
|
223
|
+
* @default '/'
|
|
224
|
+
*/
|
|
225
|
+
path?: string | undefined;
|
|
226
|
+
/**
|
|
227
|
+
* Maximum age of the cookie in seconds.
|
|
228
|
+
*/
|
|
229
|
+
maxAge?: number | undefined;
|
|
230
|
+
/**
|
|
231
|
+
* Prevents client-side scripts from accessing the cookie (XSS protection).
|
|
232
|
+
* @default true
|
|
233
|
+
*/
|
|
234
|
+
httpOnly?: boolean | undefined;
|
|
235
|
+
/**
|
|
236
|
+
* Ensures the cookie is only transmitted over secure HTTPS connections.
|
|
237
|
+
* @default false in development, true in production
|
|
238
|
+
*/
|
|
239
|
+
secure?: boolean | undefined;
|
|
240
|
+
/**
|
|
241
|
+
* Controls whether the cookie is sent with cross-site requests (CSRF protection).
|
|
242
|
+
* @default 'lax'
|
|
243
|
+
*/
|
|
244
|
+
sameSite?: "lax" | "strict" | "none" | undefined;
|
|
245
|
+
/**
|
|
246
|
+
* Cookie domain.
|
|
247
|
+
*/
|
|
248
|
+
domain?: string | undefined;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Cookie payload containing name, value, options, and formatted header.
|
|
253
|
+
*
|
|
254
|
+
* @public
|
|
255
|
+
*/
|
|
256
|
+
export declare interface CookiePayload {
|
|
257
|
+
name: string;
|
|
258
|
+
value: string;
|
|
259
|
+
options: CookieOptions;
|
|
260
|
+
/**
|
|
261
|
+
* Formatted `Set-Cookie` header value string.
|
|
262
|
+
*/
|
|
263
|
+
header: string;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Creates an Express authentication middleware that verifies the session cookie and populates req.sessionInfo.
|
|
268
|
+
*
|
|
269
|
+
* @param lixa - Lixa instance
|
|
270
|
+
* @param options - Optional session cookie name and custom unauthorized handler
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* const requireAuth = createRequireAuthMiddleware(lixa);
|
|
275
|
+
* app.get('/protected', requireAuth, (req, res) => {
|
|
276
|
+
* res.json({ user: req.sessionInfo });
|
|
277
|
+
* });
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* @public
|
|
281
|
+
*/
|
|
282
|
+
export declare function createRequireAuthMiddleware(lixa: Lixa<any>, options?: {
|
|
283
|
+
sessionCookieName?: string;
|
|
284
|
+
unauthorizedHandler?: (req: ExpressLikeRequest, res: ExpressLikeResponse) => void;
|
|
285
|
+
}): ExpressLikeRequestHandler;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Generates a session cookie payload with secure default options.
|
|
289
|
+
*
|
|
290
|
+
* @param sessionId - The session identifier string
|
|
291
|
+
* @param options - Optional overrides for cookie attributes
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```typescript
|
|
295
|
+
* const cookie = createSessionCookie(sessionId);
|
|
296
|
+
* res.setHeader("Set-Cookie", cookie.header);
|
|
297
|
+
* // or with Express:
|
|
298
|
+
* res.cookie(cookie.name, cookie.value, cookie.options);
|
|
299
|
+
* ```
|
|
300
|
+
*
|
|
301
|
+
* @public
|
|
302
|
+
*/
|
|
303
|
+
export declare function createSessionCookie(sessionId: string, options?: CookieOptions): CookiePayload;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Generates an OAuth CSRF state cookie payload for in-flight authorization flows.
|
|
307
|
+
*
|
|
308
|
+
* @param state - The random state string
|
|
309
|
+
* @param options - Optional overrides for cookie attributes
|
|
310
|
+
*
|
|
311
|
+
* @public
|
|
312
|
+
*/
|
|
313
|
+
export declare function createStateCookie(state: string, options?: CookieOptions): CookiePayload;
|
|
314
|
+
|
|
154
315
|
/**
|
|
155
316
|
* Decode JWT ID token to extract user information
|
|
156
317
|
*
|
|
@@ -158,6 +319,30 @@ export declare interface ConnectedResource {
|
|
|
158
319
|
*/
|
|
159
320
|
export declare function decodeIdToken(idToken: string): UserInfo;
|
|
160
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Default session cookie name.
|
|
324
|
+
* @public
|
|
325
|
+
*/
|
|
326
|
+
export declare const DEFAULT_SESSION_COOKIE_NAME = "lixa_session";
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Default session max age in seconds (24 hours).
|
|
330
|
+
* @public
|
|
331
|
+
*/
|
|
332
|
+
export declare const DEFAULT_SESSION_MAX_AGE_SECONDS: number;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Default OAuth state cookie name.
|
|
336
|
+
* @public
|
|
337
|
+
*/
|
|
338
|
+
export declare const DEFAULT_STATE_COOKIE_NAME = "lixa_oauth_state";
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Default OAuth state max age in seconds (5 minutes / 300 seconds).
|
|
342
|
+
* @public
|
|
343
|
+
*/
|
|
344
|
+
export declare const DEFAULT_STATE_MAX_AGE_SECONDS: number;
|
|
345
|
+
|
|
161
346
|
/**
|
|
162
347
|
* Determine OAuth provider from ID token issuer
|
|
163
348
|
*
|
|
@@ -165,6 +350,62 @@ export declare function decodeIdToken(idToken: string): UserInfo;
|
|
|
165
350
|
*/
|
|
166
351
|
export declare function determineProviderFromIssuer(userInfo: UserInfo): string | null;
|
|
167
352
|
|
|
353
|
+
/**
|
|
354
|
+
* Thrown when account linking fails, e.g. when unverified email linking is rejected.
|
|
355
|
+
*
|
|
356
|
+
* @public
|
|
357
|
+
*/
|
|
358
|
+
export declare class EmailNotVerifiedError extends LixaError {
|
|
359
|
+
constructor(email?: string, details?: Record<string, unknown>);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Options for Express authentication helpers.
|
|
364
|
+
* @public
|
|
365
|
+
*/
|
|
366
|
+
export declare interface ExpressAuthHelperOptions {
|
|
367
|
+
sessionCookieName?: string;
|
|
368
|
+
sessionCookieOptions?: CookieOptions;
|
|
369
|
+
stateCookieOptions?: CookieOptions;
|
|
370
|
+
successRedirectUrl?: string;
|
|
371
|
+
errorRedirectUrl?: string;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Express-compatible NextFunction type.
|
|
376
|
+
* @public
|
|
377
|
+
*/
|
|
378
|
+
declare type ExpressLikeNextFunction = (err?: any) => void;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Duck-typed Express request interface for framework-agnostic typing.
|
|
382
|
+
* @public
|
|
383
|
+
*/
|
|
384
|
+
declare interface ExpressLikeRequest {
|
|
385
|
+
cookies?: Record<string, string>;
|
|
386
|
+
sessionInfo?: any;
|
|
387
|
+
sessionId?: string;
|
|
388
|
+
[key: string]: any;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Express-compatible RequestHandler type.
|
|
393
|
+
* @public
|
|
394
|
+
*/
|
|
395
|
+
declare type ExpressLikeRequestHandler = (req: ExpressLikeRequest, res: ExpressLikeResponse, next: ExpressLikeNextFunction) => any;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Duck-typed Express response interface for framework-agnostic typing.
|
|
399
|
+
* @public
|
|
400
|
+
*/
|
|
401
|
+
declare interface ExpressLikeResponse {
|
|
402
|
+
cookie(name: string, value: string, options?: any): any;
|
|
403
|
+
status(code: number): this;
|
|
404
|
+
json(body: any): any;
|
|
405
|
+
redirect?(url: string): any;
|
|
406
|
+
[key: string]: any;
|
|
407
|
+
}
|
|
408
|
+
|
|
168
409
|
/**
|
|
169
410
|
* Extract user info from OAuth token data
|
|
170
411
|
*
|
|
@@ -219,6 +460,33 @@ export declare function extractUserInfo(tokenData: OAuthTokenResponse, providerM
|
|
|
219
460
|
*/
|
|
220
461
|
export declare function fetchUserInfo(accessToken: string, userInfoEndpoint: string): Promise<UserInfo>;
|
|
221
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Thrown when OAuth callback parameters (e.g. authorization code or state) are missing or malformed.
|
|
465
|
+
*
|
|
466
|
+
* @public
|
|
467
|
+
*/
|
|
468
|
+
export declare class InvalidOAuthCallbackError extends LixaError {
|
|
469
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Thrown when a provider configuration is invalid or missing required credentials.
|
|
474
|
+
*
|
|
475
|
+
* @public
|
|
476
|
+
*/
|
|
477
|
+
export declare class InvalidProviderConfigError extends LixaError {
|
|
478
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Thrown when an OAuth state parameter is invalid, missing, or has expired.
|
|
483
|
+
*
|
|
484
|
+
* @public
|
|
485
|
+
*/
|
|
486
|
+
export declare class InvalidStateError extends LixaError {
|
|
487
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
488
|
+
}
|
|
489
|
+
|
|
222
490
|
/**
|
|
223
491
|
* Interface for OAuth 2.0 and OpenID Connect provider implementations.
|
|
224
492
|
*
|
|
@@ -359,6 +627,12 @@ export declare interface IProvider {
|
|
|
359
627
|
authScopes?: string[];
|
|
360
628
|
}
|
|
361
629
|
|
|
630
|
+
/**
|
|
631
|
+
* Checks if the runtime environment is production.
|
|
632
|
+
* @public
|
|
633
|
+
*/
|
|
634
|
+
export declare function isProductionEnvironment(): boolean;
|
|
635
|
+
|
|
362
636
|
/**
|
|
363
637
|
* Represents a linked provider account within a user's session.
|
|
364
638
|
*
|
|
@@ -434,8 +708,11 @@ declare interface LinkedAccount {
|
|
|
434
708
|
export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> = LixaConfig> {
|
|
435
709
|
private static DEFAULT_PROVIDERS;
|
|
436
710
|
private static CONFIGURED_PROVIDERS;
|
|
437
|
-
private
|
|
438
|
-
private
|
|
711
|
+
private localStateHandler;
|
|
712
|
+
private localSessionHandler;
|
|
713
|
+
private localResourceHandler;
|
|
714
|
+
private userResourceStore;
|
|
715
|
+
private refreshMutexes;
|
|
439
716
|
private config;
|
|
440
717
|
private stateHandler;
|
|
441
718
|
private sessionHandler;
|
|
@@ -460,7 +737,7 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
460
737
|
*
|
|
461
738
|
* @param name - The provider name
|
|
462
739
|
* @param config - The provider configuration
|
|
463
|
-
* @throws
|
|
740
|
+
* @throws InvalidProviderConfigError when required fields are missing or invalid
|
|
464
741
|
*/
|
|
465
742
|
private validateProviderConfig;
|
|
466
743
|
/**
|
|
@@ -468,20 +745,16 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
468
745
|
*
|
|
469
746
|
* @param name - The provider name
|
|
470
747
|
* @param provider - The provider implementation
|
|
471
|
-
* @throws
|
|
748
|
+
* @throws InvalidProviderConfigError when required properties are missing
|
|
472
749
|
*/
|
|
473
750
|
private validateProviderImplementation;
|
|
474
751
|
/**
|
|
475
|
-
* Structured
|
|
752
|
+
* Structured logging with standardized format and custom logger support.
|
|
476
753
|
*
|
|
477
|
-
* @param level - Log level (INFO, WARN, ERROR)
|
|
478
|
-
* @param context - Context of the log (Init, Auth, Token, Session, State)
|
|
754
|
+
* @param level - Log level (INFO, WARN, ERROR, DEBUG)
|
|
755
|
+
* @param context - Context of the log (Init, Auth, Token, Session, State, AccountLinking, Resource)
|
|
479
756
|
* @param message - Log message
|
|
480
757
|
* @param data - Optional data to log
|
|
481
|
-
*
|
|
482
|
-
* @remarks
|
|
483
|
-
* Format: [Lixa] [timestamp] [level] [context] message
|
|
484
|
-
* Only logs when debug mode is enabled.
|
|
485
758
|
*/
|
|
486
759
|
private log;
|
|
487
760
|
/**
|
|
@@ -680,7 +953,7 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
680
953
|
*/
|
|
681
954
|
getAuthUrl(provider: ConfiguredProviderKey<TConfig> | string, state?: string): Promise<string>;
|
|
682
955
|
/**
|
|
683
|
-
* Restricts primary authentication scopes strictly to AuthN identity scopes.
|
|
956
|
+
* Restricts primary authentication scopes strictly to AuthN identity scopes unless allowNonAuthScopes is true.
|
|
684
957
|
*/
|
|
685
958
|
private resolveAuthNScopes;
|
|
686
959
|
/**
|
|
@@ -746,14 +1019,6 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
746
1019
|
prompt?: string;
|
|
747
1020
|
extraConfig?: Record<string, string>;
|
|
748
1021
|
}): Promise<string>;
|
|
749
|
-
/**
|
|
750
|
-
* Handles the OAuth callback for a connected resource provider and stores resource tokens on the session.
|
|
751
|
-
*
|
|
752
|
-
* @param params - Object containing sessionId, provider, code, state, and requested scopes
|
|
753
|
-
* @returns Updated Session containing stored resource tokens under session.resources[provider]
|
|
754
|
-
*/
|
|
755
|
-
private static userResourceStore;
|
|
756
|
-
static LOCAL_RESOURCE_HANDLER: ResourceHandler;
|
|
757
1022
|
private getUserKeyFromSession;
|
|
758
1023
|
/**
|
|
759
1024
|
* Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
|
|
@@ -786,11 +1051,16 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
786
1051
|
getConnectedResource(sessionId: string, provider: string): Promise<ConnectedResource | null>;
|
|
787
1052
|
/**
|
|
788
1053
|
* Refreshes a user's resource access token using its refresh token.
|
|
1054
|
+
* Deduplicates concurrent refresh requests via an in-flight promise mutex.
|
|
789
1055
|
*
|
|
790
1056
|
* @param userIdOrEmail - User identifier or email
|
|
791
1057
|
* @param provider - Provider identifier (e.g. 'google', 'github')
|
|
792
1058
|
*/
|
|
793
1059
|
refreshUserResourceToken(userIdOrEmail: string, provider: string, existingResource?: ConnectedResource): Promise<ConnectedResource>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Internal execution of refresh token exchange.
|
|
1062
|
+
*/
|
|
1063
|
+
private executeRefreshUserResourceToken;
|
|
794
1064
|
/**
|
|
795
1065
|
* Refreshes a connected resource access token for an active session.
|
|
796
1066
|
*/
|
|
@@ -803,7 +1073,16 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
803
1073
|
* Disconnects a resource provider from an active session and user account.
|
|
804
1074
|
*/
|
|
805
1075
|
disconnectResource(sessionId: string, provider: string): Promise<boolean>;
|
|
1076
|
+
/**
|
|
1077
|
+
* Retrieves active session details from session storage.
|
|
1078
|
+
*/
|
|
806
1079
|
fetchSessionInfo(sessionId: string): Promise<Session | null>;
|
|
1080
|
+
/**
|
|
1081
|
+
* Deletes a session from session storage (e.g. on logout).
|
|
1082
|
+
*
|
|
1083
|
+
* @param sessionId - Active session identifier
|
|
1084
|
+
*/
|
|
1085
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
807
1086
|
private exchangeCodeForToken;
|
|
808
1087
|
private findProviderByType;
|
|
809
1088
|
}
|
|
@@ -862,8 +1141,50 @@ export declare interface LixaConfig<TProviders extends Record<string, ProviderCo
|
|
|
862
1141
|
* Format: [Lixa] [timestamp] [level] [context] message
|
|
863
1142
|
*/
|
|
864
1143
|
debug?: boolean;
|
|
1144
|
+
/**
|
|
1145
|
+
* Optional custom structured logger implementation.
|
|
1146
|
+
* If provided, all Lixa logs will be routed through this logger.
|
|
1147
|
+
*/
|
|
1148
|
+
logger?: LixaLogger;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* Base error class for all Lixa authentication and authorization errors.
|
|
1153
|
+
*
|
|
1154
|
+
* @public
|
|
1155
|
+
*/
|
|
1156
|
+
export declare class LixaError extends Error {
|
|
1157
|
+
/**
|
|
1158
|
+
* Standard error code string.
|
|
1159
|
+
*/
|
|
1160
|
+
readonly code: string;
|
|
1161
|
+
/**
|
|
1162
|
+
* Additional error context data.
|
|
1163
|
+
*/
|
|
1164
|
+
readonly details: Record<string, unknown> | undefined;
|
|
1165
|
+
constructor(message: string, code?: string, details?: Record<string, unknown>);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/**
|
|
1169
|
+
* Custom logger interface for Lixa.
|
|
1170
|
+
* @public
|
|
1171
|
+
*/
|
|
1172
|
+
export declare interface LixaLogger {
|
|
1173
|
+
log(level: LogLevel, context: LogContext, message: string, data?: Record<string, unknown>): void;
|
|
865
1174
|
}
|
|
866
1175
|
|
|
1176
|
+
/**
|
|
1177
|
+
* Log context for Lixa structured logging.
|
|
1178
|
+
* @public
|
|
1179
|
+
*/
|
|
1180
|
+
export declare type LogContext = "Init" | "Auth" | "Token" | "Session" | "State" | "AccountLinking" | "Resource";
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Log level for Lixa structured logging.
|
|
1184
|
+
* @public
|
|
1185
|
+
*/
|
|
1186
|
+
export declare type LogLevel = "INFO" | "WARN" | "ERROR" | "DEBUG";
|
|
1187
|
+
|
|
867
1188
|
/**
|
|
868
1189
|
* OAuth 2.0 token response structure.
|
|
869
1190
|
* Based on RFC 6749 Section 5.1 and OpenID Connect Core 1.0 Section 3.1.3.3
|
|
@@ -958,6 +1279,12 @@ export declare type ProviderConfig = {
|
|
|
958
1279
|
redirectUri: string;
|
|
959
1280
|
/** Array of OAuth scopes to request */
|
|
960
1281
|
scopes: string[];
|
|
1282
|
+
/**
|
|
1283
|
+
* Set to true to allow non-identity (resource) scopes during primary authentication flow.
|
|
1284
|
+
* By default (false), Lixa restricts primary AuthN scopes to identity scopes to maintain
|
|
1285
|
+
* clean AuthN vs AuthZ separation.
|
|
1286
|
+
*/
|
|
1287
|
+
allowNonAuthScopes?: boolean;
|
|
961
1288
|
/** Additional provider-specific configuration parameters */
|
|
962
1289
|
extraConfig?: Record<string, string>;
|
|
963
1290
|
} & ({
|
|
@@ -986,6 +1313,24 @@ export declare interface ProviderMetadata {
|
|
|
986
1313
|
};
|
|
987
1314
|
}
|
|
988
1315
|
|
|
1316
|
+
/**
|
|
1317
|
+
* Thrown when attempting to use a provider that is not configured in the Lixa instance.
|
|
1318
|
+
*
|
|
1319
|
+
* @public
|
|
1320
|
+
*/
|
|
1321
|
+
export declare class ProviderNotConfiguredError extends LixaError {
|
|
1322
|
+
constructor(provider: string, details?: Record<string, unknown>);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Thrown when a refresh token is missing or token refresh fails for a connected resource.
|
|
1327
|
+
*
|
|
1328
|
+
* @public
|
|
1329
|
+
*/
|
|
1330
|
+
export declare class RefreshTokenError extends LixaError {
|
|
1331
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
989
1334
|
/**
|
|
990
1335
|
* Resource handler configuration.
|
|
991
1336
|
*
|
|
@@ -1048,6 +1393,18 @@ export declare type SafeLixaConfig<TProviders extends Record<string, ProviderCon
|
|
|
1048
1393
|
providers: TProviders;
|
|
1049
1394
|
};
|
|
1050
1395
|
|
|
1396
|
+
/**
|
|
1397
|
+
* Serializes a cookie name, value, and options into a standard `Set-Cookie` header string.
|
|
1398
|
+
*
|
|
1399
|
+
* @param name - Cookie name
|
|
1400
|
+
* @param value - Cookie value
|
|
1401
|
+
* @param options - Cookie attributes
|
|
1402
|
+
* @returns Formatted `Set-Cookie` string
|
|
1403
|
+
*
|
|
1404
|
+
* @public
|
|
1405
|
+
*/
|
|
1406
|
+
export declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
1407
|
+
|
|
1051
1408
|
/**
|
|
1052
1409
|
* Represents a user session after successful OAuth authentication.
|
|
1053
1410
|
*
|
|
@@ -1097,13 +1454,13 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
|
|
|
1097
1454
|
* @remarks
|
|
1098
1455
|
* The SessionHandler manages session generation and storage after successful OAuth authentication.
|
|
1099
1456
|
*
|
|
1100
|
-
* -
|
|
1457
|
+
* - generateSession: Optional. Customizes how OAuth tokens are converted into session data.
|
|
1101
1458
|
* If not provided, uses default implementation (access token as session token).
|
|
1102
1459
|
*
|
|
1103
|
-
* -
|
|
1460
|
+
* - sessionStorage: Optional. Provides custom session storage (save/get/delete operations).
|
|
1104
1461
|
* If not provided, uses in-memory cache (not suitable for production).
|
|
1105
1462
|
*
|
|
1106
|
-
* For production, implement both
|
|
1463
|
+
* For production, implement both generateSession (for user creation/lookup) and sessionStorage
|
|
1107
1464
|
* (for persistent session storage with Redis, database, etc.).
|
|
1108
1465
|
*
|
|
1109
1466
|
* @example
|
|
@@ -1112,7 +1469,7 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
|
|
|
1112
1469
|
* import { SessionHandler, Session, OAuthTokenResponse, ProviderMetadata, extractUserInfo } from '@vunexa/lixa';
|
|
1113
1470
|
*
|
|
1114
1471
|
* const sessionHandler: SessionHandler = {
|
|
1115
|
-
*
|
|
1472
|
+
* generateSession: async (tokenData, providerMetadata) => {
|
|
1116
1473
|
* // Extract user info and create/retrieve user
|
|
1117
1474
|
* const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
|
|
1118
1475
|
* const user = await db.users.upsert({
|
|
@@ -1131,7 +1488,7 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
|
|
|
1131
1488
|
* };
|
|
1132
1489
|
* },
|
|
1133
1490
|
*
|
|
1134
|
-
*
|
|
1491
|
+
* sessionStorage: {
|
|
1135
1492
|
* saveSession: async (sessionId, session, expiresInSeconds) => {
|
|
1136
1493
|
* const expiresAt = new Date(Date.now() + expiresInSeconds * 1000);
|
|
1137
1494
|
* await db.sessions.create({
|
|
@@ -1157,78 +1514,21 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
|
|
|
1157
1514
|
* };
|
|
1158
1515
|
* ```
|
|
1159
1516
|
*
|
|
1160
|
-
* @example
|
|
1161
|
-
* Minimal implementation (uses defaults):
|
|
1162
|
-
* ```typescript
|
|
1163
|
-
* const sessionHandler: SessionHandler = {
|
|
1164
|
-
* storage: {
|
|
1165
|
-
* saveSession: async (sessionId, session, expiresInSeconds) => {
|
|
1166
|
-
* await redis.setex(sessionId, expiresInSeconds, JSON.stringify(session));
|
|
1167
|
-
* },
|
|
1168
|
-
* getSession: async (sessionId) => {
|
|
1169
|
-
* const data = await redis.get(sessionId);
|
|
1170
|
-
* return data ? JSON.parse(data) : null;
|
|
1171
|
-
* },
|
|
1172
|
-
* deleteSession: async (sessionId) => {
|
|
1173
|
-
* await redis.del(sessionId);
|
|
1174
|
-
* }
|
|
1175
|
-
* }
|
|
1176
|
-
* };
|
|
1177
|
-
* ```
|
|
1178
|
-
*
|
|
1179
1517
|
* @public
|
|
1180
1518
|
*/
|
|
1181
1519
|
export declare interface SessionHandler {
|
|
1182
1520
|
/**
|
|
1183
|
-
* Generates session data from OAuth token data.
|
|
1521
|
+
* Generates session data from OAuth token data (camelCase).
|
|
1184
1522
|
*
|
|
1185
1523
|
* @param tokenData - The token data received from the OAuth provider's token endpoint
|
|
1186
1524
|
* @param providerMetadata - Provider metadata including name and endpoints
|
|
1187
1525
|
* @returns A Promise that resolves to session data
|
|
1188
|
-
*
|
|
1189
|
-
* @remarks
|
|
1190
|
-
* This method is responsible for creating session data from OAuth tokens.
|
|
1191
|
-
* It is called after successfully exchanging the authorization code for tokens.
|
|
1192
|
-
*
|
|
1193
|
-
* Token Data:
|
|
1194
|
-
* - access_token: OAuth access token
|
|
1195
|
-
* - refresh_token: OAuth refresh token (optional)
|
|
1196
|
-
* - expires_in: Token expiration time in seconds
|
|
1197
|
-
* - token_type: Token type (usually "Bearer")
|
|
1198
|
-
* - id_token: OpenID Connect ID token (for OIDC providers)
|
|
1199
|
-
* - scope: Granted scopes
|
|
1200
|
-
*
|
|
1201
|
-
* Provider Metadata:
|
|
1202
|
-
* - name: The provider name (e.g., 'google', 'github')
|
|
1203
|
-
* - endpoints: Provider endpoints (authorization, token, userInfo)
|
|
1204
|
-
*
|
|
1205
|
-
* Your implementation should:
|
|
1206
|
-
* 1. Extract user info (using extractUserInfo or decode ID token)
|
|
1207
|
-
* 2. Create or lookup users in your database
|
|
1208
|
-
* 3. Build and return session data with any custom fields
|
|
1209
|
-
*
|
|
1210
|
-
* Note: This method should NOT store the session. Storage is handled by the storage object.
|
|
1211
|
-
*
|
|
1212
|
-
* If not provided, defaults to using the access token as the session token.
|
|
1213
|
-
*
|
|
1214
|
-
* @example
|
|
1215
|
-
* ```typescript
|
|
1216
|
-
* GenerateSession: async (tokenData, providerMetadata) => {
|
|
1217
|
-
* const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
|
|
1218
|
-
* const user = await db.users.upsert({ email: userInfo.email });
|
|
1219
|
-
*
|
|
1220
|
-
* return {
|
|
1221
|
-
* token: tokenData.access_token,
|
|
1222
|
-
* raw: {
|
|
1223
|
-
* ...tokenData,
|
|
1224
|
-
* userId: user.id,
|
|
1225
|
-
* provider: providerMetadata.name
|
|
1226
|
-
* }
|
|
1227
|
-
* };
|
|
1228
|
-
* }
|
|
1229
|
-
* ```
|
|
1230
1526
|
*/
|
|
1231
1527
|
generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
|
|
1528
|
+
/**
|
|
1529
|
+
* Generates session data from OAuth token data (PascalCase alias for backward compatibility).
|
|
1530
|
+
*/
|
|
1531
|
+
GenerateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
|
|
1232
1532
|
/**
|
|
1233
1533
|
* Session storage operations.
|
|
1234
1534
|
*
|
|
@@ -1239,13 +1539,15 @@ export declare interface SessionHandler {
|
|
|
1239
1539
|
* If not provided, uses in-memory cache (not suitable for production).
|
|
1240
1540
|
*/
|
|
1241
1541
|
sessionStorage?: SessionStorage;
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
/**
|
|
1545
|
+
* Thrown when a user session is not found or has expired.
|
|
1546
|
+
*
|
|
1547
|
+
* @public
|
|
1548
|
+
*/
|
|
1549
|
+
export declare class SessionNotFoundError extends LixaError {
|
|
1550
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
1249
1551
|
}
|
|
1250
1552
|
|
|
1251
1553
|
/**
|
|
@@ -1262,7 +1564,7 @@ export declare interface SessionStorage {
|
|
|
1262
1564
|
* Saves a session with expiration.
|
|
1263
1565
|
*
|
|
1264
1566
|
* @param sessionId - Unique session identifier
|
|
1265
|
-
* @param session - Session data from
|
|
1567
|
+
* @param session - Session data from generateSession()
|
|
1266
1568
|
* @param expiresInSeconds - TTL in seconds (typically 86400 for 24 hours)
|
|
1267
1569
|
*/
|
|
1268
1570
|
saveSession<T extends Session>(sessionId: string, session: T, expiresInSeconds: number): Promise<void>;
|
|
@@ -1290,6 +1592,28 @@ export declare interface SessionStorage {
|
|
|
1290
1592
|
} | null>;
|
|
1291
1593
|
}
|
|
1292
1594
|
|
|
1595
|
+
/**
|
|
1596
|
+
* Sets an RFC 6265bis compliant session cookie on an Express response.
|
|
1597
|
+
*
|
|
1598
|
+
* @param res - Express response object
|
|
1599
|
+
* @param sessionId - Unique session ID
|
|
1600
|
+
* @param options - Optional cookie attribute overrides
|
|
1601
|
+
*
|
|
1602
|
+
* @public
|
|
1603
|
+
*/
|
|
1604
|
+
export declare function setSessionCookieOnResponse(res: ExpressLikeResponse, sessionId: string, options?: CookieOptions): void;
|
|
1605
|
+
|
|
1606
|
+
/**
|
|
1607
|
+
* Sets an OAuth CSRF state cookie on an Express response.
|
|
1608
|
+
*
|
|
1609
|
+
* @param res - Express response object
|
|
1610
|
+
* @param state - OAuth state parameter
|
|
1611
|
+
* @param options - Optional cookie attribute overrides
|
|
1612
|
+
*
|
|
1613
|
+
* @public
|
|
1614
|
+
*/
|
|
1615
|
+
export declare function setStateCookieOnResponse(res: ExpressLikeResponse, state: string, options?: CookieOptions): void;
|
|
1616
|
+
|
|
1293
1617
|
/**
|
|
1294
1618
|
* OAuth state data structure.
|
|
1295
1619
|
*
|
|
@@ -1424,10 +1748,20 @@ export declare interface StateHandler {
|
|
|
1424
1748
|
* }
|
|
1425
1749
|
* ```
|
|
1426
1750
|
*/
|
|
1751
|
+
/**
|
|
1752
|
+
* Generates OAuth state parameter and associated data (camelCase).
|
|
1753
|
+
*/
|
|
1427
1754
|
generateState?(provider: string): Promise<{
|
|
1428
1755
|
state: string;
|
|
1429
1756
|
data: StateData;
|
|
1430
1757
|
}>;
|
|
1758
|
+
/**
|
|
1759
|
+
* Generates OAuth state parameter and associated data (PascalCase alias for backward compatibility).
|
|
1760
|
+
*/
|
|
1761
|
+
GenerateState?(provider: string): Promise<{
|
|
1762
|
+
state: string;
|
|
1763
|
+
data: StateData;
|
|
1764
|
+
}>;
|
|
1431
1765
|
/**
|
|
1432
1766
|
* State storage operations.
|
|
1433
1767
|
*
|
|
@@ -1473,6 +1807,16 @@ export declare interface StateStorage {
|
|
|
1473
1807
|
deleteState(state: string): Promise<void>;
|
|
1474
1808
|
}
|
|
1475
1809
|
|
|
1810
|
+
/**
|
|
1811
|
+
* Thrown when exchanging an authorization code for OAuth tokens fails at the provider endpoint.
|
|
1812
|
+
*
|
|
1813
|
+
* @public
|
|
1814
|
+
*/
|
|
1815
|
+
export declare class TokenExchangeError extends LixaError {
|
|
1816
|
+
readonly status: number | undefined;
|
|
1817
|
+
constructor(message: string, status?: number, details?: Record<string, unknown>);
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1476
1820
|
/**
|
|
1477
1821
|
* User information extracted from OAuth provider
|
|
1478
1822
|
*
|