@vunexa/lixa 0.1.6-alpha.14 → 0.1.6-alpha.16

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/dist/index.d.cts CHANGED
@@ -58,10 +58,16 @@ interface LinkedAccount {
58
58
  providerUserId?: string | undefined;
59
59
  /** User email for this provider */
60
60
  email?: string | undefined;
61
- /** OAuth access token for this provider */
62
- accessToken: string;
63
- /** Full raw token response from provider */
64
- raw: OAuthTokenResponse;
61
+ /**
62
+ * Optional OAuth access token for this provider.
63
+ * @deprecated Authentication tokens belong strictly to session.token / session.raw for that session alone. Resource tokens belong in ConnectedResource / user_resources.
64
+ */
65
+ accessToken?: string | undefined;
66
+ /**
67
+ * Optional raw token response from provider.
68
+ * @deprecated Authentication tokens belong strictly to session.token / session.raw for that session alone. Resource tokens belong in ConnectedResource / user_resources.
69
+ */
70
+ raw?: OAuthTokenResponse | undefined;
65
71
  /** Unix timestamp in milliseconds when account was linked */
66
72
  linkedAt: number;
67
73
  }
@@ -437,6 +443,11 @@ interface AccountStorage {
437
443
  getAccount(userId: string, provider: string): Promise<LinkedAccount | null>;
438
444
  getUserAccounts(userId: string): Promise<Record<string, LinkedAccount>>;
439
445
  deleteAccount(userId: string, provider: string): Promise<void>;
446
+ findAccountsByEmail?(email: string): Promise<Array<{
447
+ userId: string;
448
+ provider: string;
449
+ account: LinkedAccount;
450
+ }>>;
440
451
  }
441
452
  /**
442
453
  * Account handler configuration.
@@ -745,6 +756,8 @@ interface IdentityAuthResult {
745
756
  * @public
746
757
  */
747
758
  interface ForgotPasswordParams {
759
+ /** Target identity provider name when using CompositeIdentityProvider */
760
+ provider?: string | undefined;
748
761
  /** Username or email of the account requesting a password reset */
749
762
  identifier: string;
750
763
  /** Optional custom client metadata or redirect URL */
@@ -769,6 +782,8 @@ interface ForgotPasswordResult {
769
782
  * @public
770
783
  */
771
784
  interface ConfirmPasswordResetParams {
785
+ /** Target identity provider name when using CompositeIdentityProvider */
786
+ provider?: string | undefined;
772
787
  /** Username or email of the account */
773
788
  identifier: string;
774
789
  /** Verification code (e.g. 6-digit OTP from email/SMS) or reset token */
@@ -782,6 +797,8 @@ interface ConfirmPasswordResetParams {
782
797
  * @public
783
798
  */
784
799
  interface ConfirmSignUpParams {
800
+ /** Target identity provider name when using CompositeIdentityProvider */
801
+ provider?: string | undefined;
785
802
  /** Username or email of the account to confirm */
786
803
  identifier: string;
787
804
  /** Verification code (e.g. 6-digit OTP from email/SMS) */
@@ -793,6 +810,8 @@ interface ConfirmSignUpParams {
793
810
  * @public
794
811
  */
795
812
  interface ResendConfirmationCodeParams {
813
+ /** Target identity provider name when using CompositeIdentityProvider */
814
+ provider?: string | undefined;
796
815
  /** Username or email of the account */
797
816
  identifier: string;
798
817
  }
@@ -979,6 +998,12 @@ interface CredentialsStorage {
979
998
  * @param username - Username string
980
999
  */
981
1000
  findUserByUsername?(username: string): Promise<UserCredentials | null>;
1001
+ /**
1002
+ * Optional helper to find user directly by email address.
1003
+ *
1004
+ * @param email - Verified email address
1005
+ */
1006
+ findUserByEmail?(email: string): Promise<UserCredentials | null>;
982
1007
  }
983
1008
  /**
984
1009
  * Interface for password hashing and verification algorithms.
@@ -1131,6 +1156,13 @@ interface CredentialsConfig {
1131
1156
  * @default 86400 (24 hours)
1132
1157
  */
1133
1158
  sessionTtlSeconds?: number | undefined;
1159
+ /**
1160
+ * Whether identity verification (e.g. email confirmation code) is required before persisting credentials to storage.
1161
+ * When true, signUp creates a pending registration without writing to storage, requiring confirmSignUp() to activate.
1162
+ *
1163
+ * @default false
1164
+ */
1165
+ requireVerification?: boolean | undefined;
1134
1166
  }
1135
1167
  /**
1136
1168
  * Parameters for user registration (signUp).
@@ -1138,6 +1170,8 @@ interface CredentialsConfig {
1138
1170
  * @public
1139
1171
  */
1140
1172
  interface SignUpParams {
1173
+ /** Target identity provider name when using CompositeIdentityProvider */
1174
+ provider?: string | undefined;
1141
1175
  /** Username for the user (can be used directly instead of identifier) */
1142
1176
  username?: string | undefined;
1143
1177
  /** Primary identifier (username or email) */
@@ -1161,6 +1195,8 @@ interface SignUpResult<TSession = Session, TUser = UserIdentity> {
1161
1195
  sessionId?: string | undefined;
1162
1196
  /** Created session object if autoCreateSessionOnSignUp is enabled */
1163
1197
  session?: TSession | undefined;
1198
+ requiresVerification?: boolean | undefined;
1199
+ devConfirmationCode?: string | undefined;
1164
1200
  }
1165
1201
  /**
1166
1202
  * Parameters for user authentication (signIn).
@@ -1168,6 +1204,8 @@ interface SignUpResult<TSession = Session, TUser = UserIdentity> {
1168
1204
  * @public
1169
1205
  */
1170
1206
  interface SignInParams {
1207
+ /** Target identity provider name when using CompositeIdentityProvider */
1208
+ provider?: string | undefined;
1171
1209
  /** Username or email of the account */
1172
1210
  username?: string | undefined;
1173
1211
  /** Primary identifier (username or email) */
@@ -1194,6 +1232,8 @@ interface SignInResult<TSession = Session, TUser = UserIdentity> {
1194
1232
  * @public
1195
1233
  */
1196
1234
  interface VerifyCredentialsParams {
1235
+ /** Target identity provider name when using CompositeIdentityProvider */
1236
+ provider?: string | undefined;
1197
1237
  /** Username or email of the account */
1198
1238
  username?: string | undefined;
1199
1239
  /** Primary identifier (username or email) */
@@ -1207,6 +1247,8 @@ interface VerifyCredentialsParams {
1207
1247
  * @public
1208
1248
  */
1209
1249
  interface ChangePasswordParams {
1250
+ /** Target identity provider name when using CompositeIdentityProvider */
1251
+ provider?: string | undefined;
1210
1252
  /** Username (optional if identifier or userId is provided) */
1211
1253
  username?: string | undefined;
1212
1254
  /** Primary identifier (optional if username or userId is provided) */
@@ -1382,6 +1424,20 @@ declare class CredentialsManager {
1382
1424
  * @returns True if password was successfully updated
1383
1425
  */
1384
1426
  changePassword(params: ChangePasswordParams): Promise<boolean>;
1427
+ /**
1428
+ * Sets a password for a user who doesn't have one yet (e.g. SSO-first users),
1429
+ * or updates an existing password without requiring the old one.
1430
+ * This should only be called from an authenticated context (user already verified their identity via SSO).
1431
+ *
1432
+ * @param params - userId and newPassword
1433
+ * @returns True if password was successfully set
1434
+ */
1435
+ setPassword(params: {
1436
+ userId: string;
1437
+ newPassword: string;
1438
+ identifier?: string;
1439
+ email?: string;
1440
+ }): Promise<boolean>;
1385
1441
  /**
1386
1442
  * Finds a user by ID and returns safe user data.
1387
1443
  */
@@ -1413,12 +1469,26 @@ declare class CredentialsManager {
1413
1469
  declare class SelfManagedIdentityProvider implements IIdentityProvider {
1414
1470
  readonly name: string;
1415
1471
  private readonly manager;
1472
+ private readonly pendingSignups;
1473
+ private readonly requireVerification;
1474
+ private readonly config;
1416
1475
  constructor(configOrManager?: CredentialsConfig | CredentialsManager);
1417
1476
  private mapUser;
1477
+ private generateConfirmationCode;
1418
1478
  /**
1419
- * Registers a new user.
1479
+ * Registers a new user with optional pending verification.
1480
+ * When requireVerification is true, credentials are NOT persisted to the database until confirmSignUp() is called.
1420
1481
  */
1421
1482
  signUp(params: SignUpParams): Promise<UserIdentity>;
1483
+ /**
1484
+ * Confirms a pending signup registration using the verification code.
1485
+ * Only after successful confirmation is the user persisted to the database.
1486
+ */
1487
+ confirmSignUp(params: ConfirmSignUpParams): Promise<boolean>;
1488
+ /**
1489
+ * Resends the verification code for a pending signup.
1490
+ */
1491
+ resendConfirmationCode(params: ResendConfirmationCodeParams): Promise<ResendConfirmationCodeResult>;
1422
1492
  /**
1423
1493
  * Authenticates a user with password.
1424
1494
  */
@@ -1449,6 +1519,68 @@ declare class SelfManagedIdentityProvider implements IIdentityProvider {
1449
1519
  getCredentialsManager(): CredentialsManager;
1450
1520
  }
1451
1521
 
1522
+ /**
1523
+ * Options for initializing a CompositeIdentityProvider.
1524
+ *
1525
+ * @public
1526
+ */
1527
+ interface CompositeIdentityProviderOptions<TProviders extends Record<string, IIdentityProvider> = Record<string, IIdentityProvider>, TOAuthProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> {
1528
+ /**
1529
+ * Record of child identity providers keyed by unique provider names.
1530
+ * e.g. `{ cognito: new CognitoIdentityProvider(...), okta: new OktaIdentityProvider(...) }`
1531
+ */
1532
+ providers: TProviders;
1533
+ /**
1534
+ * Default provider key to use when a request does not explicitly pass a `provider` parameter.
1535
+ */
1536
+ defaultProvider?: (keyof TProviders & string) | undefined;
1537
+ /**
1538
+ * Record of OAuth 2.0 / OIDC provider configurations (Google, GitHub, etc.)
1539
+ * to register alongside these identity providers.
1540
+ */
1541
+ oauthProviders?: TOAuthProviders | undefined;
1542
+ }
1543
+ /**
1544
+ * Composite Identity Provider that aggregates multiple child IIdentityProvider instances
1545
+ * and OAuth 2.0 / OIDC provider configurations under a single unified identityProvider.
1546
+ *
1547
+ * @remarks
1548
+ * Eliminates the need for separate `federatedOAuthProviders` configuration in Lixa.
1549
+ * Provides compile-time autocompletion of configured provider names.
1550
+ * Routing is strictly explicit: uses `params.provider` if provided, or `defaultProvider`.
1551
+ * No silent fallbacks or guesswork.
1552
+ *
1553
+ * @public
1554
+ */
1555
+ declare class CompositeIdentityProvider<TProviders extends Record<string, IIdentityProvider> = Record<string, IIdentityProvider>, TOAuthProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> implements IIdentityProvider {
1556
+ readonly name: string;
1557
+ readonly providers: TProviders;
1558
+ readonly defaultProvider?: (keyof TProviders & string) | undefined;
1559
+ readonly oauthProviders?: TOAuthProviders | undefined;
1560
+ constructor(options: CompositeIdentityProviderOptions<TProviders, TOAuthProviders>);
1561
+ /**
1562
+ * Resolves the target child provider based on explicit parameter or defaultProvider.
1563
+ * Throws an error immediately if the provider cannot be resolved or does not exist.
1564
+ */
1565
+ selectProvider(providerName?: string): IIdentityProvider;
1566
+ /**
1567
+ * Returns all OAuth / OIDC provider configurations aggregated across this composite provider
1568
+ * and any child providers exposing `getOAuthProviders()` or `getProviders()`.
1569
+ */
1570
+ getProviders(): Record<string, ProviderConfig>;
1571
+ signUp(params: SignUpParams): Promise<UserIdentity>;
1572
+ signIn(params: SignInParams): Promise<IdentityAuthResult>;
1573
+ verifyCredentials(params: VerifyCredentialsParams): Promise<UserIdentity | null>;
1574
+ changePassword(params: ChangePasswordParams): Promise<boolean>;
1575
+ forgotPassword(params: ForgotPasswordParams): Promise<ForgotPasswordResult>;
1576
+ confirmPasswordReset(params: ConfirmPasswordResetParams): Promise<boolean>;
1577
+ confirmSignUp(params: ConfirmSignUpParams): Promise<boolean>;
1578
+ resendConfirmationCode(params: ResendConfirmationCodeParams): Promise<ResendConfirmationCodeResult>;
1579
+ getUserById(id: string, providerName?: string): Promise<UserIdentity | null>;
1580
+ getUserByIdentifier(identifier: string, providerName?: string): Promise<UserIdentity | null>;
1581
+ deleteUser(id: string, providerName?: string): Promise<void>;
1582
+ }
1583
+
1452
1584
  /**
1453
1585
  * Configuration for an OAuth provider instance.
1454
1586
  *
@@ -1485,6 +1617,27 @@ declare class SelfManagedIdentityProvider implements IIdentityProvider {
1485
1617
  *
1486
1618
  * @public
1487
1619
  */
1620
+ /**
1621
+ * Scopes configuration explicitly partitioned into authentication and resource authorization.
1622
+ *
1623
+ * @public
1624
+ */
1625
+ interface ScopesConfig {
1626
+ /**
1627
+ * Explicit identity scopes requested during primary authentication (AuthN) (e.g. ['openid', 'email', 'profile']).
1628
+ * If omitted, uses the provider's default identity scopes.
1629
+ */
1630
+ auth?: string[];
1631
+ /**
1632
+ * Explicit permission scopes requested during post-authentication resource authorization (AuthZ)
1633
+ * (e.g. ['https://www.googleapis.com/auth/drive.readonly'] or ['repo']).
1634
+ */
1635
+ resource?: string[];
1636
+ }
1637
+ /**
1638
+ * Configuration for an OAuth provider instance.
1639
+ * @public
1640
+ */
1488
1641
  type ProviderConfig = {
1489
1642
  /** The OAuth client ID provided by the provider */
1490
1643
  clientId: string;
@@ -1492,11 +1645,25 @@ type ProviderConfig = {
1492
1645
  clientSecret: string;
1493
1646
  /** The redirect URI registered with the provider */
1494
1647
  redirectUri: string;
1495
- /** Array of OAuth scopes to request. If omitted, uses provider default identity scopes. */
1496
- scopes?: string[];
1497
1648
  /**
1498
- * Default scopes requested when connecting this provider as a third-party resource (AuthZ).
1499
- * Used automatically by getResourceAuthUrl() and handleResourceCallback() if not overridden at runtime.
1649
+ * Explicit scopes for authentication and post-login resource authorization.
1650
+ * Can be configured as `{ auth: [...], resource: [...] }` or a shorthand `string[]` for auth scopes.
1651
+ *
1652
+ * @example
1653
+ * ```typescript
1654
+ * scopes: {
1655
+ * auth: ["openid", "email", "profile"],
1656
+ * resource: ["https://www.googleapis.com/auth/drive.readonly"],
1657
+ * }
1658
+ * ```
1659
+ */
1660
+ scopes?: ScopesConfig | string[];
1661
+ /**
1662
+ * Flat alias for authentication scopes (AuthN).
1663
+ */
1664
+ authScopes?: string[];
1665
+ /**
1666
+ * Flat alias for post-authentication resource authorization scopes (AuthZ).
1500
1667
  */
1501
1668
  resourceScopes?: string[];
1502
1669
  /**
@@ -1505,7 +1672,11 @@ type ProviderConfig = {
1505
1672
  * clean AuthN vs AuthZ separation.
1506
1673
  */
1507
1674
  allowNonAuthScopes?: boolean;
1508
- /** Additional provider-specific configuration parameters */
1675
+ /**
1676
+ * Custom query parameters passed to the OAuth authorization endpoint (e.g. `{ identity_provider: "Google" }`).
1677
+ */
1678
+ authorizationParams?: Record<string, string>;
1679
+ /** Additional provider-specific configuration parameters (alias for authorizationParams) */
1509
1680
  extraConfig?: Record<string, string>;
1510
1681
  } & ({
1511
1682
  provider?: never;
@@ -1587,14 +1758,16 @@ declare enum AccountLinkingStrategy {
1587
1758
  /** Automatically merge identities matching the same verified primary email address */
1588
1759
  AUTO_LINK_BY_VERIFIED_EMAIL = "AUTO_LINK_BY_VERIFIED_EMAIL",
1589
1760
  /** Keep identity profiles isolated per provider (no automatic account merging) */
1590
- ISOLATED = "ISOLATED"
1761
+ ISOLATED = "ISOLATED",
1762
+ /** Require password or original provider step-up verification before linking secondary accounts */
1763
+ STEP_UP_VERIFICATION = "STEP_UP_VERIFICATION"
1591
1764
  }
1592
1765
  /**
1593
1766
  * Supported mode values for account linking configuration.
1594
1767
  *
1595
1768
  * @public
1596
1769
  */
1597
- type AccountLinkingMode = AccountLinkingStrategy | "AUTO_LINK_BY_VERIFIED_EMAIL" | "ISOLATED" | "linkByEmail" | "separate";
1770
+ type AccountLinkingMode = AccountLinkingStrategy | "AUTO_LINK_BY_VERIFIED_EMAIL" | "ISOLATED" | "STEP_UP_VERIFICATION" | "linkByEmail" | "separate" | "stepUp";
1598
1771
  /**
1599
1772
  * Account linking settings for Lixa.
1600
1773
  *
@@ -1628,43 +1801,54 @@ interface StorageAdapter {
1628
1801
  credentialsStorage?: any;
1629
1802
  accountStorage?: any;
1630
1803
  }
1804
+ /**
1805
+ * Inferred key of identity providers configured in a CompositeIdentityProvider.
1806
+ *
1807
+ * @public
1808
+ */
1809
+ type ConfiguredIdentityKey<TIdentity> = TIdentity extends CompositeIdentityProvider<infer TProviders, any> ? (keyof TProviders & string) : string;
1810
+ /**
1811
+ * Inferred key of OAuth / OIDC providers configured in a CompositeIdentityProvider or inline providers.
1812
+ *
1813
+ * @public
1814
+ */
1815
+ type ConfiguredOAuthKey<TIdentity = unknown, TProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> = TIdentity extends CompositeIdentityProvider<any, infer TOAuth> ? (keyof TOAuth & string) | (keyof TProviders & string) : keyof TProviders & string;
1631
1816
  /**
1632
1817
  * Main configuration object for Lixa.
1633
1818
  * Provides type-safe provider name inference.
1634
1819
  *
1635
1820
  * @public
1636
1821
  */
1637
- interface LixaConfig<TProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> {
1638
- /**
1639
- * Map of federated OAuth 2.0 / OIDC provider names to their configurations (Google, GitHub, etc.)
1640
- * that federate with and work alongside the primary identityProvider.
1641
- * Provider names will be available for autocomplete in getAuthUrl() and handleCallback().
1642
- */
1643
- federatedOAuthProviders?: TProviders;
1822
+ interface LixaConfig<TIdentity extends IIdentityProvider | IdentityConfig = IIdentityProvider | IdentityConfig, TProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> {
1644
1823
  /**
1645
- * Alias for {@link LixaConfig.federatedOAuthProviders}.
1646
- */
1647
- providers?: TProviders;
1648
- /**
1649
- * Primary Identity Provider configuration (Self-Managed Database, AWS Cognito, Auth0, Okta, or custom IIdentityProvider).
1824
+ * Primary Identity Provider configuration (Self-Managed Database, AWS Cognito, Auth0, Okta,
1825
+ * or a CompositeIdentityProvider combining multiple backends and OAuth providers).
1650
1826
  *
1651
1827
  * @example
1652
- * Self-managed with Prisma:
1828
+ * Composite Identity Provider:
1653
1829
  * ```typescript
1654
- * identityProvider: { storage: prismaAdapter.credentialsStorage }
1655
- * ```
1656
- *
1657
- * @example
1658
- * AWS Cognito:
1659
- * ```typescript
1660
- * identityProvider: new CognitoIdentityProvider({ userPoolId: '...', clientId: '...', region: 'us-east-1' })
1830
+ * identityProvider: new CompositeIdentityProvider({
1831
+ * defaultProvider: 'cognito',
1832
+ * providers: {
1833
+ * cognito: new CognitoIdentityProvider(...),
1834
+ * 'self-managed': new SelfManagedIdentityProvider(...)
1835
+ * },
1836
+ * oauthProviders: {
1837
+ * google: { provider: new GoogleProvider(), ... }
1838
+ * }
1839
+ * })
1661
1840
  * ```
1662
1841
  */
1663
- identityProvider?: IIdentityProvider | IdentityConfig;
1842
+ identityProvider?: TIdentity;
1664
1843
  /**
1665
1844
  * Alias for {@link LixaConfig.identityProvider}.
1666
1845
  */
1667
- identity?: IIdentityProvider | IdentityConfig;
1846
+ identity?: TIdentity;
1847
+ /**
1848
+ * Direct OAuth 2.0 / OIDC provider configurations (Google, GitHub, etc.).
1849
+ * When using CompositeIdentityProvider, OAuth providers can also be defined in its `oauthProviders` field.
1850
+ */
1851
+ providers?: TProviders;
1668
1852
  /**
1669
1853
  * Credentials (username and password) authentication configuration.
1670
1854
  * Automatically maps to a SelfManagedIdentityProvider.
@@ -1833,7 +2017,7 @@ type ConfiguredProviderKey<TProviders extends Record<string, ProviderConfig>> =
1833
2017
  *
1834
2018
  * @public
1835
2019
  */
1836
- declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> {
2020
+ declare class Lixa<TIdentity extends IIdentityProvider | IdentityConfig = IIdentityProvider | IdentityConfig, TProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> {
1837
2021
  private static DEFAULT_PROVIDERS;
1838
2022
  private static CONFIGURED_PROVIDERS;
1839
2023
  private localStateHandler;
@@ -1843,6 +2027,7 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
1843
2027
  private userResourceStore;
1844
2028
  private userAccountStore;
1845
2029
  private refreshMutexes;
2030
+ private linkingChallenges;
1846
2031
  private identityProvider?;
1847
2032
  private credentialsManager?;
1848
2033
  private config;
@@ -1865,7 +2050,7 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
1865
2050
  * @throws Error when provider implementation is missing required properties
1866
2051
  * @throws Error when provider is not available and no inline implementation is provided
1867
2052
  */
1868
- constructor(config: LixaConfig<TProviders>);
2053
+ constructor(config: LixaConfig<TIdentity, TProviders>);
1869
2054
  /**
1870
2055
  * Validates that a provider configuration has all required credentials.
1871
2056
  *
@@ -1906,7 +2091,7 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
1906
2091
  * }
1907
2092
  * ```
1908
2093
  */
1909
- isProviderConfigured<T extends string>(provider: T): provider is T & ConfiguredProviderKey<TProviders>;
2094
+ isProviderConfigured<T extends string>(provider: T): provider is T & (ConfiguredOAuthKey<TIdentity, TProviders> | ConfiguredProviderKey<TProviders>);
1910
2095
  /**
1911
2096
  * Gets a provider implementation by name.
1912
2097
  * Resolution priority: inline custom provider \> default providers \> legacy registry
@@ -2087,7 +2272,7 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2087
2272
  * res.redirect(authUrl);
2088
2273
  * ```
2089
2274
  */
2090
- getAuthUrl(provider: ConfiguredProviderKey<TProviders> | string, state?: string): Promise<string>;
2275
+ getAuthUrl(provider: ConfiguredOAuthKey<TIdentity, TProviders> | string, state?: string): Promise<string>;
2091
2276
  /**
2092
2277
  * Restricts primary authentication scopes strictly to AuthN identity scopes unless allowNonAuthScopes is true.
2093
2278
  */
@@ -2112,7 +2297,7 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2112
2297
  * ```
2113
2298
  */
2114
2299
  handleCallback({ provider, code, state, sessionId, }: {
2115
- provider: ConfiguredProviderKey<TProviders> | string;
2300
+ provider: ConfiguredOAuthKey<TIdentity, TProviders> | string;
2116
2301
  code: string;
2117
2302
  state?: string;
2118
2303
  sessionId?: string;
@@ -2137,6 +2322,38 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2137
2322
  * @returns Promise resolving to true on successful unlink
2138
2323
  */
2139
2324
  unlinkAccount(sessionId: string, providerToUnlink: string): Promise<boolean>;
2325
+ /**
2326
+ * Confirms a pending account linking step-up challenge using the user's password.
2327
+ * On successful verification, links the pending provider to the existing account and creates a session.
2328
+ *
2329
+ * @param params - challengeToken and password
2330
+ * @returns Session ID, Session, and User identity
2331
+ * @throws InvalidStateError if challenge is invalid or expired
2332
+ * @throws InvalidCredentialsError if password verification fails
2333
+ */
2334
+ confirmLinkingWithPassword(params: {
2335
+ challengeToken: string;
2336
+ password: string;
2337
+ }): Promise<{
2338
+ sessionId: string;
2339
+ session: Session;
2340
+ user?: any;
2341
+ }>;
2342
+ /**
2343
+ * Sets a password for an SSO-authenticated user who doesn't have one yet.
2344
+ * Must be called from an authenticated context (user has active session proving identity).
2345
+ *
2346
+ * @param params - userId, newPassword, optional identifier and email
2347
+ * @returns True if password was set successfully
2348
+ * @throws IdentityNotConfiguredError if no identity provider configured
2349
+ * @throws WeakPasswordError if password doesn't meet policy
2350
+ */
2351
+ setPassword(params: {
2352
+ userId: string;
2353
+ newPassword: string;
2354
+ identifier?: string;
2355
+ email?: string;
2356
+ }): Promise<boolean>;
2140
2357
  /**
2141
2358
  * Generates an authorization URL for connecting a resource provider (AuthZ) post-login.
2142
2359
  *
@@ -2150,19 +2367,21 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2150
2367
  */
2151
2368
  getResourceAuthUrl(params: {
2152
2369
  sessionId: string;
2153
- provider: ConfiguredProviderKey<TProviders> | string;
2370
+ provider: ConfiguredOAuthKey<TIdentity, TProviders> | string;
2154
2371
  scopes?: string[];
2155
2372
  state?: string;
2156
2373
  prompt?: string;
2374
+ authorizationParams?: Record<string, string>;
2157
2375
  extraConfig?: Record<string, string>;
2158
2376
  }): Promise<string>;
2159
2377
  private getUserKeyFromSession;
2378
+ private sanitizeIdentityForStorage;
2160
2379
  /**
2161
2380
  * Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
2162
2381
  */
2163
2382
  handleResourceCallback(params: {
2164
2383
  sessionId: string;
2165
- provider: ConfiguredProviderKey<TProviders> | string;
2384
+ provider: ConfiguredOAuthKey<TIdentity, TProviders> | string;
2166
2385
  code: string;
2167
2386
  state?: string;
2168
2387
  scopes?: string[];
@@ -2173,7 +2392,7 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2173
2392
  * @param provider - Provider name (e.g. 'github', 'google')
2174
2393
  * @returns Array of configured resource scopes, or undefined if not configured
2175
2394
  */
2176
- getResourceScopes(provider: ConfiguredProviderKey<TProviders> | string): string[] | undefined;
2395
+ getResourceScopes(provider: ConfiguredOAuthKey<TIdentity, TProviders> | string): string[] | undefined;
2177
2396
  /**
2178
2397
  * Returns the resolved session cookie name.
2179
2398
  * Dynamically reflects any changes to the active identity provider.
@@ -2235,6 +2454,13 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2235
2454
  * Retrieves active session details from session storage.
2236
2455
  */
2237
2456
  fetchSessionInfo(sessionId: string): Promise<Session | null>;
2457
+ /**
2458
+ * Retrieves all linked accounts for a user from account storage.
2459
+ *
2460
+ * @param userIdOrSessionId - User ID, email, or active session ID
2461
+ * @returns Record mapping provider name to linked account metadata
2462
+ */
2463
+ getUserAccounts(userIdOrSessionId: string): Promise<Record<string, LinkedAccount>>;
2238
2464
  /**
2239
2465
  * Deletes a session from session storage (e.g. on logout).
2240
2466
  *
@@ -2278,90 +2504,109 @@ declare class Lixa<TProviders extends Record<string, ProviderConfig> = Record<st
2278
2504
  * @throws UserAlreadyExistsError if identifier is already registered
2279
2505
  * @throws IdentityNotConfiguredError if identity authentication is not configured
2280
2506
  */
2281
- signUp(params: SignUpParams): Promise<SignUpResult>;
2507
+ signUp(params: SignUpParams & {
2508
+ provider?: ConfiguredIdentityKey<TIdentity>;
2509
+ }): Promise<SignUpResult>;
2282
2510
  /**
2283
- * Authenticates a user with credentials via the configured identity provider (Self-Managed DB, Cognito, Auth0, Okta).
2511
+ * Authenticates a user with credentials via the configured identity provider (Self-Managed DB, Cognito, Auth0, Okta, or Composite).
2284
2512
  * Creates an active session and automatically links with existing sessions when AUTO_LINK_BY_VERIFIED_EMAIL is configured.
2285
2513
  *
2286
- * @param params - Sign-in parameters (identifier, password)
2514
+ * @param params - Sign-in parameters (identifier, password, optional provider)
2287
2515
  * @returns Authenticated user, session ID, and session object
2288
2516
  * @throws InvalidCredentialsError if authentication fails
2289
2517
  * @throws IdentityNotConfiguredError if identity authentication is not configured
2290
2518
  */
2291
- signIn(params: SignInParams): Promise<SignInResult>;
2519
+ signIn(params: SignInParams & {
2520
+ provider?: ConfiguredIdentityKey<TIdentity>;
2521
+ }): Promise<SignInResult>;
2292
2522
  /**
2293
2523
  * Verifies username/email and password credentials without generating a session.
2294
2524
  *
2295
- * @param params - Verification parameters (identifier, password)
2525
+ * @param params - Verification parameters (identifier, password, optional provider)
2296
2526
  * @returns User credentials/identity or null if invalid
2297
2527
  * @throws IdentityNotConfiguredError if identity auth is not configured
2298
2528
  */
2299
- verifyCredentials(params: VerifyCredentialsParams): Promise<UserIdentity | null>;
2529
+ verifyCredentials(params: VerifyCredentialsParams & {
2530
+ provider?: ConfiguredIdentityKey<TIdentity>;
2531
+ }): Promise<UserIdentity | null>;
2300
2532
  /**
2301
2533
  * Updates a user's password after verifying the current password and enforcing policy on the new password.
2302
2534
  *
2303
- * @param params - Change password parameters (userId/identifier, oldPassword, newPassword)
2535
+ * @param params - Change password parameters (userId/identifier, oldPassword, newPassword, optional provider)
2304
2536
  * @returns True if password was updated successfully
2305
2537
  * @throws UserNotFoundError if user is not found
2306
2538
  * @throws InvalidCredentialsError if current password is incorrect
2307
2539
  * @throws WeakPasswordError if new password does not meet policy requirements
2308
2540
  * @throws IdentityNotConfiguredError if identity auth is not configured
2309
2541
  */
2310
- changePassword(params: ChangePasswordParams): Promise<boolean>;
2542
+ changePassword(params: ChangePasswordParams & {
2543
+ provider?: ConfiguredIdentityKey<TIdentity>;
2544
+ }): Promise<boolean>;
2311
2545
  /**
2312
2546
  * Initiates a password reset (forgot password flow) through the configured identity provider.
2313
2547
  *
2314
- * @param params - Forgot password parameters (identifier, optional metadata)
2548
+ * @param params - Forgot password parameters (identifier, optional metadata, optional provider)
2315
2549
  * @returns ForgotPasswordResult indicating status and delivery medium (email/SMS)
2316
2550
  * @throws IdentityNotConfiguredError if identity auth is not configured
2317
2551
  */
2318
- forgotPassword(params: ForgotPasswordParams): Promise<ForgotPasswordResult>;
2552
+ forgotPassword(params: ForgotPasswordParams & {
2553
+ provider?: ConfiguredIdentityKey<TIdentity>;
2554
+ }): Promise<ForgotPasswordResult>;
2319
2555
  /**
2320
2556
  * Confirms a password reset using a verification code / token and sets the new password.
2321
2557
  *
2322
- * @param params - Verification code, identifier, and new password
2558
+ * @param params - Verification code, identifier, new password, and optional provider
2323
2559
  * @returns True if password reset was successfully confirmed
2324
2560
  * @throws IdentityNotConfiguredError if identity auth is not configured
2325
2561
  */
2326
- confirmPasswordReset(params: ConfirmPasswordResetParams): Promise<boolean>;
2562
+ confirmPasswordReset(params: ConfirmPasswordResetParams & {
2563
+ provider?: ConfiguredIdentityKey<TIdentity>;
2564
+ }): Promise<boolean>;
2327
2565
  /**
2328
2566
  * Confirms user account registration using a verification code.
2329
2567
  *
2330
- * @param params - Verification parameters including identifier and confirmationCode
2568
+ * @param params - Verification parameters including identifier, confirmationCode, and optional provider
2331
2569
  * @returns True if confirmation was successful
2332
2570
  * @throws IdentityNotConfiguredError if identity auth is not configured
2333
2571
  * @throws IdentityProviderError if identity provider does not support confirmation
2334
2572
  */
2335
- confirmSignUp(params: ConfirmSignUpParams): Promise<boolean>;
2573
+ confirmSignUp(params: ConfirmSignUpParams & {
2574
+ provider?: ConfiguredIdentityKey<TIdentity>;
2575
+ }): Promise<boolean>;
2336
2576
  /**
2337
2577
  * Resends the sign up confirmation code to the user.
2338
2578
  *
2339
- * @param params - Resend parameters including user identifier
2579
+ * @param params - Resend parameters including user identifier and optional provider
2340
2580
  * @returns Details about the code delivery (medium, destination)
2341
2581
  * @throws IdentityNotConfiguredError if identity auth is not configured
2342
2582
  * @throws IdentityProviderError if identity provider does not support resending codes
2343
2583
  */
2344
- resendConfirmationCode(params: ResendConfirmationCodeParams): Promise<ResendConfirmationCodeResult>;
2584
+ resendConfirmationCode(params: ResendConfirmationCodeParams & {
2585
+ provider?: ConfiguredIdentityKey<TIdentity>;
2586
+ }): Promise<ResendConfirmationCodeResult>;
2345
2587
  /**
2346
2588
  * Retrieves a user by their unique ID from the configured identity provider.
2347
2589
  *
2348
2590
  * @param id - Unique user ID
2591
+ * @param provider - Optional provider key when using CompositeIdentityProvider
2349
2592
  * @returns UserIdentity or null if not found
2350
2593
  */
2351
- getUserById(id: string): Promise<UserIdentity | null>;
2594
+ getUserById(id: string, provider?: ConfiguredIdentityKey<TIdentity>): Promise<UserIdentity | null>;
2352
2595
  /**
2353
2596
  * Retrieves a user by their identifier (username or email) from the configured identity provider.
2354
2597
  *
2355
2598
  * @param identifier - Username or email string
2599
+ * @param provider - Optional provider key when using CompositeIdentityProvider
2356
2600
  * @returns UserIdentity or null if not found
2357
2601
  */
2358
- getUserByIdentifier(identifier: string): Promise<UserIdentity | null>;
2602
+ getUserByIdentifier(identifier: string, provider?: ConfiguredIdentityKey<TIdentity>): Promise<UserIdentity | null>;
2359
2603
  /**
2360
2604
  * Deletes a user account from the configured identity provider.
2361
2605
  *
2362
2606
  * @param id - Unique user ID
2607
+ * @param provider - Optional provider key when using CompositeIdentityProvider
2363
2608
  */
2364
- deleteUser(id: string): Promise<void>;
2609
+ deleteUser(id: string, provider?: ConfiguredIdentityKey<TIdentity>): Promise<void>;
2365
2610
  private findProviderByType;
2366
2611
  }
2367
2612
 
@@ -2596,6 +2841,49 @@ declare class IdentityProviderError extends LixaError {
2596
2841
  declare class IdentityNotConfiguredError extends CredentialsNotConfiguredError {
2597
2842
  constructor(message?: string, details?: Record<string, unknown>);
2598
2843
  }
2844
+ /**
2845
+ * Thrown when a login attempt matches an existing user under another provider,
2846
+ * requiring step-up verification (e.g. password or original provider login) before linking.
2847
+ *
2848
+ * @public
2849
+ */
2850
+ declare class AccountLinkingChallengeRequiredError extends LixaError {
2851
+ readonly challengeToken: string;
2852
+ readonly email: string;
2853
+ readonly incomingProvider: string;
2854
+ readonly incomingProviderUserId?: string | undefined;
2855
+ readonly existingUserId: string;
2856
+ readonly existingProviders: string[];
2857
+ readonly hasPassword: boolean;
2858
+ constructor(message: string, details: {
2859
+ challengeToken: string;
2860
+ email: string;
2861
+ incomingProvider: string;
2862
+ incomingProviderUserId?: string | undefined;
2863
+ existingUserId: string;
2864
+ existingProviders: string[];
2865
+ hasPassword: boolean;
2866
+ });
2867
+ }
2868
+ /**
2869
+ * Thrown when attempting to sign up with username+password for an email that already has an SSO account.
2870
+ * The user should sign in via their original SSO provider and set a password in Settings.
2871
+ *
2872
+ * @public
2873
+ */
2874
+ declare class SSOAccountAlreadyExistsError extends LixaError {
2875
+ readonly existingProviders: string[];
2876
+ readonly email: string;
2877
+ constructor(email: string, existingProviders: string[], details?: Record<string, unknown>);
2878
+ }
2879
+ /**
2880
+ * Thrown when a user's account has not been verified/confirmed yet.
2881
+ *
2882
+ * @public
2883
+ */
2884
+ declare class AccountNotVerifiedError extends LixaError {
2885
+ constructor(identifier?: string, details?: Record<string, unknown>);
2886
+ }
2599
2887
 
2600
2888
  /**
2601
2889
  * Sensible default cookie configuration options.
@@ -2766,6 +3054,9 @@ declare namespace index$1 {
2766
3054
  export { type index$1_ChangePasswordParams as ChangePasswordParams, type index$1_CredentialsConfig as CredentialsConfig, index$1_CredentialsManager as CredentialsManager, type index$1_CredentialsStorage as CredentialsStorage, type index$1_IPasswordHasher as IPasswordHasher, index$1_LocalCredentialsStorage as LocalCredentialsStorage, type index$1_PasswordPolicyConfig as PasswordPolicyConfig, type index$1_PasswordPolicyResult as PasswordPolicyResult, type index$1_Pbkdf2HasherOptions as Pbkdf2HasherOptions, index$1_Pbkdf2PasswordHasher as Pbkdf2PasswordHasher, type index$1_ScryptHasherOptions as ScryptHasherOptions, index$1_ScryptPasswordHasher as ScryptPasswordHasher, type index$1_SignInParams as SignInParams, type index$1_SignInResult as SignInResult, type index$1_SignUpParams as SignUpParams, type index$1_SignUpResult as SignUpResult, type index$1_UserCredentials as UserCredentials, type index$1_VerifyCredentialsParams as VerifyCredentialsParams, index$1_validatePasswordPolicy as validatePasswordPolicy };
2767
3055
  }
2768
3056
 
3057
+ type index_CompositeIdentityProvider<TProviders extends Record<string, IIdentityProvider> = Record<string, IIdentityProvider>, TOAuthProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> = CompositeIdentityProvider<TProviders, TOAuthProviders>;
3058
+ declare const index_CompositeIdentityProvider: typeof CompositeIdentityProvider;
3059
+ type index_CompositeIdentityProviderOptions<TProviders extends Record<string, IIdentityProvider> = Record<string, IIdentityProvider>, TOAuthProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> = CompositeIdentityProviderOptions<TProviders, TOAuthProviders>;
2769
3060
  type index_ConfirmPasswordResetParams = ConfirmPasswordResetParams;
2770
3061
  type index_ConfirmSignUpParams = ConfirmSignUpParams;
2771
3062
  type index_ForgotPasswordParams = ForgotPasswordParams;
@@ -2780,7 +3071,7 @@ type index_SelfManagedIdentityProvider = SelfManagedIdentityProvider;
2780
3071
  declare const index_SelfManagedIdentityProvider: typeof SelfManagedIdentityProvider;
2781
3072
  type index_UserIdentity = UserIdentity;
2782
3073
  declare namespace index {
2783
- export { type index_ConfirmPasswordResetParams as ConfirmPasswordResetParams, type index_ConfirmSignUpParams as ConfirmSignUpParams, type index_ForgotPasswordParams as ForgotPasswordParams, type index_ForgotPasswordResult as ForgotPasswordResult, type index_IIdentityProvider as IIdentityProvider, type index_IdentityAuthResult as IdentityAuthResult, type index_IdentityConfig as IdentityConfig, type index_IdentityTokens as IdentityTokens, type index_ResendConfirmationCodeParams as ResendConfirmationCodeParams, type index_ResendConfirmationCodeResult as ResendConfirmationCodeResult, index_SelfManagedIdentityProvider as SelfManagedIdentityProvider, type index_UserIdentity as UserIdentity };
3074
+ export { index_CompositeIdentityProvider as CompositeIdentityProvider, type index_CompositeIdentityProviderOptions as CompositeIdentityProviderOptions, type index_ConfirmPasswordResetParams as ConfirmPasswordResetParams, type index_ConfirmSignUpParams as ConfirmSignUpParams, type index_ForgotPasswordParams as ForgotPasswordParams, type index_ForgotPasswordResult as ForgotPasswordResult, type index_IIdentityProvider as IIdentityProvider, type index_IdentityAuthResult as IdentityAuthResult, type index_IdentityConfig as IdentityConfig, type index_IdentityTokens as IdentityTokens, type index_ResendConfirmationCodeParams as ResendConfirmationCodeParams, type index_ResendConfirmationCodeResult as ResendConfirmationCodeResult, index_SelfManagedIdentityProvider as SelfManagedIdentityProvider, type index_UserIdentity as UserIdentity };
2784
3075
  }
2785
3076
 
2786
- export { type AccountHandler, type AccountLinkingConfig, type AccountLinkingMode, AccountLinkingStrategy, type AccountStorage, AccountUnlinkError, type ChangePasswordParams, type ConfirmPasswordResetParams, type ConfirmSignUpParams, type ConnectedResource, type CookieOptions, type CookiePayload, type CredentialsConfig, CredentialsManager, CredentialsNotConfiguredError, type CredentialsStorage, DEFAULT_SESSION_COOKIE_NAME, DEFAULT_SESSION_MAX_AGE_SECONDS, DEFAULT_STATE_COOKIE_NAME, DEFAULT_STATE_MAX_AGE_SECONDS, EmailNotVerifiedError, type ForgotPasswordParams, type ForgotPasswordResult, type IIdentityProvider, type IPasswordHasher, type IProvider, type IdentityAuthResult, type IdentityConfig, IdentityNotConfiguredError, IdentityProviderError, type IdentityTokens, InvalidCredentialsError, InvalidOAuthCallbackError, InvalidProviderConfigError, InvalidStateError, type LinkedAccount, Lixa, type LixaConfig, type LixaCookieContext, LixaError, type LixaLogger, LocalCredentialsStorage, type LogContext, type LogLevel, type OAuthTokenResponse, type PasswordPolicyConfig, type PasswordPolicyResult, type Pbkdf2HasherOptions, Pbkdf2PasswordHasher, type ProviderConfig, type ProviderMetadata, ProviderNotConfiguredError, RefreshTokenError, type ResendConfirmationCodeParams, type ResendConfirmationCodeResult, type ResourceHandler, type ResourceStorage, type SafeLixaConfig, type ScryptHasherOptions, ScryptPasswordHasher, SelfManagedIdentityProvider, type Session, type SessionCookieResolver, type SessionHandler, SessionNotFoundError, type SessionStorage, type SignInParams, type SignInResult, type SignUpParams, type SignUpResult, type StateData, type StateHandler, type StateStorage, TokenExchangeError, UserAlreadyExistsError, type UserCredentials, type UserIdentity, type UserInfo, UserNotFoundError, type VerifyCredentialsParams, WeakPasswordError, clearSessionCookie, clearStateCookie, createSessionCookie, createStateCookie, index$1 as credentials, decodeIdToken, determineProviderFromIssuer, extractUserInfo, fetchUserInfo, index as identity, isProductionEnvironment, serializeCookie, validatePasswordPolicy };
3077
+ export { type AccountHandler, AccountLinkingChallengeRequiredError, type AccountLinkingConfig, type AccountLinkingMode, AccountLinkingStrategy, AccountNotVerifiedError, type AccountStorage, AccountUnlinkError, type ChangePasswordParams, CompositeIdentityProvider, type CompositeIdentityProviderOptions, type ConfiguredIdentityKey, type ConfiguredOAuthKey, type ConfirmPasswordResetParams, type ConfirmSignUpParams, type ConnectedResource, type CookieOptions, type CookiePayload, type CredentialsConfig, CredentialsManager, CredentialsNotConfiguredError, type CredentialsStorage, DEFAULT_SESSION_COOKIE_NAME, DEFAULT_SESSION_MAX_AGE_SECONDS, DEFAULT_STATE_COOKIE_NAME, DEFAULT_STATE_MAX_AGE_SECONDS, EmailNotVerifiedError, type ForgotPasswordParams, type ForgotPasswordResult, type IIdentityProvider, type IPasswordHasher, type IProvider, type IdentityAuthResult, type IdentityConfig, IdentityNotConfiguredError, IdentityProviderError, type IdentityTokens, InvalidCredentialsError, InvalidOAuthCallbackError, InvalidProviderConfigError, InvalidStateError, type LinkedAccount, Lixa, type LixaConfig, type LixaCookieContext, LixaError, type LixaLogger, LocalCredentialsStorage, type LogContext, type LogLevel, type OAuthTokenResponse, type PasswordPolicyConfig, type PasswordPolicyResult, type Pbkdf2HasherOptions, Pbkdf2PasswordHasher, type ProviderConfig, type ProviderMetadata, ProviderNotConfiguredError, RefreshTokenError, type ResendConfirmationCodeParams, type ResendConfirmationCodeResult, type ResourceHandler, type ResourceStorage, SSOAccountAlreadyExistsError, type SafeLixaConfig, type ScopesConfig, type ScryptHasherOptions, ScryptPasswordHasher, SelfManagedIdentityProvider, type Session, type SessionCookieResolver, type SessionHandler, SessionNotFoundError, type SessionStorage, type SignInParams, type SignInResult, type SignUpParams, type SignUpResult, type StateData, type StateHandler, type StateStorage, type StorageAdapter, TokenExchangeError, UserAlreadyExistsError, type UserCredentials, type UserIdentity, type UserInfo, UserNotFoundError, type VerifyCredentialsParams, WeakPasswordError, clearSessionCookie, clearStateCookie, createSessionCookie, createStateCookie, index$1 as credentials, decodeIdToken, determineProviderFromIssuer, extractUserInfo, fetchUserInfo, index as identity, isProductionEnvironment, serializeCookie, validatePasswordPolicy };