@vunexa/lixa 0.0.1-alpha.4 → 0.0.1-alpha.5
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/dao/state-cache.d.ts +10 -0
- package/dist/dao/state-cache.d.ts.map +1 -0
- package/dist/dao/state-cache.js +18 -0
- package/dist/dao/state-cache.js.map +1 -0
- package/dist/dao/types.d.ts +6 -0
- package/dist/dao/types.d.ts.map +1 -0
- package/dist/dao/types.js +2 -0
- package/dist/dao/types.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lixa.d.ts +99 -1
- package/dist/lixa.d.ts.map +1 -1
- package/dist/lixa.js +115 -4
- package/dist/lixa.js.map +1 -1
- package/dist/providers/IProvider.d.ts +11 -0
- package/dist/providers/IProvider.d.ts.map +1 -1
- package/dist/providers/IProvider.js +0 -1
- package/dist/providers/IProvider.js.map +1 -1
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/index.d.ts +150 -1
- package/package.json +6 -1
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,116 @@
|
|
|
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
|
-
|
|
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 the authorization URL for the specified provider.
|
|
80
|
+
*
|
|
81
|
+
* @param provider - The provider name (case-insensitive)
|
|
82
|
+
* @param state - The state parameter for CSRF protection
|
|
83
|
+
* @returns The complete authorization URL to redirect users to
|
|
84
|
+
*
|
|
85
|
+
* @throws Error when the provider is not configured
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const state = Lixa.generateRandomState();
|
|
90
|
+
* const authUrl = lixa.getAuthUrl('google', state);
|
|
91
|
+
* res.redirect(authUrl);
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
15
94
|
getAuthUrl(provider: string, state: string): string;
|
|
95
|
+
/**
|
|
96
|
+
* Handles the OAuth callback and creates a user session.
|
|
97
|
+
*
|
|
98
|
+
* @param provider - The provider name
|
|
99
|
+
* @param code - The authorization code from the provider
|
|
100
|
+
* @param state - The state parameter for validation
|
|
101
|
+
* @returns A Promise that resolves to a Session object
|
|
102
|
+
*
|
|
103
|
+
* @throws Error when code or state is missing/invalid, or provider is not configured
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const session = await lixa.handleCallback({
|
|
108
|
+
* provider: 'google',
|
|
109
|
+
* code: req.query.code,
|
|
110
|
+
* state: req.query.state
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
16
114
|
handleCallback({ provider, code, state, }: {
|
|
17
115
|
provider: string;
|
|
18
116
|
code: string;
|
package/dist/lixa.d.ts.map
CHANGED
|
@@ -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;
|
|
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;AAKxE;;;;;;;;;;;;;;;;;;;;;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;;;;;;;;;;;;;;;OAeG;IACI,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IA6B1D;;;;;;;;;;;;;;;;;;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;YA+CN,oBAAoB;IAsClC,OAAO,CAAC,kBAAkB;CAG3B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
package/dist/lixa.js
CHANGED
|
@@ -1,14 +1,42 @@
|
|
|
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";
|
|
4
5
|
/**
|
|
6
|
+
* A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Lixa simplifies multi-provider authentication flows and supports extensible session management.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const lixa = new Lixa({
|
|
14
|
+
* providers: {
|
|
15
|
+
* google: {
|
|
16
|
+
* clientId: 'your-client-id',
|
|
17
|
+
* clientSecret: 'your-client-secret',
|
|
18
|
+
* redirectUri: 'https://yourapp.com/auth/google/callback',
|
|
19
|
+
* scopes: ['openid', 'email', 'profile']
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
5
25
|
* @public
|
|
6
26
|
*/
|
|
7
27
|
class Lixa {
|
|
8
28
|
static CONFIGURED_PROVIDERS = new Map();
|
|
29
|
+
static LOCAL_STATE_CACHE = new LocalStateCache();
|
|
9
30
|
config;
|
|
31
|
+
stateDao;
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new Lixa instance with the provided configuration.
|
|
34
|
+
*
|
|
35
|
+
* @param config - The configuration object containing provider settings and optional session strategy
|
|
36
|
+
*/
|
|
10
37
|
constructor(config) {
|
|
11
38
|
this.config = config;
|
|
39
|
+
this.stateDao = config.stateDao || Lixa.LOCAL_STATE_CACHE;
|
|
12
40
|
if (!Lixa.CONFIGURED_PROVIDERS.has(GITHUB)) {
|
|
13
41
|
Lixa.CONFIGURED_PROVIDERS.set(GITHUB, new GithubProvider());
|
|
14
42
|
}
|
|
@@ -16,9 +44,38 @@ class Lixa {
|
|
|
16
44
|
Lixa.CONFIGURED_PROVIDERS.set(GOOGLE, new GoogleProvider());
|
|
17
45
|
}
|
|
18
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Checks if a provider is registered and available for use.
|
|
49
|
+
*
|
|
50
|
+
* @param provider - The provider name to check (case-insensitive)
|
|
51
|
+
* @returns True if the provider is registered, false otherwise
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* if (Lixa.isProviderRegistered('google')) {
|
|
56
|
+
* console.log('Google provider is available');
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
19
60
|
static isProviderRegistered(provider) {
|
|
20
61
|
return Lixa.CONFIGURED_PROVIDERS.has(provider.toLowerCase());
|
|
21
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Registers custom OAuth providers for use with Lixa.
|
|
65
|
+
*
|
|
66
|
+
* @param providerMap - A map of provider names to IProvider implementations
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* class CustomProvider implements IProvider {
|
|
71
|
+
* authorizationEndpoint = 'https://custom.com/oauth/authorize';
|
|
72
|
+
* tokenEndpoint = 'https://custom.com/oauth/token';
|
|
73
|
+
* userInfoEndpoint = 'https://custom.com/api/user';
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* Lixa.registerProvider({ custom: new CustomProvider() });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
22
79
|
static registerProvider(providerMap) {
|
|
23
80
|
// This is a static method, so we can't access instance properties.
|
|
24
81
|
// Instead, we can modify the prototype to add the new provider.
|
|
@@ -26,9 +83,33 @@ class Lixa {
|
|
|
26
83
|
Lixa.CONFIGURED_PROVIDERS.set(key, providerImpl);
|
|
27
84
|
});
|
|
28
85
|
}
|
|
29
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Generates a cryptographically secure random state parameter for OAuth flows.
|
|
88
|
+
*
|
|
89
|
+
* @returns A 32-character hexadecimal string
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* The state parameter is used to prevent CSRF attacks in OAuth flows.
|
|
93
|
+
*/
|
|
94
|
+
static generateRandomState() {
|
|
30
95
|
return randomBytes(16).toString("hex");
|
|
31
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Generates the authorization URL for the specified provider.
|
|
99
|
+
*
|
|
100
|
+
* @param provider - The provider name (case-insensitive)
|
|
101
|
+
* @param state - The state parameter for CSRF protection
|
|
102
|
+
* @returns The complete authorization URL to redirect users to
|
|
103
|
+
*
|
|
104
|
+
* @throws Error when the provider is not configured
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const state = Lixa.generateRandomState();
|
|
109
|
+
* const authUrl = lixa.getAuthUrl('google', state);
|
|
110
|
+
* res.redirect(authUrl);
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
32
113
|
getAuthUrl(provider, state) {
|
|
33
114
|
const providerType = provider.toLowerCase();
|
|
34
115
|
const providerConfig = this.findProviderByType(providerType);
|
|
@@ -36,6 +117,10 @@ class Lixa {
|
|
|
36
117
|
if (!providerConfig || !providerImpl) {
|
|
37
118
|
throw new Error(`Provider ${providerType} not configured`);
|
|
38
119
|
}
|
|
120
|
+
// Cache the state paramaeter with TTL of 5 minutes (300 seconds)
|
|
121
|
+
// We dont care about value. we are onl interested in key existence
|
|
122
|
+
this.stateDao.saveState(state, state, 300 // 5 minutes in seconds
|
|
123
|
+
);
|
|
39
124
|
const params = new URLSearchParams({
|
|
40
125
|
client_id: providerConfig.clientId,
|
|
41
126
|
redirect_uri: providerConfig.redirectUri,
|
|
@@ -46,6 +131,25 @@ class Lixa {
|
|
|
46
131
|
});
|
|
47
132
|
return `${providerImpl.authorizationEndpoint}?${params.toString()}`;
|
|
48
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Handles the OAuth callback and creates a user session.
|
|
136
|
+
*
|
|
137
|
+
* @param provider - The provider name
|
|
138
|
+
* @param code - The authorization code from the provider
|
|
139
|
+
* @param state - The state parameter for validation
|
|
140
|
+
* @returns A Promise that resolves to a Session object
|
|
141
|
+
*
|
|
142
|
+
* @throws Error when code or state is missing/invalid, or provider is not configured
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const session = await lixa.handleCallback({
|
|
147
|
+
* provider: 'google',
|
|
148
|
+
* code: req.query.code,
|
|
149
|
+
* state: req.query.state
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
49
153
|
async handleCallback({ provider, code, state, }) {
|
|
50
154
|
if (!code || code.trim() === "") {
|
|
51
155
|
throw new Error("Invalid or missing code in callback");
|
|
@@ -53,9 +157,16 @@ class Lixa {
|
|
|
53
157
|
if (!state || state.trim() === "") {
|
|
54
158
|
throw new Error("Invalid or missing state in callback");
|
|
55
159
|
}
|
|
56
|
-
//
|
|
57
|
-
const
|
|
58
|
-
|
|
160
|
+
//Validate state here
|
|
161
|
+
const cachedState = await this.stateDao.getState(state);
|
|
162
|
+
if (!cachedState) {
|
|
163
|
+
throw new Error("Invalid or expired state");
|
|
164
|
+
}
|
|
165
|
+
// State is valid, remove it from cache to prevent reuse
|
|
166
|
+
await this.stateDao.deleteState(state);
|
|
167
|
+
const providerType = provider.toLowerCase();
|
|
168
|
+
const providerConfig = this.findProviderByType(providerType);
|
|
169
|
+
const providerImpl = Lixa.CONFIGURED_PROVIDERS.get(providerType);
|
|
59
170
|
if (!providerConfig || !providerImpl) {
|
|
60
171
|
throw new Error(`Provider ${provider} not configured`);
|
|
61
172
|
}
|
package/dist/lixa.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lixa.js","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"lixa.js","sourceRoot":"","sources":["../src/lixa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,IAAI;IACA,MAAM,CAAC,oBAAoB,GAA2B,IAAI,GAAG,EAAE,CAAC;IAChE,MAAM,CAAC,iBAAiB,GAAG,IAAI,eAAe,EAAE,CAAC;IACjD,MAAM,CAAa;IACnB,QAAQ,CAAW;IAE3B;;;;OAIG;IACH,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,MAAM,CAAC,oBAAoB,CAAC,QAAgB;QACjD,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACI,MAAM,CAAC,gBAAgB,CAAC,WAE9B;QACC,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,EAAE;YAC1D,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,mBAAmB;QAC/B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACI,UAAU,CAAC,QAAgB,EAAE,KAAa;QAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEjE,IAAI,CAAC,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,YAAY,YAAY,iBAAiB,CAAC,CAAC;QAC7D,CAAC;QAED,iEAAiE;QACjE,mEAAmE;QACnE,IAAI,CAAC,QAAQ,CAAC,SAAS,CACrB,KAAK,EACL,KAAK,EACL,GAAG,CAAC,uBAAuB;SAC5B,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,SAAS,EAAE,cAAc,CAAC,QAAQ;YAClC,YAAY,EAAE,cAAc,CAAC,WAAW;YACxC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YACtC,KAAK;YACL,aAAa,EAAE,MAAM;YACrB,GAAG,cAAc,CAAC,WAAW;SAC9B,CAAC,CAAC;QAEH,OAAO,GAAG,YAAY,CAAC,qBAAqB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACtE,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACI,KAAK,CAAC,cAAc,CAAC,EAC1B,QAAQ,EACR,IAAI,EACJ,KAAK,GAKN;QACC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,qBAAqB;QACrB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,wDAAwD;QACxD,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEvC,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEjE,IAAI,CAAC,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,iBAAiB,CAAC,CAAC;QACzD,CAAC;QAED,qDAAqD;QACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAC5C,IAAI,EACJ,cAAc,EACd,YAAY,CACb,CAAC;QAEF,+DAA+D;QAC/D,wEAAwE;QACxE,MAAM,OAAO,GAAY;YACvB,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,GAAG,EAAE,MAAM,EAAE,gCAAgC;SAC9C,CAAC;QAEF,iEAAiE;QACjE,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,IAAY,EACZ,cAA8B,EAC9B,YAAuB,EACvB,YAAqB;QAErB,yBAAyB;QACzB,MAAM,IAAI,GAA2B;YACnC,SAAS,EAAE,cAAc,CAAC,QAAQ;YAClC,aAAa,EAAE,cAAc,CAAC,YAAY;YAC1C,IAAI;YACJ,YAAY,EAAE,cAAc,CAAC,WAAW;YACxC,UAAU,EAAE,oBAAoB;SACjC,CAAC;QAEF,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;gBACnD,MAAM,EAAE,kBAAkB;aAC3B;YACD,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACnE,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAEO,kBAAkB,CAAC,YAAoB;QAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;;AAGH,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -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":"
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IProvider.js","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"
|
|
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
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA
|
|
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,140 @@
|
|
|
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
|
-
|
|
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 the authorization URL for the specified provider.
|
|
104
|
+
*
|
|
105
|
+
* @param provider - The provider name (case-insensitive)
|
|
106
|
+
* @param state - The state parameter for CSRF protection
|
|
107
|
+
* @returns The complete authorization URL to redirect users to
|
|
108
|
+
*
|
|
109
|
+
* @throws Error when the provider is not configured
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const state = Lixa.generateRandomState();
|
|
114
|
+
* const authUrl = lixa.getAuthUrl('google', state);
|
|
115
|
+
* res.redirect(authUrl);
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
19
118
|
getAuthUrl(provider: string, state: string): string;
|
|
119
|
+
/**
|
|
120
|
+
* Handles the OAuth callback and creates a user session.
|
|
121
|
+
*
|
|
122
|
+
* @param provider - The provider name
|
|
123
|
+
* @param code - The authorization code from the provider
|
|
124
|
+
* @param state - The state parameter for validation
|
|
125
|
+
* @returns A Promise that resolves to a Session object
|
|
126
|
+
*
|
|
127
|
+
* @throws Error when code or state is missing/invalid, or provider is not configured
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const session = await lixa.handleCallback({
|
|
132
|
+
* provider: 'google',
|
|
133
|
+
* code: req.query.code,
|
|
134
|
+
* state: req.query.state
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
20
138
|
handleCallback({ provider, code, state, }: {
|
|
21
139
|
provider: string;
|
|
22
140
|
code: string;
|
|
@@ -27,37 +145,68 @@ export declare class Lixa {
|
|
|
27
145
|
}
|
|
28
146
|
|
|
29
147
|
/**
|
|
148
|
+
* Main configuration object for Lixa.
|
|
149
|
+
*
|
|
30
150
|
* @public
|
|
31
151
|
*/
|
|
32
152
|
export declare interface LixaConfig {
|
|
153
|
+
/** Map of provider names to their configurations */
|
|
33
154
|
providers: Record<string, ProviderConfig>;
|
|
155
|
+
/** Optional custom session creation strategy */
|
|
34
156
|
sessionStrategy?: SessionStrategy;
|
|
157
|
+
/** Optional custom state storage implementation */
|
|
158
|
+
stateDao?: StateDao;
|
|
35
159
|
}
|
|
36
160
|
|
|
37
161
|
/**
|
|
162
|
+
* Configuration for an OAuth provider.
|
|
163
|
+
*
|
|
38
164
|
* @public
|
|
39
165
|
*/
|
|
40
166
|
export declare interface ProviderConfig {
|
|
167
|
+
/** The OAuth client ID provided by the provider */
|
|
41
168
|
clientId: string;
|
|
169
|
+
/** The OAuth client secret provided by the provider */
|
|
42
170
|
clientSecret: string;
|
|
171
|
+
/** The redirect URI registered with the provider */
|
|
43
172
|
redirectUri: string;
|
|
173
|
+
/** Array of OAuth scopes to request */
|
|
44
174
|
scopes: string[];
|
|
175
|
+
/** Additional provider-specific configuration parameters */
|
|
45
176
|
extraConfig?: Record<string, any>;
|
|
46
177
|
}
|
|
47
178
|
|
|
48
179
|
/**
|
|
180
|
+
* Represents a user session after successful OAuth authentication.
|
|
181
|
+
*
|
|
49
182
|
* @public
|
|
50
183
|
*/
|
|
51
184
|
export declare interface Session {
|
|
185
|
+
/** The session token (typically the access token) */
|
|
52
186
|
token: string;
|
|
187
|
+
/** Raw token data from the OAuth provider */
|
|
53
188
|
raw: any;
|
|
54
189
|
}
|
|
55
190
|
|
|
56
191
|
/**
|
|
192
|
+
* Strategy interface for custom session creation.
|
|
193
|
+
*
|
|
57
194
|
* @public
|
|
58
195
|
*/
|
|
59
196
|
export declare interface SessionStrategy {
|
|
197
|
+
/**
|
|
198
|
+
* Creates a session from OAuth token data.
|
|
199
|
+
*
|
|
200
|
+
* @param userInfo - The token data received from the OAuth provider
|
|
201
|
+
* @returns A Promise that resolves to a Session object
|
|
202
|
+
*/
|
|
60
203
|
createSession(userInfo: any): Promise<Session>;
|
|
61
204
|
}
|
|
62
205
|
|
|
206
|
+
declare interface StateDao {
|
|
207
|
+
saveState(state: string, data: any, expiresInSeconds: number): Promise<void>;
|
|
208
|
+
getState(state: string): Promise<any | null>;
|
|
209
|
+
deleteState(state: string): Promise<void>;
|
|
210
|
+
}
|
|
211
|
+
|
|
63
212
|
export { }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vunexa/lixa",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.5",
|
|
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
|
}
|