@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.
@@ -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 static LOCAL_STATE_HANDLER;
438
- private static LOCAL_SESSION_HANDLER;
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 Error when required fields are missing or invalid
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 Error when required properties are missing
748
+ * @throws InvalidProviderConfigError when required properties are missing
472
749
  */
473
750
  private validateProviderImplementation;
474
751
  /**
475
- * Structured debug logging with standardized format.
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
- * - GenerateSession: Optional. Customizes how OAuth tokens are converted into session data.
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
- * - storage: Optional. Provides custom session storage (save/get/delete operations).
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 GenerateSession (for user creation/lookup) and storage
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
- * GenerateSession: async (tokenData, providerMetadata) => {
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
- * storage: {
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
- * Optional method to generate session data from OAuth tokens.
1244
- *
1245
- * @remarks
1246
- * If not provided, uses default implementation from LocalSessionHandler.
1247
- */
1248
- generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
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 GenerateSession()
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
  *