@vunexa/lixa 0.0.1-alpha.19 → 0.0.1-alpha.21

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/lixa.d.ts CHANGED
@@ -10,18 +10,18 @@ type ConfiguredProviderKey<T extends LixaConfig<any>> = keyof T['providers'];
10
10
  *
11
11
  * @remarks
12
12
  * Lixa simplifies multi-provider authentication flows and supports extensible session management.
13
+ * Providers can be passed inline in the configuration, eliminating the need for pre-registration.
13
14
  *
14
15
  * @example
16
+ * Using built-in providers from @vunexa/lixa-providers:
15
17
  * ```typescript
16
18
  * import { Lixa } from '@vunexa/lixa';
17
- * import { GoogleProvider } from '@vunexa/lixa/providers';
19
+ * import { GoogleProvider } from '@vunexa/lixa-providers';
18
20
  *
19
- * // Register providers before using them
20
- * Lixa.registerProvider({ google: new GoogleProvider() });
21
- *
22
- * const config = Lixa.createConfig({
21
+ * const lixa = new Lixa({
23
22
  * providers: {
24
23
  * google: {
24
+ * provider: new GoogleProvider(),
25
25
  * clientId: 'your-client-id',
26
26
  * clientSecret: 'your-client-secret',
27
27
  * redirectUri: 'https://yourapp.com/auth/google/callback',
@@ -29,13 +29,36 @@ type ConfiguredProviderKey<T extends LixaConfig<any>> = keyof T['providers'];
29
29
  * }
30
30
  * }
31
31
  * });
32
+ * ```
32
33
  *
33
- * const lixa = new Lixa(config);
34
+ * @example
35
+ * Using custom inline providers:
36
+ * ```typescript
37
+ * import { Lixa, IProvider } from '@vunexa/lixa';
38
+ *
39
+ * const customProvider: IProvider = {
40
+ * authorizationEndpoint: 'https://custom.com/oauth/authorize',
41
+ * tokenEndpoint: 'https://custom.com/oauth/token',
42
+ * userInfoEndpoint: 'https://custom.com/api/user'
43
+ * };
44
+ *
45
+ * const lixa = new Lixa({
46
+ * providers: {
47
+ * custom: {
48
+ * provider: customProvider,
49
+ * clientId: 'your-client-id',
50
+ * clientSecret: 'your-client-secret',
51
+ * redirectUri: 'https://yourapp.com/auth/custom/callback',
52
+ * scopes: ['read:user']
53
+ * }
54
+ * }
55
+ * });
34
56
  * ```
35
57
  *
36
58
  * @public
37
59
  */
38
60
  declare class Lixa<TConfig extends LixaConfig<any> = LixaConfig> {
61
+ private static DEFAULT_PROVIDERS;
39
62
  private static CONFIGURED_PROVIDERS;
40
63
  private static LOCAL_STATE_CACHE;
41
64
  private static LOCAL_SESSION_CACHE;
@@ -48,17 +71,52 @@ declare class Lixa<TConfig extends LixaConfig<any> = LixaConfig> {
48
71
  /**
49
72
  * Creates a new Lixa instance with the provided configuration.
50
73
  *
74
+ * @remarks
75
+ * Providers can be passed inline in the configuration using the `provider` field.
76
+ * Provider resolution priority: inline custom provider > default providers > legacy registry.
77
+ *
51
78
  * @param config - The configuration object containing provider settings and optional session strategy
79
+ *
80
+ * @throws Error when provider configuration is missing required fields
81
+ * @throws Error when provider implementation is missing required properties
82
+ * @throws Error when provider is not available and no inline implementation is provided
52
83
  */
53
84
  constructor(config: TConfig);
85
+ /**
86
+ * Validates that a provider configuration has all required credentials.
87
+ *
88
+ * @param name - The provider name
89
+ * @param config - The provider configuration
90
+ * @throws Error when required fields are missing or invalid
91
+ */
92
+ private validateProviderConfig;
93
+ /**
94
+ * Validates that a provider implementation has all required properties.
95
+ *
96
+ * @param name - The provider name
97
+ * @param provider - The provider implementation
98
+ * @throws Error when required properties are missing
99
+ */
100
+ private validateProviderImplementation;
101
+ /**
102
+ * Structured debug logging with standardized format.
103
+ *
104
+ * @param level - Log level (INFO, WARN, ERROR)
105
+ * @param context - Context of the log (Init, Auth, Token, Session, State)
106
+ * @param message - Log message
107
+ * @param data - Optional data to log
108
+ *
109
+ * @remarks
110
+ * Format: [Lixa] [timestamp] [level] [context] message
111
+ * Only logs when debug mode is enabled.
112
+ */
54
113
  private log;
55
- private logError;
56
114
  /**
57
- * Checks if a provider is both registered and configured for this instance.
115
+ * Checks if a provider is configured for this instance.
58
116
  * This is a type guard that narrows the provider type for use with getAuthUrl.
59
117
  *
60
118
  * @param provider - The provider name to check (case-insensitive)
61
- * @returns True if the provider is registered and configured, false otherwise
119
+ * @returns True if the provider is configured, false otherwise
62
120
  *
63
121
  * @example
64
122
  * ```typescript
@@ -69,12 +127,37 @@ declare class Lixa<TConfig extends LixaConfig<any> = LixaConfig> {
69
127
  * ```
70
128
  */
71
129
  isProviderConfigured<T extends string>(provider: T): provider is T & ConfiguredProviderKey<TConfig>;
130
+ /**
131
+ * Gets a provider implementation by name.
132
+ * Resolution priority: inline custom provider > default providers > legacy registry
133
+ *
134
+ * @param name - The provider name (case-insensitive)
135
+ * @param config - The provider configuration
136
+ * @returns The provider implementation
137
+ * @throws Error when provider is not found
138
+ */
139
+ private getProvider;
72
140
  /**
73
141
  * Registers custom OAuth providers for use with Lixa.
74
142
  *
143
+ * @deprecated This method is maintained for backward compatibility.
144
+ * The recommended approach is to pass providers inline in the configuration:
145
+ * ```typescript
146
+ * const lixa = new Lixa({
147
+ * providers: {
148
+ * custom: {
149
+ * provider: new CustomProvider(),
150
+ * clientId: '...',
151
+ * // ...
152
+ * }
153
+ * }
154
+ * });
155
+ * ```
156
+ *
75
157
  * @param providerMap - A map of provider names to IProvider implementations
76
158
  *
77
159
  * @example
160
+ * Legacy usage (still supported):
78
161
  * ```typescript
79
162
  * class CustomProvider implements IProvider {
80
163
  * authorizationEndpoint = 'https://custom.com/oauth/authorize';
@@ -93,14 +176,31 @@ declare class Lixa<TConfig extends LixaConfig<any> = LixaConfig> {
93
176
  */
94
177
  static getRegisteredProviders(): string[];
95
178
  /**
96
- * Creates a type-safe configuration that only allows registered providers.
179
+ * Creates a type-safe configuration.
180
+ *
181
+ * @deprecated This method is maintained for backward compatibility.
182
+ * You can now pass configuration directly to the Lixa constructor without this helper.
183
+ *
184
+ * @param config - Configuration object with provider settings
185
+ * @returns The same configuration object with type safety
97
186
  *
98
- * @param config - Configuration object with providers that must be registered
99
- * @returns The same configuration object, but with type safety for registered providers
187
+ * @example
188
+ * New approach (recommended):
189
+ * ```typescript
190
+ * const lixa = new Lixa({
191
+ * providers: {
192
+ * google: {
193
+ * provider: new GoogleProvider(),
194
+ * clientId: '...',
195
+ * // ...
196
+ * }
197
+ * }
198
+ * });
199
+ * ```
100
200
  */
101
- static createConfig<T extends Record<string, ProviderConfig>>(config: LixaConfig<keyof T & string> & {
201
+ static createConfig<T extends Record<string, ProviderConfig>>(config: LixaConfig<T> & {
102
202
  providers: T;
103
- }): LixaConfig<keyof T & string>;
203
+ }): LixaConfig<T>;
104
204
  /**
105
205
  * Generates a cryptographically secure random state parameter for OAuth flows.
106
206
  *
@@ -113,12 +213,81 @@ declare class Lixa<TConfig extends LixaConfig<any> = LixaConfig> {
113
213
  /**
114
214
  * Generates a cryptographically secure code verifier for PKCE flows.
115
215
  *
116
- * @returns A 64-character hexadecimal string
216
+ * @returns A 64-character hexadecimal string (32 random bytes encoded as hex)
117
217
  *
118
218
  * @remarks
119
- * The code verifier is used in PKCE (Proof Key for Code Exchange) to enhance security.
219
+ * This method implements the code verifier generation as specified in RFC 7636 (PKCE).
220
+ *
221
+ * **PKCE (Proof Key for Code Exchange)** is a security extension to OAuth 2.0 that
222
+ * prevents authorization code interception attacks. It's especially important for
223
+ * public clients (mobile apps, SPAs) but is recommended for all OAuth flows.
224
+ *
225
+ * **Generation methodology:**
226
+ * 1. Generate 32 cryptographically random bytes using Node.js crypto.randomBytes()
227
+ * 2. Encode the bytes as a hexadecimal string (64 characters)
228
+ * 3. The verifier is stored securely and used later in the token exchange
229
+ *
230
+ * **RFC 7636 Requirements:**
231
+ * - Minimum length: 43 characters
232
+ * - Maximum length: 128 characters
233
+ * - Character set: [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
234
+ * - This implementation produces 64 hex characters, meeting the requirements
235
+ *
236
+ * The code verifier is:
237
+ * - Generated when creating the authorization URL
238
+ * - Stored in state cache with the state parameter
239
+ * - Retrieved during callback handling
240
+ * - Sent to the token endpoint to prove the client's identity
241
+ *
242
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7636 | RFC 7636 - PKCE}
243
+ * @see {@link buildCodeChallenge} for the corresponding challenge generation
244
+ *
245
+ * @internal
120
246
  */
121
247
  private static generateCodeVerifier;
248
+ /**
249
+ * Generates a code challenge from a code verifier for PKCE flows.
250
+ *
251
+ * @param codeVerifier - The code verifier string (64 hex characters)
252
+ * @returns A base64url-encoded SHA-256 hash of the code verifier
253
+ *
254
+ * @remarks
255
+ * This method implements the code challenge generation as specified in RFC 7636 (PKCE)
256
+ * using the S256 (SHA-256) transformation method.
257
+ *
258
+ * **Challenge generation methodology:**
259
+ * 1. Hash the code verifier using SHA-256
260
+ * 2. Encode the hash as base64
261
+ * 3. Convert to base64url format (RFC 4648):
262
+ * - Replace '+' with '-'
263
+ * - Replace '/' with '_'
264
+ * - Remove trailing '=' padding
265
+ *
266
+ * **PKCE Flow:**
267
+ * 1. Client generates code_verifier (random string)
268
+ * 2. Client creates code_challenge = BASE64URL(SHA256(code_verifier))
269
+ * 3. Client sends code_challenge to authorization endpoint
270
+ * 4. Authorization server stores the code_challenge
271
+ * 5. Client sends code_verifier to token endpoint
272
+ * 6. Authorization server verifies: SHA256(code_verifier) == code_challenge
273
+ *
274
+ * **Security Benefits:**
275
+ * - Prevents authorization code interception attacks
276
+ * - Even if an attacker intercepts the authorization code, they cannot
277
+ * exchange it for tokens without the original code_verifier
278
+ * - The challenge is sent in the authorization request (public)
279
+ * - The verifier is sent in the token request (should be kept secret)
280
+ *
281
+ * **RFC 7636 Transformation Methods:**
282
+ * - plain: code_challenge = code_verifier (not recommended)
283
+ * - S256: code_challenge = BASE64URL(SHA256(code_verifier)) (recommended, used here)
284
+ *
285
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7636 | RFC 7636 - PKCE}
286
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc4648#section-5 | RFC 4648 - Base64url Encoding}
287
+ * @see {@link generateCodeVerifier} for the verifier generation
288
+ *
289
+ * @internal
290
+ */
122
291
  private static buildCodeChallenge;
123
292
  /**
124
293
  * Generates the authorization URL for the specified provider.
@@ -1 +1 @@
1
- {"version":3,"file":"lixa.d.ts","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKxC,OAAO,EAAE,KAAK,OAAO,EAAgD,MAAM,kBAAkB,CAAC;AAO9F;;GAEG;AACH,KAAK,qBAAqB,CAAC,CAAC,SAAS,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,cAAM,IAAI,CAAC,OAAO,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU;IACrD,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAqC;IACxE,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAyB;IACzD,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAA2B;IAC7D,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAgC;IACvE,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,KAAK,CAAU;IAEvB;;;;OAIG;gBACS,MAAM,EAAE,OAAO;IAkB3B,OAAO,CAAC,GAAG;IAMX,OAAO,CAAC,QAAQ;IAMhB;;;;;;;;;;;;;;OAcG;IACI,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAG,qBAAqB,CAAC,OAAO,CAAC;IAM1G;;;;;;;;;;;;;;;OAeG;WACW,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI;IAMzF;;;;OAIG;WACW,sBAAsB,IAAI,MAAM,EAAE;IAIhD;;;;;OAKG;WACW,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EACjE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG;QAAE,SAAS,EAAE,CAAC,CAAA;KAAE,GACtD,UAAU,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAc/B;;;;;;;OAOG;WACW,mBAAmB,IAAI,MAAM;IAI3C;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAInC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC;;;;;;;;;;;;;;;OAeG;IACI,UAAU,CAAC,QAAQ,EAAE,qBAAqB,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAsC3F;;;;;;;;;;;;;;;;;;OAkBG;IACU,cAAc,CAAC,EAC1B,QAAQ,EACR,IAAI,EACJ,KAAK,GACN,EAAE;QACD,QAAQ,EAAE,qBAAqB,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;QAClD,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,MAAM,CAAC;IAgDZ,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YAIrD,oBAAoB;IA2ClC,OAAO,CAAC,kBAAkB;CAG3B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"lixa.d.ts","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,130 @@
1
1
  /**
2
2
  * Represents a user session after successful OAuth authentication.
3
3
  *
4
+ * @remarks
5
+ * The Session object is returned by SessionStrategy.createSession() and contains
6
+ * the session identifier and any additional data needed for your application.
7
+ *
8
+ * The structure is intentionally flexible to support various session management
9
+ * approaches (JWT tokens, session IDs, etc.).
10
+ *
4
11
  * @public
5
12
  */
6
13
  export interface Session {
7
- /** The session token (typically the access token) */
14
+ /**
15
+ * The session token or identifier.
16
+ * This could be an access token, a session ID, a JWT, or any other identifier
17
+ * that your application uses to track authenticated users.
18
+ */
8
19
  token: string;
9
- /** Raw token data from the OAuth provider */
20
+ /**
21
+ * Raw session data.
22
+ * Contains the complete OAuth token response and any additional data
23
+ * your SessionStrategy adds (user info, database IDs, etc.).
24
+ *
25
+ * Typical OAuth token data includes:
26
+ * - access_token: OAuth access token
27
+ * - refresh_token: OAuth refresh token (if requested)
28
+ * - expires_in: Token expiration time in seconds
29
+ * - token_type: Token type (usually "Bearer")
30
+ * - id_token: OpenID Connect ID token (if using OIDC)
31
+ * - scope: Granted scopes
32
+ */
10
33
  raw: any;
11
34
  }
12
35
  /**
13
36
  * Strategy interface for custom session creation.
14
37
  *
38
+ * @remarks
39
+ * Implement this interface to customize how OAuth tokens are converted into
40
+ * application sessions. This is where you typically:
41
+ * - Decode ID tokens (for OpenID Connect)
42
+ * - Look up or create users in your database
43
+ * - Generate session identifiers
44
+ * - Store session data
45
+ * - Add custom claims or metadata
46
+ *
47
+ * The default implementation (DefaultSessionStrategy) simply extracts the
48
+ * access token and returns it as the session token.
49
+ *
50
+ * @example
51
+ * Custom session strategy with database integration:
52
+ * ```typescript
53
+ * class DatabaseSessionStrategy implements SessionStrategy {
54
+ * constructor(private db: Database) {}
55
+ *
56
+ * async createSession(tokenData: any): Promise<Session> {
57
+ * // Decode ID token for OIDC providers
58
+ * const idToken = tokenData.id_token;
59
+ * const payload = decodeJwt(idToken);
60
+ *
61
+ * // Create or update user in database
62
+ * const user = await this.db.users.upsert({
63
+ * email: payload.email,
64
+ * name: payload.name,
65
+ * picture: payload.picture
66
+ * });
67
+ *
68
+ * // Generate session ID
69
+ * const sessionId = generateSecureId();
70
+ *
71
+ * // Store session with tokens
72
+ * await this.db.sessions.create({
73
+ * id: sessionId,
74
+ * userId: user.id,
75
+ * accessToken: tokenData.access_token,
76
+ * refreshToken: tokenData.refresh_token,
77
+ * expiresAt: new Date(Date.now() + tokenData.expires_in * 1000)
78
+ * });
79
+ *
80
+ * return {
81
+ * token: sessionId,
82
+ * raw: {
83
+ * userId: user.id,
84
+ * email: user.email,
85
+ * ...tokenData
86
+ * }
87
+ * };
88
+ * }
89
+ * }
90
+ * ```
91
+ *
15
92
  * @public
16
93
  */
17
94
  export interface SessionStrategy {
18
95
  /**
19
96
  * Creates a session from OAuth token data.
20
97
  *
21
- * @param userInfo - The token data received from the OAuth provider
98
+ * @param tokenData - The token data received from the OAuth provider's token endpoint
22
99
  * @returns A Promise that resolves to a Session object
100
+ *
101
+ * @remarks
102
+ * This method is called after successfully exchanging the authorization code
103
+ * for tokens. The tokenData parameter contains the raw response from the
104
+ * provider's token endpoint.
105
+ *
106
+ * Common token data fields:
107
+ * - access_token: OAuth access token
108
+ * - refresh_token: OAuth refresh token (optional)
109
+ * - expires_in: Token expiration time in seconds
110
+ * - token_type: Token type (usually "Bearer")
111
+ * - id_token: OpenID Connect ID token (for OIDC providers)
112
+ * - scope: Granted scopes
113
+ *
114
+ * @throws \{Error\} If session creation fails (e.g., database error, invalid token)
115
+ *
116
+ * @example
117
+ * Simple implementation:
118
+ * ```typescript
119
+ * async createSession(tokenData: any): Promise<Session> {
120
+ * return {
121
+ * token: tokenData.access_token,
122
+ * raw: tokenData
123
+ * };
124
+ * }
125
+ * ```
23
126
  */
24
- createSession(userInfo: any): Promise<Session>;
127
+ createSession(tokenData: any): Promise<Session>;
25
128
  }
26
129
  /**
27
130
  * Default session strategy that works with any OAuth provider.
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/models/session.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,aAAa,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AAED;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAC5D;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBtD"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/models/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,OAAO;IACtB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;;;;;;OAYG;IACH,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,aAAa,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjD;AAED;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAC5D;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBtD"}
@@ -1,17 +1,134 @@
1
1
  /**
2
- * Interface for OAuth provider implementations.
2
+ * Interface for OAuth 2.0 and OpenID Connect provider implementations.
3
3
  *
4
4
  * @remarks
5
5
  * Implement this interface to add support for custom OAuth providers.
6
+ * Each provider defines the three core endpoints required for the OAuth 2.0
7
+ * authorization code flow with PKCE.
8
+ *
9
+ * Built-in providers (Google, GitHub) are available in the \@vunexa/lixa-providers package.
10
+ *
11
+ * All implementations must comply with:
12
+ * - RFC 6749 (OAuth 2.0)
13
+ * - RFC 7636 (PKCE)
14
+ * - OpenID Connect Core 1.0 (for OIDC providers)
15
+ *
16
+ * @example
17
+ * Custom provider implementation:
18
+ * ```typescript
19
+ * import { IProvider } from '@vunexa/lixa';
20
+ *
21
+ * class CustomProvider implements IProvider {
22
+ * authorizationEndpoint = 'https://auth.example.com/oauth/authorize';
23
+ * tokenEndpoint = 'https://auth.example.com/oauth/token';
24
+ * userInfoEndpoint = 'https://api.example.com/user';
25
+ * }
26
+ *
27
+ * // Use in configuration
28
+ * const lixa = new Lixa({
29
+ * providers: {
30
+ * custom: {
31
+ * provider: new CustomProvider(),
32
+ * clientId: 'your-client-id',
33
+ * clientSecret: 'your-client-secret',
34
+ * redirectUri: 'https://app.com/callback',
35
+ * scopes: ['read:user']
36
+ * }
37
+ * }
38
+ * });
39
+ * ```
40
+ *
41
+ * @example
42
+ * Object literal provider:
43
+ * ```typescript
44
+ * const customProvider: IProvider = {
45
+ * authorizationEndpoint: 'https://auth.example.com/oauth/authorize',
46
+ * tokenEndpoint: 'https://auth.example.com/oauth/token',
47
+ * userInfoEndpoint: 'https://api.example.com/user'
48
+ * };
49
+ * ```
6
50
  *
7
51
  * @public
8
52
  */
9
53
  interface IProvider {
10
- /** The OAuth authorization endpoint URL */
54
+ /**
55
+ * The OAuth 2.0 authorization endpoint URL.
56
+ *
57
+ * @remarks
58
+ * This is the URL where users are redirected to authenticate and authorize your application.
59
+ * The endpoint must support the OAuth 2.0 authorization code flow with PKCE.
60
+ *
61
+ * Standard query parameters sent to this endpoint:
62
+ * - client_id: Your application's client ID
63
+ * - redirect_uri: Where to redirect after authorization
64
+ * - response_type: Always "code" for authorization code flow
65
+ * - scope: Space-separated list of requested scopes
66
+ * - state: Random string for CSRF protection
67
+ * - code_challenge: PKCE code challenge (SHA-256 hash)
68
+ * - code_challenge_method: Always "S256" for SHA-256
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * authorizationEndpoint = 'https://accounts.google.com/o/oauth2/v2/auth'
73
+ * ```
74
+ */
11
75
  authorizationEndpoint: string;
12
- /** The OAuth token exchange endpoint URL */
76
+ /**
77
+ * The OAuth 2.0 token endpoint URL.
78
+ *
79
+ * @remarks
80
+ * This is the URL where authorization codes are exchanged for access tokens.
81
+ * The endpoint must support the OAuth 2.0 token exchange with PKCE.
82
+ *
83
+ * Standard parameters sent to this endpoint (POST request):
84
+ * - grant_type: Always "authorization_code"
85
+ * - code: The authorization code from the callback
86
+ * - redirect_uri: Must match the authorization request
87
+ * - client_id: Your application's client ID
88
+ * - client_secret: Your application's client secret
89
+ * - code_verifier: PKCE code verifier (original random string)
90
+ *
91
+ * Expected response:
92
+ * - access_token: OAuth access token
93
+ * - token_type: Token type (usually "Bearer")
94
+ * - expires_in: Token expiration time in seconds
95
+ * - refresh_token: Refresh token (optional)
96
+ * - id_token: OpenID Connect ID token (for OIDC providers)
97
+ * - scope: Granted scopes
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * tokenEndpoint = 'https://oauth2.googleapis.com/token'
102
+ * ```
103
+ */
13
104
  tokenEndpoint: string;
14
- /** The user information endpoint URL */
105
+ /**
106
+ * The user information endpoint URL.
107
+ *
108
+ * @remarks
109
+ * This is the URL where user profile information can be retrieved using the access token.
110
+ * For OpenID Connect providers, this is the UserInfo endpoint.
111
+ *
112
+ * The endpoint is called with the access token in the Authorization header:
113
+ * ```
114
+ * Authorization: Bearer <access_token>
115
+ * ```
116
+ *
117
+ * Common response fields:
118
+ * - sub: Subject identifier (user ID)
119
+ * - email: User's email address
120
+ * - name: User's full name
121
+ * - picture: User's profile picture URL
122
+ * - email_verified: Whether email is verified
123
+ *
124
+ * Note: This endpoint is not called automatically by Lixa. Your SessionStrategy
125
+ * can call it if needed to fetch user profile information.
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * userInfoEndpoint = 'https://www.googleapis.com/oauth2/v2/userinfo'
130
+ * ```
131
+ */
15
132
  userInfoEndpoint: string;
16
133
  }
17
134
  export { IProvider };
@@ -1 +1 @@
1
- {"version":3,"file":"IProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,UAAU,SAAS;IACjB,2CAA2C;IAC3C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"IProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,UAAU,SAAS;IACjB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,4 +1,2 @@
1
1
  export { IProvider } from "./IProvider";
2
- export { GithubProvider } from "./github";
3
- export { GoogleProvider } from "./google";
4
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}