@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
package/dist/index.d.cts
CHANGED
|
@@ -314,10 +314,20 @@ interface StateHandler {
|
|
|
314
314
|
* }
|
|
315
315
|
* ```
|
|
316
316
|
*/
|
|
317
|
+
/**
|
|
318
|
+
* Generates OAuth state parameter and associated data (camelCase).
|
|
319
|
+
*/
|
|
317
320
|
generateState?(provider: string): Promise<{
|
|
318
321
|
state: string;
|
|
319
322
|
data: StateData;
|
|
320
323
|
}>;
|
|
324
|
+
/**
|
|
325
|
+
* Generates OAuth state parameter and associated data (PascalCase alias for backward compatibility).
|
|
326
|
+
*/
|
|
327
|
+
GenerateState?(provider: string): Promise<{
|
|
328
|
+
state: string;
|
|
329
|
+
data: StateData;
|
|
330
|
+
}>;
|
|
321
331
|
/**
|
|
322
332
|
* State storage operations.
|
|
323
333
|
*
|
|
@@ -343,7 +353,7 @@ interface SessionStorage {
|
|
|
343
353
|
* Saves a session with expiration.
|
|
344
354
|
*
|
|
345
355
|
* @param sessionId - Unique session identifier
|
|
346
|
-
* @param session - Session data from
|
|
356
|
+
* @param session - Session data from generateSession()
|
|
347
357
|
* @param expiresInSeconds - TTL in seconds (typically 86400 for 24 hours)
|
|
348
358
|
*/
|
|
349
359
|
saveSession<T extends Session>(sessionId: string, session: T, expiresInSeconds: number): Promise<void>;
|
|
@@ -423,13 +433,13 @@ interface ResourceHandler {
|
|
|
423
433
|
* @remarks
|
|
424
434
|
* The SessionHandler manages session generation and storage after successful OAuth authentication.
|
|
425
435
|
*
|
|
426
|
-
* -
|
|
436
|
+
* - generateSession: Optional. Customizes how OAuth tokens are converted into session data.
|
|
427
437
|
* If not provided, uses default implementation (access token as session token).
|
|
428
438
|
*
|
|
429
|
-
* -
|
|
439
|
+
* - sessionStorage: Optional. Provides custom session storage (save/get/delete operations).
|
|
430
440
|
* If not provided, uses in-memory cache (not suitable for production).
|
|
431
441
|
*
|
|
432
|
-
* For production, implement both
|
|
442
|
+
* For production, implement both generateSession (for user creation/lookup) and sessionStorage
|
|
433
443
|
* (for persistent session storage with Redis, database, etc.).
|
|
434
444
|
*
|
|
435
445
|
* @example
|
|
@@ -438,7 +448,7 @@ interface ResourceHandler {
|
|
|
438
448
|
* import { SessionHandler, Session, OAuthTokenResponse, ProviderMetadata, extractUserInfo } from '@vunexa/lixa';
|
|
439
449
|
*
|
|
440
450
|
* const sessionHandler: SessionHandler = {
|
|
441
|
-
*
|
|
451
|
+
* generateSession: async (tokenData, providerMetadata) => {
|
|
442
452
|
* // Extract user info and create/retrieve user
|
|
443
453
|
* const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
|
|
444
454
|
* const user = await db.users.upsert({
|
|
@@ -457,7 +467,7 @@ interface ResourceHandler {
|
|
|
457
467
|
* };
|
|
458
468
|
* },
|
|
459
469
|
*
|
|
460
|
-
*
|
|
470
|
+
* sessionStorage: {
|
|
461
471
|
* saveSession: async (sessionId, session, expiresInSeconds) => {
|
|
462
472
|
* const expiresAt = new Date(Date.now() + expiresInSeconds * 1000);
|
|
463
473
|
* await db.sessions.create({
|
|
@@ -483,78 +493,21 @@ interface ResourceHandler {
|
|
|
483
493
|
* };
|
|
484
494
|
* ```
|
|
485
495
|
*
|
|
486
|
-
* @example
|
|
487
|
-
* Minimal implementation (uses defaults):
|
|
488
|
-
* ```typescript
|
|
489
|
-
* const sessionHandler: SessionHandler = {
|
|
490
|
-
* storage: {
|
|
491
|
-
* saveSession: async (sessionId, session, expiresInSeconds) => {
|
|
492
|
-
* await redis.setex(sessionId, expiresInSeconds, JSON.stringify(session));
|
|
493
|
-
* },
|
|
494
|
-
* getSession: async (sessionId) => {
|
|
495
|
-
* const data = await redis.get(sessionId);
|
|
496
|
-
* return data ? JSON.parse(data) : null;
|
|
497
|
-
* },
|
|
498
|
-
* deleteSession: async (sessionId) => {
|
|
499
|
-
* await redis.del(sessionId);
|
|
500
|
-
* }
|
|
501
|
-
* }
|
|
502
|
-
* };
|
|
503
|
-
* ```
|
|
504
|
-
*
|
|
505
496
|
* @public
|
|
506
497
|
*/
|
|
507
498
|
interface SessionHandler {
|
|
508
499
|
/**
|
|
509
|
-
* Generates session data from OAuth token data.
|
|
500
|
+
* Generates session data from OAuth token data (camelCase).
|
|
510
501
|
*
|
|
511
502
|
* @param tokenData - The token data received from the OAuth provider's token endpoint
|
|
512
503
|
* @param providerMetadata - Provider metadata including name and endpoints
|
|
513
504
|
* @returns A Promise that resolves to session data
|
|
514
|
-
*
|
|
515
|
-
* @remarks
|
|
516
|
-
* This method is responsible for creating session data from OAuth tokens.
|
|
517
|
-
* It is called after successfully exchanging the authorization code for tokens.
|
|
518
|
-
*
|
|
519
|
-
* Token Data:
|
|
520
|
-
* - access_token: OAuth access token
|
|
521
|
-
* - refresh_token: OAuth refresh token (optional)
|
|
522
|
-
* - expires_in: Token expiration time in seconds
|
|
523
|
-
* - token_type: Token type (usually "Bearer")
|
|
524
|
-
* - id_token: OpenID Connect ID token (for OIDC providers)
|
|
525
|
-
* - scope: Granted scopes
|
|
526
|
-
*
|
|
527
|
-
* Provider Metadata:
|
|
528
|
-
* - name: The provider name (e.g., 'google', 'github')
|
|
529
|
-
* - endpoints: Provider endpoints (authorization, token, userInfo)
|
|
530
|
-
*
|
|
531
|
-
* Your implementation should:
|
|
532
|
-
* 1. Extract user info (using extractUserInfo or decode ID token)
|
|
533
|
-
* 2. Create or lookup users in your database
|
|
534
|
-
* 3. Build and return session data with any custom fields
|
|
535
|
-
*
|
|
536
|
-
* Note: This method should NOT store the session. Storage is handled by the storage object.
|
|
537
|
-
*
|
|
538
|
-
* If not provided, defaults to using the access token as the session token.
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```typescript
|
|
542
|
-
* GenerateSession: async (tokenData, providerMetadata) => {
|
|
543
|
-
* const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
|
|
544
|
-
* const user = await db.users.upsert({ email: userInfo.email });
|
|
545
|
-
*
|
|
546
|
-
* return {
|
|
547
|
-
* token: tokenData.access_token,
|
|
548
|
-
* raw: {
|
|
549
|
-
* ...tokenData,
|
|
550
|
-
* userId: user.id,
|
|
551
|
-
* provider: providerMetadata.name
|
|
552
|
-
* }
|
|
553
|
-
* };
|
|
554
|
-
* }
|
|
555
|
-
* ```
|
|
556
505
|
*/
|
|
557
506
|
generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
|
|
507
|
+
/**
|
|
508
|
+
* Generates session data from OAuth token data (PascalCase alias for backward compatibility).
|
|
509
|
+
*/
|
|
510
|
+
GenerateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
|
|
558
511
|
/**
|
|
559
512
|
* Session storage operations.
|
|
560
513
|
*
|
|
@@ -565,13 +518,6 @@ interface SessionHandler {
|
|
|
565
518
|
* If not provided, uses in-memory cache (not suitable for production).
|
|
566
519
|
*/
|
|
567
520
|
sessionStorage?: SessionStorage;
|
|
568
|
-
/**
|
|
569
|
-
* Optional method to generate session data from OAuth tokens.
|
|
570
|
-
*
|
|
571
|
-
* @remarks
|
|
572
|
-
* If not provided, uses default implementation from LocalSessionHandler.
|
|
573
|
-
*/
|
|
574
|
-
generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
|
|
575
521
|
}
|
|
576
522
|
|
|
577
523
|
/**
|
|
@@ -759,6 +705,12 @@ type ProviderConfig = {
|
|
|
759
705
|
redirectUri: string;
|
|
760
706
|
/** Array of OAuth scopes to request */
|
|
761
707
|
scopes: string[];
|
|
708
|
+
/**
|
|
709
|
+
* Set to true to allow non-identity (resource) scopes during primary authentication flow.
|
|
710
|
+
* By default (false), Lixa restricts primary AuthN scopes to identity scopes to maintain
|
|
711
|
+
* clean AuthN vs AuthZ separation.
|
|
712
|
+
*/
|
|
713
|
+
allowNonAuthScopes?: boolean;
|
|
762
714
|
/** Additional provider-specific configuration parameters */
|
|
763
715
|
extraConfig?: Record<string, string>;
|
|
764
716
|
} & ({
|
|
@@ -924,6 +876,28 @@ interface LixaConfig<TProviders extends Record<string, ProviderConfig> = Record<
|
|
|
924
876
|
* Format: [Lixa] [timestamp] [level] [context] message
|
|
925
877
|
*/
|
|
926
878
|
debug?: boolean;
|
|
879
|
+
/**
|
|
880
|
+
* Optional custom structured logger implementation.
|
|
881
|
+
* If provided, all Lixa logs will be routed through this logger.
|
|
882
|
+
*/
|
|
883
|
+
logger?: LixaLogger;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Log level for Lixa structured logging.
|
|
887
|
+
* @public
|
|
888
|
+
*/
|
|
889
|
+
type LogLevel = "INFO" | "WARN" | "ERROR" | "DEBUG";
|
|
890
|
+
/**
|
|
891
|
+
* Log context for Lixa structured logging.
|
|
892
|
+
* @public
|
|
893
|
+
*/
|
|
894
|
+
type LogContext = "Init" | "Auth" | "Token" | "Session" | "State" | "AccountLinking" | "Resource";
|
|
895
|
+
/**
|
|
896
|
+
* Custom logger interface for Lixa.
|
|
897
|
+
* @public
|
|
898
|
+
*/
|
|
899
|
+
interface LixaLogger {
|
|
900
|
+
log(level: LogLevel, context: LogContext, message: string, data?: Record<string, unknown>): void;
|
|
927
901
|
}
|
|
928
902
|
/**
|
|
929
903
|
* Helper type to create a configuration with only registered providers.
|
|
@@ -997,8 +971,11 @@ type ConfiguredProviderKey<T extends LixaConfig<Record<string, ProviderConfig>>>
|
|
|
997
971
|
declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> = LixaConfig> {
|
|
998
972
|
private static DEFAULT_PROVIDERS;
|
|
999
973
|
private static CONFIGURED_PROVIDERS;
|
|
1000
|
-
private
|
|
1001
|
-
private
|
|
974
|
+
private localStateHandler;
|
|
975
|
+
private localSessionHandler;
|
|
976
|
+
private localResourceHandler;
|
|
977
|
+
private userResourceStore;
|
|
978
|
+
private refreshMutexes;
|
|
1002
979
|
private config;
|
|
1003
980
|
private stateHandler;
|
|
1004
981
|
private sessionHandler;
|
|
@@ -1023,7 +1000,7 @@ declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> =
|
|
|
1023
1000
|
*
|
|
1024
1001
|
* @param name - The provider name
|
|
1025
1002
|
* @param config - The provider configuration
|
|
1026
|
-
* @throws
|
|
1003
|
+
* @throws InvalidProviderConfigError when required fields are missing or invalid
|
|
1027
1004
|
*/
|
|
1028
1005
|
private validateProviderConfig;
|
|
1029
1006
|
/**
|
|
@@ -1031,20 +1008,16 @@ declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> =
|
|
|
1031
1008
|
*
|
|
1032
1009
|
* @param name - The provider name
|
|
1033
1010
|
* @param provider - The provider implementation
|
|
1034
|
-
* @throws
|
|
1011
|
+
* @throws InvalidProviderConfigError when required properties are missing
|
|
1035
1012
|
*/
|
|
1036
1013
|
private validateProviderImplementation;
|
|
1037
1014
|
/**
|
|
1038
|
-
* Structured
|
|
1015
|
+
* Structured logging with standardized format and custom logger support.
|
|
1039
1016
|
*
|
|
1040
|
-
* @param level - Log level (INFO, WARN, ERROR)
|
|
1041
|
-
* @param context - Context of the log (Init, Auth, Token, Session, State)
|
|
1017
|
+
* @param level - Log level (INFO, WARN, ERROR, DEBUG)
|
|
1018
|
+
* @param context - Context of the log (Init, Auth, Token, Session, State, AccountLinking, Resource)
|
|
1042
1019
|
* @param message - Log message
|
|
1043
1020
|
* @param data - Optional data to log
|
|
1044
|
-
*
|
|
1045
|
-
* @remarks
|
|
1046
|
-
* Format: [Lixa] [timestamp] [level] [context] message
|
|
1047
|
-
* Only logs when debug mode is enabled.
|
|
1048
1021
|
*/
|
|
1049
1022
|
private log;
|
|
1050
1023
|
/**
|
|
@@ -1243,7 +1216,7 @@ declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> =
|
|
|
1243
1216
|
*/
|
|
1244
1217
|
getAuthUrl(provider: ConfiguredProviderKey<TConfig> | string, state?: string): Promise<string>;
|
|
1245
1218
|
/**
|
|
1246
|
-
* Restricts primary authentication scopes strictly to AuthN identity scopes.
|
|
1219
|
+
* Restricts primary authentication scopes strictly to AuthN identity scopes unless allowNonAuthScopes is true.
|
|
1247
1220
|
*/
|
|
1248
1221
|
private resolveAuthNScopes;
|
|
1249
1222
|
/**
|
|
@@ -1309,14 +1282,6 @@ declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> =
|
|
|
1309
1282
|
prompt?: string;
|
|
1310
1283
|
extraConfig?: Record<string, string>;
|
|
1311
1284
|
}): Promise<string>;
|
|
1312
|
-
/**
|
|
1313
|
-
* Handles the OAuth callback for a connected resource provider and stores resource tokens on the session.
|
|
1314
|
-
*
|
|
1315
|
-
* @param params - Object containing sessionId, provider, code, state, and requested scopes
|
|
1316
|
-
* @returns Updated Session containing stored resource tokens under session.resources[provider]
|
|
1317
|
-
*/
|
|
1318
|
-
private static userResourceStore;
|
|
1319
|
-
static LOCAL_RESOURCE_HANDLER: ResourceHandler;
|
|
1320
1285
|
private getUserKeyFromSession;
|
|
1321
1286
|
/**
|
|
1322
1287
|
* Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
|
|
@@ -1349,11 +1314,16 @@ declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> =
|
|
|
1349
1314
|
getConnectedResource(sessionId: string, provider: string): Promise<ConnectedResource | null>;
|
|
1350
1315
|
/**
|
|
1351
1316
|
* Refreshes a user's resource access token using its refresh token.
|
|
1317
|
+
* Deduplicates concurrent refresh requests via an in-flight promise mutex.
|
|
1352
1318
|
*
|
|
1353
1319
|
* @param userIdOrEmail - User identifier or email
|
|
1354
1320
|
* @param provider - Provider identifier (e.g. 'google', 'github')
|
|
1355
1321
|
*/
|
|
1356
1322
|
refreshUserResourceToken(userIdOrEmail: string, provider: string, existingResource?: ConnectedResource): Promise<ConnectedResource>;
|
|
1323
|
+
/**
|
|
1324
|
+
* Internal execution of refresh token exchange.
|
|
1325
|
+
*/
|
|
1326
|
+
private executeRefreshUserResourceToken;
|
|
1357
1327
|
/**
|
|
1358
1328
|
* Refreshes a connected resource access token for an active session.
|
|
1359
1329
|
*/
|
|
@@ -1366,7 +1336,16 @@ declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> =
|
|
|
1366
1336
|
* Disconnects a resource provider from an active session and user account.
|
|
1367
1337
|
*/
|
|
1368
1338
|
disconnectResource(sessionId: string, provider: string): Promise<boolean>;
|
|
1339
|
+
/**
|
|
1340
|
+
* Retrieves active session details from session storage.
|
|
1341
|
+
*/
|
|
1369
1342
|
fetchSessionInfo(sessionId: string): Promise<Session | null>;
|
|
1343
|
+
/**
|
|
1344
|
+
* Deletes a session from session storage (e.g. on logout).
|
|
1345
|
+
*
|
|
1346
|
+
* @param sessionId - Active session identifier
|
|
1347
|
+
*/
|
|
1348
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
1370
1349
|
private exchangeCodeForToken;
|
|
1371
1350
|
private findProviderByType;
|
|
1372
1351
|
}
|
|
@@ -1452,4 +1431,337 @@ declare function extractUserInfo(tokenData: OAuthTokenResponse, providerMetadata
|
|
|
1452
1431
|
userInfo: UserInfo;
|
|
1453
1432
|
}>;
|
|
1454
1433
|
|
|
1455
|
-
|
|
1434
|
+
/**
|
|
1435
|
+
* Base error class for all Lixa authentication and authorization errors.
|
|
1436
|
+
*
|
|
1437
|
+
* @public
|
|
1438
|
+
*/
|
|
1439
|
+
declare class LixaError extends Error {
|
|
1440
|
+
/**
|
|
1441
|
+
* Standard error code string.
|
|
1442
|
+
*/
|
|
1443
|
+
readonly code: string;
|
|
1444
|
+
/**
|
|
1445
|
+
* Additional error context data.
|
|
1446
|
+
*/
|
|
1447
|
+
readonly details: Record<string, unknown> | undefined;
|
|
1448
|
+
constructor(message: string, code?: string, details?: Record<string, unknown>);
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Thrown when an OAuth state parameter is invalid, missing, or has expired.
|
|
1452
|
+
*
|
|
1453
|
+
* @public
|
|
1454
|
+
*/
|
|
1455
|
+
declare class InvalidStateError extends LixaError {
|
|
1456
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Thrown when attempting to use a provider that is not configured in the Lixa instance.
|
|
1460
|
+
*
|
|
1461
|
+
* @public
|
|
1462
|
+
*/
|
|
1463
|
+
declare class ProviderNotConfiguredError extends LixaError {
|
|
1464
|
+
constructor(provider: string, details?: Record<string, unknown>);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Thrown when a provider configuration is invalid or missing required credentials.
|
|
1468
|
+
*
|
|
1469
|
+
* @public
|
|
1470
|
+
*/
|
|
1471
|
+
declare class InvalidProviderConfigError extends LixaError {
|
|
1472
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Thrown when OAuth callback parameters (e.g. authorization code or state) are missing or malformed.
|
|
1476
|
+
*
|
|
1477
|
+
* @public
|
|
1478
|
+
*/
|
|
1479
|
+
declare class InvalidOAuthCallbackError extends LixaError {
|
|
1480
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Thrown when exchanging an authorization code for OAuth tokens fails at the provider endpoint.
|
|
1484
|
+
*
|
|
1485
|
+
* @public
|
|
1486
|
+
*/
|
|
1487
|
+
declare class TokenExchangeError extends LixaError {
|
|
1488
|
+
readonly status: number | undefined;
|
|
1489
|
+
constructor(message: string, status?: number, details?: Record<string, unknown>);
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Thrown when a user session is not found or has expired.
|
|
1493
|
+
*
|
|
1494
|
+
* @public
|
|
1495
|
+
*/
|
|
1496
|
+
declare class SessionNotFoundError extends LixaError {
|
|
1497
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Thrown when account linking fails, e.g. when unverified email linking is rejected.
|
|
1501
|
+
*
|
|
1502
|
+
* @public
|
|
1503
|
+
*/
|
|
1504
|
+
declare class EmailNotVerifiedError extends LixaError {
|
|
1505
|
+
constructor(email?: string, details?: Record<string, unknown>);
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* Thrown when unlinking an account violates security constraints (e.g. unlinking the only login provider).
|
|
1509
|
+
*
|
|
1510
|
+
* @public
|
|
1511
|
+
*/
|
|
1512
|
+
declare class AccountUnlinkError extends LixaError {
|
|
1513
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Thrown when a refresh token is missing or token refresh fails for a connected resource.
|
|
1517
|
+
*
|
|
1518
|
+
* @public
|
|
1519
|
+
*/
|
|
1520
|
+
declare class RefreshTokenError extends LixaError {
|
|
1521
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
/**
|
|
1525
|
+
* Sensible default cookie configuration options.
|
|
1526
|
+
* Follows RFC 6265bis and OAuth 2.0 security best practices.
|
|
1527
|
+
*
|
|
1528
|
+
* @public
|
|
1529
|
+
*/
|
|
1530
|
+
interface CookieOptions {
|
|
1531
|
+
/**
|
|
1532
|
+
* Cookie name.
|
|
1533
|
+
* @default 'lixa_session'
|
|
1534
|
+
*/
|
|
1535
|
+
name?: string | undefined;
|
|
1536
|
+
/**
|
|
1537
|
+
* Cookie path.
|
|
1538
|
+
* @default '/'
|
|
1539
|
+
*/
|
|
1540
|
+
path?: string | undefined;
|
|
1541
|
+
/**
|
|
1542
|
+
* Maximum age of the cookie in seconds.
|
|
1543
|
+
*/
|
|
1544
|
+
maxAge?: number | undefined;
|
|
1545
|
+
/**
|
|
1546
|
+
* Prevents client-side scripts from accessing the cookie (XSS protection).
|
|
1547
|
+
* @default true
|
|
1548
|
+
*/
|
|
1549
|
+
httpOnly?: boolean | undefined;
|
|
1550
|
+
/**
|
|
1551
|
+
* Ensures the cookie is only transmitted over secure HTTPS connections.
|
|
1552
|
+
* @default false in development, true in production
|
|
1553
|
+
*/
|
|
1554
|
+
secure?: boolean | undefined;
|
|
1555
|
+
/**
|
|
1556
|
+
* Controls whether the cookie is sent with cross-site requests (CSRF protection).
|
|
1557
|
+
* @default 'lax'
|
|
1558
|
+
*/
|
|
1559
|
+
sameSite?: "lax" | "strict" | "none" | undefined;
|
|
1560
|
+
/**
|
|
1561
|
+
* Cookie domain.
|
|
1562
|
+
*/
|
|
1563
|
+
domain?: string | undefined;
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Cookie payload containing name, value, options, and formatted header.
|
|
1567
|
+
*
|
|
1568
|
+
* @public
|
|
1569
|
+
*/
|
|
1570
|
+
interface CookiePayload {
|
|
1571
|
+
name: string;
|
|
1572
|
+
value: string;
|
|
1573
|
+
options: CookieOptions;
|
|
1574
|
+
/**
|
|
1575
|
+
* Formatted `Set-Cookie` header value string.
|
|
1576
|
+
*/
|
|
1577
|
+
header: string;
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Default session cookie name.
|
|
1581
|
+
* @public
|
|
1582
|
+
*/
|
|
1583
|
+
declare const DEFAULT_SESSION_COOKIE_NAME = "lixa_session";
|
|
1584
|
+
/**
|
|
1585
|
+
* Default OAuth state cookie name.
|
|
1586
|
+
* @public
|
|
1587
|
+
*/
|
|
1588
|
+
declare const DEFAULT_STATE_COOKIE_NAME = "lixa_oauth_state";
|
|
1589
|
+
/**
|
|
1590
|
+
* Default session max age in seconds (24 hours).
|
|
1591
|
+
* @public
|
|
1592
|
+
*/
|
|
1593
|
+
declare const DEFAULT_SESSION_MAX_AGE_SECONDS: number;
|
|
1594
|
+
/**
|
|
1595
|
+
* Default OAuth state max age in seconds (5 minutes / 300 seconds).
|
|
1596
|
+
* @public
|
|
1597
|
+
*/
|
|
1598
|
+
declare const DEFAULT_STATE_MAX_AGE_SECONDS: number;
|
|
1599
|
+
/**
|
|
1600
|
+
* Checks if the runtime environment is production.
|
|
1601
|
+
* @public
|
|
1602
|
+
*/
|
|
1603
|
+
declare function isProductionEnvironment(): boolean;
|
|
1604
|
+
/**
|
|
1605
|
+
* Serializes a cookie name, value, and options into a standard `Set-Cookie` header string.
|
|
1606
|
+
*
|
|
1607
|
+
* @param name - Cookie name
|
|
1608
|
+
* @param value - Cookie value
|
|
1609
|
+
* @param options - Cookie attributes
|
|
1610
|
+
* @returns Formatted `Set-Cookie` string
|
|
1611
|
+
*
|
|
1612
|
+
* @public
|
|
1613
|
+
*/
|
|
1614
|
+
declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
1615
|
+
/**
|
|
1616
|
+
* Generates a session cookie payload with secure default options.
|
|
1617
|
+
*
|
|
1618
|
+
* @param sessionId - The session identifier string
|
|
1619
|
+
* @param options - Optional overrides for cookie attributes
|
|
1620
|
+
*
|
|
1621
|
+
* @example
|
|
1622
|
+
* ```typescript
|
|
1623
|
+
* const cookie = createSessionCookie(sessionId);
|
|
1624
|
+
* res.setHeader("Set-Cookie", cookie.header);
|
|
1625
|
+
* // or with Express:
|
|
1626
|
+
* res.cookie(cookie.name, cookie.value, cookie.options);
|
|
1627
|
+
* ```
|
|
1628
|
+
*
|
|
1629
|
+
* @public
|
|
1630
|
+
*/
|
|
1631
|
+
declare function createSessionCookie(sessionId: string, options?: CookieOptions): CookiePayload;
|
|
1632
|
+
/**
|
|
1633
|
+
* Generates an expired session cookie payload to clear the session on logout.
|
|
1634
|
+
*
|
|
1635
|
+
* @param options - Optional overrides for cookie name or attributes
|
|
1636
|
+
*
|
|
1637
|
+
* @example
|
|
1638
|
+
* ```typescript
|
|
1639
|
+
* const cookie = clearSessionCookie();
|
|
1640
|
+
* res.setHeader("Set-Cookie", cookie.header);
|
|
1641
|
+
* // or with Express:
|
|
1642
|
+
* res.clearCookie(cookie.name, cookie.options);
|
|
1643
|
+
* ```
|
|
1644
|
+
*
|
|
1645
|
+
* @public
|
|
1646
|
+
*/
|
|
1647
|
+
declare function clearSessionCookie(options?: CookieOptions): CookiePayload;
|
|
1648
|
+
/**
|
|
1649
|
+
* Generates an OAuth CSRF state cookie payload for in-flight authorization flows.
|
|
1650
|
+
*
|
|
1651
|
+
* @param state - The random state string
|
|
1652
|
+
* @param options - Optional overrides for cookie attributes
|
|
1653
|
+
*
|
|
1654
|
+
* @public
|
|
1655
|
+
*/
|
|
1656
|
+
declare function createStateCookie(state: string, options?: CookieOptions): CookiePayload;
|
|
1657
|
+
/**
|
|
1658
|
+
* Generates an expired OAuth state cookie payload to clean up the state cookie after callback.
|
|
1659
|
+
*
|
|
1660
|
+
* @param options - Optional overrides for cookie attributes
|
|
1661
|
+
*
|
|
1662
|
+
* @public
|
|
1663
|
+
*/
|
|
1664
|
+
declare function clearStateCookie(options?: CookieOptions): CookiePayload;
|
|
1665
|
+
|
|
1666
|
+
/**
|
|
1667
|
+
* Duck-typed Express request interface for framework-agnostic typing.
|
|
1668
|
+
* @public
|
|
1669
|
+
*/
|
|
1670
|
+
interface ExpressLikeRequest {
|
|
1671
|
+
cookies?: Record<string, string>;
|
|
1672
|
+
sessionInfo?: any;
|
|
1673
|
+
sessionId?: string;
|
|
1674
|
+
[key: string]: any;
|
|
1675
|
+
}
|
|
1676
|
+
/**
|
|
1677
|
+
* Duck-typed Express response interface for framework-agnostic typing.
|
|
1678
|
+
* @public
|
|
1679
|
+
*/
|
|
1680
|
+
interface ExpressLikeResponse {
|
|
1681
|
+
cookie(name: string, value: string, options?: any): any;
|
|
1682
|
+
status(code: number): this;
|
|
1683
|
+
json(body: any): any;
|
|
1684
|
+
redirect?(url: string): any;
|
|
1685
|
+
[key: string]: any;
|
|
1686
|
+
}
|
|
1687
|
+
/**
|
|
1688
|
+
* Express-compatible NextFunction type.
|
|
1689
|
+
* @public
|
|
1690
|
+
*/
|
|
1691
|
+
type ExpressLikeNextFunction = (err?: any) => void;
|
|
1692
|
+
/**
|
|
1693
|
+
* Express-compatible RequestHandler type.
|
|
1694
|
+
* @public
|
|
1695
|
+
*/
|
|
1696
|
+
type ExpressLikeRequestHandler = (req: ExpressLikeRequest, res: ExpressLikeResponse, next: ExpressLikeNextFunction) => any;
|
|
1697
|
+
/**
|
|
1698
|
+
* Options for Express authentication helpers.
|
|
1699
|
+
* @public
|
|
1700
|
+
*/
|
|
1701
|
+
interface ExpressAuthHelperOptions {
|
|
1702
|
+
sessionCookieName?: string;
|
|
1703
|
+
sessionCookieOptions?: CookieOptions;
|
|
1704
|
+
stateCookieOptions?: CookieOptions;
|
|
1705
|
+
successRedirectUrl?: string;
|
|
1706
|
+
errorRedirectUrl?: string;
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* Sets an RFC 6265bis compliant session cookie on an Express response.
|
|
1710
|
+
*
|
|
1711
|
+
* @param res - Express response object
|
|
1712
|
+
* @param sessionId - Unique session ID
|
|
1713
|
+
* @param options - Optional cookie attribute overrides
|
|
1714
|
+
*
|
|
1715
|
+
* @public
|
|
1716
|
+
*/
|
|
1717
|
+
declare function setSessionCookieOnResponse(res: ExpressLikeResponse, sessionId: string, options?: CookieOptions): void;
|
|
1718
|
+
/**
|
|
1719
|
+
* Clears the session cookie on an Express response.
|
|
1720
|
+
*
|
|
1721
|
+
* @param res - Express response object
|
|
1722
|
+
* @param options - Optional cookie attribute overrides
|
|
1723
|
+
*
|
|
1724
|
+
* @public
|
|
1725
|
+
*/
|
|
1726
|
+
declare function clearSessionCookieOnResponse(res: ExpressLikeResponse, options?: CookieOptions): void;
|
|
1727
|
+
/**
|
|
1728
|
+
* Sets an OAuth CSRF state cookie on an Express response.
|
|
1729
|
+
*
|
|
1730
|
+
* @param res - Express response object
|
|
1731
|
+
* @param state - OAuth state parameter
|
|
1732
|
+
* @param options - Optional cookie attribute overrides
|
|
1733
|
+
*
|
|
1734
|
+
* @public
|
|
1735
|
+
*/
|
|
1736
|
+
declare function setStateCookieOnResponse(res: ExpressLikeResponse, state: string, options?: CookieOptions): void;
|
|
1737
|
+
/**
|
|
1738
|
+
* Clears the OAuth CSRF state cookie on an Express response.
|
|
1739
|
+
*
|
|
1740
|
+
* @param res - Express response object
|
|
1741
|
+
* @param options - Optional cookie attribute overrides
|
|
1742
|
+
*
|
|
1743
|
+
* @public
|
|
1744
|
+
*/
|
|
1745
|
+
declare function clearStateCookieOnResponse(res: ExpressLikeResponse, options?: CookieOptions): void;
|
|
1746
|
+
/**
|
|
1747
|
+
* Creates an Express authentication middleware that verifies the session cookie and populates req.sessionInfo.
|
|
1748
|
+
*
|
|
1749
|
+
* @param lixa - Lixa instance
|
|
1750
|
+
* @param options - Optional session cookie name and custom unauthorized handler
|
|
1751
|
+
*
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```typescript
|
|
1754
|
+
* const requireAuth = createRequireAuthMiddleware(lixa);
|
|
1755
|
+
* app.get('/protected', requireAuth, (req, res) => {
|
|
1756
|
+
* res.json({ user: req.sessionInfo });
|
|
1757
|
+
* });
|
|
1758
|
+
* ```
|
|
1759
|
+
*
|
|
1760
|
+
* @public
|
|
1761
|
+
*/
|
|
1762
|
+
declare function createRequireAuthMiddleware(lixa: Lixa<any>, options?: {
|
|
1763
|
+
sessionCookieName?: string;
|
|
1764
|
+
unauthorizedHandler?: (req: ExpressLikeRequest, res: ExpressLikeResponse) => void;
|
|
1765
|
+
}): ExpressLikeRequestHandler;
|
|
1766
|
+
|
|
1767
|
+
export { type AccountLinkingConfig, type AccountLinkingMode, AccountLinkingStrategy, AccountUnlinkError, type ConnectedResource, type CookieOptions, type CookiePayload, DEFAULT_SESSION_COOKIE_NAME, DEFAULT_SESSION_MAX_AGE_SECONDS, DEFAULT_STATE_COOKIE_NAME, DEFAULT_STATE_MAX_AGE_SECONDS, EmailNotVerifiedError, type ExpressAuthHelperOptions, type IProvider, InvalidOAuthCallbackError, InvalidProviderConfigError, InvalidStateError, Lixa, type LixaConfig, LixaError, type LixaLogger, type LogContext, type LogLevel, type OAuthTokenResponse, type ProviderConfig, type ProviderMetadata, ProviderNotConfiguredError, RefreshTokenError, type ResourceHandler, type ResourceStorage, type SafeLixaConfig, type Session, type SessionHandler, SessionNotFoundError, type SessionStorage, type StateData, type StateHandler, type StateStorage, TokenExchangeError, type UserInfo, clearSessionCookie, clearSessionCookieOnResponse, clearStateCookie, clearStateCookieOnResponse, createRequireAuthMiddleware, createSessionCookie, createStateCookie, decodeIdToken, determineProviderFromIssuer, extractUserInfo, fetchUserInfo, isProductionEnvironment, serializeCookie, setSessionCookieOnResponse, setStateCookieOnResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
* @packageDocumentation
|
|
17
17
|
*/
|
|
18
18
|
export { Lixa } from "./lixa";
|
|
19
|
-
export { type ProviderConfig, type LixaConfig, type SafeLixaConfig, type IProvider, type Session, type ConnectedResource, type ProviderMetadata, type OAuthTokenResponse, type StateHandler, type StateStorage, type SessionHandler, type SessionStorage, type ResourceHandler, type ResourceStorage, type StateData, AccountLinkingStrategy, type AccountLinkingMode, type AccountLinkingConfig, } from "./types";
|
|
19
|
+
export { type ProviderConfig, type LixaConfig, type SafeLixaConfig, type IProvider, type Session, type ConnectedResource, type ProviderMetadata, type OAuthTokenResponse, type StateHandler, type StateStorage, type SessionHandler, type SessionStorage, type ResourceHandler, type ResourceStorage, type StateData, AccountLinkingStrategy, type AccountLinkingMode, type AccountLinkingConfig, type LogLevel, type LogContext, type LixaLogger, } from "./types";
|
|
20
20
|
export { type UserInfo, extractUserInfo, decodeIdToken, fetchUserInfo, determineProviderFromIssuer, } from "./utils/user-info";
|
|
21
|
+
export { LixaError, InvalidStateError, ProviderNotConfiguredError, InvalidProviderConfigError, InvalidOAuthCallbackError, TokenExchangeError, SessionNotFoundError, EmailNotVerifiedError, AccountUnlinkError, RefreshTokenError, } from "./errors";
|
|
22
|
+
export { type CookieOptions, type CookiePayload, DEFAULT_SESSION_COOKIE_NAME, DEFAULT_STATE_COOKIE_NAME, DEFAULT_SESSION_MAX_AGE_SECONDS, DEFAULT_STATE_MAX_AGE_SECONDS, isProductionEnvironment, serializeCookie, createSessionCookie, clearSessionCookie, createStateCookie, clearStateCookie, } from "./utils/cookies";
|
|
23
|
+
export { type ExpressAuthHelperOptions, setSessionCookieOnResponse, clearSessionCookieOnResponse, setStateCookieOnResponse, clearStateCookieOnResponse, createRequireAuthMiddleware, } from "./express";
|
|
21
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,KAAK,QAAQ,EACb,eAAe,EACf,aAAa,EACb,aAAa,EACb,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,2BAA2B,EAC3B,yBAAyB,EACzB,+BAA+B,EAC/B,6BAA6B,EAC7B,uBAAuB,EACvB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,wBAAwB,EAC7B,0BAA0B,EAC1B,4BAA4B,EAC5B,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,WAAW,CAAC"}
|