@vunexa/lixa 0.1.6-alpha.3 → 0.1.6-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.
- package/README.md +277 -18
- package/README.template.md +277 -18
- package/dist/dao/types.d.ts +47 -0
- package/dist/dao/types.d.ts.map +1 -1
- package/dist/export-types/index.d.ts +95 -5
- package/dist/index.cjs +185 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -12
- package/dist/index.js.map +1 -1
- package/dist/lixa.d.ts +37 -5
- package/dist/lixa.d.ts.map +1 -1
- package/dist/models/session.d.ts +2 -0
- package/dist/models/session.d.ts.map +1 -1
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/dao/types.d.ts
CHANGED
|
@@ -220,6 +220,53 @@ export interface SessionStorage {
|
|
|
220
220
|
session: T;
|
|
221
221
|
} | null>;
|
|
222
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Resource storage operations interface.
|
|
225
|
+
*
|
|
226
|
+
* @remarks
|
|
227
|
+
* Manages long-lived third-party resource provider tokens (AuthZ) bound to a user account
|
|
228
|
+
* (User ID or Email), independent of short-lived user sessions.
|
|
229
|
+
*
|
|
230
|
+
* @public
|
|
231
|
+
*/
|
|
232
|
+
export interface ResourceStorage {
|
|
233
|
+
/**
|
|
234
|
+
* Saves a connected resource token for a user.
|
|
235
|
+
*
|
|
236
|
+
* @param userId - Unique user identifier or email
|
|
237
|
+
* @param provider - Resource provider name (e.g. 'github', 'google')
|
|
238
|
+
* @param resource - Connected resource details including access & refresh tokens
|
|
239
|
+
*/
|
|
240
|
+
saveResource(userId: string, provider: string, resource: import("../models/session").ConnectedResource): Promise<void>;
|
|
241
|
+
/**
|
|
242
|
+
* Retrieves a connected resource token for a user.
|
|
243
|
+
*
|
|
244
|
+
* @param userId - Unique user identifier or email
|
|
245
|
+
* @param provider - Resource provider name
|
|
246
|
+
*/
|
|
247
|
+
getResource(userId: string, provider: string): Promise<import("../models/session").ConnectedResource | null>;
|
|
248
|
+
/**
|
|
249
|
+
* Retrieves all connected resources for a user.
|
|
250
|
+
*
|
|
251
|
+
* @param userId - Unique user identifier or email
|
|
252
|
+
*/
|
|
253
|
+
getUserResources(userId: string): Promise<Record<string, import("../models/session").ConnectedResource>>;
|
|
254
|
+
/**
|
|
255
|
+
* Deletes a connected resource token for a user.
|
|
256
|
+
*
|
|
257
|
+
* @param userId - Unique user identifier or email
|
|
258
|
+
* @param provider - Resource provider name
|
|
259
|
+
*/
|
|
260
|
+
deleteResource(userId: string, provider: string): Promise<void>;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Resource handler configuration.
|
|
264
|
+
*
|
|
265
|
+
* @public
|
|
266
|
+
*/
|
|
267
|
+
export interface ResourceHandler {
|
|
268
|
+
resourceStorage?: ResourceStorage;
|
|
269
|
+
}
|
|
223
270
|
/**
|
|
224
271
|
* Session handler for OAuth authentication.
|
|
225
272
|
*
|
package/dist/dao/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAEnD;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,aAAa,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAE9E;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvG;;;;;OAKG;IACH,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpE;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACzG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgDG;IACH,eAAe,CAAC,CAAC,CAAC,SAAS,OAAO,EAChC,SAAS,EAAE,OAAO,mBAAmB,EAAE,kBAAkB,EACzD,gBAAgB,EAAE,OAAO,mBAAmB,EAAE,gBAAgB,GAC7D,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;OAKG;IACH,eAAe,CAAC,CAAC,CAAC,SAAS,OAAO,EAChC,SAAS,EAAE,OAAO,mBAAmB,EAAE,kBAAkB,EACzD,gBAAgB,EAAE,OAAO,mBAAmB,EAAE,gBAAgB,GAC7D,OAAO,CAAC,CAAC,CAAC,CAAC;CACf"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -141,6 +141,8 @@ export declare interface ConnectedResource {
|
|
|
141
141
|
accessToken: string;
|
|
142
142
|
/** Optional refresh token for offline resource access */
|
|
143
143
|
refreshToken?: string | undefined;
|
|
144
|
+
/** Unix timestamp in milliseconds when the resource access token expires */
|
|
145
|
+
expiresAt?: number | undefined;
|
|
144
146
|
/** Resource scopes granted by the user */
|
|
145
147
|
scopes: string[];
|
|
146
148
|
/** Full raw token response from provider */
|
|
@@ -437,6 +439,7 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
437
439
|
private config;
|
|
438
440
|
private stateHandler;
|
|
439
441
|
private sessionHandler;
|
|
442
|
+
private resourceHandler;
|
|
440
443
|
private debug;
|
|
441
444
|
/**
|
|
442
445
|
* Creates a new Lixa instance with the provided configuration.
|
|
@@ -749,6 +752,12 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
749
752
|
* @param params - Object containing sessionId, provider, code, state, and requested scopes
|
|
750
753
|
* @returns Updated Session containing stored resource tokens under session.resources[provider]
|
|
751
754
|
*/
|
|
755
|
+
private static userResourceStore;
|
|
756
|
+
static LOCAL_RESOURCE_HANDLER: ResourceHandler;
|
|
757
|
+
private getUserKeyFromSession;
|
|
758
|
+
/**
|
|
759
|
+
* Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
|
|
760
|
+
*/
|
|
752
761
|
handleResourceCallback(params: {
|
|
753
762
|
sessionId: string;
|
|
754
763
|
provider: ConfiguredProviderKey<TConfig> | string;
|
|
@@ -757,17 +766,41 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
757
766
|
scopes?: string[];
|
|
758
767
|
}): Promise<Session>;
|
|
759
768
|
/**
|
|
760
|
-
* Retrieves a connected resource
|
|
769
|
+
* Retrieves a connected resource for a specific User ID / Email directly (independent of session IDs).
|
|
770
|
+
* Automatically refreshes expired access tokens if a refresh token is present.
|
|
771
|
+
*
|
|
772
|
+
* @param userIdOrEmail - User identifier or email
|
|
773
|
+
* @param provider - Resource provider identifier (e.g. 'github', 'google')
|
|
774
|
+
*/
|
|
775
|
+
getUserResource(userIdOrEmail: string, provider: string): Promise<ConnectedResource | null>;
|
|
776
|
+
/**
|
|
777
|
+
* Retrieves all connected resources for a specific User ID / Email.
|
|
778
|
+
*/
|
|
779
|
+
getUserResources(userIdOrEmail: string): Promise<Record<string, ConnectedResource>>;
|
|
780
|
+
/**
|
|
781
|
+
* Retrieves a connected resource provider token for an active session, auto-refreshing expired tokens if possible.
|
|
761
782
|
*
|
|
762
783
|
* @param sessionId - Active session ID
|
|
763
|
-
* @param provider - Provider identifier (e.g. 'github')
|
|
784
|
+
* @param provider - Provider identifier (e.g. 'github', 'google')
|
|
764
785
|
*/
|
|
765
786
|
getConnectedResource(sessionId: string, provider: string): Promise<ConnectedResource | null>;
|
|
766
787
|
/**
|
|
767
|
-
*
|
|
788
|
+
* Refreshes a user's resource access token using its refresh token.
|
|
768
789
|
*
|
|
769
|
-
* @param
|
|
770
|
-
* @param provider - Provider identifier
|
|
790
|
+
* @param userIdOrEmail - User identifier or email
|
|
791
|
+
* @param provider - Provider identifier (e.g. 'google', 'github')
|
|
792
|
+
*/
|
|
793
|
+
refreshUserResourceToken(userIdOrEmail: string, provider: string, existingResource?: ConnectedResource): Promise<ConnectedResource>;
|
|
794
|
+
/**
|
|
795
|
+
* Refreshes a connected resource access token for an active session.
|
|
796
|
+
*/
|
|
797
|
+
refreshResourceToken(sessionId: string, provider: string): Promise<ConnectedResource>;
|
|
798
|
+
/**
|
|
799
|
+
* Disconnects a resource provider for a specific User ID / Email.
|
|
800
|
+
*/
|
|
801
|
+
disconnectUserResource(userIdOrEmail: string, provider: string): Promise<boolean>;
|
|
802
|
+
/**
|
|
803
|
+
* Disconnects a resource provider from an active session and user account.
|
|
771
804
|
*/
|
|
772
805
|
disconnectResource(sessionId: string, provider: string): Promise<boolean>;
|
|
773
806
|
fetchSessionInfo(sessionId: string): Promise<Session | null>;
|
|
@@ -815,6 +848,14 @@ export declare interface LixaConfig<TProviders extends Record<string, ProviderCo
|
|
|
815
848
|
* @see {@link SessionHandler}
|
|
816
849
|
*/
|
|
817
850
|
sessionHandler?: SessionHandler;
|
|
851
|
+
/**
|
|
852
|
+
* Optional custom resource handler.
|
|
853
|
+
* Handles storage and management of long-lived third-party resource provider tokens (AuthZ)
|
|
854
|
+
* bound directly to user accounts (User ID or Email), independent of transient session IDs.
|
|
855
|
+
*
|
|
856
|
+
* @see {@link ResourceHandler}
|
|
857
|
+
*/
|
|
858
|
+
resourceHandler?: ResourceHandler;
|
|
818
859
|
/**
|
|
819
860
|
* Enable debug logging.
|
|
820
861
|
* When enabled, outputs structured logs for initialization, auth flow, and errors.
|
|
@@ -945,6 +986,55 @@ export declare interface ProviderMetadata {
|
|
|
945
986
|
};
|
|
946
987
|
}
|
|
947
988
|
|
|
989
|
+
/**
|
|
990
|
+
* Resource handler configuration.
|
|
991
|
+
*
|
|
992
|
+
* @public
|
|
993
|
+
*/
|
|
994
|
+
export declare interface ResourceHandler {
|
|
995
|
+
resourceStorage?: ResourceStorage;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Resource storage operations interface.
|
|
1000
|
+
*
|
|
1001
|
+
* @remarks
|
|
1002
|
+
* Manages long-lived third-party resource provider tokens (AuthZ) bound to a user account
|
|
1003
|
+
* (User ID or Email), independent of short-lived user sessions.
|
|
1004
|
+
*
|
|
1005
|
+
* @public
|
|
1006
|
+
*/
|
|
1007
|
+
export declare interface ResourceStorage {
|
|
1008
|
+
/**
|
|
1009
|
+
* Saves a connected resource token for a user.
|
|
1010
|
+
*
|
|
1011
|
+
* @param userId - Unique user identifier or email
|
|
1012
|
+
* @param provider - Resource provider name (e.g. 'github', 'google')
|
|
1013
|
+
* @param resource - Connected resource details including access & refresh tokens
|
|
1014
|
+
*/
|
|
1015
|
+
saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Retrieves a connected resource token for a user.
|
|
1018
|
+
*
|
|
1019
|
+
* @param userId - Unique user identifier or email
|
|
1020
|
+
* @param provider - Resource provider name
|
|
1021
|
+
*/
|
|
1022
|
+
getResource(userId: string, provider: string): Promise<ConnectedResource | null>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Retrieves all connected resources for a user.
|
|
1025
|
+
*
|
|
1026
|
+
* @param userId - Unique user identifier or email
|
|
1027
|
+
*/
|
|
1028
|
+
getUserResources(userId: string): Promise<Record<string, ConnectedResource>>;
|
|
1029
|
+
/**
|
|
1030
|
+
* Deletes a connected resource token for a user.
|
|
1031
|
+
*
|
|
1032
|
+
* @param userId - Unique user identifier or email
|
|
1033
|
+
* @param provider - Resource provider name
|
|
1034
|
+
*/
|
|
1035
|
+
deleteResource(userId: string, provider: string): Promise<void>;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
948
1038
|
/**
|
|
949
1039
|
* Helper type to create a configuration with only registered providers.
|
|
950
1040
|
* Use this with Lixa.createConfig() for type safety.
|
package/dist/index.cjs
CHANGED
|
@@ -217,6 +217,7 @@ var Lixa = class _Lixa {
|
|
|
217
217
|
config;
|
|
218
218
|
stateHandler;
|
|
219
219
|
sessionHandler;
|
|
220
|
+
resourceHandler;
|
|
220
221
|
debug;
|
|
221
222
|
/**
|
|
222
223
|
* Creates a new Lixa instance with the provided configuration.
|
|
@@ -235,6 +236,7 @@ var Lixa = class _Lixa {
|
|
|
235
236
|
this.config = config;
|
|
236
237
|
this.stateHandler = config.stateHandler || _Lixa.LOCAL_STATE_HANDLER;
|
|
237
238
|
this.sessionHandler = config.sessionHandler || _Lixa.LOCAL_SESSION_HANDLER;
|
|
239
|
+
this.resourceHandler = config.resourceHandler || _Lixa.LOCAL_RESOURCE_HANDLER;
|
|
238
240
|
this.debug = config.debug || false;
|
|
239
241
|
this.log("INFO", "Init", "Initializing Lixa instance", {
|
|
240
242
|
providers: Object.keys(config.providers),
|
|
@@ -914,6 +916,45 @@ var Lixa = class _Lixa {
|
|
|
914
916
|
* @param params - Object containing sessionId, provider, code, state, and requested scopes
|
|
915
917
|
* @returns Updated Session containing stored resource tokens under session.resources[provider]
|
|
916
918
|
*/
|
|
919
|
+
static userResourceStore = /* @__PURE__ */ new Map();
|
|
920
|
+
static LOCAL_RESOURCE_HANDLER = {
|
|
921
|
+
resourceStorage: {
|
|
922
|
+
saveResource: async (userId, provider, resource) => {
|
|
923
|
+
let userMap = _Lixa.userResourceStore.get(userId);
|
|
924
|
+
if (!userMap) {
|
|
925
|
+
userMap = /* @__PURE__ */ new Map();
|
|
926
|
+
_Lixa.userResourceStore.set(userId, userMap);
|
|
927
|
+
}
|
|
928
|
+
userMap.set(provider.toLowerCase(), resource);
|
|
929
|
+
},
|
|
930
|
+
getResource: async (userId, provider) => {
|
|
931
|
+
const userMap = _Lixa.userResourceStore.get(userId);
|
|
932
|
+
return userMap?.get(provider.toLowerCase()) || null;
|
|
933
|
+
},
|
|
934
|
+
getUserResources: async (userId) => {
|
|
935
|
+
const userMap = _Lixa.userResourceStore.get(userId);
|
|
936
|
+
const result = {};
|
|
937
|
+
if (userMap) {
|
|
938
|
+
for (const [p, r] of userMap.entries()) {
|
|
939
|
+
result[p] = r;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
return result;
|
|
943
|
+
},
|
|
944
|
+
deleteResource: async (userId, provider) => {
|
|
945
|
+
const userMap = _Lixa.userResourceStore.get(userId);
|
|
946
|
+
if (userMap) {
|
|
947
|
+
userMap.delete(provider.toLowerCase());
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
getUserKeyFromSession(session) {
|
|
953
|
+
return session.userId || session.email || session.id || "anonymous";
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
|
|
957
|
+
*/
|
|
917
958
|
async handleResourceCallback(params) {
|
|
918
959
|
const { sessionId, provider, code, state, scopes } = params;
|
|
919
960
|
const sessionStorage = this.sessionHandler.sessionStorage || _Lixa.LOCAL_SESSION_HANDLER.sessionStorage;
|
|
@@ -937,44 +978,176 @@ var Lixa = class _Lixa {
|
|
|
937
978
|
}
|
|
938
979
|
}
|
|
939
980
|
const tokens = await this.exchangeCodeForToken(code, providerConfig, providerImpl, codeVerifier);
|
|
940
|
-
|
|
941
|
-
|
|
981
|
+
const expiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : void 0;
|
|
982
|
+
const connectedResource = {
|
|
942
983
|
provider: providerType,
|
|
943
984
|
accessToken: tokens.access_token,
|
|
944
985
|
refreshToken: tokens.refresh_token,
|
|
986
|
+
expiresAt,
|
|
945
987
|
scopes: scopes || (tokens.scope ? tokens.scope.split(" ") : []),
|
|
946
988
|
raw: tokens,
|
|
947
989
|
connectedAt: Date.now()
|
|
948
990
|
};
|
|
991
|
+
const userKey = this.getUserKeyFromSession(activeSession);
|
|
992
|
+
const resourceStorage = this.resourceHandler.resourceStorage || _Lixa.LOCAL_RESOURCE_HANDLER.resourceStorage;
|
|
993
|
+
await resourceStorage.saveResource(userKey, providerType, connectedResource);
|
|
994
|
+
activeSession.resources = activeSession.resources || {};
|
|
995
|
+
activeSession.resources[providerType] = connectedResource;
|
|
949
996
|
await sessionStorage.saveSession(sessionId, activeSession, 86400);
|
|
950
997
|
return activeSession;
|
|
951
998
|
}
|
|
952
999
|
/**
|
|
953
|
-
* Retrieves a connected resource
|
|
1000
|
+
* Retrieves a connected resource for a specific User ID / Email directly (independent of session IDs).
|
|
1001
|
+
* Automatically refreshes expired access tokens if a refresh token is present.
|
|
1002
|
+
*
|
|
1003
|
+
* @param userIdOrEmail - User identifier or email
|
|
1004
|
+
* @param provider - Resource provider identifier (e.g. 'github', 'google')
|
|
1005
|
+
*/
|
|
1006
|
+
async getUserResource(userIdOrEmail, provider) {
|
|
1007
|
+
const resourceStorage = this.resourceHandler.resourceStorage || _Lixa.LOCAL_RESOURCE_HANDLER.resourceStorage;
|
|
1008
|
+
const providerType = provider.toLowerCase();
|
|
1009
|
+
const resource = await resourceStorage.getResource(userIdOrEmail, providerType);
|
|
1010
|
+
if (!resource) return null;
|
|
1011
|
+
if (resource.refreshToken && resource.expiresAt && Date.now() >= resource.expiresAt - 6e4) {
|
|
1012
|
+
this.log("INFO", "Token", `Resource access token for user '${userIdOrEmail}' on '${providerType}' is expired. Auto-refreshing...`);
|
|
1013
|
+
try {
|
|
1014
|
+
return await this.refreshUserResourceToken(userIdOrEmail, providerType);
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
this.log("ERROR", "Token", `Failed to auto-refresh resource token for user '${userIdOrEmail}' on '${providerType}'`, { error: String(error) });
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return resource;
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Retrieves all connected resources for a specific User ID / Email.
|
|
1023
|
+
*/
|
|
1024
|
+
async getUserResources(userIdOrEmail) {
|
|
1025
|
+
const resourceStorage = this.resourceHandler.resourceStorage || _Lixa.LOCAL_RESOURCE_HANDLER.resourceStorage;
|
|
1026
|
+
return await resourceStorage.getUserResources(userIdOrEmail);
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Retrieves a connected resource provider token for an active session, auto-refreshing expired tokens if possible.
|
|
954
1030
|
*
|
|
955
1031
|
* @param sessionId - Active session ID
|
|
956
|
-
* @param provider - Provider identifier (e.g. 'github')
|
|
1032
|
+
* @param provider - Provider identifier (e.g. 'github', 'google')
|
|
957
1033
|
*/
|
|
958
1034
|
async getConnectedResource(sessionId, provider) {
|
|
959
1035
|
const sessionStorage = this.sessionHandler.sessionStorage || _Lixa.LOCAL_SESSION_HANDLER.sessionStorage;
|
|
960
1036
|
const activeSession = await sessionStorage.getSession(sessionId);
|
|
961
|
-
if (!activeSession
|
|
962
|
-
|
|
1037
|
+
if (!activeSession) return null;
|
|
1038
|
+
const providerType = provider.toLowerCase();
|
|
1039
|
+
const userKey = this.getUserKeyFromSession(activeSession);
|
|
1040
|
+
let resource = await this.getUserResource(userKey, providerType);
|
|
1041
|
+
if (!resource && activeSession.resources) {
|
|
1042
|
+
resource = activeSession.resources[providerType] || null;
|
|
1043
|
+
}
|
|
1044
|
+
if (resource) {
|
|
1045
|
+
if (resource.refreshToken && resource.expiresAt && Date.now() >= resource.expiresAt - 6e4) {
|
|
1046
|
+
this.log("INFO", "Token", `Resource access token for user '${userKey}' on '${providerType}' is expired. Auto-refreshing...`);
|
|
1047
|
+
try {
|
|
1048
|
+
resource = await this.refreshResourceToken(sessionId, providerType);
|
|
1049
|
+
} catch (error) {
|
|
1050
|
+
this.log("ERROR", "Token", `Failed to auto-refresh resource token for user '${userKey}' on '${providerType}'`, { error: String(error) });
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
activeSession.resources = activeSession.resources || {};
|
|
1054
|
+
activeSession.resources[providerType] = resource;
|
|
1055
|
+
}
|
|
1056
|
+
return resource;
|
|
963
1057
|
}
|
|
964
1058
|
/**
|
|
965
|
-
*
|
|
1059
|
+
* Refreshes a user's resource access token using its refresh token.
|
|
966
1060
|
*
|
|
967
|
-
* @param
|
|
968
|
-
* @param provider - Provider identifier
|
|
1061
|
+
* @param userIdOrEmail - User identifier or email
|
|
1062
|
+
* @param provider - Provider identifier (e.g. 'google', 'github')
|
|
969
1063
|
*/
|
|
970
|
-
async
|
|
1064
|
+
async refreshUserResourceToken(userIdOrEmail, provider, existingResource) {
|
|
1065
|
+
const resourceStorage = this.resourceHandler.resourceStorage || _Lixa.LOCAL_RESOURCE_HANDLER.resourceStorage;
|
|
1066
|
+
const providerType = provider.toLowerCase();
|
|
1067
|
+
let resource = existingResource || await resourceStorage.getResource(userIdOrEmail, providerType);
|
|
1068
|
+
if (!resource || !resource.refreshToken) {
|
|
1069
|
+
throw new Error(`No refresh token available for user '${userIdOrEmail}' on connected resource '${provider}'`);
|
|
1070
|
+
}
|
|
1071
|
+
const providerConfig = this.findProviderByType(providerType);
|
|
1072
|
+
if (!providerConfig) {
|
|
1073
|
+
throw new Error(`Provider '${provider}' is not configured`);
|
|
1074
|
+
}
|
|
1075
|
+
const providerImpl = this.getProvider(providerType, providerConfig);
|
|
1076
|
+
const body = {
|
|
1077
|
+
client_id: providerConfig.clientId,
|
|
1078
|
+
client_secret: providerConfig.clientSecret,
|
|
1079
|
+
grant_type: "refresh_token",
|
|
1080
|
+
refresh_token: resource.refreshToken
|
|
1081
|
+
};
|
|
1082
|
+
const response = await fetch(providerImpl.tokenEndpoint, {
|
|
1083
|
+
method: "POST",
|
|
1084
|
+
headers: {
|
|
1085
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1086
|
+
Accept: "application/json"
|
|
1087
|
+
},
|
|
1088
|
+
body: new URLSearchParams(body).toString()
|
|
1089
|
+
});
|
|
1090
|
+
if (!response.ok) {
|
|
1091
|
+
const errorText = await response.text();
|
|
1092
|
+
throw new Error(`Failed to refresh resource token for user '${userIdOrEmail}' on '${provider}': ${response.status} - ${errorText}`);
|
|
1093
|
+
}
|
|
1094
|
+
const tokens = await response.json();
|
|
1095
|
+
const expiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : void 0;
|
|
1096
|
+
resource.accessToken = tokens.access_token;
|
|
1097
|
+
if (tokens.refresh_token) {
|
|
1098
|
+
resource.refreshToken = tokens.refresh_token;
|
|
1099
|
+
}
|
|
1100
|
+
if (expiresAt) {
|
|
1101
|
+
resource.expiresAt = expiresAt;
|
|
1102
|
+
}
|
|
1103
|
+
resource.raw = tokens;
|
|
1104
|
+
resource.connectedAt = Date.now();
|
|
1105
|
+
await resourceStorage.saveResource(userIdOrEmail, providerType, resource);
|
|
1106
|
+
return resource;
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Refreshes a connected resource access token for an active session.
|
|
1110
|
+
*/
|
|
1111
|
+
async refreshResourceToken(sessionId, provider) {
|
|
971
1112
|
const sessionStorage = this.sessionHandler.sessionStorage || _Lixa.LOCAL_SESSION_HANDLER.sessionStorage;
|
|
972
1113
|
const activeSession = await sessionStorage.getSession(sessionId);
|
|
973
|
-
if (!activeSession
|
|
974
|
-
|
|
1114
|
+
if (!activeSession) {
|
|
1115
|
+
throw new Error("Active session not found.");
|
|
1116
|
+
}
|
|
1117
|
+
const providerType = provider.toLowerCase();
|
|
1118
|
+
const userKey = this.getUserKeyFromSession(activeSession);
|
|
1119
|
+
const existingResource = activeSession.resources ? activeSession.resources[providerType] : void 0;
|
|
1120
|
+
const refreshed = await this.refreshUserResourceToken(userKey, providerType, existingResource);
|
|
1121
|
+
activeSession.resources = activeSession.resources || {};
|
|
1122
|
+
activeSession.resources[providerType] = refreshed;
|
|
975
1123
|
await sessionStorage.saveSession(sessionId, activeSession, 86400);
|
|
1124
|
+
return refreshed;
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Disconnects a resource provider for a specific User ID / Email.
|
|
1128
|
+
*/
|
|
1129
|
+
async disconnectUserResource(userIdOrEmail, provider) {
|
|
1130
|
+
const resourceStorage = this.resourceHandler.resourceStorage || _Lixa.LOCAL_RESOURCE_HANDLER.resourceStorage;
|
|
1131
|
+
await resourceStorage.deleteResource(userIdOrEmail, provider.toLowerCase());
|
|
976
1132
|
return true;
|
|
977
1133
|
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Disconnects a resource provider from an active session and user account.
|
|
1136
|
+
*/
|
|
1137
|
+
async disconnectResource(sessionId, provider) {
|
|
1138
|
+
const sessionStorage = this.sessionHandler.sessionStorage || _Lixa.LOCAL_SESSION_HANDLER.sessionStorage;
|
|
1139
|
+
const activeSession = await sessionStorage.getSession(sessionId);
|
|
1140
|
+
if (activeSession) {
|
|
1141
|
+
const userKey = this.getUserKeyFromSession(activeSession);
|
|
1142
|
+
await this.disconnectUserResource(userKey, provider);
|
|
1143
|
+
if (activeSession.resources) {
|
|
1144
|
+
delete activeSession.resources[provider.toLowerCase()];
|
|
1145
|
+
await sessionStorage.saveSession(sessionId, activeSession, 86400);
|
|
1146
|
+
}
|
|
1147
|
+
return true;
|
|
1148
|
+
}
|
|
1149
|
+
return false;
|
|
1150
|
+
}
|
|
978
1151
|
async fetchSessionInfo(sessionId) {
|
|
979
1152
|
const sessionStorage = this.sessionHandler.sessionStorage || _Lixa.LOCAL_SESSION_HANDLER.sessionStorage;
|
|
980
1153
|
return await sessionStorage.getSession(sessionId);
|