@vunexa/lixa 0.0.1-alpha.3 → 0.0.1-alpha.33

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.
Files changed (48) hide show
  1. package/README.md +1081 -76
  2. package/dist/dao/session-cache.d.ts +10 -0
  3. package/dist/dao/session-cache.d.ts.map +1 -0
  4. package/dist/dao/state-cache.d.ts +12 -0
  5. package/dist/dao/state-cache.d.ts.map +1 -0
  6. package/dist/dao/types.d.ts +370 -0
  7. package/dist/dao/types.d.ts.map +1 -0
  8. package/dist/export-types/index.d.ts +1220 -0
  9. package/dist/export-types/tsdoc-metadata.json +11 -0
  10. package/dist/index.cjs +723 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +1189 -0
  13. package/dist/index.d.ts +19 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +681 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/lixa.d.ts +322 -11
  18. package/dist/lixa.d.ts.map +1 -1
  19. package/dist/models/session.d.ts +273 -0
  20. package/dist/models/session.d.ts.map +1 -0
  21. package/dist/providers/IProvider.d.ts +128 -0
  22. package/dist/providers/IProvider.d.ts.map +1 -1
  23. package/dist/providers/index.d.ts +0 -2
  24. package/dist/providers/index.d.ts.map +1 -1
  25. package/dist/types.d.ts +167 -16
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/utils/user-info.d.ts +82 -0
  28. package/dist/utils/user-info.d.ts.map +1 -0
  29. package/package.json +20 -10
  30. package/dist/lixa.js +0 -107
  31. package/dist/lixa.js.map +0 -1
  32. package/dist/providers/IProvider.js +0 -3
  33. package/dist/providers/IProvider.js.map +0 -1
  34. package/dist/providers/github.d.ts +0 -9
  35. package/dist/providers/github.d.ts.map +0 -1
  36. package/dist/providers/github.js +0 -8
  37. package/dist/providers/github.js.map +0 -1
  38. package/dist/providers/google.d.ts +0 -9
  39. package/dist/providers/google.d.ts.map +0 -1
  40. package/dist/providers/google.js +0 -8
  41. package/dist/providers/google.js.map +0 -1
  42. package/dist/providers/index.js +0 -3
  43. package/dist/providers/index.js.map +0 -1
  44. package/dist/types.js +0 -2
  45. package/dist/types.js.map +0 -1
  46. package/dist/utils/constants.js +0 -4
  47. package/dist/utils/constants.js.map +0 -1
  48. package/index.d.ts +0 -63
@@ -0,0 +1,1220 @@
1
+ /**
2
+ * A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library for backend applications.
3
+ *
4
+ * @remarks
5
+ * This package simplifies multi-provider authentication flows (e.g., Google, GitHub), supports extensible session management, and enables custom provider registration.
6
+ *
7
+ * Key features:
8
+ * - OAuth 2.0 authorization code flow with PKCE (RFC 6749, RFC 7636)
9
+ * - OpenID Connect support
10
+ * - Built-in providers available in \@vunexa/lixa-providers
11
+ * - Custom provider support via IProvider interface
12
+ * - Extensible session management via SessionDao.CreateSession
13
+ * - Pluggable state and session storage via StateDao and SessionDao
14
+ * - TypeScript-first with comprehensive type safety
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+
19
+ /**
20
+ * Type representing the keys of configured providers
21
+ */
22
+ declare type ConfiguredProviderKey<T extends LixaConfig<Record<string, ProviderConfig>>> = keyof T['providers'];
23
+
24
+ /**
25
+ * Decode JWT ID token to extract user information
26
+ *
27
+ * @public
28
+ */
29
+ export declare function decodeIdToken(idToken: string): UserInfo;
30
+
31
+ /**
32
+ * Determine OAuth provider from ID token issuer
33
+ *
34
+ * @public
35
+ */
36
+ export declare function determineProviderFromIssuer(userInfo: UserInfo): string | null;
37
+
38
+ /**
39
+ * Extract user info from OAuth token data
40
+ *
41
+ * @param tokenData - OAuth token response from provider
42
+ * @param providerMetadata - Provider metadata containing endpoints configuration
43
+ * @returns User info extracted from token or fetched from provider
44
+ *
45
+ * @remarks
46
+ * This function attempts to extract user information in the following order:
47
+ * 1. Decode ID token if present (preferred method for OIDC providers)
48
+ * 2. Fetch from userinfo endpoint using access token (uses providerMetadata.endpoints.userInfo)
49
+ *
50
+ * The function automatically determines the best method based on available token data.
51
+ * For OIDC providers (like Google), it decodes the JWT ID token.
52
+ * For OAuth-only providers (like GitHub), it fetches from the userinfo endpoint.
53
+ *
54
+ * @throws Error if no ID token or access token is available
55
+ * @throws Error if userinfo endpoint is required but not provided in providerMetadata
56
+ *
57
+ * @example
58
+ * With ID token (OIDC provider like Google):
59
+ * ```typescript
60
+ * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
61
+ * console.log(`User ${userInfo.email} authenticated`);
62
+ * ```
63
+ *
64
+ * @example
65
+ * Without ID token (OAuth provider like GitHub):
66
+ * ```typescript
67
+ * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
68
+ * // Automatically fetches from providerMetadata.endpoints.userInfo
69
+ * console.log(`User ${userInfo.email} authenticated`);
70
+ * ```
71
+ *
72
+ * @public
73
+ */
74
+ export declare function extractUserInfo(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<{
75
+ userInfo: UserInfo;
76
+ }>;
77
+
78
+ /**
79
+ * Fetch user info from OAuth provider's userinfo endpoint
80
+ *
81
+ * @param accessToken - OAuth access token
82
+ * @param userInfoEndpoint - The provider's userinfo endpoint URL
83
+ * @param providerName - Provider name for error messages (optional)
84
+ * @returns User information from the provider
85
+ *
86
+ * @throws Error if the request fails or response is invalid
87
+ *
88
+ * @public
89
+ */
90
+ export declare function fetchUserInfo(accessToken: string, userInfoEndpoint: string): Promise<UserInfo>;
91
+
92
+ /**
93
+ * Interface for OAuth 2.0 and OpenID Connect provider implementations.
94
+ *
95
+ * @remarks
96
+ * Implement this interface to add support for custom OAuth providers.
97
+ * Each provider defines the three core endpoints required for the OAuth 2.0
98
+ * authorization code flow with PKCE.
99
+ *
100
+ * Built-in providers (Google, GitHub) are available in the \@vunexa/lixa-providers package.
101
+ *
102
+ * All implementations must comply with:
103
+ * - RFC 6749 (OAuth 2.0)
104
+ * - RFC 7636 (PKCE)
105
+ * - OpenID Connect Core 1.0 (for OIDC providers)
106
+ *
107
+ * @example
108
+ * Custom provider implementation:
109
+ * ```typescript
110
+ * import { IProvider } from '@vunexa/lixa';
111
+ *
112
+ * class CustomProvider implements IProvider {
113
+ * authorizationEndpoint = 'https://auth.example.com/oauth/authorize';
114
+ * tokenEndpoint = 'https://auth.example.com/oauth/token';
115
+ * userInfoEndpoint = 'https://api.example.com/user';
116
+ * }
117
+ *
118
+ * // Use in configuration
119
+ * const lixa = new Lixa({
120
+ * providers: {
121
+ * custom: {
122
+ * provider: new CustomProvider(),
123
+ * clientId: 'your-client-id',
124
+ * clientSecret: 'your-client-secret',
125
+ * redirectUri: 'https://app.com/callback',
126
+ * scopes: ['read:user']
127
+ * }
128
+ * }
129
+ * });
130
+ * ```
131
+ *
132
+ * @example
133
+ * Object literal provider:
134
+ * ```typescript
135
+ * const customProvider: IProvider = {
136
+ * authorizationEndpoint: 'https://auth.example.com/oauth/authorize',
137
+ * tokenEndpoint: 'https://auth.example.com/oauth/token',
138
+ * userInfoEndpoint: 'https://api.example.com/user'
139
+ * };
140
+ * ```
141
+ *
142
+ * @public
143
+ */
144
+ export declare interface IProvider {
145
+ /**
146
+ * The OAuth 2.0 authorization endpoint URL.
147
+ *
148
+ * @remarks
149
+ * This is the URL where users are redirected to authenticate and authorize your application.
150
+ * The endpoint must support the OAuth 2.0 authorization code flow with PKCE.
151
+ *
152
+ * Standard query parameters sent to this endpoint:
153
+ * - client_id: Your application's client ID
154
+ * - redirect_uri: Where to redirect after authorization
155
+ * - response_type: Always "code" for authorization code flow
156
+ * - scope: Space-separated list of requested scopes
157
+ * - state: Random string for CSRF protection
158
+ * - code_challenge: PKCE code challenge (SHA-256 hash)
159
+ * - code_challenge_method: Always "S256" for SHA-256
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * authorizationEndpoint = 'https://accounts.google.com/o/oauth2/v2/auth'
164
+ * ```
165
+ */
166
+ authorizationEndpoint: string;
167
+ /**
168
+ * The OAuth 2.0 token endpoint URL.
169
+ *
170
+ * @remarks
171
+ * This is the URL where authorization codes are exchanged for access tokens.
172
+ * The endpoint must support the OAuth 2.0 token exchange with PKCE.
173
+ *
174
+ * Standard parameters sent to this endpoint (POST request):
175
+ * - grant_type: Always "authorization_code"
176
+ * - code: The authorization code from the callback
177
+ * - redirect_uri: Must match the authorization request
178
+ * - client_id: Your application's client ID
179
+ * - client_secret: Your application's client secret
180
+ * - code_verifier: PKCE code verifier (original random string)
181
+ *
182
+ * Expected response:
183
+ * - access_token: OAuth access token
184
+ * - token_type: Token type (usually "Bearer")
185
+ * - expires_in: Token expiration time in seconds
186
+ * - refresh_token: Refresh token (optional)
187
+ * - id_token: OpenID Connect ID token (for OIDC providers)
188
+ * - scope: Granted scopes
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * tokenEndpoint = 'https://oauth2.googleapis.com/token'
193
+ * ```
194
+ */
195
+ tokenEndpoint: string;
196
+ /**
197
+ * The user information endpoint URL.
198
+ *
199
+ * @remarks
200
+ * This is the URL where user profile information can be retrieved using the access token.
201
+ * For OpenID Connect providers, this is the UserInfo endpoint.
202
+ *
203
+ * The endpoint is called with the access token in the Authorization header:
204
+ * ```
205
+ * Authorization: Bearer <access_token>
206
+ * ```
207
+ *
208
+ * Common response fields:
209
+ * - sub: Subject identifier (user ID)
210
+ * - email: User's email address
211
+ * - name: User's full name
212
+ * - picture: User's profile picture URL
213
+ * - email_verified: Whether email is verified
214
+ *
215
+ * Note: This endpoint is not called automatically by Lixa. Your SessionStrategy
216
+ * can call it if needed to fetch user profile information.
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * userInfoEndpoint = 'https://www.googleapis.com/oauth2/v2/userinfo'
221
+ * ```
222
+ */
223
+ userInfoEndpoint: string;
224
+ }
225
+
226
+ /**
227
+ * A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library.
228
+ *
229
+ * @remarks
230
+ * Lixa simplifies multi-provider authentication flows and supports extensible session management.
231
+ * Providers can be passed inline in the configuration, eliminating the need for pre-registration.
232
+ *
233
+ * @example
234
+ * Using built-in providers from \@vunexa/lixa-providers:
235
+ * ```typescript
236
+ * import { Lixa } from '@vunexa/lixa';
237
+ * import { GoogleProvider } from '@vunexa/lixa-providers';
238
+ *
239
+ * const lixa = new Lixa({
240
+ * providers: {
241
+ * google: {
242
+ * provider: new GoogleProvider(),
243
+ * clientId: 'your-client-id',
244
+ * clientSecret: 'your-client-secret',
245
+ * redirectUri: 'https://yourapp.com/auth/google/callback',
246
+ * scopes: ['openid', 'email', 'profile']
247
+ * }
248
+ * }
249
+ * });
250
+ * ```
251
+ *
252
+ * @example
253
+ * Using custom inline providers:
254
+ * ```typescript
255
+ * import { Lixa, IProvider } from '@vunexa/lixa';
256
+ *
257
+ * const customProvider: IProvider = {
258
+ * authorizationEndpoint: 'https://custom.com/oauth/authorize',
259
+ * tokenEndpoint: 'https://custom.com/oauth/token',
260
+ * userInfoEndpoint: 'https://custom.com/api/user'
261
+ * };
262
+ *
263
+ * const lixa = new Lixa({
264
+ * providers: {
265
+ * custom: {
266
+ * provider: customProvider,
267
+ * clientId: 'your-client-id',
268
+ * clientSecret: 'your-client-secret',
269
+ * redirectUri: 'https://yourapp.com/auth/custom/callback',
270
+ * scopes: ['read:user']
271
+ * }
272
+ * }
273
+ * });
274
+ * ```
275
+ *
276
+ * @public
277
+ */
278
+ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConfig>> = LixaConfig> {
279
+ private static DEFAULT_PROVIDERS;
280
+ private static CONFIGURED_PROVIDERS;
281
+ private static LOCAL_STATE_HANDLER;
282
+ private static LOCAL_SESSION_HANDLER;
283
+ private config;
284
+ private stateHandler;
285
+ private sessionHandler;
286
+ private debug;
287
+ /**
288
+ * Creates a new Lixa instance with the provided configuration.
289
+ *
290
+ * @remarks
291
+ * Providers can be passed inline in the configuration using the `provider` field.
292
+ * Provider resolution priority: inline custom provider \> default providers \> legacy registry.
293
+ *
294
+ * @param config - The configuration object containing provider settings and optional session strategy
295
+ *
296
+ * @throws Error when provider configuration is missing required fields
297
+ * @throws Error when provider implementation is missing required properties
298
+ * @throws Error when provider is not available and no inline implementation is provided
299
+ */
300
+ constructor(config: TConfig);
301
+ /**
302
+ * Validates that a provider configuration has all required credentials.
303
+ *
304
+ * @param name - The provider name
305
+ * @param config - The provider configuration
306
+ * @throws Error when required fields are missing or invalid
307
+ */
308
+ private validateProviderConfig;
309
+ /**
310
+ * Validates that a provider implementation has all required properties.
311
+ *
312
+ * @param name - The provider name
313
+ * @param provider - The provider implementation
314
+ * @throws Error when required properties are missing
315
+ */
316
+ private validateProviderImplementation;
317
+ /**
318
+ * Structured debug logging with standardized format.
319
+ *
320
+ * @param level - Log level (INFO, WARN, ERROR)
321
+ * @param context - Context of the log (Init, Auth, Token, Session, State)
322
+ * @param message - Log message
323
+ * @param data - Optional data to log
324
+ *
325
+ * @remarks
326
+ * Format: [Lixa] [timestamp] [level] [context] message
327
+ * Only logs when debug mode is enabled.
328
+ */
329
+ private log;
330
+ /**
331
+ * Checks if a provider is configured for this instance.
332
+ * This is a type guard that narrows the provider type for use with getAuthUrl.
333
+ *
334
+ * @param provider - The provider name to check (case-insensitive)
335
+ * @returns True if the provider is configured, false otherwise
336
+ *
337
+ * @example
338
+ * ```typescript
339
+ * if (lixa.isProviderConfigured(provider)) {
340
+ * // TypeScript now knows provider is a valid ConfiguredProviderKey
341
+ * const authUrl = lixa.getAuthUrl(provider, state);
342
+ * }
343
+ * ```
344
+ */
345
+ isProviderConfigured<T extends string>(provider: T): provider is T & ConfiguredProviderKey<TConfig>;
346
+ /**
347
+ * Gets a provider implementation by name.
348
+ * Resolution priority: inline custom provider \> default providers \> legacy registry
349
+ *
350
+ * @param name - The provider name (case-insensitive)
351
+ * @param config - The provider configuration
352
+ * @returns The provider implementation
353
+ * @throws Error when provider is not found
354
+ */
355
+ private getProvider;
356
+ /**
357
+ * Registers custom OAuth providers for use with Lixa.
358
+ *
359
+ * @deprecated This method is maintained for backward compatibility.
360
+ * The recommended approach is to pass providers inline in the configuration:
361
+ * ```typescript
362
+ * const lixa = new Lixa({
363
+ * providers: {
364
+ * custom: {
365
+ * provider: new CustomProvider(),
366
+ * clientId: '...',
367
+ * // ...
368
+ * }
369
+ * }
370
+ * });
371
+ * ```
372
+ *
373
+ * @param providerMap - A map of provider names to IProvider implementations
374
+ *
375
+ * @example
376
+ * Legacy usage (still supported):
377
+ * ```typescript
378
+ * class CustomProvider implements IProvider {
379
+ * authorizationEndpoint = 'https://custom.com/oauth/authorize';
380
+ * tokenEndpoint = 'https://custom.com/oauth/token';
381
+ * userInfoEndpoint = 'https://custom.com/api/user';
382
+ * }
383
+ *
384
+ * Lixa.registerProvider({ custom: new CustomProvider() });
385
+ * ```
386
+ */
387
+ static registerProvider<T extends Record<string, IProvider>>(providerMap: T): void;
388
+ /**
389
+ * Gets the list of registered provider names.
390
+ *
391
+ * @returns Array of registered provider names
392
+ */
393
+ static getRegisteredProviders(): string[];
394
+ /**
395
+ * Creates a type-safe configuration.
396
+ *
397
+ * @deprecated This method is maintained for backward compatibility.
398
+ * You can now pass configuration directly to the Lixa constructor without this helper.
399
+ *
400
+ * @param config - Configuration object with provider settings
401
+ * @returns The same configuration object with type safety
402
+ *
403
+ * @example
404
+ * New approach (recommended):
405
+ * ```typescript
406
+ * const lixa = new Lixa({
407
+ * providers: {
408
+ * google: {
409
+ * provider: new GoogleProvider(),
410
+ * clientId: '...',
411
+ * // ...
412
+ * }
413
+ * }
414
+ * });
415
+ * ```
416
+ */
417
+ static createConfig<T extends Record<string, ProviderConfig>>(config: LixaConfig<T> & {
418
+ providers: T;
419
+ }): LixaConfig<T>;
420
+ /**
421
+ * Generates a cryptographically secure random state parameter for OAuth flows.
422
+ *
423
+ * @returns A 32-character hexadecimal string
424
+ *
425
+ * @remarks
426
+ * The state parameter is used to prevent CSRF attacks in OAuth flows.
427
+ */
428
+ static generateRandomState(): string;
429
+ /**
430
+ * Generates a cryptographically secure code verifier for PKCE flows.
431
+ *
432
+ * @returns A 64-character hexadecimal string (32 random bytes encoded as hex)
433
+ *
434
+ * @remarks
435
+ * This method implements the code verifier generation as specified in RFC 7636 (PKCE).
436
+ *
437
+ * **PKCE (Proof Key for Code Exchange)** is a security extension to OAuth 2.0 that
438
+ * prevents authorization code interception attacks. It's especially important for
439
+ * public clients (mobile apps, SPAs) but is recommended for all OAuth flows.
440
+ *
441
+ * **Generation methodology:**
442
+ * 1. Generate 32 cryptographically random bytes using Node.js crypto.randomBytes()
443
+ * 2. Encode the bytes as a hexadecimal string (64 characters)
444
+ * 3. The verifier is stored securely and used later in the token exchange
445
+ *
446
+ * **RFC 7636 Requirements:**
447
+ * - Minimum length: 43 characters
448
+ * - Maximum length: 128 characters
449
+ * - Character set: [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
450
+ * - This implementation produces 64 hex characters, meeting the requirements
451
+ *
452
+ * The code verifier is:
453
+ * - Generated when creating the authorization URL
454
+ * - Stored in state cache with the state parameter
455
+ * - Retrieved during callback handling
456
+ * - Sent to the token endpoint to prove the client's identity
457
+ *
458
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7636 | RFC 7636 - PKCE}
459
+ * @see buildCodeChallenge for the corresponding challenge generation
460
+ *
461
+ * @internal
462
+ */
463
+ private static generateCodeVerifier;
464
+ /**
465
+ * Generates a code challenge from a code verifier for PKCE flows.
466
+ *
467
+ * @param codeVerifier - The code verifier string (64 hex characters)
468
+ * @returns A base64url-encoded SHA-256 hash of the code verifier
469
+ *
470
+ * @remarks
471
+ * This method implements the code challenge generation as specified in RFC 7636 (PKCE)
472
+ * using the S256 (SHA-256) transformation method.
473
+ *
474
+ * **Challenge generation methodology:**
475
+ * 1. Hash the code verifier using SHA-256
476
+ * 2. Encode the hash as base64
477
+ * 3. Convert to base64url format (RFC 4648):
478
+ * - Replace '+' with '-'
479
+ * - Replace '/' with '_'
480
+ * - Remove trailing '=' padding
481
+ *
482
+ * **PKCE Flow:**
483
+ * 1. Client generates code_verifier (random string)
484
+ * 2. Client creates code_challenge = BASE64URL(SHA256(code_verifier))
485
+ * 3. Client sends code_challenge to authorization endpoint
486
+ * 4. Authorization server stores the code_challenge
487
+ * 5. Client sends code_verifier to token endpoint
488
+ * 6. Authorization server verifies: SHA256(code_verifier) == code_challenge
489
+ *
490
+ * **Security Benefits:**
491
+ * - Prevents authorization code interception attacks
492
+ * - Even if an attacker intercepts the authorization code, they cannot
493
+ * exchange it for tokens without the original code_verifier
494
+ * - The challenge is sent in the authorization request (public)
495
+ * - The verifier is sent in the token request (should be kept secret)
496
+ *
497
+ * **RFC 7636 Transformation Methods:**
498
+ * - plain: code_challenge = code_verifier (not recommended)
499
+ * - S256: code_challenge = BASE64URL(SHA256(code_verifier)) (recommended, used here)
500
+ *
501
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7636 | RFC 7636 - PKCE}
502
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc4648#section-5 | RFC 4648 - Base64url Encoding}
503
+ * @see generateCodeVerifier for the verifier generation
504
+ *
505
+ * @internal
506
+ */
507
+ private static buildCodeChallenge;
508
+ /**
509
+ * Generates the authorization URL for the specified provider.
510
+ *
511
+ * @param provider - The provider name (must be a configured provider key)
512
+ * @param state - The state parameter for CSRF protection
513
+ * @returns The complete authorization URL to redirect users to
514
+ *
515
+ * @throws Error when the provider is not configured
516
+ *
517
+ * @example
518
+ * ```typescript
519
+ * const state = Lixa.generateRandomState();
520
+ * const authUrl = lixa.getAuthUrl('google', state);
521
+ * res.redirect(authUrl);
522
+ * ```
523
+ */
524
+ getAuthUrl(provider: ConfiguredProviderKey<TConfig> | string, state?: string): Promise<string>;
525
+ /**
526
+ * Handles the OAuth callback and creates a user session.
527
+ *
528
+ * @param provider - The provider name (must be a configured provider key)
529
+ * @param code - The authorization code from the provider
530
+ * @param state - The state parameter for validation
531
+ * @returns A Promise that resolves to the session ID
532
+ *
533
+ * @throws Error when code or state is missing/invalid, or provider is not configured
534
+ *
535
+ * @example
536
+ * ```typescript
537
+ * const sessionId = await lixa.handleCallback({
538
+ * provider: 'google',
539
+ * code: req.query.code,
540
+ * state: req.query.state
541
+ * });
542
+ * ```
543
+ */
544
+ handleCallback({ provider, code, state, }: {
545
+ provider: ConfiguredProviderKey<TConfig> | string;
546
+ code: string;
547
+ state?: string;
548
+ }): Promise<string>;
549
+ fetchSessionInfo(sessionId: string): Promise<Session | null>;
550
+ private exchangeCodeForToken;
551
+ private findProviderByType;
552
+ }
553
+
554
+ /**
555
+ * Main configuration object for Lixa.
556
+ * Provides type-safe provider name inference.
557
+ *
558
+ * @remarks
559
+ * The generic type parameter TProviders enables TypeScript to infer provider names
560
+ * from the configuration object, providing autocomplete and type checking for
561
+ * provider names in methods like getAuthUrl() and handleCallback().
562
+ *
563
+ * @typeParam TProviders - The provider configuration map type, defaults to a generic record
564
+ *
565
+ * @example
566
+ * Basic configuration with built-in providers:
567
+ * ```typescript
568
+ * import { Lixa } from '@vunexa/lixa';
569
+ * import { GoogleProvider } from '@vunexa/lixa-providers';
570
+ *
571
+ * const lixa = new Lixa({
572
+ * providers: {
573
+ * google: {
574
+ * provider: new GoogleProvider(),
575
+ * clientId: process.env.GOOGLE_CLIENT_ID!,
576
+ * clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
577
+ * redirectUri: 'https://app.com/auth/google/callback',
578
+ * scopes: ['openid', 'email', 'profile']
579
+ * }
580
+ * }
581
+ * });
582
+ * ```
583
+ *
584
+ * @example
585
+ * Configuration with custom session and state handlers:
586
+ * ```typescript
587
+ * const lixa = new Lixa({
588
+ * providers: {
589
+ * google: {
590
+ * provider: new GoogleProvider(),
591
+ * clientId: process.env.GOOGLE_CLIENT_ID!,
592
+ * clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
593
+ * redirectUri: 'https://app.com/auth/google/callback',
594
+ * scopes: ['openid', 'email', 'profile']
595
+ * }
596
+ * },
597
+ * stateHandler: {
598
+ * storage: {
599
+ * saveState: async (state, data, ttl) => await redis.setex(state, ttl, JSON.stringify(data)),
600
+ * getState: async (state) => JSON.parse(await redis.get(state) || 'null'),
601
+ * deleteState: async (state) => await redis.del(state)
602
+ * }
603
+ * },
604
+ * sessionHandler: {
605
+ * GenerateSession: async (tokenData, providerMetadata) => {
606
+ * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
607
+ * const user = await db.users.upsert({ email: userInfo.email });
608
+ * return { token: tokenData.access_token, raw: { ...tokenData, userId: user.id } };
609
+ * },
610
+ * storage: {
611
+ * saveSession: async (id, session, ttl) => await db.sessions.create({ id, session, ttl }),
612
+ * getSession: async (id) => await db.sessions.findOne({ id }),
613
+ * deleteSession: async (id) => await db.sessions.delete({ id })
614
+ * }
615
+ * },
616
+ * debug: true
617
+ * });
618
+ * ```
619
+ *
620
+ * @public
621
+ */
622
+ export declare interface LixaConfig<TProviders extends Record<string, ProviderConfig> = Record<string, ProviderConfig>> {
623
+ /**
624
+ * Map of provider names to their configurations.
625
+ * Provider names will be available for autocomplete in getAuthUrl() and handleCallback().
626
+ */
627
+ providers: TProviders;
628
+ /**
629
+ * Optional custom state handler.
630
+ * Handles state generation and storage during OAuth authorization flow.
631
+ *
632
+ * - GenerateState: Customizes how state parameters and PKCE verifiers are generated
633
+ * - storage: Provides persistent state storage (save/get/delete operations)
634
+ *
635
+ * Defaults to in-memory cache if not provided (not suitable for production).
636
+ *
637
+ * @see {@link StateHandler}
638
+ */
639
+ stateHandler?: StateHandler;
640
+ /**
641
+ * Optional custom session handler.
642
+ * Handles session generation and storage after authentication.
643
+ *
644
+ * - GenerateSession: Customizes how OAuth tokens are converted into session data
645
+ * - storage: Provides persistent session storage (save/get/delete operations)
646
+ *
647
+ * Defaults to in-memory cache if not provided (not suitable for production).
648
+ *
649
+ * @see {@link SessionHandler}
650
+ */
651
+ sessionHandler?: SessionHandler;
652
+ /**
653
+ * Enable debug logging.
654
+ * When enabled, outputs structured logs for initialization, auth flow, and errors.
655
+ * Format: [Lixa] [timestamp] [level] [context] message
656
+ */
657
+ debug?: boolean;
658
+ }
659
+
660
+ /**
661
+ * OAuth 2.0 token response structure.
662
+ * Based on RFC 6749 Section 5.1 and OpenID Connect Core 1.0 Section 3.1.3.3
663
+ *
664
+ * @remarks
665
+ * This interface represents the standard OAuth 2.0 token response with
666
+ * optional OpenID Connect extensions. All OAuth providers should return
667
+ * at minimum the required fields (access_token, token_type).
668
+ *
669
+ * @public
670
+ */
671
+ export declare interface OAuthTokenResponse {
672
+ /**
673
+ * OAuth 2.0 access token (required).
674
+ * Used to access protected resources on behalf of the user.
675
+ */
676
+ access_token: string;
677
+ /**
678
+ * Token type (required).
679
+ * Typically "Bearer" for OAuth 2.0.
680
+ */
681
+ token_type: string;
682
+ /**
683
+ * Token expiration time in seconds (optional).
684
+ * Time until the access token expires.
685
+ */
686
+ expires_in?: number;
687
+ /**
688
+ * OAuth 2.0 refresh token (optional).
689
+ * Used to obtain new access tokens without re-authentication.
690
+ */
691
+ refresh_token?: string;
692
+ /**
693
+ * Granted OAuth scopes (optional).
694
+ * Space-separated list of scopes that were granted.
695
+ */
696
+ scope?: string;
697
+ /**
698
+ * OpenID Connect ID token (optional).
699
+ * JWT containing user identity claims (only present for OIDC providers).
700
+ */
701
+ id_token?: string;
702
+ /**
703
+ * Additional provider-specific fields.
704
+ * Some providers may include extra fields like user_id, account_id, etc.
705
+ */
706
+ [key: string]: string | number | boolean | undefined;
707
+ }
708
+
709
+ /**
710
+ * Configuration for an OAuth provider instance.
711
+ *
712
+ * @remarks
713
+ * For built-in providers (google, github), just provide credentials.
714
+ * For custom providers, include the provider implementation.
715
+ *
716
+ * The provider field uses a discriminated union to ensure type safety:
717
+ * - When omitted or undefined: assumes a built-in provider
718
+ * - When provided: must be a valid IProvider implementation
719
+ *
720
+ * @example
721
+ * Built-in provider configuration:
722
+ * ```typescript
723
+ * {
724
+ * clientId: 'your-client-id',
725
+ * clientSecret: 'your-client-secret',
726
+ * redirectUri: 'https://app.com/callback',
727
+ * scopes: ['openid', 'email']
728
+ * }
729
+ * ```
730
+ *
731
+ * @example
732
+ * Custom provider configuration:
733
+ * ```typescript
734
+ * {
735
+ * provider: new CustomProvider(),
736
+ * clientId: 'your-client-id',
737
+ * clientSecret: 'your-client-secret',
738
+ * redirectUri: 'https://app.com/callback',
739
+ * scopes: ['read:user']
740
+ * }
741
+ * ```
742
+ *
743
+ * @public
744
+ */
745
+ export declare type ProviderConfig = {
746
+ /** The OAuth client ID provided by the provider */
747
+ clientId: string;
748
+ /** The OAuth client secret provided by the provider */
749
+ clientSecret: string;
750
+ /** The redirect URI registered with the provider */
751
+ redirectUri: string;
752
+ /** Array of OAuth scopes to request */
753
+ scopes: string[];
754
+ /** Additional provider-specific configuration parameters */
755
+ extraConfig?: Record<string, string>;
756
+ } & ({
757
+ provider?: never;
758
+ } | {
759
+ provider: IProvider;
760
+ });
761
+
762
+ /**
763
+ * Provider metadata passed to session strategy.
764
+ * Contains provider name and endpoints for user info extraction.
765
+ *
766
+ * @public
767
+ */
768
+ export declare interface ProviderMetadata {
769
+ /** The provider name (e.g., 'google', 'github') */
770
+ name: string;
771
+ /** Provider endpoints */
772
+ endpoints: {
773
+ /** Authorization endpoint URL */
774
+ authorization: string;
775
+ /** Token endpoint URL */
776
+ token: string;
777
+ /** UserInfo endpoint URL */
778
+ userInfo: string;
779
+ };
780
+ }
781
+
782
+ /**
783
+ * Helper type to create a configuration with only registered providers.
784
+ * Use this with Lixa.createConfig() for type safety.
785
+ *
786
+ * @deprecated This type is maintained for backward compatibility.
787
+ * The new inline provider configuration pattern makes this unnecessary.
788
+ *
789
+ * @public
790
+ */
791
+ export declare type SafeLixaConfig<TProviders extends Record<string, ProviderConfig>> = LixaConfig<TProviders> & {
792
+ providers: TProviders;
793
+ };
794
+
795
+ /**
796
+ * Represents a user session after successful OAuth authentication.
797
+ *
798
+ * @remarks
799
+ * The Session object is returned by SessionStrategy.createSession() and contains
800
+ * the session identifier and any additional data needed for your application.
801
+ *
802
+ * The structure is intentionally flexible to support various session management
803
+ * approaches (JWT tokens, session IDs, etc.).
804
+ *
805
+ * @public
806
+ */
807
+ export declare interface Session<TRaw = OAuthTokenResponse> {
808
+ /**
809
+ * The session token or identifier.
810
+ * This could be an access token, a session ID, a JWT, or any other identifier
811
+ * that your application uses to track authenticated users.
812
+ */
813
+ token: string;
814
+ /**
815
+ * Raw session data.
816
+ * Contains the complete OAuth token response and any additional data
817
+ * your SessionStrategy adds (user info, database IDs, etc.).
818
+ *
819
+ * Typical OAuth token data includes:
820
+ * - access_token: OAuth access token
821
+ * - refresh_token: OAuth refresh token (if requested)
822
+ * - expires_in: Token expiration time in seconds
823
+ * - token_type: Token type (usually "Bearer")
824
+ * - id_token: OpenID Connect ID token (if using OIDC)
825
+ * - scope: Granted scopes
826
+ */
827
+ raw: TRaw;
828
+ }
829
+
830
+ /**
831
+ * Session handler for OAuth authentication.
832
+ *
833
+ * @remarks
834
+ * The SessionHandler manages session generation and storage after successful OAuth authentication.
835
+ *
836
+ * - GenerateSession: Optional. Customizes how OAuth tokens are converted into session data.
837
+ * If not provided, uses default implementation (access token as session token).
838
+ *
839
+ * - storage: Optional. Provides custom session storage (save/get/delete operations).
840
+ * If not provided, uses in-memory cache (not suitable for production).
841
+ *
842
+ * For production, implement both GenerateSession (for user creation/lookup) and storage
843
+ * (for persistent session storage with Redis, database, etc.).
844
+ *
845
+ * @example
846
+ * Full implementation with database:
847
+ * ```typescript
848
+ * import { SessionHandler, Session, OAuthTokenResponse, ProviderMetadata, extractUserInfo } from '@vunexa/lixa';
849
+ *
850
+ * const sessionHandler: SessionHandler = {
851
+ * GenerateSession: async (tokenData, providerMetadata) => {
852
+ * // Extract user info and create/retrieve user
853
+ * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
854
+ * const user = await db.users.upsert({
855
+ * email: userInfo.email,
856
+ * name: userInfo.name
857
+ * });
858
+ *
859
+ * // Return session data (not stored yet)
860
+ * return {
861
+ * token: tokenData.access_token,
862
+ * raw: {
863
+ * ...tokenData,
864
+ * userId: user.id,
865
+ * provider: providerMetadata.name
866
+ * }
867
+ * };
868
+ * },
869
+ *
870
+ * storage: {
871
+ * saveSession: async (sessionId, session, expiresInSeconds) => {
872
+ * const expiresAt = new Date(Date.now() + expiresInSeconds * 1000);
873
+ * await db.sessions.create({
874
+ * id: sessionId,
875
+ * token: session.token,
876
+ * data: session.raw,
877
+ * expiresAt
878
+ * });
879
+ * },
880
+ *
881
+ * getSession: async (sessionId) => {
882
+ * const record = await db.sessions.findOne({
883
+ * id: sessionId,
884
+ * expiresAt: { $gt: new Date() }
885
+ * });
886
+ * return record ? { token: record.token, raw: record.data } : null;
887
+ * },
888
+ *
889
+ * deleteSession: async (sessionId) => {
890
+ * await db.sessions.delete({ id: sessionId });
891
+ * }
892
+ * }
893
+ * };
894
+ * ```
895
+ *
896
+ * @example
897
+ * Minimal implementation (uses defaults):
898
+ * ```typescript
899
+ * const sessionHandler: SessionHandler = {
900
+ * storage: {
901
+ * saveSession: async (sessionId, session, expiresInSeconds) => {
902
+ * await redis.setex(sessionId, expiresInSeconds, JSON.stringify(session));
903
+ * },
904
+ * getSession: async (sessionId) => {
905
+ * const data = await redis.get(sessionId);
906
+ * return data ? JSON.parse(data) : null;
907
+ * },
908
+ * deleteSession: async (sessionId) => {
909
+ * await redis.del(sessionId);
910
+ * }
911
+ * }
912
+ * };
913
+ * ```
914
+ *
915
+ * @public
916
+ */
917
+ export declare interface SessionHandler {
918
+ /**
919
+ * Generates session data from OAuth token data.
920
+ *
921
+ * @param tokenData - The token data received from the OAuth provider's token endpoint
922
+ * @param providerMetadata - Provider metadata including name and endpoints
923
+ * @returns A Promise that resolves to session data
924
+ *
925
+ * @remarks
926
+ * This method is responsible for creating session data from OAuth tokens.
927
+ * It is called after successfully exchanging the authorization code for tokens.
928
+ *
929
+ * Token Data:
930
+ * - access_token: OAuth access token
931
+ * - refresh_token: OAuth refresh token (optional)
932
+ * - expires_in: Token expiration time in seconds
933
+ * - token_type: Token type (usually "Bearer")
934
+ * - id_token: OpenID Connect ID token (for OIDC providers)
935
+ * - scope: Granted scopes
936
+ *
937
+ * Provider Metadata:
938
+ * - name: The provider name (e.g., 'google', 'github')
939
+ * - endpoints: Provider endpoints (authorization, token, userInfo)
940
+ *
941
+ * Your implementation should:
942
+ * 1. Extract user info (using extractUserInfo or decode ID token)
943
+ * 2. Create or lookup users in your database
944
+ * 3. Build and return session data with any custom fields
945
+ *
946
+ * Note: This method should NOT store the session. Storage is handled by the storage object.
947
+ *
948
+ * If not provided, defaults to using the access token as the session token.
949
+ *
950
+ * @example
951
+ * ```typescript
952
+ * GenerateSession: async (tokenData, providerMetadata) => {
953
+ * const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
954
+ * const user = await db.users.upsert({ email: userInfo.email });
955
+ *
956
+ * return {
957
+ * token: tokenData.access_token,
958
+ * raw: {
959
+ * ...tokenData,
960
+ * userId: user.id,
961
+ * provider: providerMetadata.name
962
+ * }
963
+ * };
964
+ * }
965
+ * ```
966
+ */
967
+ generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
968
+ /**
969
+ * Session storage operations.
970
+ *
971
+ * @remarks
972
+ * Provides methods for saving, retrieving, and deleting sessions.
973
+ * All three methods must be implemented together.
974
+ *
975
+ * If not provided, uses in-memory cache (not suitable for production).
976
+ */
977
+ sessionStorage?: SessionStorage;
978
+ /**
979
+ * Optional method to generate session data from OAuth tokens.
980
+ *
981
+ * @remarks
982
+ * If not provided, uses default implementation from LocalSessionHandler.
983
+ */
984
+ generateSession?<T extends Session>(tokenData: OAuthTokenResponse, providerMetadata: ProviderMetadata): Promise<T>;
985
+ }
986
+
987
+ /**
988
+ * Session storage operations interface.
989
+ *
990
+ * @remarks
991
+ * Groups all session storage operations together. All methods must be implemented
992
+ * if this interface is provided.
993
+ *
994
+ * @public
995
+ */
996
+ export declare interface SessionStorage {
997
+ /**
998
+ * Saves a session with expiration.
999
+ *
1000
+ * @param sessionId - Unique session identifier
1001
+ * @param session - Session data from GenerateSession()
1002
+ * @param expiresInSeconds - TTL in seconds (typically 86400 for 24 hours)
1003
+ */
1004
+ saveSession<T extends Session>(sessionId: string, session: T, expiresInSeconds: number): Promise<void>;
1005
+ /**
1006
+ * Retrieves a session by ID.
1007
+ *
1008
+ * @param sessionId - Unique session identifier
1009
+ * @returns Session data or null if not found or expired
1010
+ */
1011
+ getSession<T extends Session>(sessionId: string): Promise<T | null>;
1012
+ /**
1013
+ * Deletes a session (e.g., on logout).
1014
+ *
1015
+ * @param sessionId - Unique session identifier
1016
+ */
1017
+ deleteSession(sessionId: string): Promise<void>;
1018
+ }
1019
+
1020
+ /**
1021
+ * OAuth state data structure.
1022
+ *
1023
+ * @remarks
1024
+ * This structure is used internally by Lixa to store OAuth flow state
1025
+ * during the authorization process. It contains the information needed
1026
+ * to complete the PKCE flow and route callbacks to the correct provider.
1027
+ *
1028
+ * @public
1029
+ */
1030
+ export declare interface StateData {
1031
+ /**
1032
+ * Provider name for callback routing.
1033
+ * Used to identify which provider configuration to use when handling the callback.
1034
+ *
1035
+ * @example 'google', 'github', 'custom'
1036
+ */
1037
+ provider: string;
1038
+ /**
1039
+ * PKCE code verifier for secure token exchange.
1040
+ * A cryptographically random string (64 hex characters) used in the PKCE flow
1041
+ * to prevent authorization code interception attacks.
1042
+ *
1043
+ * @see RFC 7636 - Proof Key for Code Exchange
1044
+ */
1045
+ codeVerifier: string;
1046
+ /**
1047
+ * Unix timestamp in milliseconds when the state was created.
1048
+ * Used for debugging and validation purposes.
1049
+ */
1050
+ createdAt: number;
1051
+ }
1052
+
1053
+ /**
1054
+ * State handler for OAuth authorization flow.
1055
+ *
1056
+ * @remarks
1057
+ * The StateHandler manages state generation and storage during the OAuth authorization flow.
1058
+ *
1059
+ * - GenerateState: Optional. Customizes how state parameters and PKCE verifiers are generated.
1060
+ * If not provided, uses default implementation (cryptographically secure random strings).
1061
+ *
1062
+ * - storage: Optional. Provides custom state storage (save/get/delete operations).
1063
+ * If not provided, uses in-memory cache (not suitable for production).
1064
+ *
1065
+ * For production, implement storage with Redis, database, or other distributed cache.
1066
+ *
1067
+ * @example
1068
+ * Full implementation with Redis:
1069
+ * ```typescript
1070
+ * import { StateHandler, StateData } from '@vunexa/lixa';
1071
+ *
1072
+ * const stateHandler: StateHandler = {
1073
+ * GenerateState: async (provider) => {
1074
+ * const state = generateSecureRandomString(32);
1075
+ * const codeVerifier = generateSecureRandomString(64);
1076
+ * return {
1077
+ * state,
1078
+ * data: {
1079
+ * provider,
1080
+ * codeVerifier,
1081
+ * createdAt: Date.now()
1082
+ * }
1083
+ * };
1084
+ * },
1085
+ *
1086
+ * storage: {
1087
+ * saveState: async (state, data, expiresInSeconds) => {
1088
+ * await redis.setex(`oauth:state:${state}`, expiresInSeconds, JSON.stringify(data));
1089
+ * },
1090
+ * getState: async (state) => {
1091
+ * const data = await redis.get(`oauth:state:${state}`);
1092
+ * return data ? JSON.parse(data) : null;
1093
+ * },
1094
+ * deleteState: async (state) => {
1095
+ * await redis.del(`oauth:state:${state}`);
1096
+ * }
1097
+ * }
1098
+ * };
1099
+ * ```
1100
+ *
1101
+ * @example
1102
+ * Minimal implementation (uses defaults):
1103
+ * ```typescript
1104
+ * const stateHandler: StateHandler = {
1105
+ * storage: {
1106
+ * saveState: async (state, data, expiresInSeconds) => {
1107
+ * await redis.setex(state, expiresInSeconds, JSON.stringify(data));
1108
+ * },
1109
+ * getState: async (state) => {
1110
+ * const data = await redis.get(state);
1111
+ * return data ? JSON.parse(data) : null;
1112
+ * },
1113
+ * deleteState: async (state) => {
1114
+ * await redis.del(state);
1115
+ * }
1116
+ * }
1117
+ * };
1118
+ * ```
1119
+ *
1120
+ * @public
1121
+ */
1122
+ export declare interface StateHandler {
1123
+ /**
1124
+ * Generates OAuth state parameter and associated data.
1125
+ *
1126
+ * @param provider - The provider name for callback routing
1127
+ * @returns A Promise that resolves to state string and state data
1128
+ *
1129
+ * @remarks
1130
+ * This method generates:
1131
+ * - state: A cryptographically secure random string for CSRF protection
1132
+ * - codeVerifier: A PKCE code verifier for secure token exchange
1133
+ * - createdAt: Timestamp for debugging
1134
+ *
1135
+ * If not provided, defaults to generating 32-byte hex strings for state
1136
+ * and 64-byte hex strings for code verifier.
1137
+ *
1138
+ * @example
1139
+ * ```typescript
1140
+ * GenerateState: async (provider) => {
1141
+ * const state = crypto.randomBytes(16).toString('hex');
1142
+ * const codeVerifier = crypto.randomBytes(32).toString('hex');
1143
+ * return {
1144
+ * state,
1145
+ * data: {
1146
+ * provider,
1147
+ * codeVerifier,
1148
+ * createdAt: Date.now()
1149
+ * }
1150
+ * };
1151
+ * }
1152
+ * ```
1153
+ */
1154
+ generateState?(provider: string): Promise<{
1155
+ state: string;
1156
+ data: StateData;
1157
+ }>;
1158
+ /**
1159
+ * State storage operations.
1160
+ *
1161
+ * @remarks
1162
+ * Provides methods for saving, retrieving, and deleting OAuth state.
1163
+ * All three methods must be implemented together.
1164
+ *
1165
+ * If not provided, uses in-memory cache (not suitable for production).
1166
+ */
1167
+ stateStorage?: StateStorage;
1168
+ }
1169
+
1170
+ /**
1171
+ * State storage operations interface.
1172
+ *
1173
+ * @remarks
1174
+ * Groups all state storage operations together. All methods must be implemented
1175
+ * if this interface is provided.
1176
+ *
1177
+ * @public
1178
+ */
1179
+ export declare interface StateStorage {
1180
+ /**
1181
+ * Saves OAuth state with expiration.
1182
+ *
1183
+ * @param state - The state parameter value (random string for CSRF protection)
1184
+ * @param data - State data including provider name and PKCE code verifier
1185
+ * @param expiresInSeconds - TTL in seconds (typically 300 for 5 minutes)
1186
+ */
1187
+ saveState(state: string, data: StateData, expiresInSeconds: number): Promise<void>;
1188
+ /**
1189
+ * Retrieves OAuth state data.
1190
+ *
1191
+ * @param state - The state parameter value
1192
+ * @returns State data or null if not found or expired
1193
+ */
1194
+ getState(state: string): Promise<StateData | null>;
1195
+ /**
1196
+ * Deletes OAuth state (called after successful validation).
1197
+ *
1198
+ * @param state - The state parameter value
1199
+ */
1200
+ deleteState(state: string): Promise<void>;
1201
+ }
1202
+
1203
+ /**
1204
+ * User information extracted from OAuth provider
1205
+ *
1206
+ * @public
1207
+ */
1208
+ export declare interface UserInfo {
1209
+ email: string;
1210
+ id?: string | undefined;
1211
+ sub?: string | undefined;
1212
+ given_name?: string | undefined;
1213
+ family_name?: string | undefined;
1214
+ name?: string | undefined;
1215
+ picture?: string | undefined;
1216
+ email_verified?: boolean | undefined;
1217
+ iss?: string | undefined;
1218
+ }
1219
+
1220
+ export { }