@vunexa/lixa 0.0.1-alpha.4 → 0.0.1-alpha.6

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.
@@ -0,0 +1,10 @@
1
+ import { StateDao } from "./types";
2
+ declare class LocalStateCache implements StateDao {
3
+ private cache;
4
+ constructor(defaultTtlSeconds?: number);
5
+ saveState(state: string, data: any, expiresInSeconds: number): Promise<void>;
6
+ getState(state: string): Promise<any | null>;
7
+ deleteState(state: string): Promise<void>;
8
+ }
9
+ export { LocalStateCache };
10
+ //# sourceMappingURL=state-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-cache.d.ts","sourceRoot":"","sources":["../../src/dao/state-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,cAAM,eAAgB,YAAW,QAAQ;IACvC,OAAO,CAAC,KAAK,CAAY;gBAEb,iBAAiB,GAAE,MAAY;IAIrC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAI5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhD;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import NodeCache from 'node-cache';
2
+ class LocalStateCache {
3
+ cache;
4
+ constructor(defaultTtlSeconds = 600) {
5
+ this.cache = new NodeCache({ stdTTL: defaultTtlSeconds });
6
+ }
7
+ async saveState(state, data, expiresInSeconds) {
8
+ this.cache.set(state, data, expiresInSeconds);
9
+ }
10
+ async getState(state) {
11
+ return this.cache.get(state) || null;
12
+ }
13
+ async deleteState(state) {
14
+ this.cache.del(state);
15
+ }
16
+ }
17
+ export { LocalStateCache };
18
+ //# sourceMappingURL=state-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-cache.js","sourceRoot":"","sources":["../../src/dao/state-cache.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AAGnC,MAAM,eAAe;IACX,KAAK,CAAY;IAEzB,YAAY,oBAA4B,GAAG;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAa,EAAE,IAAS,EAAE,gBAAwB;QAChE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;CACF;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface StateDao {
2
+ saveState(state: string, data: any, expiresInSeconds: number): Promise<void>;
3
+ getState(state: string): Promise<any | null>;
4
+ deleteState(state: string): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAC7C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,11 @@
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
+ * @packageDocumentation
8
+ */
1
9
  export { Lixa } from "./lixa";
2
10
  export { type ProviderConfig, type LixaConfig, type SessionStrategy, type Session, } from "./types";
3
11
  export { type IProvider } from "./providers";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,OAAO,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,OAAO,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,10 @@
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
+ * @packageDocumentation
8
+ */
1
9
  export { Lixa } from "./lixa";
2
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
package/dist/lixa.d.ts CHANGED
@@ -1,18 +1,126 @@
1
1
  import { type LixaConfig, type Session } from "./types";
2
2
  import { IProvider } from "./providers";
3
3
  /**
4
+ * A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library.
5
+ *
6
+ * @remarks
7
+ * Lixa simplifies multi-provider authentication flows and supports extensible session management.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const lixa = new Lixa({
12
+ * providers: {
13
+ * google: {
14
+ * clientId: 'your-client-id',
15
+ * clientSecret: 'your-client-secret',
16
+ * redirectUri: 'https://yourapp.com/auth/google/callback',
17
+ * scopes: ['openid', 'email', 'profile']
18
+ * }
19
+ * }
20
+ * });
21
+ * ```
22
+ *
4
23
  * @public
5
24
  */
6
25
  declare class Lixa {
7
26
  private static CONFIGURED_PROVIDERS;
27
+ private static LOCAL_STATE_CACHE;
8
28
  private config;
29
+ private stateDao;
30
+ /**
31
+ * Creates a new Lixa instance with the provided configuration.
32
+ *
33
+ * @param config - The configuration object containing provider settings and optional session strategy
34
+ */
9
35
  constructor(config: LixaConfig);
36
+ /**
37
+ * Checks if a provider is registered and available for use.
38
+ *
39
+ * @param provider - The provider name to check (case-insensitive)
40
+ * @returns True if the provider is registered, false otherwise
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * if (Lixa.isProviderRegistered('google')) {
45
+ * console.log('Google provider is available');
46
+ * }
47
+ * ```
48
+ */
10
49
  static isProviderRegistered(provider: string): boolean;
50
+ /**
51
+ * Registers custom OAuth providers for use with Lixa.
52
+ *
53
+ * @param providerMap - A map of provider names to IProvider implementations
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * class CustomProvider implements IProvider {
58
+ * authorizationEndpoint = 'https://custom.com/oauth/authorize';
59
+ * tokenEndpoint = 'https://custom.com/oauth/token';
60
+ * userInfoEndpoint = 'https://custom.com/api/user';
61
+ * }
62
+ *
63
+ * Lixa.registerProvider({ custom: new CustomProvider() });
64
+ * ```
65
+ */
11
66
  static registerProvider(providerMap: {
12
67
  [key: string]: IProvider;
13
68
  }): void;
14
- generateRandomState(): string;
69
+ /**
70
+ * Generates a cryptographically secure random state parameter for OAuth flows.
71
+ *
72
+ * @returns A 32-character hexadecimal string
73
+ *
74
+ * @remarks
75
+ * The state parameter is used to prevent CSRF attacks in OAuth flows.
76
+ */
77
+ static generateRandomState(): string;
78
+ /**
79
+ * Generates a cryptographically secure code verifier for PKCE flows.
80
+ *
81
+ * @returns A 64-character hexadecimal string
82
+ *
83
+ * @remarks
84
+ * The code verifier is used in PKCE (Proof Key for Code Exchange) to enhance security.
85
+ */
86
+ private static generateCodeVerifier;
87
+ private static buildCodeChallenge;
88
+ /**
89
+ * Generates the authorization URL for the specified provider.
90
+ *
91
+ * @param provider - The provider name (case-insensitive)
92
+ * @param state - The state parameter for CSRF protection
93
+ * @returns The complete authorization URL to redirect users to
94
+ *
95
+ * @throws Error when the provider is not configured
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const state = Lixa.generateRandomState();
100
+ * const authUrl = lixa.getAuthUrl('google', state);
101
+ * res.redirect(authUrl);
102
+ * ```
103
+ */
15
104
  getAuthUrl(provider: string, state: string): string;
105
+ /**
106
+ * Handles the OAuth callback and creates a user session.
107
+ *
108
+ * @param provider - The provider name
109
+ * @param code - The authorization code from the provider
110
+ * @param state - The state parameter for validation
111
+ * @returns A Promise that resolves to a Session object
112
+ *
113
+ * @throws Error when code or state is missing/invalid, or provider is not configured
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const session = await lixa.handleCallback({
118
+ * provider: 'google',
119
+ * code: req.query.code,
120
+ * state: req.query.state
121
+ * });
122
+ * ```
123
+ */
16
124
  handleCallback({ provider, code, state, }: {
17
125
  provider: string;
18
126
  code: string;
@@ -1 +1 @@
1
- {"version":3,"file":"lixa.d.ts","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAuB,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAkC,MAAM,aAAa,CAAC;AAGxE;;GAEG;AACH,cAAM,IAAI;IACR,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAqC;IACxE,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,UAAU;WAUhB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;WAI/C,gBAAgB,CAAC,WAAW,EAAE;QAC1C,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B,GAAG,IAAI;IAQD,mBAAmB,IAAI,MAAM;IAI7B,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAqB7C,cAAc,CAAC,EAC1B,QAAQ,EACR,IAAI,EACJ,KAAK,GACN,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,OAAO,CAAC;YAuCN,oBAAoB;IAsClC,OAAO,CAAC,kBAAkB;CAG3B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"lixa.d.ts","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAuB,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAkC,MAAM,aAAa,CAAC;AAMxE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,cAAM,IAAI;IACR,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAqC;IACxE,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAyB;IACzD,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAE3B;;;;OAIG;gBACS,MAAM,EAAE,UAAU;IAW9B;;;;;;;;;;;;OAYG;WACW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI7D;;;;;;;;;;;;;;;OAeG;WACW,gBAAgB,CAAC,WAAW,EAAE;QAC1C,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B,GAAG,IAAI;IAQR;;;;;;;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,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAsC1D;;;;;;;;;;;;;;;;;;OAkBG;IACU,cAAc,CAAC,EAC1B,QAAQ,EACR,IAAI,EACJ,KAAK,GACN,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,OAAO,CAAC;YAmDN,oBAAoB;IAsClC,OAAO,CAAC,kBAAkB;CAG3B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
package/dist/lixa.js CHANGED
@@ -1,14 +1,43 @@
1
1
  import { randomBytes } from "crypto";
2
2
  import { GithubProvider, GoogleProvider } from "./providers";
3
3
  import { GITHUB, GOOGLE } from "./utils/constants";
4
+ import { LocalStateCache } from "./dao/state-cache";
5
+ import crypto from "crypto";
4
6
  /**
7
+ * A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library.
8
+ *
9
+ * @remarks
10
+ * Lixa simplifies multi-provider authentication flows and supports extensible session management.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const lixa = new Lixa({
15
+ * providers: {
16
+ * google: {
17
+ * clientId: 'your-client-id',
18
+ * clientSecret: 'your-client-secret',
19
+ * redirectUri: 'https://yourapp.com/auth/google/callback',
20
+ * scopes: ['openid', 'email', 'profile']
21
+ * }
22
+ * }
23
+ * });
24
+ * ```
25
+ *
5
26
  * @public
6
27
  */
7
28
  class Lixa {
8
29
  static CONFIGURED_PROVIDERS = new Map();
30
+ static LOCAL_STATE_CACHE = new LocalStateCache();
9
31
  config;
32
+ stateDao;
33
+ /**
34
+ * Creates a new Lixa instance with the provided configuration.
35
+ *
36
+ * @param config - The configuration object containing provider settings and optional session strategy
37
+ */
10
38
  constructor(config) {
11
39
  this.config = config;
40
+ this.stateDao = config.stateDao || Lixa.LOCAL_STATE_CACHE;
12
41
  if (!Lixa.CONFIGURED_PROVIDERS.has(GITHUB)) {
13
42
  Lixa.CONFIGURED_PROVIDERS.set(GITHUB, new GithubProvider());
14
43
  }
@@ -16,9 +45,38 @@ class Lixa {
16
45
  Lixa.CONFIGURED_PROVIDERS.set(GOOGLE, new GoogleProvider());
17
46
  }
18
47
  }
48
+ /**
49
+ * Checks if a provider is registered and available for use.
50
+ *
51
+ * @param provider - The provider name to check (case-insensitive)
52
+ * @returns True if the provider is registered, false otherwise
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * if (Lixa.isProviderRegistered('google')) {
57
+ * console.log('Google provider is available');
58
+ * }
59
+ * ```
60
+ */
19
61
  static isProviderRegistered(provider) {
20
62
  return Lixa.CONFIGURED_PROVIDERS.has(provider.toLowerCase());
21
63
  }
64
+ /**
65
+ * Registers custom OAuth providers for use with Lixa.
66
+ *
67
+ * @param providerMap - A map of provider names to IProvider implementations
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * class CustomProvider implements IProvider {
72
+ * authorizationEndpoint = 'https://custom.com/oauth/authorize';
73
+ * tokenEndpoint = 'https://custom.com/oauth/token';
74
+ * userInfoEndpoint = 'https://custom.com/api/user';
75
+ * }
76
+ *
77
+ * Lixa.registerProvider({ custom: new CustomProvider() });
78
+ * ```
79
+ */
22
80
  static registerProvider(providerMap) {
23
81
  // This is a static method, so we can't access instance properties.
24
82
  // Instead, we can modify the prototype to add the new provider.
@@ -26,9 +84,52 @@ class Lixa {
26
84
  Lixa.CONFIGURED_PROVIDERS.set(key, providerImpl);
27
85
  });
28
86
  }
29
- generateRandomState() {
87
+ /**
88
+ * Generates a cryptographically secure random state parameter for OAuth flows.
89
+ *
90
+ * @returns A 32-character hexadecimal string
91
+ *
92
+ * @remarks
93
+ * The state parameter is used to prevent CSRF attacks in OAuth flows.
94
+ */
95
+ static generateRandomState() {
30
96
  return randomBytes(16).toString("hex");
31
97
  }
98
+ /**
99
+ * Generates a cryptographically secure code verifier for PKCE flows.
100
+ *
101
+ * @returns A 64-character hexadecimal string
102
+ *
103
+ * @remarks
104
+ * The code verifier is used in PKCE (Proof Key for Code Exchange) to enhance security.
105
+ */
106
+ static generateCodeVerifier() {
107
+ return randomBytes(32).toString("hex");
108
+ }
109
+ static buildCodeChallenge(codeVerifier) {
110
+ const hash = crypto
111
+ .createHash("sha256")
112
+ .update(codeVerifier)
113
+ .digest("base64");
114
+ // Convert to base64url
115
+ return hash.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
116
+ }
117
+ /**
118
+ * Generates the authorization URL for the specified provider.
119
+ *
120
+ * @param provider - The provider name (case-insensitive)
121
+ * @param state - The state parameter for CSRF protection
122
+ * @returns The complete authorization URL to redirect users to
123
+ *
124
+ * @throws Error when the provider is not configured
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const state = Lixa.generateRandomState();
129
+ * const authUrl = lixa.getAuthUrl('google', state);
130
+ * res.redirect(authUrl);
131
+ * ```
132
+ */
32
133
  getAuthUrl(provider, state) {
33
134
  const providerType = provider.toLowerCase();
34
135
  const providerConfig = this.findProviderByType(providerType);
@@ -36,16 +137,47 @@ class Lixa {
36
137
  if (!providerConfig || !providerImpl) {
37
138
  throw new Error(`Provider ${providerType} not configured`);
38
139
  }
140
+ const codeVerifier = Lixa.generateCodeVerifier();
141
+ const codeChallenge = Lixa.buildCodeChallenge(codeVerifier);
142
+ // Cache the state paramaeter with TTL of 5 minutes (300 seconds)
143
+ // We dont care about value. we are onl interested in key existence
144
+ this.stateDao.saveState(state, {
145
+ createdAt: Date.now(),
146
+ provider: providerType,
147
+ codeVerifier,
148
+ }, 300 // 5 minutes in seconds
149
+ );
39
150
  const params = new URLSearchParams({
40
151
  client_id: providerConfig.clientId,
41
152
  redirect_uri: providerConfig.redirectUri,
42
153
  scope: providerConfig.scopes.join(" "),
43
154
  state,
44
155
  response_type: "code",
156
+ code_challenge: codeChallenge,
157
+ code_challenge_method: "S256",
45
158
  ...providerConfig.extraConfig,
46
159
  });
47
160
  return `${providerImpl.authorizationEndpoint}?${params.toString()}`;
48
161
  }
162
+ /**
163
+ * Handles the OAuth callback and creates a user session.
164
+ *
165
+ * @param provider - The provider name
166
+ * @param code - The authorization code from the provider
167
+ * @param state - The state parameter for validation
168
+ * @returns A Promise that resolves to a Session object
169
+ *
170
+ * @throws Error when code or state is missing/invalid, or provider is not configured
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * const session = await lixa.handleCallback({
175
+ * provider: 'google',
176
+ * code: req.query.code,
177
+ * state: req.query.state
178
+ * });
179
+ * ```
180
+ */
49
181
  async handleCallback({ provider, code, state, }) {
50
182
  if (!code || code.trim() === "") {
51
183
  throw new Error("Invalid or missing code in callback");
@@ -53,14 +185,23 @@ class Lixa {
53
185
  if (!state || state.trim() === "") {
54
186
  throw new Error("Invalid or missing state in callback");
55
187
  }
56
- //TODO: Validate state here
57
- const providerConfig = this.findProviderByType(provider.toLowerCase());
58
- const providerImpl = Lixa.CONFIGURED_PROVIDERS.get(provider);
188
+ //Validate state here
189
+ const cachedState = await this.stateDao.getState(state);
190
+ if (!cachedState) {
191
+ throw new Error("Invalid or expired state");
192
+ }
193
+ // State is valid, remove it from cache to prevent reuse
194
+ await this.stateDao.deleteState(state);
195
+ //Get code verifier from cached state
196
+ const codeVerifier = cachedState.codeVerifier;
197
+ const providerType = provider.toLowerCase();
198
+ const providerConfig = this.findProviderByType(providerType);
199
+ const providerImpl = Lixa.CONFIGURED_PROVIDERS.get(providerType);
59
200
  if (!providerConfig || !providerImpl) {
60
201
  throw new Error(`Provider ${provider} not configured`);
61
202
  }
62
203
  // Exchange code for tokens and fetch user info here.
63
- const tokens = await this.exchangeCodeForToken(code, providerConfig, providerImpl);
204
+ const tokens = await this.exchangeCodeForToken(code, providerConfig, providerImpl, codeVerifier);
64
205
  // For simplicity, we'll just return the tokens as the session.
65
206
  // In a real implementation, you'd fetch user info and create a session.
66
207
  const session = {
package/dist/lixa.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lixa.js","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lixa.js","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,17 @@
1
+ /**
2
+ * Interface for OAuth provider implementations.
3
+ *
4
+ * @remarks
5
+ * Implement this interface to add support for custom OAuth providers.
6
+ *
7
+ * @public
8
+ */
1
9
  interface IProvider {
10
+ /** The OAuth authorization endpoint URL */
2
11
  authorizationEndpoint: string;
12
+ /** The OAuth token exchange endpoint URL */
3
13
  tokenEndpoint: string;
14
+ /** The user information endpoint URL */
4
15
  userInfoEndpoint: string;
5
16
  }
6
17
  export { IProvider };
@@ -1 +1 @@
1
- {"version":3,"file":"IProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAEA,UAAU,SAAS;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,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;;;;;;;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,3 +1,2 @@
1
- // Implement an extandable interface for authentication providers
2
1
  export {};
3
2
  //# sourceMappingURL=IProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IProvider.js","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAAA,iEAAiE"}
1
+ {"version":3,"file":"IProvider.js","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":""}
package/dist/types.d.ts CHANGED
@@ -1,31 +1,57 @@
1
+ import { StateDao } from "./dao/types";
1
2
  /**
3
+ * Configuration for an OAuth provider.
4
+ *
2
5
  * @public
3
6
  */
4
7
  export interface ProviderConfig {
8
+ /** The OAuth client ID provided by the provider */
5
9
  clientId: string;
10
+ /** The OAuth client secret provided by the provider */
6
11
  clientSecret: string;
12
+ /** The redirect URI registered with the provider */
7
13
  redirectUri: string;
14
+ /** Array of OAuth scopes to request */
8
15
  scopes: string[];
16
+ /** Additional provider-specific configuration parameters */
9
17
  extraConfig?: Record<string, any>;
10
18
  }
11
19
  /**
20
+ * Main configuration object for Lixa.
21
+ *
12
22
  * @public
13
23
  */
14
24
  export interface LixaConfig {
25
+ /** Map of provider names to their configurations */
15
26
  providers: Record<string, ProviderConfig>;
27
+ /** Optional custom session creation strategy */
16
28
  sessionStrategy?: SessionStrategy;
29
+ /** Optional custom state storage implementation */
30
+ stateDao?: StateDao;
17
31
  }
18
32
  /**
33
+ * Strategy interface for custom session creation.
34
+ *
19
35
  * @public
20
36
  */
21
37
  export interface SessionStrategy {
38
+ /**
39
+ * Creates a session from OAuth token data.
40
+ *
41
+ * @param userInfo - The token data received from the OAuth provider
42
+ * @returns A Promise that resolves to a Session object
43
+ */
22
44
  createSession(userInfo: any): Promise<Session>;
23
45
  }
24
46
  /**
47
+ * Represents a user session after successful OAuth authentication.
48
+ *
25
49
  * @public
26
50
  */
27
51
  export interface Session {
52
+ /** The session token (typically the access token) */
28
53
  token: string;
54
+ /** Raw token data from the OAuth provider */
29
55
  raw: any;
30
56
  }
31
57
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,GAAG,CAAC;CACV"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,gDAAgD;IAChD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,aAAa,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,GAAG,EAAE,GAAG,CAAC;CACV"}
package/index.d.ts CHANGED
@@ -1,22 +1,150 @@
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
+ * @packageDocumentation
8
+ */
9
+
10
+ /**
11
+ * Interface for OAuth provider implementations.
12
+ *
13
+ * @remarks
14
+ * Implement this interface to add support for custom OAuth providers.
15
+ *
16
+ * @public
17
+ */
1
18
  export declare interface IProvider {
19
+ /** The OAuth authorization endpoint URL */
2
20
  authorizationEndpoint: string;
21
+ /** The OAuth token exchange endpoint URL */
3
22
  tokenEndpoint: string;
23
+ /** The user information endpoint URL */
4
24
  userInfoEndpoint: string;
5
25
  }
6
26
 
7
27
  /**
28
+ * A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library.
29
+ *
30
+ * @remarks
31
+ * Lixa simplifies multi-provider authentication flows and supports extensible session management.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const lixa = new Lixa({
36
+ * providers: {
37
+ * google: {
38
+ * clientId: 'your-client-id',
39
+ * clientSecret: 'your-client-secret',
40
+ * redirectUri: 'https://yourapp.com/auth/google/callback',
41
+ * scopes: ['openid', 'email', 'profile']
42
+ * }
43
+ * }
44
+ * });
45
+ * ```
46
+ *
8
47
  * @public
9
48
  */
10
49
  export declare class Lixa {
11
50
  private static CONFIGURED_PROVIDERS;
51
+ private static LOCAL_STATE_CACHE;
12
52
  private config;
53
+ private stateDao;
54
+ /**
55
+ * Creates a new Lixa instance with the provided configuration.
56
+ *
57
+ * @param config - The configuration object containing provider settings and optional session strategy
58
+ */
13
59
  constructor(config: LixaConfig);
60
+ /**
61
+ * Checks if a provider is registered and available for use.
62
+ *
63
+ * @param provider - The provider name to check (case-insensitive)
64
+ * @returns True if the provider is registered, false otherwise
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * if (Lixa.isProviderRegistered('google')) {
69
+ * console.log('Google provider is available');
70
+ * }
71
+ * ```
72
+ */
14
73
  static isProviderRegistered(provider: string): boolean;
74
+ /**
75
+ * Registers custom OAuth providers for use with Lixa.
76
+ *
77
+ * @param providerMap - A map of provider names to IProvider implementations
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * class CustomProvider implements IProvider {
82
+ * authorizationEndpoint = 'https://custom.com/oauth/authorize';
83
+ * tokenEndpoint = 'https://custom.com/oauth/token';
84
+ * userInfoEndpoint = 'https://custom.com/api/user';
85
+ * }
86
+ *
87
+ * Lixa.registerProvider({ custom: new CustomProvider() });
88
+ * ```
89
+ */
15
90
  static registerProvider(providerMap: {
16
91
  [key: string]: IProvider;
17
92
  }): void;
18
- generateRandomState(): string;
93
+ /**
94
+ * Generates a cryptographically secure random state parameter for OAuth flows.
95
+ *
96
+ * @returns A 32-character hexadecimal string
97
+ *
98
+ * @remarks
99
+ * The state parameter is used to prevent CSRF attacks in OAuth flows.
100
+ */
101
+ static generateRandomState(): string;
102
+ /**
103
+ * Generates a cryptographically secure code verifier for PKCE flows.
104
+ *
105
+ * @returns A 64-character hexadecimal string
106
+ *
107
+ * @remarks
108
+ * The code verifier is used in PKCE (Proof Key for Code Exchange) to enhance security.
109
+ */
110
+ private static generateCodeVerifier;
111
+ private static buildCodeChallenge;
112
+ /**
113
+ * Generates the authorization URL for the specified provider.
114
+ *
115
+ * @param provider - The provider name (case-insensitive)
116
+ * @param state - The state parameter for CSRF protection
117
+ * @returns The complete authorization URL to redirect users to
118
+ *
119
+ * @throws Error when the provider is not configured
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const state = Lixa.generateRandomState();
124
+ * const authUrl = lixa.getAuthUrl('google', state);
125
+ * res.redirect(authUrl);
126
+ * ```
127
+ */
19
128
  getAuthUrl(provider: string, state: string): string;
129
+ /**
130
+ * Handles the OAuth callback and creates a user session.
131
+ *
132
+ * @param provider - The provider name
133
+ * @param code - The authorization code from the provider
134
+ * @param state - The state parameter for validation
135
+ * @returns A Promise that resolves to a Session object
136
+ *
137
+ * @throws Error when code or state is missing/invalid, or provider is not configured
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const session = await lixa.handleCallback({
142
+ * provider: 'google',
143
+ * code: req.query.code,
144
+ * state: req.query.state
145
+ * });
146
+ * ```
147
+ */
20
148
  handleCallback({ provider, code, state, }: {
21
149
  provider: string;
22
150
  code: string;
@@ -27,37 +155,68 @@ export declare class Lixa {
27
155
  }
28
156
 
29
157
  /**
158
+ * Main configuration object for Lixa.
159
+ *
30
160
  * @public
31
161
  */
32
162
  export declare interface LixaConfig {
163
+ /** Map of provider names to their configurations */
33
164
  providers: Record<string, ProviderConfig>;
165
+ /** Optional custom session creation strategy */
34
166
  sessionStrategy?: SessionStrategy;
167
+ /** Optional custom state storage implementation */
168
+ stateDao?: StateDao;
35
169
  }
36
170
 
37
171
  /**
172
+ * Configuration for an OAuth provider.
173
+ *
38
174
  * @public
39
175
  */
40
176
  export declare interface ProviderConfig {
177
+ /** The OAuth client ID provided by the provider */
41
178
  clientId: string;
179
+ /** The OAuth client secret provided by the provider */
42
180
  clientSecret: string;
181
+ /** The redirect URI registered with the provider */
43
182
  redirectUri: string;
183
+ /** Array of OAuth scopes to request */
44
184
  scopes: string[];
185
+ /** Additional provider-specific configuration parameters */
45
186
  extraConfig?: Record<string, any>;
46
187
  }
47
188
 
48
189
  /**
190
+ * Represents a user session after successful OAuth authentication.
191
+ *
49
192
  * @public
50
193
  */
51
194
  export declare interface Session {
195
+ /** The session token (typically the access token) */
52
196
  token: string;
197
+ /** Raw token data from the OAuth provider */
53
198
  raw: any;
54
199
  }
55
200
 
56
201
  /**
202
+ * Strategy interface for custom session creation.
203
+ *
57
204
  * @public
58
205
  */
59
206
  export declare interface SessionStrategy {
207
+ /**
208
+ * Creates a session from OAuth token data.
209
+ *
210
+ * @param userInfo - The token data received from the OAuth provider
211
+ * @returns A Promise that resolves to a Session object
212
+ */
60
213
  createSession(userInfo: any): Promise<Session>;
61
214
  }
62
215
 
216
+ declare interface StateDao {
217
+ saveState(state: string, data: any, expiresInSeconds: number): Promise<void>;
218
+ getState(state: string): Promise<any | null>;
219
+ deleteState(state: string): Promise<void>;
220
+ }
221
+
63
222
  export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vunexa/lixa",
3
- "version": "0.0.1-alpha.4",
3
+ "version": "0.0.1-alpha.6",
4
4
  "description": "Lixa is a flexible, provider-agnostic OAuth and OpenID Connect (OIDC) client library that simplifies multi-provider authentication flows. It supports seamless integration with providers like Google and GitHub, offers extensible session management, and enables dynamic provider resolution based on callback URLs.",
5
5
  "keywords": [
6
6
  "oauth",
@@ -27,6 +27,7 @@
27
27
  "test:watch": "jest --watch",
28
28
  "test:coverage": "jest --coverage",
29
29
  "api-extractor": "api-extractor run --local --verbose",
30
+ "docs:api": "npm run build && api-documenter markdown --input temp --output ./docs/api",
30
31
  "publish:alpha": "npm run build && npm version prerelease --preid=alpha && npm publish --tag alpha",
31
32
  "publish:beta": "npm run build && npm version prerelease --preid=beta && npm publish --tag beta",
32
33
  "publish:stable": "npm run build && npm version patch && npm publish --tag latest"
@@ -42,6 +43,7 @@
42
43
  "@microsoft/api-extractor": "^7.52.11",
43
44
  "@types/jest": "^29.5.12",
44
45
  "@types/node": "^24.3.1",
46
+ "@types/node-cache": "^4.1.3",
45
47
  "@typescript-eslint/eslint-plugin": "^8.42.0",
46
48
  "@typescript-eslint/parser": "^8.42.0",
47
49
  "eslint": "^9.35.0",
@@ -49,5 +51,8 @@
49
51
  "jest": "^29.7.0",
50
52
  "ts-jest": "^29.1.2",
51
53
  "typescript": "^5.9.2"
54
+ },
55
+ "dependencies": {
56
+ "node-cache": "^5.1.2"
52
57
  }
53
58
  }