@vunexa/lixa 0.1.4 → 0.1.6-alpha.10

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,41 @@ 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
+ * Generates an expired OAuth state cookie payload to clean up the state cookie after callback.
154
+ *
155
+ * @param options - Optional overrides for cookie attributes
156
+ *
157
+ * @public
158
+ */
159
+ export declare function clearStateCookie(options?: CookieOptions): CookiePayload;
160
+
126
161
  /**
127
162
  * Type representing the keys of configured providers
128
163
  */
@@ -141,6 +176,8 @@ export declare interface ConnectedResource {
141
176
  accessToken: string;
142
177
  /** Optional refresh token for offline resource access */
143
178
  refreshToken?: string | undefined;
179
+ /** Unix timestamp in milliseconds when the resource access token expires */
180
+ expiresAt?: number | undefined;
144
181
  /** Resource scopes granted by the user */
145
182
  scopes: string[];
146
183
  /** Full raw token response from provider */
@@ -149,6 +186,91 @@ export declare interface ConnectedResource {
149
186
  connectedAt: number;
150
187
  }
151
188
 
189
+ /**
190
+ * Sensible default cookie configuration options.
191
+ * Follows RFC 6265bis and OAuth 2.0 security best practices.
192
+ *
193
+ * @public
194
+ */
195
+ export declare interface CookieOptions {
196
+ /**
197
+ * Cookie name.
198
+ * @default 'lixa_session'
199
+ */
200
+ name?: string | undefined;
201
+ /**
202
+ * Cookie path.
203
+ * @default '/'
204
+ */
205
+ path?: string | undefined;
206
+ /**
207
+ * Maximum age of the cookie in seconds.
208
+ */
209
+ maxAge?: number | undefined;
210
+ /**
211
+ * Prevents client-side scripts from accessing the cookie (XSS protection).
212
+ * @default true
213
+ */
214
+ httpOnly?: boolean | undefined;
215
+ /**
216
+ * Ensures the cookie is only transmitted over secure HTTPS connections.
217
+ * @default false in development, true in production
218
+ */
219
+ secure?: boolean | undefined;
220
+ /**
221
+ * Controls whether the cookie is sent with cross-site requests (CSRF protection).
222
+ * @default 'lax'
223
+ */
224
+ sameSite?: "lax" | "strict" | "none" | undefined;
225
+ /**
226
+ * Cookie domain.
227
+ */
228
+ domain?: string | undefined;
229
+ }
230
+
231
+ /**
232
+ * Cookie payload containing name, value, options, and formatted header.
233
+ *
234
+ * @public
235
+ */
236
+ export declare interface CookiePayload {
237
+ name: string;
238
+ value: string;
239
+ options: CookieOptions;
240
+ /**
241
+ * Formatted `Set-Cookie` header value string.
242
+ */
243
+ header: string;
244
+ }
245
+
246
+ /**
247
+ * Generates a session cookie payload with secure default options.
248
+ *
249
+ * @param sessionId - The session identifier string
250
+ * @param options - Optional overrides for cookie attributes
251
+ *
252
+ * @example
253
+ * ```typescript
254
+ * const cookie = createSessionCookie(sessionId);
255
+ * res.setHeader("Set-Cookie", cookie.header);
256
+ * // or with Express:
257
+ * res.cookie(cookie.name, cookie.value, cookie.options);
258
+ * ```
259
+ *
260
+ * @public
261
+ */
262
+ export declare function createSessionCookie(sessionId: string, options?: CookieOptions): CookiePayload;
263
+
264
+ /**
265
+ * Generates an OAuth CSRF state cookie payload for in-flight authorization flows.
266
+ *
267
+ * @param state - The random state string
268
+ * @param options - Optional overrides for cookie attributes
269
+ *
270
+ * @public
271
+ */
272
+ export declare function createStateCookie(state: string, options?: CookieOptions): CookiePayload;
273
+
152
274
  /**
153
275
  * Decode JWT ID token to extract user information
154
276
  *
@@ -156,6 +278,30 @@ export declare interface ConnectedResource {
156
278
  */
157
279
  export declare function decodeIdToken(idToken: string): UserInfo;
158
280
 
281
+ /**
282
+ * Default session cookie name.
283
+ * @public
284
+ */
285
+ export declare const DEFAULT_SESSION_COOKIE_NAME = "lixa_session";
286
+
287
+ /**
288
+ * Default session max age in seconds (24 hours).
289
+ * @public
290
+ */
291
+ export declare const DEFAULT_SESSION_MAX_AGE_SECONDS: number;
292
+
293
+ /**
294
+ * Default OAuth state cookie name.
295
+ * @public
296
+ */
297
+ export declare const DEFAULT_STATE_COOKIE_NAME = "lixa_oauth_state";
298
+
299
+ /**
300
+ * Default OAuth state max age in seconds (5 minutes / 300 seconds).
301
+ * @public
302
+ */
303
+ export declare const DEFAULT_STATE_MAX_AGE_SECONDS: number;
304
+
159
305
  /**
160
306
  * Determine OAuth provider from ID token issuer
161
307
  *
@@ -163,6 +309,15 @@ export declare function decodeIdToken(idToken: string): UserInfo;
163
309
  */
164
310
  export declare function determineProviderFromIssuer(userInfo: UserInfo): string | null;
165
311
 
312
+ /**
313
+ * Thrown when account linking fails, e.g. when unverified email linking is rejected.
314
+ *
315
+ * @public
316
+ */
317
+ export declare class EmailNotVerifiedError extends LixaError {
318
+ constructor(email?: string, details?: Record<string, unknown>);
319
+ }
320
+
166
321
  /**
167
322
  * Extract user info from OAuth token data
168
323
  *
@@ -217,6 +372,33 @@ export declare function extractUserInfo(tokenData: OAuthTokenResponse, providerM
217
372
  */
218
373
  export declare function fetchUserInfo(accessToken: string, userInfoEndpoint: string): Promise<UserInfo>;
219
374
 
375
+ /**
376
+ * Thrown when OAuth callback parameters (e.g. authorization code or state) are missing or malformed.
377
+ *
378
+ * @public
379
+ */
380
+ export declare class InvalidOAuthCallbackError extends LixaError {
381
+ constructor(message: string, details?: Record<string, unknown>);
382
+ }
383
+
384
+ /**
385
+ * Thrown when a provider configuration is invalid or missing required credentials.
386
+ *
387
+ * @public
388
+ */
389
+ export declare class InvalidProviderConfigError extends LixaError {
390
+ constructor(message: string, details?: Record<string, unknown>);
391
+ }
392
+
393
+ /**
394
+ * Thrown when an OAuth state parameter is invalid, missing, or has expired.
395
+ *
396
+ * @public
397
+ */
398
+ export declare class InvalidStateError extends LixaError {
399
+ constructor(message?: string, details?: Record<string, unknown>);
400
+ }
401
+
220
402
  /**
221
403
  * Interface for OAuth 2.0 and OpenID Connect provider implementations.
222
404
  *
@@ -357,6 +539,12 @@ export declare interface IProvider {
357
539
  authScopes?: string[];
358
540
  }
359
541
 
542
+ /**
543
+ * Checks if the runtime environment is production.
544
+ * @public
545
+ */
546
+ export declare function isProductionEnvironment(): boolean;
547
+
360
548
  /**
361
549
  * Represents a linked provider account within a user's session.
362
550
  *
@@ -432,11 +620,15 @@ declare interface LinkedAccount {
432
620
  export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> = LixaConfig> {
433
621
  private static DEFAULT_PROVIDERS;
434
622
  private static CONFIGURED_PROVIDERS;
435
- private static LOCAL_STATE_HANDLER;
436
- private static LOCAL_SESSION_HANDLER;
623
+ private localStateHandler;
624
+ private localSessionHandler;
625
+ private localResourceHandler;
626
+ private userResourceStore;
627
+ private refreshMutexes;
437
628
  private config;
438
629
  private stateHandler;
439
630
  private sessionHandler;
631
+ private resourceHandler;
440
632
  private debug;
441
633
  /**
442
634
  * Creates a new Lixa instance with the provided configuration.
@@ -457,7 +649,7 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
457
649
  *
458
650
  * @param name - The provider name
459
651
  * @param config - The provider configuration
460
- * @throws Error when required fields are missing or invalid
652
+ * @throws InvalidProviderConfigError when required fields are missing or invalid
461
653
  */
462
654
  private validateProviderConfig;
463
655
  /**
@@ -465,20 +657,16 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
465
657
  *
466
658
  * @param name - The provider name
467
659
  * @param provider - The provider implementation
468
- * @throws Error when required properties are missing
660
+ * @throws InvalidProviderConfigError when required properties are missing
469
661
  */
470
662
  private validateProviderImplementation;
471
663
  /**
472
- * Structured debug logging with standardized format.
664
+ * Structured logging with standardized format and custom logger support.
473
665
  *
474
- * @param level - Log level (INFO, WARN, ERROR)
475
- * @param context - Context of the log (Init, Auth, Token, Session, State)
666
+ * @param level - Log level (INFO, WARN, ERROR, DEBUG)
667
+ * @param context - Context of the log (Init, Auth, Token, Session, State, AccountLinking, Resource)
476
668
  * @param message - Log message
477
669
  * @param data - Optional data to log
478
- *
479
- * @remarks
480
- * Format: [Lixa] [timestamp] [level] [context] message
481
- * Only logs when debug mode is enabled.
482
670
  */
483
671
  private log;
484
672
  /**
@@ -677,7 +865,7 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
677
865
  */
678
866
  getAuthUrl(provider: ConfiguredProviderKey<TConfig> | string, state?: string): Promise<string>;
679
867
  /**
680
- * Restricts primary authentication scopes strictly to AuthN identity scopes.
868
+ * Restricts primary authentication scopes strictly to AuthN identity scopes unless allowNonAuthScopes is true.
681
869
  */
682
870
  private resolveAuthNScopes;
683
871
  /**
@@ -743,11 +931,9 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
743
931
  prompt?: string;
744
932
  extraConfig?: Record<string, string>;
745
933
  }): Promise<string>;
934
+ private getUserKeyFromSession;
746
935
  /**
747
- * Handles the OAuth callback for a connected resource provider and stores resource tokens on the session.
748
- *
749
- * @param params - Object containing sessionId, provider, code, state, and requested scopes
750
- * @returns Updated Session containing stored resource tokens under session.resources[provider]
936
+ * Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
751
937
  */
752
938
  handleResourceCallback(params: {
753
939
  sessionId: string;
@@ -757,20 +943,58 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
757
943
  scopes?: string[];
758
944
  }): Promise<Session>;
759
945
  /**
760
- * Retrieves a connected resource provider token for an active session.
946
+ * Retrieves a connected resource for a specific User ID / Email directly (independent of session IDs).
947
+ * Automatically refreshes expired access tokens if a refresh token is present.
948
+ *
949
+ * @param userIdOrEmail - User identifier or email
950
+ * @param provider - Resource provider identifier (e.g. 'github', 'google')
951
+ */
952
+ getUserResource(userIdOrEmail: string, provider: string): Promise<ConnectedResource | null>;
953
+ /**
954
+ * Retrieves all connected resources for a specific User ID / Email.
955
+ */
956
+ getUserResources(userIdOrEmail: string): Promise<Record<string, ConnectedResource>>;
957
+ /**
958
+ * Retrieves a connected resource provider token for an active session, auto-refreshing expired tokens if possible.
761
959
  *
762
960
  * @param sessionId - Active session ID
763
- * @param provider - Provider identifier (e.g. 'github')
961
+ * @param provider - Provider identifier (e.g. 'github', 'google')
764
962
  */
765
963
  getConnectedResource(sessionId: string, provider: string): Promise<ConnectedResource | null>;
766
964
  /**
767
- * Disconnects a resource provider from an active session.
965
+ * Refreshes a user's resource access token using its refresh token.
966
+ * Deduplicates concurrent refresh requests via an in-flight promise mutex.
768
967
  *
769
- * @param sessionId - Active session ID
770
- * @param provider - Provider identifier to disconnect
968
+ * @param userIdOrEmail - User identifier or email
969
+ * @param provider - Provider identifier (e.g. 'google', 'github')
970
+ */
971
+ refreshUserResourceToken(userIdOrEmail: string, provider: string, existingResource?: ConnectedResource): Promise<ConnectedResource>;
972
+ /**
973
+ * Internal execution of refresh token exchange.
974
+ */
975
+ private executeRefreshUserResourceToken;
976
+ /**
977
+ * Refreshes a connected resource access token for an active session.
978
+ */
979
+ refreshResourceToken(sessionId: string, provider: string): Promise<ConnectedResource>;
980
+ /**
981
+ * Disconnects a resource provider for a specific User ID / Email.
982
+ */
983
+ disconnectUserResource(userIdOrEmail: string, provider: string): Promise<boolean>;
984
+ /**
985
+ * Disconnects a resource provider from an active session and user account.
771
986
  */
772
987
  disconnectResource(sessionId: string, provider: string): Promise<boolean>;
988
+ /**
989
+ * Retrieves active session details from session storage.
990
+ */
773
991
  fetchSessionInfo(sessionId: string): Promise<Session | null>;
992
+ /**
993
+ * Deletes a session from session storage (e.g. on logout).
994
+ *
995
+ * @param sessionId - Active session identifier
996
+ */
997
+ deleteSession(sessionId: string): Promise<void>;
774
998
  private exchangeCodeForToken;
775
999
  private findProviderByType;
776
1000
  }
@@ -815,14 +1039,64 @@ export declare interface LixaConfig<TProviders extends Record<string, ProviderCo
815
1039
  * @see {@link SessionHandler}
816
1040
  */
817
1041
  sessionHandler?: SessionHandler;
1042
+ /**
1043
+ * Optional custom resource handler.
1044
+ * Handles storage and management of long-lived third-party resource provider tokens (AuthZ)
1045
+ * bound directly to user accounts (User ID or Email), independent of transient session IDs.
1046
+ *
1047
+ * @see {@link ResourceHandler}
1048
+ */
1049
+ resourceHandler?: ResourceHandler;
818
1050
  /**
819
1051
  * Enable debug logging.
820
1052
  * When enabled, outputs structured logs for initialization, auth flow, and errors.
821
1053
  * Format: [Lixa] [timestamp] [level] [context] message
822
1054
  */
823
1055
  debug?: boolean;
1056
+ /**
1057
+ * Optional custom structured logger implementation.
1058
+ * If provided, all Lixa logs will be routed through this logger.
1059
+ */
1060
+ logger?: LixaLogger;
824
1061
  }
825
1062
 
1063
+ /**
1064
+ * Base error class for all Lixa authentication and authorization errors.
1065
+ *
1066
+ * @public
1067
+ */
1068
+ export declare class LixaError extends Error {
1069
+ /**
1070
+ * Standard error code string.
1071
+ */
1072
+ readonly code: string;
1073
+ /**
1074
+ * Additional error context data.
1075
+ */
1076
+ readonly details: Record<string, unknown> | undefined;
1077
+ constructor(message: string, code?: string, details?: Record<string, unknown>);
1078
+ }
1079
+
1080
+ /**
1081
+ * Custom logger interface for Lixa.
1082
+ * @public
1083
+ */
1084
+ export declare interface LixaLogger {
1085
+ log(level: LogLevel, context: LogContext, message: string, data?: Record<string, unknown>): void;
1086
+ }
1087
+
1088
+ /**
1089
+ * Log context for Lixa structured logging.
1090
+ * @public
1091
+ */
1092
+ export declare type LogContext = "Init" | "Auth" | "Token" | "Session" | "State" | "AccountLinking" | "Resource";
1093
+
1094
+ /**
1095
+ * Log level for Lixa structured logging.
1096
+ * @public
1097
+ */
1098
+ export declare type LogLevel = "INFO" | "WARN" | "ERROR" | "DEBUG";
1099
+
826
1100
  /**
827
1101
  * OAuth 2.0 token response structure.
828
1102
  * Based on RFC 6749 Section 5.1 and OpenID Connect Core 1.0 Section 3.1.3.3
@@ -917,6 +1191,12 @@ export declare type ProviderConfig = {
917
1191
  redirectUri: string;
918
1192
  /** Array of OAuth scopes to request */
919
1193
  scopes: string[];
1194
+ /**
1195
+ * Set to true to allow non-identity (resource) scopes during primary authentication flow.
1196
+ * By default (false), Lixa restricts primary AuthN scopes to identity scopes to maintain
1197
+ * clean AuthN vs AuthZ separation.
1198
+ */
1199
+ allowNonAuthScopes?: boolean;
920
1200
  /** Additional provider-specific configuration parameters */
921
1201
  extraConfig?: Record<string, string>;
922
1202
  } & ({
@@ -945,6 +1225,73 @@ export declare interface ProviderMetadata {
945
1225
  };
946
1226
  }
947
1227
 
1228
+ /**
1229
+ * Thrown when attempting to use a provider that is not configured in the Lixa instance.
1230
+ *
1231
+ * @public
1232
+ */
1233
+ export declare class ProviderNotConfiguredError extends LixaError {
1234
+ constructor(provider: string, details?: Record<string, unknown>);
1235
+ }
1236
+
1237
+ /**
1238
+ * Thrown when a refresh token is missing or token refresh fails for a connected resource.
1239
+ *
1240
+ * @public
1241
+ */
1242
+ export declare class RefreshTokenError extends LixaError {
1243
+ constructor(message: string, details?: Record<string, unknown>);
1244
+ }
1245
+
1246
+ /**
1247
+ * Resource handler configuration.
1248
+ *
1249
+ * @public
1250
+ */
1251
+ export declare interface ResourceHandler {
1252
+ resourceStorage?: ResourceStorage;
1253
+ }
1254
+
1255
+ /**
1256
+ * Resource storage operations interface.
1257
+ *
1258
+ * @remarks
1259
+ * Manages long-lived third-party resource provider tokens (AuthZ) bound to a user account
1260
+ * (User ID or Email), independent of short-lived user sessions.
1261
+ *
1262
+ * @public
1263
+ */
1264
+ export declare interface ResourceStorage {
1265
+ /**
1266
+ * Saves a connected resource token for a user.
1267
+ *
1268
+ * @param userId - Unique user identifier or email
1269
+ * @param provider - Resource provider name (e.g. 'github', 'google')
1270
+ * @param resource - Connected resource details including access & refresh tokens
1271
+ */
1272
+ saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void>;
1273
+ /**
1274
+ * Retrieves a connected resource token for a user.
1275
+ *
1276
+ * @param userId - Unique user identifier or email
1277
+ * @param provider - Resource provider name
1278
+ */
1279
+ getResource(userId: string, provider: string): Promise<ConnectedResource | null>;
1280
+ /**
1281
+ * Retrieves all connected resources for a user.
1282
+ *
1283
+ * @param userId - Unique user identifier or email
1284
+ */
1285
+ getUserResources(userId: string): Promise<Record<string, ConnectedResource>>;
1286
+ /**
1287
+ * Deletes a connected resource token for a user.
1288
+ *
1289
+ * @param userId - Unique user identifier or email
1290
+ * @param provider - Resource provider name
1291
+ */
1292
+ deleteResource(userId: string, provider: string): Promise<void>;
1293
+ }
1294
+
948
1295
  /**
949
1296
  * Helper type to create a configuration with only registered providers.
950
1297
  * Use this with Lixa.createConfig() for type safety.
@@ -958,6 +1305,18 @@ export declare type SafeLixaConfig<TProviders extends Record<string, ProviderCon
958
1305
  providers: TProviders;
959
1306
  };
960
1307
 
1308
+ /**
1309
+ * Serializes a cookie name, value, and options into a standard `Set-Cookie` header string.
1310
+ *
1311
+ * @param name - Cookie name
1312
+ * @param value - Cookie value
1313
+ * @param options - Cookie attributes
1314
+ * @returns Formatted `Set-Cookie` string
1315
+ *
1316
+ * @public
1317
+ */
1318
+ export declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
1319
+
961
1320
  /**
962
1321
  * Represents a user session after successful OAuth authentication.
963
1322
  *
@@ -976,25 +1335,29 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
976
1335
  */
977
1336
  id?: string;
978
1337
  /**
979
- * The primary access token or session token identifier.
1338
+ * Linked identity provider accounts (AuthN) keyed by provider name.
1339
+ * Single source of truth for all authenticated user SSO identities.
980
1340
  */
981
- token: string;
1341
+ accounts?: Record<string, LinkedAccount>;
1342
+ /**
1343
+ * Connected third-party resource provider tokens (AuthZ) keyed by provider name.
1344
+ * Single source of truth for all post-login third-party API permissions.
1345
+ */
1346
+ resources?: Record<string, ConnectedResource>;
982
1347
  /** Unique unified user ID across linked accounts */
983
1348
  userId?: string;
984
1349
  /** Primary user email */
985
1350
  email?: string;
986
- /** Current active auth provider for this session turn */
1351
+ /**
1352
+ * Optional primary access token or custom session token identifier.
1353
+ */
1354
+ token?: string;
1355
+ /** Optional current active auth provider for this session turn */
987
1356
  provider?: string;
988
- /** Linked SSO provider accounts keyed by provider name */
989
- accounts?: Record<string, LinkedAccount>;
990
- /** Connected third-party resource provider tokens keyed by provider name */
991
- resources?: Record<string, ConnectedResource>;
992
1357
  /**
993
- * Raw session data.
994
- * Contains the complete OAuth token response and any additional data
995
- * your SessionStrategy adds (user info, database IDs, etc.).
1358
+ * Optional raw session token response data from provider.
996
1359
  */
997
- raw: TRaw;
1360
+ raw?: TRaw;
998
1361
  }
999
1362
 
1000
1363
  /**
@@ -1003,13 +1366,13 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
1003
1366
  * @remarks
1004
1367
  * The SessionHandler manages session generation and storage after successful OAuth authentication.
1005
1368
  *
1006
- * - GenerateSession: Optional. Customizes how OAuth tokens are converted into session data.
1369
+ * - generateSession: Optional. Customizes how OAuth tokens are converted into session data.
1007
1370
  * If not provided, uses default implementation (access token as session token).
1008
1371
  *
1009
- * - storage: Optional. Provides custom session storage (save/get/delete operations).
1372
+ * - sessionStorage: Optional. Provides custom session storage (save/get/delete operations).
1010
1373
  * If not provided, uses in-memory cache (not suitable for production).
1011
1374
  *
1012
- * For production, implement both GenerateSession (for user creation/lookup) and storage
1375
+ * For production, implement both generateSession (for user creation/lookup) and sessionStorage
1013
1376
  * (for persistent session storage with Redis, database, etc.).
1014
1377
  *
1015
1378
  * @example
@@ -1018,7 +1381,7 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
1018
1381
  * import { SessionHandler, Session, OAuthTokenResponse, ProviderMetadata, extractUserInfo } from '@vunexa/lixa';
1019
1382
  *
1020
1383
  * const sessionHandler: SessionHandler = {
1021
- * GenerateSession: async (tokenData, providerMetadata) => {
1384
+ * generateSession: async (tokenData, providerMetadata) => {
1022
1385
  * // Extract user info and create/retrieve user
1023
1386
  * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
1024
1387
  * const user = await db.users.upsert({
@@ -1037,7 +1400,7 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
1037
1400
  * };
1038
1401
  * },
1039
1402
  *
1040
- * storage: {
1403
+ * sessionStorage: {
1041
1404
  * saveSession: async (sessionId, session, expiresInSeconds) => {
1042
1405
  * const expiresAt = new Date(Date.now() + expiresInSeconds * 1000);
1043
1406
  * await db.sessions.create({
@@ -1063,78 +1426,21 @@ export declare interface Session<TRaw = OAuthTokenResponse> {
1063
1426
  * };
1064
1427
  * ```
1065
1428
  *
1066
- * @example
1067
- * Minimal implementation (uses defaults):
1068
- * ```typescript
1069
- * const sessionHandler: SessionHandler = {
1070
- * storage: {
1071
- * saveSession: async (sessionId, session, expiresInSeconds) => {
1072
- * await redis.setex(sessionId, expiresInSeconds, JSON.stringify(session));
1073
- * },
1074
- * getSession: async (sessionId) => {
1075
- * const data = await redis.get(sessionId);
1076
- * return data ? JSON.parse(data) : null;
1077
- * },
1078
- * deleteSession: async (sessionId) => {
1079
- * await redis.del(sessionId);
1080
- * }
1081
- * }
1082
- * };
1083
- * ```
1084
- *
1085
1429
  * @public
1086
1430
  */
1087
1431
  export declare interface SessionHandler {
1088
1432
  /**
1089
- * Generates session data from OAuth token data.
1433
+ * Generates session data from OAuth token data (camelCase).
1090
1434
  *
1091
1435
  * @param tokenData - The token data received from the OAuth provider's token endpoint
1092
1436
  * @param providerMetadata - Provider metadata including name and endpoints
1093
1437
  * @returns A Promise that resolves to session data
1094
- *
1095
- * @remarks
1096
- * This method is responsible for creating session data from OAuth tokens.
1097
- * It is called after successfully exchanging the authorization code for tokens.
1098
- *
1099
- * Token Data:
1100
- * - access_token: OAuth access token
1101
- * - refresh_token: OAuth refresh token (optional)
1102
- * - expires_in: Token expiration time in seconds
1103
- * - token_type: Token type (usually "Bearer")
1104
- * - id_token: OpenID Connect ID token (for OIDC providers)
1105
- * - scope: Granted scopes
1106
- *
1107
- * Provider Metadata:
1108
- * - name: The provider name (e.g., 'google', 'github')
1109
- * - endpoints: Provider endpoints (authorization, token, userInfo)
1110
- *
1111
- * Your implementation should:
1112
- * 1. Extract user info (using extractUserInfo or decode ID token)
1113
- * 2. Create or lookup users in your database
1114
- * 3. Build and return session data with any custom fields
1115
- *
1116
- * Note: This method should NOT store the session. Storage is handled by the storage object.
1117
- *
1118
- * If not provided, defaults to using the access token as the session token.
1119
- *
1120
- * @example
1121
- * ```typescript
1122
- * GenerateSession: async (tokenData, providerMetadata) => {
1123
- * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
1124
- * const user = await db.users.upsert({ email: userInfo.email });
1125
- *
1126
- * return {
1127
- * token: tokenData.access_token,
1128
- * raw: {
1129
- * ...tokenData,
1130
- * userId: user.id,
1131
- * provider: providerMetadata.name
1132
- * }
1133
- * };
1134
- * }
1135
- * ```
1136
1438
  */
1137
1439
  generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
1440
+ /**
1441
+ * Generates session data from OAuth token data (PascalCase alias for backward compatibility).
1442
+ */
1443
+ GenerateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
1138
1444
  /**
1139
1445
  * Session storage operations.
1140
1446
  *
@@ -1145,13 +1451,15 @@ export declare interface SessionHandler {
1145
1451
  * If not provided, uses in-memory cache (not suitable for production).
1146
1452
  */
1147
1453
  sessionStorage?: SessionStorage;
1148
- /**
1149
- * Optional method to generate session data from OAuth tokens.
1150
- *
1151
- * @remarks
1152
- * If not provided, uses default implementation from LocalSessionHandler.
1153
- */
1154
- generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
1454
+ }
1455
+
1456
+ /**
1457
+ * Thrown when a user session is not found or has expired.
1458
+ *
1459
+ * @public
1460
+ */
1461
+ export declare class SessionNotFoundError extends LixaError {
1462
+ constructor(message?: string, details?: Record<string, unknown>);
1155
1463
  }
1156
1464
 
1157
1465
  /**
@@ -1168,7 +1476,7 @@ export declare interface SessionStorage {
1168
1476
  * Saves a session with expiration.
1169
1477
  *
1170
1478
  * @param sessionId - Unique session identifier
1171
- * @param session - Session data from GenerateSession()
1479
+ * @param session - Session data from generateSession()
1172
1480
  * @param expiresInSeconds - TTL in seconds (typically 86400 for 24 hours)
1173
1481
  */
1174
1482
  saveSession<T extends Session>(sessionId: string, session: T, expiresInSeconds: number): Promise<void>;
@@ -1330,10 +1638,20 @@ export declare interface StateHandler {
1330
1638
  * }
1331
1639
  * ```
1332
1640
  */
1641
+ /**
1642
+ * Generates OAuth state parameter and associated data (camelCase).
1643
+ */
1333
1644
  generateState?(provider: string): Promise<{
1334
1645
  state: string;
1335
1646
  data: StateData;
1336
1647
  }>;
1648
+ /**
1649
+ * Generates OAuth state parameter and associated data (PascalCase alias for backward compatibility).
1650
+ */
1651
+ GenerateState?(provider: string): Promise<{
1652
+ state: string;
1653
+ data: StateData;
1654
+ }>;
1337
1655
  /**
1338
1656
  * State storage operations.
1339
1657
  *
@@ -1379,6 +1697,16 @@ export declare interface StateStorage {
1379
1697
  deleteState(state: string): Promise<void>;
1380
1698
  }
1381
1699
 
1700
+ /**
1701
+ * Thrown when exchanging an authorization code for OAuth tokens fails at the provider endpoint.
1702
+ *
1703
+ * @public
1704
+ */
1705
+ export declare class TokenExchangeError extends LixaError {
1706
+ readonly status: number | undefined;
1707
+ constructor(message: string, status?: number, details?: Record<string, unknown>);
1708
+ }
1709
+
1382
1710
  /**
1383
1711
  * User information extracted from OAuth provider
1384
1712
  *