@dainprotocol/oauth2-token-manager 0.1.0
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 +786 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +785 -0
- package/dist/index.d.ts +785 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +99 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {createHash,randomBytes}from'crypto';import {sealData,unsealData}from'iron-session';var P=class{buildUrlParams(e){return Object.entries(e).filter(([,t])=>t!==void 0).map(([t,s])=>`${t}=${encodeURIComponent(s)}`).join("&")}generateAuthorizationUrl(e,r,t){let s={client_id:e.clientId,redirect_uri:e.redirectUri,response_type:"code",scope:e.scopes.join(" "),state:r};(e.usePKCE||e.pkce)&&t&&(s.code_challenge=t,s.code_challenge_method="S256");let o={...e.additionalParams,...e.extraAuthParams};return Object.assign(s,o),`${e.authorizationUrl}?${this.buildUrlParams(s)}`}};var v=class{buildUrlParams(e){return Object.entries(e).filter(([,t])=>t!==void 0).map(([t,s])=>`${t}=${encodeURIComponent(s)}`).join("&")}async exchangeCodeForToken(e,r,t){let s={grant_type:"authorization_code",code:e,redirect_uri:r.redirectUri,client_id:r.clientId};(r.usePKCE||r.pkce)&&t?s.code_verifier=t:r.clientSecret&&(s.client_secret=r.clientSecret);let o=await fetch(r.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildUrlParams(s)});if(!o.ok){let c=await o.text();throw new Error(`Token exchange failed: ${o.statusText} - ${c}`)}let n=await o.json(),a=r.responseRootKey?n[r.responseRootKey]:n,i=Date.now(),d=a.expires_in||3600;return {accessToken:a.access_token,refreshToken:a.refresh_token,expiresAt:new Date(i+d*1e3),expiresIn:d,tokenType:a.token_type||"Bearer",scope:a.scope,createdAt:i,raw:n}}async refreshToken(e,r){let t={grant_type:"refresh_token",refresh_token:e,client_id:r.clientId};!(r.usePKCE||r.pkce)&&r.clientSecret&&(t.client_secret=r.clientSecret);let s=await fetch(r.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildUrlParams(t)});if(!s.ok){let d=await s.text();throw new Error(`Token refresh failed: ${s.statusText} - ${d}`)}let o=await s.json(),n=r.responseRootKey?o[r.responseRootKey]:o,a=Date.now(),i=n.expires_in||3600;return {accessToken:n.access_token,refreshToken:n.refresh_token||e,expiresAt:new Date(a+i*1e3),expiresIn:i,tokenType:n.token_type||"Bearer",scope:n.scope,createdAt:a,raw:o}}};var k=class{constructor(e,r,t,s){this.config=e;this.authUrlStrategy=r||this.createAuthorizationUrlStrategy(),this.tokenStrategy=t||this.createTokenExchangeStrategy(),this.profileFetcher=s;}authUrlStrategy;tokenStrategy;profileFetcher;async fetchProfile(e){if(!this.profileFetcher)throw new Error("Profile fetcher not configured for this provider");return this.profileFetcher.fetchUserInfo(e)}getProfileEndpoint(){if(!this.profileFetcher)throw new Error("Profile fetcher not configured for this provider");return this.profileFetcher.getEndpoint()}setProfileFetcher(e){this.profileFetcher=e;}hasProfileFetcher(){return !!this.profileFetcher}generateAuthorizationUrl(e,r){return this.authUrlStrategy.generateAuthorizationUrl(this.config,e,r)}async exchangeCodeForToken(e,r){return this.tokenStrategy.exchangeCodeForToken(e,this.config,r)}async refreshToken(e){return this.tokenStrategy.refreshToken(e,this.config)}};var U=class extends k{constructor(e,r,t,s){super(e,r,t,s);}createAuthorizationUrlStrategy(){return new P}createTokenExchangeStrategy(){return new v}};var m=class{constructor(e){this.profileEndpoint=e;}async fetchUserInfo(e){let r=await fetch(this.profileEndpoint,{headers:{Authorization:`Bearer ${e}`,Accept:"application/json",...this.getAdditionalHeaders()}});if(!r.ok)throw new Error(`Failed to fetch profile from ${this.profileEndpoint}: ${r.statusText}`);let t=await r.json();return this.mapToUserProfile(t)}getAdditionalHeaders(){return {}}getEndpoint(){return this.profileEndpoint}};var w=class extends m{constructor(){super("https://www.googleapis.com/oauth2/v2/userinfo");}mapToUserProfile(e){return {email:e.email,name:e.name,id:e.id,avatar:e.picture,username:e.email,raw:e}}};var S=class extends m{constructor(){super("https://api.github.com/user");}mapToUserProfile(e){var r;return {email:e.email,name:e.name||e.login,id:(r=e.id)==null?void 0:r.toString(),avatar:e.avatar_url,username:e.login,raw:e}}getAdditionalHeaders(){return {"User-Agent":"OAuth2-Token-Manager"}}};var I=class extends m{constructor(){super("https://graph.microsoft.com/v1.0/me");}mapToUserProfile(e){return {email:e.mail||e.userPrincipalName,name:e.displayName,id:e.id,avatar:void 0,username:e.userPrincipalName,raw:e}}};var f=class extends m{constructor(r,t,s){super(r);this.mapping=t;this.additionalHeaders=s;}mapToUserProfile(r){return this.mapping?{email:this.getNestedProperty(r,this.mapping.email),name:this.mapping.name?this.getNestedProperty(r,this.mapping.name):void 0,id:this.mapping.id?this.getNestedProperty(r,this.mapping.id):void 0,avatar:this.mapping.avatar?this.getNestedProperty(r,this.mapping.avatar):void 0,username:this.mapping.username?this.getNestedProperty(r,this.mapping.username):void 0,raw:r}:{email:r.email||r.mail||r.emailAddress,name:r.name||r.displayName||r.full_name,id:r.id||r.sub||r.user_id,avatar:r.avatar||r.picture||r.avatar_url,username:r.username||r.login||r.preferred_username,raw:r}}getAdditionalHeaders(){return this.additionalHeaders||{}}getNestedProperty(r,t){return t.split(".").reduce((s,o)=>s==null?void 0:s[o],r)}};var A=class{static createProfileFetcher(e,r,t){if(t!=null&&t.profileUrl)return new f(t.profileUrl,t.profileMapping,t.profileHeaders);switch(e){case "google":return new w;case "github":return new S;case "microsoft":case "outlook":return new I;case "facebook":return new f("https://graph.facebook.com/me?fields=id,name,email,picture");case "generic":default:let s=r.profileUrl||r.userInfoUrl;if(!s)throw new Error(`Profile URL must be provided for ${e} provider`);return new f(s)}}static registerCustomProfileFetcher(e,r){this.customFetchers.set(e,r);}static customFetchers=new Map;static getCustomProfileFetcher(e){return this.customFetchers.get(e)}};var E=class u{static presetConfigs={google:{authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",profileUrl:"https://www.googleapis.com/oauth2/v2/userinfo",usePKCE:true,extraAuthParams:{access_type:"offline",prompt:"consent"}},github:{authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",profileUrl:"https://api.github.com/user"},microsoft:{authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",profileUrl:"https://graph.microsoft.com/v1.0/me",usePKCE:true},outlook:{authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",profileUrl:"https://graph.microsoft.com/v1.0/me",usePKCE:true,extraAuthParams:{prompt:"select_account"}},facebook:{authorizationUrl:"https://www.facebook.com/v12.0/dialog/oauth",tokenUrl:"https://graph.facebook.com/v12.0/oauth/access_token",profileUrl:"https://graph.facebook.com/me?fields=id,name,email,picture"}};createProvider(e,r){let t=e!=="generic"?u.presetConfigs[e]||{}:{},s={...t,...r,extraAuthParams:{...t.extraAuthParams||{},...r.extraAuthParams||{}}},o=A.createProfileFetcher(e,s);return new U(s,void 0,void 0,o)}static registerPreset(e,r){u.presetConfigs[e]=r;}static getPresetConfig(e){return u.presetConfigs[e]}};var y=class{systems=new Map;scopes=new Map;users=new Map;tokens=new Map;states=new Map;generateId(){return Math.random().toString(36).substring(2)+Date.now().toString(36)}async createSystem(e){let r={...e,id:this.generateId(),createdAt:new Date,updatedAt:new Date};return this.systems.set(r.id,r),r}async getSystem(e){return this.systems.get(e)||null}async updateSystem(e,r){let t=this.systems.get(e);if(!t)throw new Error("System not found");let s={...t,...r,updatedAt:new Date};return this.systems.set(e,s),s}async deleteSystem(e){this.systems.delete(e);}async listSystems(){return Array.from(this.systems.values())}async createScope(e){let r={...e,id:this.generateId()};return this.scopes.set(r.id,r),r}async getScope(e){return this.scopes.get(e)||null}async getScopesBySystem(e){return Array.from(this.scopes.values()).filter(r=>r.systemId===e)}async updateScope(e,r){let t=this.scopes.get(e);if(!t)throw new Error("Scope not found");let s={...t,...r};return this.scopes.set(e,s),s}async deleteScope(e){this.scopes.delete(e);}async createUser(e){let r={...e,id:this.generateId(),createdAt:new Date,updatedAt:new Date};return this.users.set(r.id,r),r}async getOrCreateUser(e){if(e.email){let r=await this.findUserByEmail(e.systemId,e.email);if(r)return r}if(e.externalId){let r=await this.findUserByExternalId(e.systemId,e.externalId);if(r)return r}return this.createUser({systemId:e.systemId,metadata:{...e.metadata,...e.email&&{email:e.email},...e.externalId&&{externalId:e.externalId}}})}async findUserByEmail(e,r){return Array.from(this.users.values()).find(s=>{var o;return s.systemId===e&&((o=s.metadata)==null?void 0:o.email)===r})||null}async findUserByExternalId(e,r){return Array.from(this.users.values()).find(s=>{var o;return s.systemId===e&&((o=s.metadata)==null?void 0:o.externalId)===r})||null}async getUser(e){return this.users.get(e)||null}async getUsersBySystem(e){return Array.from(this.users.values()).filter(r=>r.systemId===e)}async updateUser(e,r){let t=this.users.get(e);if(!t)throw new Error("User not found");let s={...t,...r,updatedAt:new Date};return this.users.set(e,s),s}async deleteUser(e){this.users.delete(e);}async saveToken(e){let r={...e,id:this.generateId(),createdAt:new Date,updatedAt:new Date};return this.tokens.set(r.id,r),r}async saveTokenWithEmailValidation(e,r,t,s,o,n){if((await this.findTokensByEmailInUserScopeProvider(e,t,s,o)).length>0)return this.replaceTokensByEmailInUserScopeProvider(e,t,s,o,n);let i={...n,userId:e,systemId:r,scopeId:t,provider:s,email:o};return this.saveToken(i)}async getTokensByUser(e){return Array.from(this.tokens.values()).filter(r=>r.userId===e)}async getTokensByUserAndScope(e,r){return Array.from(this.tokens.values()).filter(t=>t.userId===e&&t.scopeId===r)}async getTokensByUserAndProvider(e,r){return Array.from(this.tokens.values()).filter(t=>t.userId===e&&t.provider===r)}async getTokensByUserScopeProvider(e,r,t){return Array.from(this.tokens.values()).filter(s=>s.userId===e&&s.scopeId===r&&s.provider===t)}async getTokensByScope(e,r){return Array.from(this.tokens.values()).filter(t=>t.systemId===e&&t.scopeId===r)}async getTokensByProvider(e,r){return Array.from(this.tokens.values()).filter(t=>t.systemId===e&&t.provider===r)}async getTokensBySystem(e){return Array.from(this.tokens.values()).filter(r=>r.systemId===e)}async findTokensByEmail(e,r){return Array.from(this.tokens.values()).filter(t=>t.systemId===r&&t.email===e)}async findTokensByEmailAndScope(e,r,t){return Array.from(this.tokens.values()).filter(s=>s.systemId===r&&s.scopeId===t&&s.email===e)}async findTokensByEmailAndProvider(e,r,t){return Array.from(this.tokens.values()).filter(s=>s.systemId===r&&s.provider===t&&s.email===e)}async findTokenByEmailScopeProvider(e,r,t,s){return Array.from(this.tokens.values()).find(o=>o.systemId===r&&o.scopeId===t&&o.provider===s&&o.email===e)||null}async findTokensByEmailInUserScopeProvider(e,r,t,s){return Array.from(this.tokens.values()).filter(o=>o.userId===e&&o.scopeId===r&&o.provider===t&&o.email===s)}async hasTokenWithEmailInUserScopeProvider(e,r,t,s){return (await this.findTokensByEmailInUserScopeProvider(e,r,t,s)).length>0}async replaceTokensByEmailInUserScopeProvider(e,r,t,s,o){(await this.findTokensByEmailInUserScopeProvider(e,r,t,s)).forEach(i=>{this.tokens.delete(i.id);});let a={...o,userId:e,systemId:o.systemId,scopeId:r,provider:t};return this.saveToken(a)}async getTokenById(e){return this.tokens.get(e)||null}async updateToken(e,r){let t=this.tokens.get(e);if(!t)throw new Error("Token not found");let s={...t,...r,updatedAt:new Date};return this.tokens.set(e,s),s}async deleteToken(e){this.tokens.delete(e);}async deleteTokensByUser(e){Array.from(this.tokens.entries()).filter(([,t])=>t.userId===e).map(([t])=>t).forEach(t=>this.tokens.delete(t));}async deleteTokensByUserAndScope(e,r){Array.from(this.tokens.entries()).filter(([,s])=>s.userId===e&&s.scopeId===r).map(([s])=>s).forEach(s=>this.tokens.delete(s));}async deleteTokensByUserAndProvider(e,r){Array.from(this.tokens.entries()).filter(([,s])=>s.userId===e&&s.provider===r).map(([s])=>s).forEach(s=>this.tokens.delete(s));}async saveAuthorizationState(e){this.states.set(e.state,e);}async getAuthorizationState(e){return this.states.get(e)||null}async deleteAuthorizationState(e){this.states.delete(e);}async cleanupExpiredStates(e){let r=new Date;Array.from(this.states.entries()).filter(([,s])=>r.getTime()-s.timestamp.getTime()>e).map(([s])=>s).forEach(s=>this.states.delete(s));}async getTokensByUserWithProfile(e){var s,o,n;let r=await this.getTokensByUser(e),t=[];for(let a of r){let i=this.users.get(a.userId);i&&t.push({...a,user:{email:(s=i.metadata)==null?void 0:s.email,name:(o=i.metadata)==null?void 0:o.name,externalId:(n=i.metadata)==null?void 0:n.externalId,metadata:i.metadata}});}return t}async getTokensByUserAndScopeWithProfile(e,r){var o,n,a;let t=await this.getTokensByUserAndScope(e,r),s=[];for(let i of t){let d=this.users.get(i.userId);d&&s.push({...i,user:{email:(o=d.metadata)==null?void 0:o.email,name:(n=d.metadata)==null?void 0:n.name,externalId:(a=d.metadata)==null?void 0:a.externalId,metadata:d.metadata}});}return s}async getTokensByUserAndProviderWithProfile(e,r){var o,n,a;let t=await this.getTokensByUserAndProvider(e,r),s=[];for(let i of t){let d=this.users.get(i.userId);d&&s.push({...i,user:{email:(o=d.metadata)==null?void 0:o.email,name:(n=d.metadata)==null?void 0:n.name,externalId:(a=d.metadata)==null?void 0:a.externalId,metadata:d.metadata}});}return s}async getTokensByUserScopeProviderWithProfile(e,r,t){var n,a,i;let s=await this.getTokensByUserScopeProvider(e,r,t),o=[];for(let d of s){let c=this.users.get(d.userId);c&&o.push({...d,user:{email:(n=c.metadata)==null?void 0:n.email,name:(a=c.metadata)==null?void 0:a.name,externalId:(i=c.metadata)==null?void 0:i.externalId,metadata:c.metadata}});}return o}async getTokensByScopeWithProfile(e,r){var o,n,a;let t=await this.getTokensByScope(e,r),s=[];for(let i of t){let d=this.users.get(i.userId);d&&s.push({...i,user:{email:(o=d.metadata)==null?void 0:o.email,name:(n=d.metadata)==null?void 0:n.name,externalId:(a=d.metadata)==null?void 0:a.externalId,metadata:d.metadata}});}return s}async getTokensBySystemWithProfile(e){var s,o,n;let r=await this.getTokensBySystem(e),t=[];for(let a of r){let i=this.users.get(a.userId);i&&t.push({...a,user:{email:(s=i.metadata)==null?void 0:s.email,name:(o=i.metadata)==null?void 0:o.name,externalId:(n=i.metadata)==null?void 0:n.externalId,metadata:i.metadata}});}return t}};var C=()=>randomBytes(32).toString("base64").replace(/[^a-zA-Z0-9]/g,"").substring(0,128),$=u=>createHash("sha256").update(u).digest("base64url"),R=()=>randomBytes(16).toString("base64url");var T=class{constructor(e,r,t=Date.now){this.storage=e;this.providers=r;this.now=t;}async createUserInSystem(e,r={}){return this.storage.createUser({systemId:e,metadata:{...r.metadata,...r.email&&{email:r.email},...r.externalId&&{externalId:r.externalId}}})}async getOrCreateUserInSystem(e,r={}){return this.storage.getOrCreateUser({systemId:e,email:r.email,externalId:r.externalId,metadata:r.metadata})}async getUserById(e){return this.storage.getUser(e)}async findUserByEmailInSystem(e,r){return this.storage.findUserByEmail(e,r)}async findUserByExternalIdInSystem(e,r){return this.storage.findUserByExternalId(e,r)}async getUsersBySystem(e){return this.storage.getUsersBySystem(e)}async saveTokenForUser(e,r,t,s,o,n){return this.storage.saveTokenWithEmailValidation(e,r,t,s,o,{userId:e,systemId:r,scopeId:t,provider:s,token:n})}async getTokensByUser(e){return this.storage.getTokensByUser(e)}async getTokensByUserAndScope(e,r){return this.storage.getTokensByUserAndScope(e,r)}async getTokensByUserAndProvider(e,r){return this.storage.getTokensByUserAndProvider(e,r)}async getTokensByUserScopeProvider(e,r,t){return this.storage.getTokensByUserScopeProvider(e,r,t)}async getTokensByScope(e,r){return this.storage.getTokensByScope(e,r)}async getTokensByProvider(e,r){return this.storage.getTokensByProvider(e,r)}async getTokensBySystem(e){return this.storage.getTokensBySystem(e)}async findTokensByEmail(e,r){return this.storage.findTokensByEmail(e,r)}async findTokensByEmailAndScope(e,r,t){return this.storage.findTokensByEmailAndScope(e,r,t)}async findTokensByEmailAndProvider(e,r,t){return this.storage.findTokensByEmailAndProvider(e,r,t)}async findTokenByEmailScopeProvider(e,r,t,s){return this.storage.findTokenByEmailScopeProvider(e,r,t,s)}async getValidTokenByEmail(e,r,t,s,o={}){let n=await this.storage.findTokenByEmailScopeProvider(e,r,t,s);if(!n)throw new Error(`No token found for email ${e} and provider ${s}`);if(!(o.autoRefresh!==false&&this.isTokenExpired(n.token,o)))return n.token;if(!n.token.refreshToken)throw new Error("Token expired and no refresh token available");let i=this.providers.get(s);if(!i)throw new Error(`Provider ${s} not found`);let d=await i.refreshToken(n.token.refreshToken);return await this.storage.updateToken(n.id,{token:d}),d}async getAccessTokenByEmail(e,r,t,s,o={}){return (await this.getValidTokenByEmail(e,r,t,s,o)).accessToken}async getAllValidTokensForUser(e,r={}){let t=await this.storage.getTokensByUser(e),s=[];for(let o of t)if(o)try{let n=r.autoRefresh!==!1&&this.isTokenExpired(o.token,r),a=o.token;if(n){if(!o.token.refreshToken){console.warn(`Token for provider ${o.provider} expired and no refresh token available`);continue}let i=this.providers.get(o.provider);if(!i){console.warn(`Provider ${o.provider} not found`);continue}try{let d=await i.refreshToken(o.token.refreshToken);await this.storage.updateToken(o.id,{token:d}),a=d;}catch(d){console.warn(`Failed to refresh token for provider ${o.provider}:`,d);continue}}s.push({provider:o.provider,scopeId:o.scopeId,token:a,userToken:{...o,token:a}});}catch(n){console.warn(`Error processing token for provider ${o.provider}:`,n);continue}return s}async getAllValidTokensForUserScopeProvider(e,r,t,s={}){var a;let o=await this.storage.getTokensByUserScopeProvider(e,r,t),n=[];for(let i of o)if(i)try{let d=await this.storage.getUser(i.userId),c=(a=d==null?void 0:d.metadata)==null?void 0:a.email;if(!c){console.warn(`No email found for user ${i.userId}, skipping token`);continue}let l=s.autoRefresh!==!1&&this.isTokenExpired(i.token,s),g=i.token;if(l){if(!i.token.refreshToken){console.warn(`Token for provider ${i.provider} expired and no refresh token available`);continue}let p=this.providers.get(i.provider);if(!p){console.warn(`Provider ${i.provider} not found`);continue}try{let h=await p.refreshToken(i.token.refreshToken);await this.storage.updateToken(i.id,{token:h}),g=h;}catch(h){console.warn(`Failed to refresh token for provider ${i.provider}:`,h);continue}}n.push({email:c,token:g,userToken:{...i,token:g}});}catch(d){console.warn(`Error processing token for provider ${i.provider}:`,d);continue}return n}async getAllValidTokensForEmail(e,r,t={}){let s=await this.storage.findTokensByEmail(e,r),o=[];for(let n of s)if(n)try{let a=t.autoRefresh!==!1&&this.isTokenExpired(n.token,t),i=n.token;if(a){if(!n.token.refreshToken){console.warn(`Token for provider ${n.provider} expired and no refresh token available`);continue}let d=this.providers.get(n.provider);if(!d){console.warn(`Provider ${n.provider} not found`);continue}try{let c=await d.refreshToken(n.token.refreshToken);await this.storage.updateToken(n.id,{token:c}),i=c;}catch(c){console.warn(`Failed to refresh token for provider ${n.provider}:`,c);continue}}o.push({provider:n.provider,scopeId:n.scopeId,token:i,userToken:{...n,token:i}});}catch(a){console.warn(`Error processing token for provider ${n.provider}:`,a);continue}return o}async withValidTokenByEmail(e,r,t,s,o,n={}){let a=await this.getValidTokenByEmail(e,r,t,s,n);return await o(a.accessToken)}async hasTokensForUserScopeProvider(e,r,t){return (await this.storage.getTokensByUserScopeProvider(e,r,t)).length>0}async hasTokenByEmail(e,r,t,s){return await this.storage.findTokenByEmailScopeProvider(e,r,t,s)!==null}async hasTokenWithEmailInUserScopeProvider(e,r,t,s){return this.storage.hasTokenWithEmailInUserScopeProvider(e,r,t,s)}async replaceTokensByEmailInUserScopeProvider(e,r,t,s,o){var n;return this.storage.replaceTokensByEmailInUserScopeProvider(e,r,t,s,{userId:e,systemId:((n=await this.storage.getUser(e))==null?void 0:n.systemId)||"",scopeId:r,provider:t,token:o})}async deleteTokensByUser(e){return this.storage.deleteTokensByUser(e)}async deleteTokensByUserAndScope(e,r){return this.storage.deleteTokensByUserAndScope(e,r)}async deleteTokensByUserAndProvider(e,r){return this.storage.deleteTokensByUserAndProvider(e,r)}async deleteTokensByUserScopeProvider(e,r,t){let s=await this.storage.getTokensByUserScopeProvider(e,r,t);for(let o of s)await this.storage.deleteToken(o.id);}async deleteTokenByEmail(e,r,t,s){let o=await this.storage.findTokenByEmailScopeProvider(e,r,t,s);o&&await this.storage.deleteToken(o.id);}async createSystem(e,r){return this.storage.createSystem({name:e,description:r,scopes:[]})}async getSystem(e){return this.storage.getSystem(e)}async createScopeInSystem(e,r,t={}){return this.storage.createScope({systemId:e,name:r,type:t.type||"authentication",permissions:t.permissions||[],isolated:t.isolated??true})}async getScope(e){return this.storage.getScope(e)}async getScopesBySystem(e){return this.storage.getScopesBySystem(e)}isTokenExpired(e,r={}){let{expirationBuffer:t=300}=r;if(e.createdAt&&e.expiresIn!==void 0){let n=e.createdAt+e.expiresIn*1e3;return this.now()+t*1e3>=n}let s=new Date(e.expiresAt).getTime();return this.now()+t*1e3>=s}};var x=class u{storage;providerFactory;providers=new Map;providerConfigs=new Map;now;currentSystem;currentUser;defaultScope;granular;constructor(e={}){this.storage=e.storage||new y,this.providerFactory=new E,this.now=Date.now,this.granular=new T(this.storage,this.providers,this.now),e.providers&&Object.entries(e.providers).forEach(([r,t])=>{this.registerProvider(r,t);});}static async quickSetup(e,r){let t=new u({providers:r}),s=await t.createSystem(e);await t.useSystem(s.id);let o=await t.createScope("default",{type:"authentication",permissions:["*"],isolated:false});return t.setDefaultScope(o.id),t}registerProvider(e,r){this.providerConfigs.set(e,r);let t=this.detectProviderType(e,r),s=this.providerFactory.createProvider(t,r);this.providers.set(e,s);}async createSystem(e,r){let t=await this.storage.createSystem({name:e,description:r,scopes:[]});return this.currentSystem=t,t}async useSystem(e){let r=await this.storage.getSystem(e);if(!r)throw new Error("System not found");this.currentSystem=r;}async createScope(e,r={}){if(!this.currentSystem)throw new Error("No system selected");return this.storage.createScope({systemId:this.currentSystem.id,name:e,type:r.type||"authentication",permissions:r.permissions||[],isolated:r.isolated??true})}setDefaultScope(e){this.defaultScope={id:e};}async createUser(e){if(!this.currentSystem)throw new Error("No system selected");let r=await this.storage.createUser({systemId:this.currentSystem.id,metadata:e});return this.currentUser=r,r}async getOrCreateUser(e={}){if(!this.currentSystem)throw new Error("No system selected");let r={systemId:this.currentSystem.id,email:e.email,externalId:e.externalId,metadata:e.metadata},t=await this.storage.getOrCreateUser(r);return this.currentUser=t,t}async getOrCreateUserStateless(e,r={}){let t={systemId:e,email:r.email,externalId:r.externalId,metadata:r.metadata};return this.storage.getOrCreateUser(t)}async authorizeForUser(e,r,t={}){var n,a;let s=t.systemId||((n=this.currentSystem)==null?void 0:n.id),o=t.scopeId||((a=this.defaultScope)==null?void 0:a.id);if(!s)throw new Error("System ID must be provided or current system must be set");return this.authorize({provider:r,scopes:t.scopes,metadata:{...t.metadata,systemId:s,scopeId:o},usePKCE:t.usePKCE,userId:e})}async createUserAndAuthorize(e,r,t,s={}){let o=await this.getOrCreateUserStateless(e,t),{url:n,state:a}=await this.authorizeForUser(o.id,r,{systemId:e,...s});return {user:o,authUrl:n,state:a}}async findUserByEmail(e){if(!this.currentSystem)throw new Error("No system selected");return this.storage.findUserByEmail(this.currentSystem.id,e)}async findUserByEmailStateless(e,r){return this.storage.findUserByEmail(e,r)}async findUserByExternalId(e){if(!this.currentSystem)throw new Error("No system selected");return this.storage.findUserByExternalId(this.currentSystem.id,e)}async findUserByExternalIdStateless(e,r){return this.storage.findUserByExternalId(e,r)}async useUser(e){let r=await this.storage.getUser(e);if(!r)throw new Error("User not found");this.currentUser=r;}async authorize(e){var l,g,p;let r=this.providerConfigs.get(e.provider);if(!r)throw new Error(`Provider ${e.provider} not registered`);let t={...r,scopes:e.scopes||r.scopes,usePKCE:e.usePKCE??r.usePKCE??r.pkce},s=R(),o,n;(t.usePKCE||t.pkce)&&(o=C(),n=$(o));let a=e.userId||((l=this.currentUser)==null?void 0:l.id),i={state:s,codeVerifier:o,config:t,timestamp:new Date,metadata:{...e.metadata,provider:e.provider,userId:a,systemId:(g=this.currentSystem)==null?void 0:g.id,scopeId:(p=this.defaultScope)==null?void 0:p.id}};await this.storage.saveAuthorizationState(i);let d=this.providers.get(e.provider);if(!d)throw new Error(`Provider ${e.provider} not found`);return {url:d.generateAuthorizationUrl(s,n),state:s}}async handleCallback(e,r,t){var h,B,O,b;let s=await this.storage.getAuthorizationState(r);if(!s)throw new Error("Invalid or expired state");let o=s.metadata||{},n=o.provider;if(console.log("metadata [",o,"]"),!n)throw new Error("Provider not found in state");let a=(t==null?void 0:t.userId)||o.userId||((h=this.currentUser)==null?void 0:h.id);console.log("userId [",a,"]");let i=o.systemId||((B=this.currentSystem)==null?void 0:B.id),d=(t==null?void 0:t.scopeId)||o.scopeId||((O=this.defaultScope)==null?void 0:O.id);if(!a||!i||!d)throw new Error("Missing required context: userId, systemId, or scopeId");let c=this.providers.get(n);if(!c)throw new Error(`Provider ${n} not found`);let l=await c.exchangeCodeForToken(e,s.codeVerifier);await this.storage.deleteAuthorizationState(r);let g,p;if(console.log("providerInstance.hasProfileFetcher() [",c.hasProfileFetcher(),"]"),c.hasProfileFetcher())try{p=await c.fetchProfile(l.accessToken),console.log("profile [",p,"]"),g=await this.storage.saveTokenWithEmailValidation(a,i,d,n,p.email,{userId:a,systemId:i,scopeId:d,provider:n,token:l}),(b=t==null?void 0:t.profileOptions)!=null&&b.mergeUserData&&await this.mergeUserDataFromProfile(a,p);}catch(z){console.warn("Failed to fetch profile or save with email validation:",z),g=await this.storage.saveToken({userId:a,systemId:i,scopeId:d,provider:n,token:l});}else g=await this.storage.saveToken({userId:a,systemId:i,scopeId:d,provider:n,token:l});return {userToken:g,userId:a,systemId:i,scopeId:d,provider:n,profile:p}}async mergeUserDataFromProfile(e,r){var o,n,a,i;let t=await this.storage.getUser(e);if(!t)return;let s={...t.metadata,email:r.email,name:r.name||((o=t.metadata)==null?void 0:o.name),avatar:r.avatar||((n=t.metadata)==null?void 0:n.avatar),username:r.username||((a=t.metadata)==null?void 0:a.username),profileId:r.id||((i=t.metadata)==null?void 0:i.profileId),lastProfileUpdate:new Date().toISOString()};await this.storage.updateUser(e,{metadata:s});}async fetchUserProfile(e,r){var c,l;if(!r&&!this.currentUser)throw new Error("No user specified and no current user set");let t=r||this.currentUser.id,s=(c=this.currentSystem)==null?void 0:c.id,o=(l=this.defaultScope)==null?void 0:l.id;if(!s||!o)throw new Error("Missing system or scope context");let n=await this.storage.getTokensByUserScopeProvider(t,o,e);if(n.length===0)throw new Error("No token found for user and provider");if(n.length>1)throw new Error(`Multiple tokens found for provider ${e}. Use fetchUserProfileByEmail() to specify which token to use.`);let a=this.providers.get(e);if(!a)throw new Error(`Provider ${e} not found`);let i=n[0];if(!i)throw new Error("Token not found");let d=i.token.accessToken;return a.fetchProfile(d)}async fetchUserProfileByEmail(e,r,t,s){var d,c;let o=t||((d=this.currentSystem)==null?void 0:d.id),n=s||((c=this.defaultScope)==null?void 0:c.id);if(!o)throw new Error("System ID must be provided or current system must be set");if(!n)throw new Error("Scope ID must be provided or default scope must be set");let a=await this.getAccessTokenByEmail(r,e,o,n),i=this.providers.get(e);if(!i)throw new Error(`Provider ${e} not found`);return i.fetchProfile(a)}async replaceConflictingTokensByEmail(e,r,t,s){if(!this.currentSystem||!this.defaultScope)throw new Error("Missing system or scope context");return this.storage.replaceTokensByEmailInUserScopeProvider(t,this.defaultScope.id,r,e,{userId:t,systemId:this.currentSystem.id,scopeId:this.defaultScope.id,provider:r,token:s})}isTokenExpired(e,r={}){let{expirationBuffer:t=300}=r;if(e.createdAt&&e.expiresIn!==void 0){let n=e.createdAt+e.expiresIn*1e3;return this.now()+t*1e3>=n}let s=new Date(e.expiresAt).getTime();return this.now()+t*1e3>=s}async getAccessToken(e,r={}){if(!this.currentUser||!this.currentSystem||!this.defaultScope)throw new Error("Missing required context");let t=await this.storage.getTokensByUserScopeProvider(this.currentUser.id,this.defaultScope.id,e);if(t.length===0)throw new Error("No token found for provider");if(t.length>1)throw new Error(`Multiple tokens found for provider ${e}. Use getAccessTokenByEmail() or getAllValidTokensForUser() to specify which token to use.`);let s=t[0];if(!s)throw new Error("No token found for provider");if(!(r.autoRefresh!==false&&this.isTokenExpired(s.token,r)))return s.token.accessToken;if(!s.token.refreshToken)throw new Error("Token expired and no refresh token available");let n=this.providers.get(e);if(!n)throw new Error(`Provider ${e} not found`);let a=await n.refreshToken(s.token.refreshToken);return await this.storage.updateToken(s.id,{token:a}),a.accessToken}async getAccessTokenByEmail(e,r,t,s,o={}){return (await this.getValidTokenForEmail(e,s,r,t,o)).accessToken}async ensureValidToken(e,r={}){if(!this.currentUser||!this.currentSystem||!this.defaultScope)throw new Error("Missing required context");let t=await this.storage.getTokensByUserScopeProvider(this.currentUser.id,this.defaultScope.id,e);if(t.length===0)throw new Error(`No tokens found for provider ${e}`);if(t.length>1)throw new Error(`Multiple tokens found for provider ${e}. Use getValidTokenForEmail() to specify which token to use.`);let s=t[0];if(!s)throw new Error(`No tokens found for provider ${e}`);if(!this.isTokenExpired(s.token,r))return s.token;if(!s.token.refreshToken)throw new Error("Token expired and no refresh token available");let o=this.providers.get(e);if(!o)throw new Error(`Provider ${e} not found`);let n=await o.refreshToken(s.token.refreshToken);return await this.storage.updateToken(s.id,{token:n}),n}async withValidToken(e,r,t={}){let s=await this.ensureValidToken(e,t);return await r(s.accessToken)}async getUserTokenForUser(e,r,t,s){let o=await this.storage.getTokensByUserScopeProvider(e,t,s);return o.length>0&&o[0]?o[0]:null}async hasTokenForUser(e,r,t,s){return (await this.storage.getTokensByUserScopeProvider(e,t,s)).length>0}async revokeTokensForUser(e,r,t,s){let o=await this.storage.getTokensByUserScopeProvider(e,t,s);for(let n of o)await this.storage.deleteToken(n.id);}async revokeTokens(e){if(!this.currentUser||!this.currentSystem||!this.defaultScope)throw new Error("Missing required context");let r=await this.storage.getTokensByUserScopeProvider(this.currentUser.id,this.defaultScope.id,e);for(let t of r)await this.storage.deleteToken(t.id);}async getUserTokens(){if(!this.currentUser)throw new Error("No user selected");return this.storage.getTokensByUser(this.currentUser.id)}async getAllValidTokensForUser(e,r={}){let t=await this.storage.getTokensByUser(e),s=[];for(let o of t)if(o)try{let n=r.autoRefresh!==!1&&this.isTokenExpired(o.token,r),a=o.token;if(n){if(!o.token.refreshToken){console.warn(`Token for provider ${o.provider} expired and no refresh token available`);continue}let i=this.providers.get(o.provider);if(!i){console.warn(`Provider ${o.provider} not found`);continue}try{let d=await i.refreshToken(o.token.refreshToken);await this.storage.updateToken(o.id,{token:d}),a=d;}catch(d){console.warn(`Failed to refresh token for provider ${o.provider}:`,d);continue}}s.push({provider:o.provider,scopeId:o.scopeId,token:a,userToken:{...o,token:a}});}catch(n){console.warn(`Error processing token for provider ${o.provider}:`,n);continue}return s}async getAllValidTokensForEmail(e,r,t={}){var a;let s=r||((a=this.currentSystem)==null?void 0:a.id);if(!s)throw new Error("System ID must be provided or current system must be set");let o=await this.storage.findTokensByEmail(e,s),n=[];for(let i of o)if(i)try{let d=t.autoRefresh!==!1&&this.isTokenExpired(i.token,t),c=i.token;if(d){if(!i.token.refreshToken){console.warn(`Token for provider ${i.provider} expired and no refresh token available`);continue}let l=this.providers.get(i.provider);if(!l){console.warn(`Provider ${i.provider} not found`);continue}try{let g=await l.refreshToken(i.token.refreshToken);await this.storage.updateToken(i.id,{token:g}),c=g;}catch(g){console.warn(`Failed to refresh token for provider ${i.provider}:`,g);continue}}n.push({provider:i.provider,scopeId:i.scopeId,token:c,userToken:{...i,token:c}});}catch(d){console.warn(`Error processing token for provider ${i.provider}:`,d);continue}return n}async getTokenForEmail(e,r,t,s){var a,i;let o=t||((a=this.currentSystem)==null?void 0:a.id),n=s||((i=this.defaultScope)==null?void 0:i.id);if(!o)throw new Error("System ID must be provided or current system must be set");if(!n)throw new Error("Scope ID must be provided or default scope must be set");return this.storage.findTokenByEmailScopeProvider(e,o,n,r)}async getValidTokenForEmail(e,r,t,s,o={}){var g,p;let n=t||((g=this.currentSystem)==null?void 0:g.id),a=s||((p=this.defaultScope)==null?void 0:p.id);if(!n)throw new Error("System ID must be provided or current system must be set");if(!a)throw new Error("Scope ID must be provided or default scope must be set");let i=await this.storage.findTokenByEmailScopeProvider(e,n,a,r);if(!i)throw new Error(`No token found for email ${e} and provider ${r}`);if(!(o.autoRefresh!==false&&this.isTokenExpired(i.token,o)))return i.token;if(!i.token.refreshToken)throw new Error("Token expired and no refresh token available");let c=this.providers.get(r);if(!c)throw new Error(`Provider ${r} not found`);let l=await c.refreshToken(i.token.refreshToken);return await this.storage.updateToken(i.id,{token:l}),l}async getAccessTokenForEmail(e,r,t,s,o={}){return (await this.getValidTokenForEmail(e,r,t,s,o)).accessToken}async withValidTokenForEmail(e,r,t,s,o,n={}){let a=await this.getValidTokenForEmail(e,r,s,o,n);return await t(a.accessToken)}async hasTokenForEmail(e,r,t,s){var i,d;let o=t||((i=this.currentSystem)==null?void 0:i.id),n=s||((d=this.defaultScope)==null?void 0:d.id);if(!o)throw new Error("System ID must be provided or current system must be set");if(!n)throw new Error("Scope ID must be provided or default scope must be set");return await this.storage.findTokenByEmailScopeProvider(e,o,n,r)!==null}async revokeTokensForEmail(e,r,t,s){var i,d;let o=t||((i=this.currentSystem)==null?void 0:i.id),n=s||((d=this.defaultScope)==null?void 0:d.id);if(!o)throw new Error("System ID must be provided or current system must be set");if(!n)throw new Error("Scope ID must be provided or default scope must be set");let a=await this.storage.findTokenByEmailScopeProvider(e,o,n,r);a&&await this.storage.deleteToken(a.id);}async getTokensByScope(e,r){var o,n;let t=e||((o=this.currentSystem)==null?void 0:o.id),s=r||((n=this.defaultScope)==null?void 0:n.id);if(!t)throw new Error("System ID must be provided or current system must be set");if(!s)throw new Error("Scope ID must be provided or default scope must be set");return this.storage.getTokensByScope(t,s)}async findTokenByEmailAndScope(e,r,t,s){var a,i;let o=t||((a=this.currentSystem)==null?void 0:a.id),n=s||((i=this.defaultScope)==null?void 0:i.id);if(!o)throw new Error("System ID must be provided or current system must be set");if(!n)throw new Error("Scope ID must be provided or default scope must be set");return this.storage.findTokenByEmailScopeProvider(e,o,n,r)}async findAllTokensByEmailAndScope(e,r,t,s){var a,i;let o=t||((a=this.currentSystem)==null?void 0:a.id),n=s||((i=this.defaultScope)==null?void 0:i.id);if(!o)throw new Error("System ID must be provided or current system must be set");if(!n)throw new Error("Scope ID must be provided or default scope must be set");return this.storage.findTokensByEmailAndScope(e,o,n).then(d=>d.filter(c=>c.provider===r))}detectProviderType(e,r){return ["google","github","microsoft","outlook","facebook"].includes(e)?e:r.authorizationUrl.includes("google.com")?"google":r.authorizationUrl.includes("github.com")?"github":r.authorizationUrl.includes("microsoft.com")||r.authorizationUrl.includes("microsoftonline.com")?"microsoft":r.authorizationUrl.includes("facebook.com")?"facebook":"generic"}async cleanup(e=10*60*1e3){await this.storage.cleanupExpiredStates(e);}async getAllValidTokensWithProviderProfiles(e,r={}){let t=await this.storage.getTokensByUser(e),s=[];for(let o of t)if(o)try{let n=r.autoRefresh!==!1&&this.isTokenExpired(o.token,r),a=o.token;if(n){if(!o.token.refreshToken){console.warn(`Token for provider ${o.provider} expired and no refresh token available`);continue}let c=this.providers.get(o.provider);if(!c){console.warn(`Provider ${o.provider} not found`);continue}try{let l=await c.refreshToken(o.token.refreshToken);await this.storage.updateToken(o.id,{token:l}),a=l;}catch(l){console.warn(`Failed to refresh token for provider ${o.provider}:`,l);continue}}let i,d=this.providers.get(o.provider);if(d&&d.hasProfileFetcher())try{i=await d.fetchProfile(a.accessToken);}catch(c){console.warn(`Failed to fetch profile for provider ${o.provider}:`,c);}s.push({provider:o.provider,scopeId:o.scopeId,token:a,userToken:{...o,token:a},profile:i});}catch(n){console.warn(`Error processing token for provider ${o.provider}:`,n);continue}return s}async getAllValidTokensForUserAndScopeWithProviderProfiles(e,r,t={}){let s=await this.storage.getTokensByUserAndScope(e,r),o=[];for(let n of s)if(n)try{let a=t.autoRefresh!==!1&&this.isTokenExpired(n.token,t),i=n.token;if(a){if(!n.token.refreshToken){console.warn(`Token for provider ${n.provider} expired and no refresh token available`);continue}let l=this.providers.get(n.provider);if(!l){console.warn(`Provider ${n.provider} not found`);continue}try{let g=await l.refreshToken(n.token.refreshToken);await this.storage.updateToken(n.id,{token:g}),i=g;}catch(g){console.warn(`Failed to refresh token for provider ${n.provider}:`,g);continue}}let d,c=this.providers.get(n.provider);if(c&&c.hasProfileFetcher())try{d=await c.fetchProfile(i.accessToken);}catch(l){console.warn(`Failed to fetch profile for provider ${n.provider}:`,l);}o.push({provider:n.provider,token:i,userToken:{...n,token:i},profile:d});}catch(a){console.warn(`Error processing token for provider ${n.provider}:`,a);continue}return o}async getAllValidTokensForUserAndProviderWithProviderProfiles(e,r,t={}){let s=await this.storage.getTokensByUserAndProvider(e,r),o=[];for(let n of s)if(n)try{let a=t.autoRefresh!==!1&&this.isTokenExpired(n.token,t),i=n.token;if(a){if(!n.token.refreshToken){console.warn(`Token for provider ${n.provider} expired and no refresh token available`);continue}let l=this.providers.get(n.provider);if(!l){console.warn(`Provider ${n.provider} not found`);continue}try{let g=await l.refreshToken(n.token.refreshToken);await this.storage.updateToken(n.id,{token:g}),i=g;}catch(g){console.warn(`Failed to refresh token for provider ${n.provider}:`,g);continue}}let d,c=this.providers.get(n.provider);if(c&&c.hasProfileFetcher())try{d=await c.fetchProfile(i.accessToken);}catch(l){console.warn(`Failed to fetch profile for provider ${n.provider}:`,l);}o.push({scopeId:n.scopeId,token:i,userToken:{...n,token:i},profile:d});}catch(a){console.warn(`Error processing token for provider ${n.provider}:`,a);continue}return o}async getTokenProfile(e,r){let t=this.providers.get(r);if(!t||!t.hasProfileFetcher())return null;try{return await t.fetchProfile(e.accessToken)}catch(s){return console.warn(`Failed to fetch profile for provider ${r}:`,s),null}}async getUserTokenProfile(e){return this.getTokenProfile(e.token,e.provider)}};var Ue=(u,e)=>sealData(u,{password:e}),we=(u,e)=>unsealData(u,{password:e});
|
|
2
|
+
export{m as BaseProfileFetcher,U as GenericOAuth2Provider,f as GenericProfileFetcher,S as GitHubProfileFetcher,w as GoogleProfileFetcher,y as InMemoryStorageAdapter,I as MicrosoftProfileFetcher,x as OAuth2Client,T as OAuth2GranularClient,k as OAuth2Provider,A as ProfileFetcherFactory,P as StandardAuthorizationUrlStrategy,v as StandardTokenExchangeStrategy,$ as createCodeChallenge,C as createCodeVerifier,R as generateState,Ue as seal,we as unseal};//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/strategies/standard-authorization-url.strategy.ts","../src/strategies/standard-token-exchange.strategy.ts","../src/providers/base.provider.ts","../src/providers/generic.provider.ts","../src/profile/base-profile-fetcher.ts","../src/profile/google-profile-fetcher.ts","../src/profile/github-profile-fetcher.ts","../src/profile/microsoft-profile-fetcher.ts","../src/profile/generic-profile-fetcher.ts","../src/profile/profile-fetcher-factory.ts","../src/providers/provider.factory.ts","../src/storage/memory.adapter.ts","../src/utils/crypto.ts","../src/facade/oauth2-granular.facade.ts","../src/facade/oauth2.facade.ts","../src/utils/seal.ts"],"names":["StandardAuthorizationUrlStrategy","params","value","key","config","state","codeChallenge","extraParams","StandardTokenExchangeStrategy","code","codeVerifier","response","errorText","data","tokenData","now","expiresIn","refreshToken","OAuth2Provider","authUrlStrategy","tokenStrategy","profileFetcher","accessToken","GenericOAuth2Provider","BaseProfileFetcher","profileEndpoint","rawData","GoogleProfileFetcher","GitHubProfileFetcher","_a","MicrosoftProfileFetcher","GenericProfileFetcher","mapping","additionalHeaders","obj","path","current","ProfileFetcherFactory","providerType","options","profileUrl","providerName","OAuth2ProviderFactory","_OAuth2ProviderFactory","type","presetConfig","mergedConfig","name","InMemoryStorageAdapter","system","newSystem","id","updates","updatedSystem","scope","newScope","systemId","s","updatedScope","user","newUser","input","existingUser","email","u","externalId","updatedUser","token","newToken","userId","scopeId","provider","tokenWithEmail","t","updatedToken","expiryMs","_b","_c","tokens","tokensWithProfile","createCodeVerifier","randomBytes","createCodeChallenge","verifier","createHash","generateState","OAuth2GranularClient","storage","providers","userToken","providerInstance","userTokens","validTokens","needsRefresh","finalToken","refreshError","error","callback","description","expirationBuffer","expiresAt","OAuth2Client","_OAuth2Client","appName","client","metadata","userOptions","authOptions","url","finalConfig","authState","_d","profile","updatedMetadata","actualUserId","actualSystemId","actualScopeId","newUserId","_systemId","profileError","seal","d","sealData","unseal","unsealData"],"mappings":"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","file":"index.js","sourcesContent":["import { OAuth2Config } from '../types';\nimport { AuthorizationUrlStrategy } from './authorization-url.strategy';\n\nexport class StandardAuthorizationUrlStrategy implements AuthorizationUrlStrategy {\n protected buildUrlParams(params: Record<string, string | undefined>): string {\n const filtered = Object.entries(params)\n .filter(([, value]) => value !== undefined)\n\n .map(([key, value]) => `${key}=${encodeURIComponent(value as string)}`);\n\n return filtered.join('&');\n }\n\n generateAuthorizationUrl(config: OAuth2Config, state: string, codeChallenge?: string): string {\n const params: Record<string, string | undefined> = {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: 'code',\n scope: config.scopes.join(' '),\n state,\n };\n\n // Add PKCE parameters\n if ((config.usePKCE || config.pkce) && codeChallenge) {\n params.code_challenge = codeChallenge;\n params.code_challenge_method = 'S256';\n }\n\n // Merge additional parameters (for both additionalParams and extraAuthParams)\n const extraParams = {\n ...config.additionalParams,\n ...config.extraAuthParams,\n };\n\n Object.assign(params, extraParams);\n\n return `${config.authorizationUrl}?${this.buildUrlParams(params)}`;\n }\n}\n","import { OAuth2Config, OAuth2Token } from '../types';\nimport { TokenExchangeStrategy } from './token-exchange.strategy';\n\nexport class StandardTokenExchangeStrategy implements TokenExchangeStrategy {\n protected buildUrlParams(params: Record<string, string | undefined>): string {\n const filtered = Object.entries(params)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}=${encodeURIComponent(value as string)}`);\n\n return filtered.join('&');\n }\n\n async exchangeCodeForToken(\n code: string,\n config: OAuth2Config,\n codeVerifier?: string,\n ): Promise<OAuth2Token> {\n const params: Record<string, string | undefined> = {\n grant_type: 'authorization_code',\n code,\n redirect_uri: config.redirectUri,\n client_id: config.clientId,\n };\n\n // Handle PKCE\n if ((config.usePKCE || config.pkce) && codeVerifier) {\n params.code_verifier = codeVerifier;\n } else if (config.clientSecret) {\n params.client_secret = config.clientSecret;\n }\n\n const response = await fetch(config.tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: this.buildUrlParams(params),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Token exchange failed: ${response.statusText} - ${errorText}`);\n }\n\n const data = await response.json();\n\n // Handle nested response (e.g., Outlook might nest tokens)\n const tokenData = config.responseRootKey ? data[config.responseRootKey] : data;\n\n const now = Date.now();\n const expiresIn = tokenData.expires_in || 3600;\n\n return {\n accessToken: tokenData.access_token,\n refreshToken: tokenData.refresh_token,\n expiresAt: new Date(now + expiresIn * 1000),\n expiresIn: expiresIn,\n tokenType: tokenData.token_type || 'Bearer',\n scope: tokenData.scope,\n createdAt: now,\n raw: data,\n };\n }\n\n async refreshToken(refreshToken: string, config: OAuth2Config): Promise<OAuth2Token> {\n const params: Record<string, string | undefined> = {\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: config.clientId,\n };\n\n // Only add client_secret if not using PKCE\n if (!(config.usePKCE || config.pkce) && config.clientSecret) {\n params.client_secret = config.clientSecret;\n }\n\n const response = await fetch(config.tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: this.buildUrlParams(params),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Token refresh failed: ${response.statusText} - ${errorText}`);\n }\n\n const data = await response.json();\n const tokenData = config.responseRootKey ? data[config.responseRootKey] : data;\n\n const now = Date.now();\n const expiresIn = tokenData.expires_in || 3600;\n\n return {\n accessToken: tokenData.access_token,\n refreshToken: tokenData.refresh_token || refreshToken,\n expiresAt: new Date(now + expiresIn * 1000),\n expiresIn: expiresIn,\n tokenType: tokenData.token_type || 'Bearer',\n scope: tokenData.scope,\n createdAt: now,\n raw: data,\n };\n }\n}\n","import { OAuth2Config, OAuth2Token } from '../types';\n\nimport { AuthorizationUrlStrategy } from '../strategies/authorization-url.strategy';\nimport { TokenExchangeStrategy } from '../strategies/token-exchange.strategy';\nimport { UserProfile } from './interfaces/profile-fetcher.interface';\nimport { BaseProfileFetcher } from '../profile/base-profile-fetcher';\n\nexport abstract class OAuth2Provider {\n protected authUrlStrategy: AuthorizationUrlStrategy;\n protected tokenStrategy: TokenExchangeStrategy;\n protected profileFetcher?: BaseProfileFetcher;\n\n constructor(\n protected config: OAuth2Config,\n authUrlStrategy?: AuthorizationUrlStrategy,\n tokenStrategy?: TokenExchangeStrategy,\n profileFetcher?: BaseProfileFetcher,\n ) {\n this.authUrlStrategy = authUrlStrategy || this.createAuthorizationUrlStrategy();\n this.tokenStrategy = tokenStrategy || this.createTokenExchangeStrategy();\n this.profileFetcher = profileFetcher;\n }\n\n // Factory methods\n protected abstract createAuthorizationUrlStrategy(): AuthorizationUrlStrategy;\n protected abstract createTokenExchangeStrategy(): TokenExchangeStrategy;\n\n // Profile fetching methods\n async fetchProfile(accessToken: string): Promise<UserProfile> {\n if (!this.profileFetcher) {\n throw new Error('Profile fetcher not configured for this provider');\n }\n return this.profileFetcher.fetchUserInfo(accessToken);\n }\n\n getProfileEndpoint(): string {\n if (!this.profileFetcher) {\n throw new Error('Profile fetcher not configured for this provider');\n }\n return this.profileFetcher.getEndpoint();\n }\n\n setProfileFetcher(profileFetcher: BaseProfileFetcher): void {\n this.profileFetcher = profileFetcher;\n }\n\n hasProfileFetcher(): boolean {\n return !!this.profileFetcher;\n }\n\n generateAuthorizationUrl(state: string, codeChallenge?: string): string {\n return this.authUrlStrategy.generateAuthorizationUrl(this.config, state, codeChallenge);\n }\n\n async exchangeCodeForToken(code: string, codeVerifier?: string): Promise<OAuth2Token> {\n return this.tokenStrategy.exchangeCodeForToken(code, this.config, codeVerifier);\n }\n\n async refreshToken(refreshToken: string): Promise<OAuth2Token> {\n return this.tokenStrategy.refreshToken(refreshToken, this.config);\n }\n}\n","import { AuthorizationUrlStrategy } from '../strategies/authorization-url.strategy';\nimport { StandardAuthorizationUrlStrategy } from '../strategies/standard-authorization-url.strategy';\nimport { StandardTokenExchangeStrategy } from '../strategies/standard-token-exchange.strategy';\nimport { TokenExchangeStrategy } from '../strategies/token-exchange.strategy';\nimport { OAuth2Provider } from './base.provider';\nimport { BaseProfileFetcher } from '../profile/base-profile-fetcher';\n\nexport class GenericOAuth2Provider extends OAuth2Provider {\n constructor(\n config: any,\n authUrlStrategy?: AuthorizationUrlStrategy,\n tokenStrategy?: TokenExchangeStrategy,\n profileFetcher?: BaseProfileFetcher,\n ) {\n super(config, authUrlStrategy, tokenStrategy, profileFetcher);\n }\n\n protected createAuthorizationUrlStrategy(): AuthorizationUrlStrategy {\n return new StandardAuthorizationUrlStrategy();\n }\n\n protected createTokenExchangeStrategy(): TokenExchangeStrategy {\n return new StandardTokenExchangeStrategy();\n }\n}\n","import { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport abstract class BaseProfileFetcher {\n constructor(protected profileEndpoint: string) {}\n\n /**\n * Fetch user profile information from the OAuth provider\n * @param accessToken The OAuth access token\n * @returns Promise resolving to standardized user profile\n */\n async fetchUserInfo(accessToken: string): Promise<UserProfile> {\n const response = await fetch(this.profileEndpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'application/json',\n ...this.getAdditionalHeaders(),\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch profile from ${this.profileEndpoint}: ${response.statusText}`,\n );\n }\n\n const rawData = await response.json();\n return this.mapToUserProfile(rawData);\n }\n\n /**\n * Map the raw API response to our standardized UserProfile structure\n * Override this method to customize mapping for different providers\n */\n protected abstract mapToUserProfile(rawData: any): UserProfile;\n\n /**\n * Get additional headers if needed for the profile request\n * Override this method to add provider-specific headers\n */\n protected getAdditionalHeaders(): Record<string, string> {\n return {};\n }\n\n /**\n * Get the profile endpoint URL\n */\n getEndpoint(): string {\n return this.profileEndpoint;\n }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport class GoogleProfileFetcher extends BaseProfileFetcher {\n constructor() {\n super('https://www.googleapis.com/oauth2/v2/userinfo');\n }\n\n mapToUserProfile(rawData: any): UserProfile {\n return {\n email: rawData.email,\n name: rawData.name,\n id: rawData.id,\n avatar: rawData.picture,\n username: rawData.email,\n raw: rawData,\n };\n }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport class GitHubProfileFetcher extends BaseProfileFetcher {\n constructor() {\n super('https://api.github.com/user');\n }\n\n protected mapToUserProfile(rawData: any): UserProfile {\n return {\n email: rawData.email,\n name: rawData.name || rawData.login,\n id: rawData.id?.toString(),\n avatar: rawData.avatar_url,\n username: rawData.login,\n raw: rawData,\n };\n }\n\n protected getAdditionalHeaders(): Record<string, string> {\n return {\n 'User-Agent': 'OAuth2-Token-Manager', // GitHub requires User-Agent\n };\n }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport class MicrosoftProfileFetcher extends BaseProfileFetcher {\n constructor() {\n super('https://graph.microsoft.com/v1.0/me');\n }\n\n protected mapToUserProfile(rawData: any): UserProfile {\n return {\n email: rawData.mail || rawData.userPrincipalName,\n name: rawData.displayName,\n id: rawData.id,\n avatar: undefined, // Microsoft Graph doesn't include avatar in basic profile\n username: rawData.userPrincipalName,\n raw: rawData,\n };\n }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport interface ProfileMapping {\n email: string;\n name?: string;\n id?: string;\n avatar?: string;\n username?: string;\n}\n\nexport class GenericProfileFetcher extends BaseProfileFetcher {\n constructor(\n profileEndpoint: string,\n private mapping?: ProfileMapping,\n private additionalHeaders?: Record<string, string>,\n ) {\n super(profileEndpoint);\n }\n\n protected mapToUserProfile(rawData: any): UserProfile {\n if (this.mapping) {\n return {\n email: this.getNestedProperty(rawData, this.mapping.email),\n name: this.mapping.name ? this.getNestedProperty(rawData, this.mapping.name) : undefined,\n id: this.mapping.id ? this.getNestedProperty(rawData, this.mapping.id) : undefined,\n avatar: this.mapping.avatar\n ? this.getNestedProperty(rawData, this.mapping.avatar)\n : undefined,\n username: this.mapping.username\n ? this.getNestedProperty(rawData, this.mapping.username)\n : undefined,\n raw: rawData,\n };\n }\n\n // Default generic mapping\n return {\n email: rawData.email || rawData.mail || rawData.emailAddress,\n name: rawData.name || rawData.displayName || rawData.full_name,\n id: rawData.id || rawData.sub || rawData.user_id,\n avatar: rawData.avatar || rawData.picture || rawData.avatar_url,\n username: rawData.username || rawData.login || rawData.preferred_username,\n raw: rawData,\n };\n }\n\n protected getAdditionalHeaders(): Record<string, string> {\n return this.additionalHeaders || {};\n }\n\n private getNestedProperty(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj);\n }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { GoogleProfileFetcher } from './google-profile-fetcher';\nimport { GitHubProfileFetcher } from './github-profile-fetcher';\nimport { MicrosoftProfileFetcher } from './microsoft-profile-fetcher';\nimport { GenericProfileFetcher, ProfileMapping } from './generic-profile-fetcher';\nimport { ProviderType } from '../providers/provider.factory';\nimport { OAuth2Config } from '../types';\n\nexport interface ProfileFetcherOptions {\n profileUrl?: string;\n profileMapping?: ProfileMapping;\n profileHeaders?: Record<string, string>;\n}\n\nexport class ProfileFetcherFactory {\n static createProfileFetcher(\n providerType: ProviderType,\n config: OAuth2Config,\n options?: ProfileFetcherOptions,\n ): BaseProfileFetcher {\n // If custom options are provided, use GenericProfileFetcher\n if (options?.profileUrl) {\n return new GenericProfileFetcher(\n options.profileUrl,\n options.profileMapping,\n options.profileHeaders,\n );\n }\n\n // Use provider-specific fetchers for known providers\n switch (providerType) {\n case 'google':\n return new GoogleProfileFetcher();\n case 'github':\n return new GitHubProfileFetcher();\n case 'microsoft':\n case 'outlook':\n return new MicrosoftProfileFetcher();\n case 'facebook':\n return new GenericProfileFetcher(\n 'https://graph.facebook.com/me?fields=id,name,email,picture',\n );\n case 'generic':\n default:\n // For generic providers, use the profileUrl from config\n const profileUrl = config.profileUrl || config.userInfoUrl;\n if (!profileUrl) {\n throw new Error(`Profile URL must be provided for ${providerType} provider`);\n }\n return new GenericProfileFetcher(profileUrl);\n }\n }\n\n static registerCustomProfileFetcher(\n providerName: string,\n profileFetcher: BaseProfileFetcher,\n ): void {\n // Store custom profile fetchers for later use\n this.customFetchers.set(providerName, profileFetcher);\n }\n\n private static customFetchers = new Map<string, BaseProfileFetcher>();\n\n static getCustomProfileFetcher(providerName: string): BaseProfileFetcher | undefined {\n return this.customFetchers.get(providerName);\n }\n}\n","import { OAuth2Config } from '../types';\nimport { OAuth2Provider } from './base.provider';\nimport { GenericOAuth2Provider } from './generic.provider';\nimport { ProfileFetcherFactory } from '../profile/profile-fetcher-factory';\n\nexport type ProviderType = 'google' | 'github' | 'microsoft' | 'outlook' | 'facebook' | 'generic';\n\nexport interface ProviderFactory {\n createProvider(type: ProviderType, config: OAuth2Config): OAuth2Provider;\n}\n\nexport class OAuth2ProviderFactory implements ProviderFactory {\n private static presetConfigs: Record<string, Partial<OAuth2Config>> = {\n google: {\n authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',\n tokenUrl: 'https://oauth2.googleapis.com/token',\n profileUrl: 'https://www.googleapis.com/oauth2/v2/userinfo',\n usePKCE: true,\n extraAuthParams: {\n access_type: 'offline',\n prompt: 'consent'\n }\n },\n github: {\n authorizationUrl: 'https://github.com/login/oauth/authorize',\n tokenUrl: 'https://github.com/login/oauth/access_token',\n profileUrl: 'https://api.github.com/user',\n },\n microsoft: {\n authorizationUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',\n tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',\n profileUrl: 'https://graph.microsoft.com/v1.0/me',\n usePKCE: true,\n },\n outlook: {\n authorizationUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',\n tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',\n profileUrl: 'https://graph.microsoft.com/v1.0/me',\n usePKCE: true,\n extraAuthParams: {\n prompt: 'select_account',\n },\n },\n facebook: {\n authorizationUrl: 'https://www.facebook.com/v12.0/dialog/oauth',\n tokenUrl: 'https://graph.facebook.com/v12.0/oauth/access_token',\n profileUrl: 'https://graph.facebook.com/me?fields=id,name,email,picture',\n },\n };\n\n createProvider(type: ProviderType, config: OAuth2Config): OAuth2Provider {\n const presetConfig = type !== 'generic' ? OAuth2ProviderFactory.presetConfigs[type] || {} : {};\n\n const mergedConfig = {\n ...presetConfig,\n ...config,\n extraAuthParams: {\n ...(presetConfig.extraAuthParams || {}),\n ...(config.extraAuthParams || {})\n }\n };\n\n const profileFetcher = ProfileFetcherFactory.createProfileFetcher(type, mergedConfig);\n\n return new GenericOAuth2Provider(\n mergedConfig,\n undefined,\n undefined,\n profileFetcher,\n );\n }\n\n static registerPreset(name: string, config: Partial<OAuth2Config>): void {\n OAuth2ProviderFactory.presetConfigs[name] = config;\n }\n\n static getPresetConfig(name: string): Partial<OAuth2Config> | undefined {\n return OAuth2ProviderFactory.presetConfigs[name];\n }\n}\n","import { AuthorizationState, Scope, System, User, UserToken } from '../types';\nimport { StorageAdapter, CreateUserInput, UserTokenWithProfile } from './interfaces';\n\nexport class InMemoryStorageAdapter implements StorageAdapter {\n private systems: Map<string, System> = new Map();\n private scopes: Map<string, Scope> = new Map();\n private users: Map<string, User> = new Map();\n private tokens: Map<string, UserToken> = new Map();\n private states: Map<string, AuthorizationState> = new Map();\n\n private generateId(): string {\n return Math.random().toString(36).substring(2) + Date.now().toString(36);\n }\n\n async createSystem(system: Omit<System, 'id' | 'createdAt' | 'updatedAt'>): Promise<System> {\n const newSystem: System = {\n ...system,\n id: this.generateId(),\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n this.systems.set(newSystem.id, newSystem);\n return newSystem;\n }\n\n async getSystem(id: string): Promise<System | null> {\n return this.systems.get(id) || null;\n }\n\n async updateSystem(id: string, updates: Partial<System>): Promise<System> {\n const system = this.systems.get(id);\n if (!system) throw new Error('System not found');\n\n const updatedSystem = { ...system, ...updates, updatedAt: new Date() };\n this.systems.set(id, updatedSystem);\n return updatedSystem;\n }\n\n async deleteSystem(id: string): Promise<void> {\n this.systems.delete(id);\n }\n\n async listSystems(): Promise<System[]> {\n return Array.from(this.systems.values());\n }\n\n async createScope(scope: Omit<Scope, 'id'>): Promise<Scope> {\n const newScope: Scope = {\n ...scope,\n id: this.generateId(),\n };\n this.scopes.set(newScope.id, newScope);\n return newScope;\n }\n\n async getScope(id: string): Promise<Scope | null> {\n return this.scopes.get(id) || null;\n }\n\n async getScopesBySystem(systemId: string): Promise<Scope[]> {\n return Array.from(this.scopes.values()).filter((s) => s.systemId === systemId);\n }\n\n async updateScope(id: string, updates: Partial<Scope>): Promise<Scope> {\n const scope = this.scopes.get(id);\n if (!scope) throw new Error('Scope not found');\n\n const updatedScope = { ...scope, ...updates };\n this.scopes.set(id, updatedScope);\n return updatedScope;\n }\n\n async deleteScope(id: string): Promise<void> {\n this.scopes.delete(id);\n }\n\n async createUser(user: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User> {\n const newUser: User = {\n ...user,\n id: this.generateId(),\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n this.users.set(newUser.id, newUser);\n return newUser;\n }\n\n async getOrCreateUser(input: CreateUserInput): Promise<User> {\n // First, try to find existing user by email\n if (input.email) {\n const existingUser = await this.findUserByEmail(input.systemId, input.email);\n if (existingUser) {\n return existingUser;\n }\n }\n\n // Then try to find by external ID\n if (input.externalId) {\n const existingUser = await this.findUserByExternalId(input.systemId, input.externalId);\n if (existingUser) {\n return existingUser;\n }\n }\n\n // Create new user if not found\n return this.createUser({\n systemId: input.systemId,\n metadata: {\n ...input.metadata,\n ...(input.email && { email: input.email }),\n ...(input.externalId && { externalId: input.externalId }),\n },\n });\n }\n\n async findUserByEmail(systemId: string, email: string): Promise<User | null> {\n const users = Array.from(this.users.values());\n return users.find((u) => u.systemId === systemId && u.metadata?.email === email) || null;\n }\n\n async findUserByExternalId(systemId: string, externalId: string): Promise<User | null> {\n const users = Array.from(this.users.values());\n return (\n users.find((u) => u.systemId === systemId && u.metadata?.externalId === externalId) || null\n );\n }\n\n async getUser(id: string): Promise<User | null> {\n return this.users.get(id) || null;\n }\n\n async getUsersBySystem(systemId: string): Promise<User[]> {\n return Array.from(this.users.values()).filter((u) => u.systemId === systemId);\n }\n\n async updateUser(id: string, updates: Partial<User>): Promise<User> {\n const user = this.users.get(id);\n if (!user) throw new Error('User not found');\n\n const updatedUser = { ...user, ...updates, updatedAt: new Date() };\n this.users.set(id, updatedUser);\n return updatedUser;\n }\n\n async deleteUser(id: string): Promise<void> {\n this.users.delete(id);\n }\n\n async saveToken(token: Omit<UserToken, 'id' | 'createdAt' | 'updatedAt'>): Promise<UserToken> {\n // Create new token\n const newToken: UserToken = {\n ...token,\n id: this.generateId(),\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n this.tokens.set(newToken.id, newToken);\n return newToken;\n }\n\n async saveTokenWithEmailValidation(\n userId: string,\n systemId: string,\n scopeId: string,\n provider: string,\n email: string,\n token: Omit<UserToken, 'id' | 'createdAt' | 'updatedAt'>,\n ): Promise<UserToken> {\n // Check if there's already a token with this email for this user/scope/provider\n const existingTokens = await this.findTokensByEmailInUserScopeProvider(\n userId,\n scopeId,\n provider,\n email,\n );\n\n if (existingTokens.length > 0) {\n // Replace existing token(s) with same email\n return this.replaceTokensByEmailInUserScopeProvider(userId, scopeId, provider, email, token);\n }\n\n // Create new token with email stored directly in the token\n const tokenWithEmail: Omit<UserToken, 'id' | 'createdAt' | 'updatedAt'> = {\n ...token,\n userId,\n systemId,\n scopeId,\n provider,\n email, // Store email directly in token\n };\n\n return this.saveToken(tokenWithEmail);\n }\n\n // Query by User (all levels)\n async getTokensByUser(userId: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter((t) => t.userId === userId);\n }\n\n async getTokensByUserAndScope(userId: string, scopeId: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.userId === userId && t.scopeId === scopeId,\n );\n }\n\n async getTokensByUserAndProvider(userId: string, provider: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.userId === userId && t.provider === provider,\n );\n }\n\n async getTokensByUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.userId === userId && t.scopeId === scopeId && t.provider === provider,\n );\n }\n\n // Query by System/Scope (cross-user)\n async getTokensByScope(systemId: string, scopeId: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.systemId === systemId && t.scopeId === scopeId,\n );\n }\n\n async getTokensByProvider(systemId: string, provider: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.systemId === systemId && t.provider === provider,\n );\n }\n\n async getTokensBySystem(systemId: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter((t) => t.systemId === systemId);\n }\n\n // Query by Email (cross-user, cross-provider)\n async findTokensByEmail(email: string, systemId: string): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.systemId === systemId && t.email === email,\n );\n }\n\n async findTokensByEmailAndScope(\n email: string,\n systemId: string,\n scopeId: string,\n ): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.systemId === systemId && t.scopeId === scopeId && t.email === email,\n );\n }\n\n async findTokensByEmailAndProvider(\n email: string,\n systemId: string,\n provider: string,\n ): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) => t.systemId === systemId && t.provider === provider && t.email === email,\n );\n }\n\n async findTokenByEmailScopeProvider(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken | null> {\n return (\n Array.from(this.tokens.values()).find(\n (t) =>\n t.systemId === systemId &&\n t.scopeId === scopeId &&\n t.provider === provider &&\n t.email === email,\n ) || null\n );\n }\n\n // Email validation within provider\n async findTokensByEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n ): Promise<UserToken[]> {\n return Array.from(this.tokens.values()).filter(\n (t) =>\n t.userId === userId &&\n t.scopeId === scopeId &&\n t.provider === provider &&\n t.email === email,\n );\n }\n\n async hasTokenWithEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n ): Promise<boolean> {\n const tokens = await this.findTokensByEmailInUserScopeProvider(\n userId,\n scopeId,\n provider,\n email,\n );\n return tokens.length > 0;\n }\n\n async replaceTokensByEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n newToken: Omit<UserToken, 'id' | 'createdAt' | 'updatedAt'>,\n ): Promise<UserToken> {\n // Find and delete all existing tokens with this email in this user/scope/provider\n const existingTokens = await this.findTokensByEmailInUserScopeProvider(\n userId,\n scopeId,\n provider,\n email,\n );\n existingTokens.forEach((token) => {\n this.tokens.delete(token.id);\n });\n\n // Create the new token\n const tokenData = {\n ...newToken,\n userId,\n systemId: newToken.systemId,\n scopeId,\n provider,\n };\n\n return this.saveToken(tokenData);\n }\n\n // Token management\n async getTokenById(id: string): Promise<UserToken | null> {\n return this.tokens.get(id) || null;\n }\n\n async updateToken(id: string, updates: Partial<UserToken>): Promise<UserToken> {\n const token = this.tokens.get(id);\n if (!token) throw new Error('Token not found');\n\n const updatedToken = { ...token, ...updates, updatedAt: new Date() };\n this.tokens.set(id, updatedToken);\n return updatedToken;\n }\n\n async deleteToken(id: string): Promise<void> {\n this.tokens.delete(id);\n }\n\n async deleteTokensByUser(userId: string): Promise<void> {\n const tokensToDelete = Array.from(this.tokens.entries())\n .filter(([, token]) => token.userId === userId)\n .map(([id]) => id);\n\n tokensToDelete.forEach((id) => this.tokens.delete(id));\n }\n\n async deleteTokensByUserAndScope(userId: string, scopeId: string): Promise<void> {\n const tokensToDelete = Array.from(this.tokens.entries())\n .filter(([, token]) => token.userId === userId && token.scopeId === scopeId)\n .map(([id]) => id);\n\n tokensToDelete.forEach((id) => this.tokens.delete(id));\n }\n\n async deleteTokensByUserAndProvider(userId: string, provider: string): Promise<void> {\n const tokensToDelete = Array.from(this.tokens.entries())\n .filter(([, token]) => token.userId === userId && token.provider === provider)\n .map(([id]) => id);\n\n tokensToDelete.forEach((id) => this.tokens.delete(id));\n }\n\n async saveAuthorizationState(state: AuthorizationState): Promise<void> {\n this.states.set(state.state, state);\n }\n\n async getAuthorizationState(state: string): Promise<AuthorizationState | null> {\n return this.states.get(state) || null;\n }\n\n async deleteAuthorizationState(state: string): Promise<void> {\n this.states.delete(state);\n }\n\n async cleanupExpiredStates(expiryMs: number): Promise<void> {\n const now = new Date();\n const expiredStates = Array.from(this.states.entries())\n .filter(([, state]) => {\n const stateAge = now.getTime() - state.timestamp.getTime();\n return stateAge > expiryMs;\n })\n .map(([key]) => key);\n\n expiredStates.forEach((key) => this.states.delete(key));\n }\n\n // Enhanced token queries with user information\n async getTokensByUserWithProfile(userId: string): Promise<UserTokenWithProfile[]> {\n const tokens = await this.getTokensByUser(userId);\n const tokensWithProfile: UserTokenWithProfile[] = [];\n\n for (const token of tokens) {\n const user = this.users.get(token.userId);\n if (user) {\n tokensWithProfile.push({\n ...token,\n user: {\n email: user.metadata?.email,\n name: user.metadata?.name,\n externalId: user.metadata?.externalId,\n metadata: user.metadata,\n },\n });\n }\n }\n\n return tokensWithProfile;\n }\n\n async getTokensByUserAndScopeWithProfile(\n userId: string,\n scopeId: string,\n ): Promise<UserTokenWithProfile[]> {\n const tokens = await this.getTokensByUserAndScope(userId, scopeId);\n const tokensWithProfile: UserTokenWithProfile[] = [];\n\n for (const token of tokens) {\n const user = this.users.get(token.userId);\n if (user) {\n tokensWithProfile.push({\n ...token,\n user: {\n email: user.metadata?.email,\n name: user.metadata?.name,\n externalId: user.metadata?.externalId,\n metadata: user.metadata,\n },\n });\n }\n }\n\n return tokensWithProfile;\n }\n\n async getTokensByUserAndProviderWithProfile(\n userId: string,\n provider: string,\n ): Promise<UserTokenWithProfile[]> {\n const tokens = await this.getTokensByUserAndProvider(userId, provider);\n const tokensWithProfile: UserTokenWithProfile[] = [];\n\n for (const token of tokens) {\n const user = this.users.get(token.userId);\n if (user) {\n tokensWithProfile.push({\n ...token,\n user: {\n email: user.metadata?.email,\n name: user.metadata?.name,\n externalId: user.metadata?.externalId,\n metadata: user.metadata,\n },\n });\n }\n }\n\n return tokensWithProfile;\n }\n\n async getTokensByUserScopeProviderWithProfile(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserTokenWithProfile[]> {\n const tokens = await this.getTokensByUserScopeProvider(userId, scopeId, provider);\n const tokensWithProfile: UserTokenWithProfile[] = [];\n\n for (const token of tokens) {\n const user = this.users.get(token.userId);\n if (user) {\n tokensWithProfile.push({\n ...token,\n user: {\n email: user.metadata?.email,\n name: user.metadata?.name,\n externalId: user.metadata?.externalId,\n metadata: user.metadata,\n },\n });\n }\n }\n\n return tokensWithProfile;\n }\n\n async getTokensByScopeWithProfile(\n systemId: string,\n scopeId: string,\n ): Promise<UserTokenWithProfile[]> {\n const tokens = await this.getTokensByScope(systemId, scopeId);\n const tokensWithProfile: UserTokenWithProfile[] = [];\n\n for (const token of tokens) {\n const user = this.users.get(token.userId);\n if (user) {\n tokensWithProfile.push({\n ...token,\n user: {\n email: user.metadata?.email,\n name: user.metadata?.name,\n externalId: user.metadata?.externalId,\n metadata: user.metadata,\n },\n });\n }\n }\n\n return tokensWithProfile;\n }\n\n async getTokensBySystemWithProfile(systemId: string): Promise<UserTokenWithProfile[]> {\n const tokens = await this.getTokensBySystem(systemId);\n const tokensWithProfile: UserTokenWithProfile[] = [];\n\n for (const token of tokens) {\n const user = this.users.get(token.userId);\n if (user) {\n tokensWithProfile.push({\n ...token,\n user: {\n email: user.metadata?.email,\n name: user.metadata?.name,\n externalId: user.metadata?.externalId,\n metadata: user.metadata,\n },\n });\n }\n }\n\n return tokensWithProfile;\n }\n}\n","import { createHash, randomBytes } from 'crypto';\n\nexport const createCodeVerifier = () =>\n randomBytes(32)\n .toString('base64')\n .replace(/[^a-zA-Z0-9]/g, '')\n .substring(0, 128);\n\nexport const createCodeChallenge = (verifier: string): string => {\n return createHash('sha256').update(verifier).digest('base64url');\n};\n\nexport const generateState = (): string => {\n return randomBytes(16).toString('base64url');\n};\n","import { OAuth2Token, UserToken } from '../types';\nimport { StorageAdapter } from '../storage/interfaces';\nimport { System, Scope, User } from '../types';\nimport { OAuth2Provider } from '../providers/base.provider';\nimport { TokenOptions, UserCreationOptions } from './oauth2.facade';\n\n// Granular facade interface for explicit operations\nexport interface OAuth2GranularOperations {\n // User operations\n createUserInSystem(systemId: string, options: UserCreationOptions): Promise<User>;\n getOrCreateUserInSystem(systemId: string, options: UserCreationOptions): Promise<User>;\n getUserById(userId: string): Promise<User | null>;\n findUserByEmailInSystem(systemId: string, email: string): Promise<User | null>;\n findUserByExternalIdInSystem(systemId: string, externalId: string): Promise<User | null>;\n getUsersBySystem(systemId: string): Promise<User[]>;\n\n // Token operations - all levels of querying\n saveTokenForUser(\n userId: string,\n systemId: string,\n scopeId: string,\n provider: string,\n email: string,\n token: OAuth2Token,\n ): Promise<UserToken>;\n getTokensByUser(userId: string): Promise<UserToken[]>;\n getTokensByUserAndScope(userId: string, scopeId: string): Promise<UserToken[]>;\n getTokensByUserAndProvider(userId: string, provider: string): Promise<UserToken[]>;\n getTokensByUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken[]>;\n getTokensByScope(systemId: string, scopeId: string): Promise<UserToken[]>;\n getTokensByProvider(systemId: string, provider: string): Promise<UserToken[]>;\n getTokensBySystem(systemId: string): Promise<UserToken[]>;\n\n // Email-based queries\n findTokensByEmail(email: string, systemId: string): Promise<UserToken[]>;\n findTokensByEmailAndScope(email: string, systemId: string, scopeId: string): Promise<UserToken[]>;\n findTokensByEmailAndProvider(\n email: string,\n systemId: string,\n provider: string,\n ): Promise<UserToken[]>;\n findTokenByEmailScopeProvider(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken | null>;\n\n // Token validation and refresh - Email-specific (unambiguous)\n getValidTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n options?: TokenOptions,\n ): Promise<OAuth2Token>;\n getAccessTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n options?: TokenOptions,\n ): Promise<string>;\n withValidTokenByEmail<T>(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n callback: (accessToken: string) => Promise<T>,\n options?: TokenOptions,\n ): Promise<T>;\n\n // Token validation and refresh - Bulk operations (return all valid tokens)\n getAllValidTokensForUser(\n userId: string,\n options?: TokenOptions,\n ): Promise<{ provider: string; scopeId: string; token: OAuth2Token; userToken: UserToken }[]>;\n getAllValidTokensForUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n options?: TokenOptions,\n ): Promise<{ email: string; token: OAuth2Token; userToken: UserToken }[]>;\n getAllValidTokensForEmail(\n email: string,\n systemId: string,\n options?: TokenOptions,\n ): Promise<{ provider: string; scopeId: string; token: OAuth2Token; userToken: UserToken }[]>;\n\n // Token existence checks\n hasTokensForUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<boolean>;\n hasTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<boolean>;\n hasTokenWithEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n ): Promise<boolean>;\n\n // Email validation within provider\n replaceTokensByEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n token: OAuth2Token,\n ): Promise<UserToken>;\n\n // Token management - User-based deletions\n deleteTokensByUser(userId: string): Promise<void>;\n deleteTokensByUserAndScope(userId: string, scopeId: string): Promise<void>;\n deleteTokensByUserAndProvider(userId: string, provider: string): Promise<void>;\n deleteTokensByUserScopeProvider(userId: string, scopeId: string, provider: string): Promise<void>;\n deleteTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<void>;\n\n // System and scope operations\n createSystem(name: string, description?: string): Promise<System>;\n getSystem(systemId: string): Promise<System | null>;\n createScopeInSystem(\n systemId: string,\n name: string,\n options?: {\n type?: 'authentication' | 'access' | 'custom';\n permissions?: string[];\n isolated?: boolean;\n },\n ): Promise<Scope>;\n getScope(scopeId: string): Promise<Scope | null>;\n getScopesBySystem(systemId: string): Promise<Scope[]>;\n}\n\nexport class OAuth2GranularClient implements OAuth2GranularOperations {\n constructor(\n private storage: StorageAdapter,\n private providers: Map<string, OAuth2Provider>,\n private now: () => number = Date.now,\n ) {}\n\n // User operations\n async createUserInSystem(systemId: string, options: UserCreationOptions = {}): Promise<User> {\n return this.storage.createUser({\n systemId,\n metadata: {\n ...options.metadata,\n ...(options.email && { email: options.email }),\n ...(options.externalId && { externalId: options.externalId }),\n },\n });\n }\n\n async getOrCreateUserInSystem(\n systemId: string,\n options: UserCreationOptions = {},\n ): Promise<User> {\n return this.storage.getOrCreateUser({\n systemId,\n email: options.email,\n externalId: options.externalId,\n metadata: options.metadata,\n });\n }\n\n async getUserById(userId: string): Promise<User | null> {\n return this.storage.getUser(userId);\n }\n\n async findUserByEmailInSystem(systemId: string, email: string): Promise<User | null> {\n return this.storage.findUserByEmail(systemId, email);\n }\n\n async findUserByExternalIdInSystem(systemId: string, externalId: string): Promise<User | null> {\n return this.storage.findUserByExternalId(systemId, externalId);\n }\n\n async getUsersBySystem(systemId: string): Promise<User[]> {\n return this.storage.getUsersBySystem(systemId);\n }\n\n // Token operations\n async saveTokenForUser(\n userId: string,\n systemId: string,\n scopeId: string,\n provider: string,\n email: string,\n token: OAuth2Token,\n ): Promise<UserToken> {\n return this.storage.saveTokenWithEmailValidation(userId, systemId, scopeId, provider, email, {\n userId,\n systemId,\n scopeId,\n provider,\n token,\n });\n }\n\n async getTokensByUser(userId: string): Promise<UserToken[]> {\n return this.storage.getTokensByUser(userId);\n }\n\n async getTokensByUserAndScope(userId: string, scopeId: string): Promise<UserToken[]> {\n return this.storage.getTokensByUserAndScope(userId, scopeId);\n }\n\n async getTokensByUserAndProvider(userId: string, provider: string): Promise<UserToken[]> {\n return this.storage.getTokensByUserAndProvider(userId, provider);\n }\n\n async getTokensByUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken[]> {\n return this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n }\n\n async getTokensByScope(systemId: string, scopeId: string): Promise<UserToken[]> {\n return this.storage.getTokensByScope(systemId, scopeId);\n }\n\n async getTokensByProvider(systemId: string, provider: string): Promise<UserToken[]> {\n return this.storage.getTokensByProvider(systemId, provider);\n }\n\n async getTokensBySystem(systemId: string): Promise<UserToken[]> {\n return this.storage.getTokensBySystem(systemId);\n }\n\n // Email-based queries\n async findTokensByEmail(email: string, systemId: string): Promise<UserToken[]> {\n return this.storage.findTokensByEmail(email, systemId);\n }\n\n async findTokensByEmailAndScope(\n email: string,\n systemId: string,\n scopeId: string,\n ): Promise<UserToken[]> {\n return this.storage.findTokensByEmailAndScope(email, systemId, scopeId);\n }\n\n async findTokensByEmailAndProvider(\n email: string,\n systemId: string,\n provider: string,\n ): Promise<UserToken[]> {\n return this.storage.findTokensByEmailAndProvider(email, systemId, provider);\n }\n\n async findTokenByEmailScopeProvider(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken | null> {\n return this.storage.findTokenByEmailScopeProvider(email, systemId, scopeId, provider);\n }\n\n // Token validation and refresh - Email-specific (unambiguous)\n async getValidTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n options: TokenOptions = {},\n ): Promise<OAuth2Token> {\n const userToken = await this.storage.findTokenByEmailScopeProvider(\n email,\n systemId,\n scopeId,\n provider,\n );\n if (!userToken) {\n throw new Error(`No token found for email ${email} and provider ${provider}`);\n }\n\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n if (!needsRefresh) {\n return userToken.token;\n }\n\n // Refresh the token\n if (!userToken.token.refreshToken) {\n throw new Error('Token expired and no refresh token available');\n }\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n\n return newToken;\n }\n\n async getAccessTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n options: TokenOptions = {},\n ): Promise<string> {\n const token = await this.getValidTokenByEmail(email, systemId, scopeId, provider, options);\n return token.accessToken;\n }\n\n // Token validation and refresh - Bulk operations (return all valid tokens)\n async getAllValidTokensForUser(\n userId: string,\n options: TokenOptions = {},\n ): Promise<{ provider: string; scopeId: string; token: OAuth2Token; userToken: UserToken }[]> {\n const userTokens = await this.storage.getTokensByUser(userId);\n const validTokens: {\n provider: string;\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n validTokens.push({\n provider: userToken.provider,\n scopeId: userToken.scopeId,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n async getAllValidTokensForUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n options: TokenOptions = {},\n ): Promise<{ email: string; token: OAuth2Token; userToken: UserToken }[]> {\n const userTokens = await this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n const validTokens: { email: string; token: OAuth2Token; userToken: UserToken }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Get user to extract email from metadata\n const user = await this.storage.getUser(userToken.userId);\n const email = user?.metadata?.email as string;\n\n if (!email) {\n console.warn(`No email found for user ${userToken.userId}, skipping token`);\n continue;\n }\n\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n validTokens.push({\n email,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n async getAllValidTokensForEmail(\n email: string,\n systemId: string,\n options: TokenOptions = {},\n ): Promise<{ provider: string; scopeId: string; token: OAuth2Token; userToken: UserToken }[]> {\n const userTokens = await this.storage.findTokensByEmail(email, systemId);\n const validTokens: {\n provider: string;\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n validTokens.push({\n provider: userToken.provider,\n scopeId: userToken.scopeId,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n async withValidTokenByEmail<T>(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n callback: (accessToken: string) => Promise<T>,\n options: TokenOptions = {},\n ): Promise<T> {\n const token = await this.getValidTokenByEmail(email, systemId, scopeId, provider, options);\n return await callback(token.accessToken);\n }\n\n // Token existence checks\n async hasTokensForUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<boolean> {\n const userTokens = await this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n return userTokens.length > 0;\n }\n\n async hasTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<boolean> {\n const userToken = await this.storage.findTokenByEmailScopeProvider(\n email,\n systemId,\n scopeId,\n provider,\n );\n return userToken !== null;\n }\n\n async hasTokenWithEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n ): Promise<boolean> {\n return this.storage.hasTokenWithEmailInUserScopeProvider(userId, scopeId, provider, email);\n }\n\n // Email validation within provider\n async replaceTokensByEmailInUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n email: string,\n token: OAuth2Token,\n ): Promise<UserToken> {\n return this.storage.replaceTokensByEmailInUserScopeProvider(userId, scopeId, provider, email, {\n userId,\n systemId: (await this.storage.getUser(userId))?.systemId || '',\n scopeId,\n provider,\n token,\n });\n }\n\n // Token management - User-based deletions\n async deleteTokensByUser(userId: string): Promise<void> {\n return this.storage.deleteTokensByUser(userId);\n }\n\n async deleteTokensByUserAndScope(userId: string, scopeId: string): Promise<void> {\n return this.storage.deleteTokensByUserAndScope(userId, scopeId);\n }\n\n async deleteTokensByUserAndProvider(userId: string, provider: string): Promise<void> {\n return this.storage.deleteTokensByUserAndProvider(userId, provider);\n }\n\n async deleteTokensByUserScopeProvider(\n userId: string,\n scopeId: string,\n provider: string,\n ): Promise<void> {\n const userTokens = await this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n for (const userToken of userTokens) {\n await this.storage.deleteToken(userToken.id);\n }\n }\n\n async deleteTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<void> {\n const userToken = await this.storage.findTokenByEmailScopeProvider(\n email,\n systemId,\n scopeId,\n provider,\n );\n if (userToken) {\n await this.storage.deleteToken(userToken.id);\n }\n }\n\n // System and scope operations\n async createSystem(name: string, description?: string): Promise<System> {\n return this.storage.createSystem({ name, description, scopes: [] });\n }\n\n async getSystem(systemId: string): Promise<System | null> {\n return this.storage.getSystem(systemId);\n }\n\n async createScopeInSystem(\n systemId: string,\n name: string,\n options: {\n type?: 'authentication' | 'access' | 'custom';\n permissions?: string[];\n isolated?: boolean;\n } = {},\n ): Promise<Scope> {\n return this.storage.createScope({\n systemId,\n name,\n type: options.type || 'authentication',\n permissions: options.permissions || [],\n isolated: options.isolated ?? true,\n });\n }\n\n async getScope(scopeId: string): Promise<Scope | null> {\n return this.storage.getScope(scopeId);\n }\n\n async getScopesBySystem(systemId: string): Promise<Scope[]> {\n return this.storage.getScopesBySystem(systemId);\n }\n\n // Helper methods\n private isTokenExpired(token: OAuth2Token, options: TokenOptions = {}): boolean {\n const { expirationBuffer = 300 } = options;\n\n // Use createdAt if available, otherwise use expiresAt\n if (token.createdAt && token.expiresIn !== undefined) {\n const expiresAt = token.createdAt + token.expiresIn * 1000;\n const effectiveNow = this.now() + expirationBuffer * 1000;\n return effectiveNow >= expiresAt;\n }\n\n // Fallback to expiresAt date\n const expiresAt = new Date(token.expiresAt).getTime();\n const effectiveNow = this.now() + expirationBuffer * 1000;\n return effectiveNow >= expiresAt;\n }\n}\n","import { OAuth2Config, OAuth2Token, UserToken, AuthorizationState } from '../types';\n\nimport { ProviderType } from '../providers/provider.factory';\nimport { OAuth2ProviderFactory } from '../providers/provider.factory';\nimport { StorageAdapter, CreateUserInput, ProfileBasedTokenOptions } from '../storage/interfaces';\nimport { InMemoryStorageAdapter } from '../storage/memory.adapter';\nimport { ProviderFactory } from '../providers/provider.factory';\nimport { System, Scope, User } from '../types';\nimport { createCodeVerifier, createCodeChallenge, generateState } from '../utils/crypto';\nimport { OAuth2Provider } from '../providers/base.provider';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\nimport { OAuth2GranularOperations, OAuth2GranularClient } from './oauth2-granular.facade';\n\nexport interface OAuth2Options {\n storage?: StorageAdapter;\n sealKey?: string;\n providers?: Record<string, OAuth2Config>;\n}\n\nexport interface AuthorizationOptions {\n provider: string;\n scopes?: string[];\n metadata?: Record<string, any>;\n usePKCE?: boolean;\n userId?: string; // Optional explicit user ID for backend APIs\n}\n\nexport interface TokenOptions {\n autoRefresh?: boolean;\n refreshBuffer?: number; // minutes before expiry to refresh\n expirationBuffer?: number; // seconds before expiry to consider expired\n defaultExpiresIn?: number; // default expiration in seconds\n}\n\nexport interface UserCreationOptions {\n email?: string;\n externalId?: string;\n metadata?: Record<string, any>;\n}\n\nexport interface CallbackOptions {\n userId?: string;\n scopeId?: string;\n profileOptions?: ProfileBasedTokenOptions;\n}\n\nexport interface CallbackResult {\n userToken: UserToken;\n userId: string;\n systemId: string;\n scopeId: string;\n provider: string;\n profile?: UserProfile; // Available if profile options were used\n}\n\n// Main Facade class for better developer experience with context management\nexport class OAuth2Client {\n private storage: StorageAdapter;\n private providerFactory: ProviderFactory;\n private providers: Map<string, OAuth2Provider> = new Map();\n private providerConfigs: Map<string, OAuth2Config> = new Map();\n private now: () => number;\n\n // Current context (for context-managed operations)\n private currentSystem?: System;\n private currentUser?: User;\n private defaultScope?: Scope;\n\n // Granular operations (delegate to separate instance)\n public readonly granular: OAuth2GranularOperations;\n\n constructor(options: OAuth2Options = {}) {\n this.storage = options.storage || new InMemoryStorageAdapter();\n this.providerFactory = new OAuth2ProviderFactory();\n this.now = Date.now;\n\n // Create granular operations instance\n this.granular = new OAuth2GranularClient(this.storage, this.providers, this.now);\n\n // Register predefined providers\n if (options.providers) {\n Object.entries(options.providers).forEach(([name, config]) => {\n this.registerProvider(name, config);\n });\n }\n }\n\n // ===== Simple Setup Methods =====\n\n /**\n * Quick setup for common use cases\n */\n static async quickSetup(\n appName: string,\n providers: Record<string, OAuth2Config>,\n ): Promise<OAuth2Client> {\n const client = new OAuth2Client({ providers });\n\n // Create default system and scope\n const system = await client.createSystem(appName);\n await client.useSystem(system.id);\n\n const scope = await client.createScope('default', {\n type: 'authentication',\n permissions: ['*'],\n isolated: false,\n });\n\n client.setDefaultScope(scope.id);\n\n return client;\n }\n\n /**\n * Register a provider configuration\n */\n registerProvider(name: string, config: OAuth2Config): void {\n this.providerConfigs.set(name, config);\n\n // Determine provider type\n const providerType = this.detectProviderType(name, config);\n const provider = this.providerFactory.createProvider(providerType, config);\n this.providers.set(name, provider);\n }\n\n /**\n * Create or select a system to work with\n */\n async createSystem(name: string, description?: string): Promise<System> {\n const system = await this.storage.createSystem({ name, description, scopes: [] });\n this.currentSystem = system;\n return system;\n }\n\n async useSystem(systemId: string): Promise<void> {\n const system = await this.storage.getSystem(systemId);\n if (!system) throw new Error('System not found');\n this.currentSystem = system;\n }\n\n /**\n * Create a scope within the current system\n */\n async createScope(\n name: string,\n options: {\n type?: 'authentication' | 'access' | 'custom';\n permissions?: string[];\n isolated?: boolean;\n } = {},\n ): Promise<Scope> {\n if (!this.currentSystem) throw new Error('No system selected');\n\n return this.storage.createScope({\n systemId: this.currentSystem.id,\n name,\n type: options.type || 'authentication',\n permissions: options.permissions || [],\n isolated: options.isolated ?? true,\n });\n }\n\n setDefaultScope(scopeId: string): void {\n this.defaultScope = { id: scopeId } as Scope;\n }\n\n /**\n * Create a user (legacy method - always creates new user)\n * @deprecated Use getOrCreateUser for better user management\n */\n async createUser(metadata?: Record<string, any>): Promise<User> {\n if (!this.currentSystem) throw new Error('No system selected');\n\n const user = await this.storage.createUser({\n systemId: this.currentSystem.id,\n metadata,\n });\n this.currentUser = user;\n return user;\n }\n\n /**\n * Get or create a user (recommended method)\n */\n async getOrCreateUser(options: UserCreationOptions = {}): Promise<User> {\n if (!this.currentSystem) throw new Error('No system selected');\n\n const input: CreateUserInput = {\n systemId: this.currentSystem.id,\n email: options.email,\n externalId: options.externalId,\n metadata: options.metadata,\n };\n\n const user = await this.storage.getOrCreateUser(input);\n this.currentUser = user;\n return user;\n }\n\n /**\n * Get or create a user (stateless version for backend APIs)\n */\n async getOrCreateUserStateless(\n systemId: string,\n options: UserCreationOptions = {},\n ): Promise<User> {\n const input: CreateUserInput = {\n systemId,\n email: options.email,\n externalId: options.externalId,\n metadata: options.metadata,\n };\n\n return this.storage.getOrCreateUser(input);\n }\n\n /**\n * Start authorization flow for a specific user (stateless backend API method)\n */\n async authorizeForUser(\n userId: string,\n provider: string,\n options: {\n systemId?: string;\n scopeId?: string;\n scopes?: string[];\n metadata?: Record<string, any>;\n usePKCE?: boolean;\n } = {},\n ): Promise<{ url: string; state: string }> {\n const systemId = options.systemId || this.currentSystem?.id;\n const scopeId = options.scopeId || this.defaultScope?.id;\n\n if (!systemId) throw new Error('System ID must be provided or current system must be set');\n\n return this.authorize({\n provider,\n scopes: options.scopes,\n metadata: {\n ...options.metadata,\n systemId,\n scopeId,\n },\n usePKCE: options.usePKCE,\n userId, // Pass the explicit user ID\n });\n }\n\n /**\n * Complete workflow: get/create user and start authorization (for backend APIs)\n */\n async createUserAndAuthorize(\n systemId: string,\n provider: string,\n userOptions: UserCreationOptions,\n authOptions: {\n scopeId?: string;\n scopes?: string[];\n metadata?: Record<string, any>;\n usePKCE?: boolean;\n } = {},\n ): Promise<{ user: User; authUrl: string; state: string }> {\n // Create or get the user\n const user = await this.getOrCreateUserStateless(systemId, userOptions);\n\n // Start authorization for this user\n const { url, state } = await this.authorizeForUser(user.id, provider, {\n systemId,\n ...authOptions,\n });\n\n return {\n user,\n authUrl: url,\n state,\n };\n }\n\n /**\n * Find user by email\n */\n async findUserByEmail(email: string): Promise<User | null> {\n if (!this.currentSystem) throw new Error('No system selected');\n return this.storage.findUserByEmail(this.currentSystem.id, email);\n }\n\n /**\n * Find user by email (stateless version)\n */\n async findUserByEmailStateless(systemId: string, email: string): Promise<User | null> {\n return this.storage.findUserByEmail(systemId, email);\n }\n\n /**\n * Find user by external ID\n */\n async findUserByExternalId(externalId: string): Promise<User | null> {\n if (!this.currentSystem) throw new Error('No system selected');\n return this.storage.findUserByExternalId(this.currentSystem.id, externalId);\n }\n\n /**\n * Find user by external ID (stateless version)\n */\n async findUserByExternalIdStateless(systemId: string, externalId: string): Promise<User | null> {\n return this.storage.findUserByExternalId(systemId, externalId);\n }\n\n async useUser(userId: string): Promise<void> {\n const user = await this.storage.getUser(userId);\n if (!user) throw new Error('User not found');\n this.currentUser = user;\n }\n\n // ===== OAuth Flow Methods =====\n\n /**\n * Start the OAuth authorization flow\n */\n async authorize(options: AuthorizationOptions): Promise<{ url: string; state: string }> {\n const config = this.providerConfigs.get(options.provider);\n if (!config) throw new Error(`Provider ${options.provider} not registered`);\n\n const finalConfig: OAuth2Config = {\n ...config,\n scopes: options.scopes || config.scopes,\n usePKCE: options.usePKCE ?? config.usePKCE ?? config.pkce,\n };\n\n const state = generateState();\n let codeVerifier: string | undefined;\n let codeChallenge: string | undefined;\n\n if (finalConfig.usePKCE || finalConfig.pkce) {\n codeVerifier = createCodeVerifier();\n codeChallenge = createCodeChallenge(codeVerifier as string);\n }\n\n // Use explicit userId if provided, otherwise fall back to current user\n const userId = options.userId || this.currentUser?.id;\n\n const authState: AuthorizationState = {\n state,\n codeVerifier,\n config: finalConfig,\n timestamp: new Date(),\n metadata: {\n ...options.metadata,\n provider: options.provider,\n userId: userId, // Use explicit or current user\n systemId: this.currentSystem?.id,\n scopeId: this.defaultScope?.id,\n },\n };\n\n await this.storage.saveAuthorizationState(authState);\n\n const provider = this.providers.get(options.provider);\n if (!provider) throw new Error(`Provider ${options.provider} not found`);\n\n const url = provider.generateAuthorizationUrl(state, codeChallenge);\n\n return { url, state };\n }\n\n /**\n * Handle the OAuth callback\n */\n async handleCallback(\n code: string,\n state: string,\n options?: CallbackOptions,\n ): Promise<CallbackResult> {\n const authState = await this.storage.getAuthorizationState(state);\n if (!authState) throw new Error('Invalid or expired state');\n\n const metadata = authState.metadata || {};\n const provider = metadata.provider as string;\n\n console.log('metadata [', metadata, ']');\n\n if (!provider) throw new Error('Provider not found in state');\n\n const userId = options?.userId || metadata.userId || this.currentUser?.id;\n\n console.log('userId [', userId, ']');\n\n const systemId = metadata.systemId || this.currentSystem?.id;\n const scopeId = options?.scopeId || metadata.scopeId || this.defaultScope?.id;\n\n if (!userId || !systemId || !scopeId) {\n throw new Error('Missing required context: userId, systemId, or scopeId');\n }\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n const token = await providerInstance.exchangeCodeForToken(code, authState.codeVerifier);\n\n // Clean up the used state\n await this.storage.deleteAuthorizationState(state);\n\n let userToken: UserToken;\n let profile: UserProfile | undefined;\n\n // Always use email-based validation if provider supports profile fetching\n\n console.log(\n 'providerInstance.hasProfileFetcher() [',\n providerInstance.hasProfileFetcher(),\n ']',\n );\n\n if (providerInstance.hasProfileFetcher()) {\n try {\n // Fetch user profile to get the email\n profile = await providerInstance.fetchProfile(token.accessToken);\n\n console.log('profile [', profile, ']');\n\n // Always use email validation to prevent duplicate emails for same provider\n userToken = await this.storage.saveTokenWithEmailValidation(\n userId,\n systemId,\n scopeId,\n provider,\n profile.email,\n {\n userId,\n systemId,\n scopeId,\n provider,\n token,\n },\n );\n\n // Apply additional profile options if provided\n if (options?.profileOptions?.mergeUserData) {\n await this.mergeUserDataFromProfile(userId, profile);\n }\n } catch (error) {\n console.warn('Failed to fetch profile or save with email validation:', error);\n // Fallback to saving without email validation\n userToken = await this.storage.saveToken({\n userId,\n systemId,\n scopeId,\n provider,\n token,\n });\n }\n } else {\n // Provider doesn't support profile fetching - save token normally\n userToken = await this.storage.saveToken({\n userId,\n systemId,\n scopeId,\n provider,\n token,\n });\n }\n\n return {\n userToken,\n userId,\n systemId,\n scopeId,\n provider,\n profile,\n };\n }\n\n /**\n * Merge user data from OAuth profile\n */\n private async mergeUserDataFromProfile(userId: string, profile: UserProfile): Promise<void> {\n const user = await this.storage.getUser(userId);\n if (!user) return;\n\n const updatedMetadata = {\n ...user.metadata,\n email: profile.email,\n name: profile.name || user.metadata?.name,\n avatar: profile.avatar || user.metadata?.avatar,\n username: profile.username || user.metadata?.username,\n profileId: profile.id || user.metadata?.profileId,\n lastProfileUpdate: new Date().toISOString(),\n };\n\n await this.storage.updateUser(userId, { metadata: updatedMetadata });\n }\n\n /**\n * Fetch user profile for a given provider and user\n * Note: If user has multiple tokens for the provider, this will fail.\n * Use fetchUserProfileByEmail() for unambiguous profile fetching.\n */\n async fetchUserProfile(provider: string, userId?: string): Promise<UserProfile> {\n if (!userId && !this.currentUser) {\n throw new Error('No user specified and no current user set');\n }\n\n const actualUserId = userId || this.currentUser!.id;\n const systemId = this.currentSystem?.id;\n const scopeId = this.defaultScope?.id;\n\n if (!systemId || !scopeId) {\n throw new Error('Missing system or scope context');\n }\n\n const userTokens = await this.storage.getTokensByUserScopeProvider(\n actualUserId,\n scopeId,\n provider,\n );\n if (userTokens.length === 0) {\n throw new Error('No token found for user and provider');\n }\n\n // If multiple tokens exist, this is ambiguous\n if (userTokens.length > 1) {\n throw new Error(\n `Multiple tokens found for provider ${provider}. Use fetchUserProfileByEmail() to specify which token to use.`,\n );\n }\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n // Use the single token\n const userToken = userTokens[0];\n if (!userToken) {\n throw new Error('Token not found');\n }\n\n const accessToken = userToken.token.accessToken;\n\n return providerInstance.fetchProfile(accessToken);\n }\n\n /**\n * Fetch user profile by email (unambiguous)\n */\n async fetchUserProfileByEmail(\n provider: string,\n email: string,\n systemId?: string,\n scopeId?: string,\n ): Promise<UserProfile> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n const accessToken = await this.getAccessTokenByEmail(\n email,\n provider,\n actualSystemId,\n actualScopeId,\n );\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n return providerInstance.fetchProfile(accessToken);\n }\n\n /**\n * Replace tokens for users with conflicting email addresses\n */\n async replaceConflictingTokensByEmail(\n email: string,\n provider: string,\n newUserId: string,\n newToken: OAuth2Token,\n ): Promise<UserToken> {\n if (!this.currentSystem || !this.defaultScope) {\n throw new Error('Missing system or scope context');\n }\n\n return this.storage.replaceTokensByEmailInUserScopeProvider(\n newUserId,\n this.defaultScope.id,\n provider,\n email,\n {\n userId: newUserId,\n systemId: this.currentSystem.id,\n scopeId: this.defaultScope.id,\n provider,\n token: newToken,\n },\n );\n }\n\n /**\n * Check if a token is expired\n */\n isTokenExpired(token: OAuth2Token, options: TokenOptions = {}): boolean {\n const { expirationBuffer = 300 } = options;\n\n // Use createdAt if available, otherwise use expiresAt\n if (token.createdAt && token.expiresIn !== undefined) {\n const expiresAt = token.createdAt + token.expiresIn * 1000;\n const effectiveNow = this.now() + expirationBuffer * 1000;\n return effectiveNow >= expiresAt;\n }\n\n // Fallback to expiresAt date\n const expiresAt = new Date(token.expiresAt).getTime();\n const effectiveNow = this.now() + expirationBuffer * 1000;\n return effectiveNow >= expiresAt;\n }\n\n /**\n * Get a valid access token (auto-refresh if needed)\n * Uses current context (user + default scope)\n */\n async getAccessToken(provider: string, options: TokenOptions = {}): Promise<string> {\n if (!this.currentUser || !this.currentSystem || !this.defaultScope) {\n throw new Error('Missing required context');\n }\n\n const userTokens = await this.storage.getTokensByUserScopeProvider(\n this.currentUser.id,\n this.defaultScope.id,\n provider,\n );\n\n if (userTokens.length === 0) {\n throw new Error('No token found for provider');\n }\n\n // If multiple tokens exist, this is ambiguous - user should use email-specific methods\n if (userTokens.length > 1) {\n throw new Error(\n `Multiple tokens found for provider ${provider}. Use getAccessTokenByEmail() or getAllValidTokensForUser() to specify which token to use.`,\n );\n }\n\n const userToken = userTokens[0];\n if (!userToken) {\n throw new Error('No token found for provider');\n }\n\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n if (!needsRefresh) {\n return userToken.token.accessToken;\n }\n\n // Refresh the token\n if (!userToken.token.refreshToken) {\n throw new Error('Token expired and no refresh token available');\n }\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n\n await this.storage.updateToken(userToken.id, { token: newToken });\n\n return newToken.accessToken;\n }\n\n /**\n * Get access token by email (unambiguous)\n */\n async getAccessTokenByEmail(\n email: string,\n systemId: string,\n scopeId: string,\n provider: string,\n options: TokenOptions = {},\n ): Promise<string> {\n const token = await this.getValidTokenForEmail(email, provider, systemId, scopeId, options);\n return token.accessToken;\n }\n\n /**\n * Ensure we have a valid token, refreshing if needed\n * Uses current context (user + default scope)\n */\n async ensureValidToken(provider: string, options: TokenOptions = {}): Promise<OAuth2Token> {\n if (!this.currentUser || !this.currentSystem || !this.defaultScope) {\n throw new Error('Missing required context');\n }\n\n const userTokens = await this.storage.getTokensByUserScopeProvider(\n this.currentUser.id,\n this.defaultScope.id,\n provider,\n );\n\n if (userTokens.length === 0) {\n throw new Error(`No tokens found for provider ${provider}`);\n }\n\n // If multiple tokens exist, this is ambiguous - user should use email-specific methods\n if (userTokens.length > 1) {\n throw new Error(\n `Multiple tokens found for provider ${provider}. Use getValidTokenForEmail() to specify which token to use.`,\n );\n }\n\n const userToken = userTokens[0];\n if (!userToken) {\n throw new Error(`No tokens found for provider ${provider}`);\n }\n\n if (!this.isTokenExpired(userToken.token, options)) {\n return userToken.token;\n }\n\n // Token is expired, refresh it\n if (!userToken.token.refreshToken) {\n throw new Error('Token expired and no refresh token available');\n }\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n\n return newToken;\n }\n\n /**\n * Execute a callback with a valid access token\n * Uses current context (user + default scope)\n */\n async withValidToken<T>(\n provider: string,\n callback: (accessToken: string) => Promise<T>,\n options: TokenOptions = {},\n ): Promise<T> {\n const token = await this.ensureValidToken(provider, options);\n return await callback(token.accessToken);\n }\n\n /**\n * Get user token entity (includes all metadata) for specific user\n */\n async getUserTokenForUser(\n userId: string,\n _systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<UserToken | null> {\n const userTokens = await this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n return userTokens.length > 0 && userTokens[0] ? userTokens[0] : null;\n }\n\n /**\n * Check if token exists for specific user/provider combination\n */\n async hasTokenForUser(\n userId: string,\n _systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<boolean> {\n const userTokens = await this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n return userTokens.length > 0;\n }\n\n /**\n * Revoke tokens for a specific user and provider (stateless method)\n * This removes ALL tokens for the user/scope/provider combination\n */\n async revokeTokensForUser(\n userId: string,\n _systemId: string,\n scopeId: string,\n provider: string,\n ): Promise<void> {\n const userTokens = await this.storage.getTokensByUserScopeProvider(userId, scopeId, provider);\n for (const userToken of userTokens) {\n await this.storage.deleteToken(userToken.id);\n }\n }\n\n /**\n * Revoke tokens for a provider\n */\n async revokeTokens(provider: string): Promise<void> {\n if (!this.currentUser || !this.currentSystem || !this.defaultScope) {\n throw new Error('Missing required context');\n }\n\n const userTokens = await this.storage.getTokensByUserScopeProvider(\n this.currentUser.id,\n this.defaultScope.id,\n provider,\n );\n\n for (const userToken of userTokens) {\n await this.storage.deleteToken(userToken.id);\n }\n }\n\n /**\n * Get all tokens for the current user\n */\n async getUserTokens(): Promise<UserToken[]> {\n if (!this.currentUser) throw new Error('No user selected');\n return this.storage.getTokensByUser(this.currentUser.id);\n }\n\n /**\n * Get all tokens for a user by ID with validation and auto-refresh\n */\n async getAllValidTokensForUser(\n userId: string,\n options: TokenOptions = {},\n ): Promise<{ provider: string; scopeId: string; token: OAuth2Token; userToken: UserToken }[]> {\n const userTokens = await this.storage.getTokensByUser(userId);\n const validTokens: {\n provider: string;\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n validTokens.push({\n provider: userToken.provider,\n scopeId: userToken.scopeId,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n /**\n * Get all valid tokens for a user by email with validation and auto-refresh\n */\n async getAllValidTokensForEmail(\n email: string,\n systemId?: string,\n options: TokenOptions = {},\n ): Promise<{ provider: string; scopeId: string; token: OAuth2Token; userToken: UserToken }[]> {\n const actualSystemId = systemId || this.currentSystem?.id;\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n\n // Get all tokens for this email\n const userTokens = await this.storage.findTokensByEmail(email, actualSystemId);\n const validTokens: {\n provider: string;\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n validTokens.push({\n provider: userToken.provider,\n scopeId: userToken.scopeId,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n /**\n * Get specific token for an email\n */\n async getTokenForEmail(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n ): Promise<UserToken | null> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n return this.storage.findTokenByEmailScopeProvider(\n email,\n actualSystemId,\n actualScopeId,\n provider,\n );\n }\n\n /**\n * Get valid token for an email (with auto-refresh)\n */\n async getValidTokenForEmail(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n options: TokenOptions = {},\n ): Promise<OAuth2Token> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n const userToken = await this.storage.findTokenByEmailScopeProvider(\n email,\n actualSystemId,\n actualScopeId,\n provider,\n );\n\n if (!userToken) {\n throw new Error(`No token found for email ${email} and provider ${provider}`);\n }\n\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n if (!needsRefresh) {\n return userToken.token;\n }\n\n // Refresh the token\n if (!userToken.token.refreshToken) {\n throw new Error('Token expired and no refresh token available');\n }\n\n const providerInstance = this.providers.get(provider);\n if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n\n return newToken;\n }\n\n /**\n * Get valid access token for an email (with auto-refresh)\n */\n async getAccessTokenForEmail(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n options: TokenOptions = {},\n ): Promise<string> {\n const token = await this.getValidTokenForEmail(email, provider, systemId, scopeId, options);\n return token.accessToken;\n }\n\n /**\n * Execute a callback with a valid access token for an email\n */\n async withValidTokenForEmail<T>(\n email: string,\n provider: string,\n callback: (accessToken: string) => Promise<T>,\n systemId?: string,\n scopeId?: string,\n options: TokenOptions = {},\n ): Promise<T> {\n const token = await this.getValidTokenForEmail(email, provider, systemId, scopeId, options);\n return await callback(token.accessToken);\n }\n\n /**\n * Check if token exists for specific email/provider combination\n */\n async hasTokenForEmail(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n ): Promise<boolean> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n const token = await this.storage.findTokenByEmailScopeProvider(\n email,\n actualSystemId,\n actualScopeId,\n provider,\n );\n return token !== null;\n }\n\n /**\n * Revoke tokens for a specific email and provider\n */\n async revokeTokensForEmail(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n ): Promise<void> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n const token = await this.storage.findTokenByEmailScopeProvider(\n email,\n actualSystemId,\n actualScopeId,\n provider,\n );\n if (token) {\n await this.storage.deleteToken(token.id);\n }\n }\n\n /**\n * Get tokens by scope (stateless method)\n */\n async getTokensByScope(systemId?: string, scopeId?: string): Promise<UserToken[]> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n return this.storage.getTokensByScope(actualSystemId, actualScopeId);\n }\n\n /**\n * Find token by email and scope\n */\n async findTokenByEmailAndScope(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n ): Promise<UserToken | null> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n return this.storage.findTokenByEmailScopeProvider(\n email,\n actualSystemId,\n actualScopeId,\n provider,\n );\n }\n\n /**\n * Find all tokens by email and scope\n */\n async findAllTokensByEmailAndScope(\n email: string,\n provider: string,\n systemId?: string,\n scopeId?: string,\n ): Promise<UserToken[]> {\n const actualSystemId = systemId || this.currentSystem?.id;\n const actualScopeId = scopeId || this.defaultScope?.id;\n\n if (!actualSystemId) {\n throw new Error('System ID must be provided or current system must be set');\n }\n if (!actualScopeId) {\n throw new Error('Scope ID must be provided or default scope must be set');\n }\n\n return this.storage\n .findTokensByEmailAndScope(email, actualSystemId, actualScopeId)\n .then((tokens) => tokens.filter((t) => t.provider === provider));\n }\n\n // ===== Utility Methods =====\n\n private detectProviderType(name: string, config: OAuth2Config): ProviderType {\n // Check by name first\n const knownProviders: ProviderType[] = ['google', 'github', 'microsoft', 'outlook', 'facebook'];\n if (knownProviders.includes(name as ProviderType)) {\n return name as ProviderType;\n }\n\n // Check by URL patterns\n if (config.authorizationUrl.includes('google.com')) return 'google';\n if (config.authorizationUrl.includes('github.com')) return 'github';\n if (\n config.authorizationUrl.includes('microsoft.com') ||\n config.authorizationUrl.includes('microsoftonline.com')\n )\n return 'microsoft';\n if (config.authorizationUrl.includes('facebook.com')) return 'facebook';\n\n return 'generic';\n }\n\n /**\n * Clean up expired authorization states\n */\n async cleanup(expiryMs: number = 10 * 60 * 1000): Promise<void> {\n await this.storage.cleanupExpiredStates(expiryMs);\n }\n\n /**\n * Get all valid tokens for a user with OAuth provider profile information (RECOMMENDED FOR UI)\n * This fetches the actual email/profile from each OAuth provider using the access token\n */\n async getAllValidTokensWithProviderProfiles(\n userId: string,\n options: TokenOptions = {},\n ): Promise<\n {\n provider: string;\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n profile?: UserProfile;\n }[]\n > {\n const userTokens = await this.storage.getTokensByUser(userId);\n const validTokens: {\n provider: string;\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n profile?: UserProfile;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n // Fetch OAuth provider profile if provider supports it\n let profile: UserProfile | undefined;\n const providerInstance = this.providers.get(userToken.provider);\n if (providerInstance && providerInstance.hasProfileFetcher()) {\n try {\n profile = await providerInstance.fetchProfile(finalToken.accessToken);\n } catch (profileError) {\n console.warn(\n `Failed to fetch profile for provider ${userToken.provider}:`,\n profileError,\n );\n // Continue without profile rather than skipping the token\n }\n }\n\n validTokens.push({\n provider: userToken.provider,\n scopeId: userToken.scopeId,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n profile,\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n /**\n * Get all valid tokens for a user and scope with OAuth provider profile information\n */\n async getAllValidTokensForUserAndScopeWithProviderProfiles(\n userId: string,\n scopeId: string,\n options: TokenOptions = {},\n ): Promise<\n { provider: string; token: OAuth2Token; userToken: UserToken; profile?: UserProfile }[]\n > {\n const userTokens = await this.storage.getTokensByUserAndScope(userId, scopeId);\n const validTokens: {\n provider: string;\n token: OAuth2Token;\n userToken: UserToken;\n profile?: UserProfile;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n // Fetch OAuth provider profile if provider supports it\n let profile: UserProfile | undefined;\n const providerInstance = this.providers.get(userToken.provider);\n if (providerInstance && providerInstance.hasProfileFetcher()) {\n try {\n profile = await providerInstance.fetchProfile(finalToken.accessToken);\n } catch (profileError) {\n console.warn(\n `Failed to fetch profile for provider ${userToken.provider}:`,\n profileError,\n );\n // Continue without profile rather than skipping the token\n }\n }\n\n validTokens.push({\n provider: userToken.provider,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n profile,\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n /**\n * Get all valid tokens for a user and provider with OAuth provider profile information\n */\n async getAllValidTokensForUserAndProviderWithProviderProfiles(\n userId: string,\n provider: string,\n options: TokenOptions = {},\n ): Promise<\n { scopeId: string; token: OAuth2Token; userToken: UserToken; profile?: UserProfile }[]\n > {\n const userTokens = await this.storage.getTokensByUserAndProvider(userId, provider);\n const validTokens: {\n scopeId: string;\n token: OAuth2Token;\n userToken: UserToken;\n profile?: UserProfile;\n }[] = [];\n\n for (const userToken of userTokens) {\n if (!userToken) continue;\n\n try {\n // Check if token needs refresh\n const needsRefresh =\n options.autoRefresh !== false && this.isTokenExpired(userToken.token, options);\n\n let finalToken = userToken.token;\n\n if (needsRefresh) {\n // Try to refresh the token\n if (!userToken.token.refreshToken) {\n console.warn(\n `Token for provider ${userToken.provider} expired and no refresh token available`,\n );\n continue; // Skip this token\n }\n\n const providerInstance = this.providers.get(userToken.provider);\n if (!providerInstance) {\n console.warn(`Provider ${userToken.provider} not found`);\n continue; // Skip this token\n }\n\n try {\n const newToken = await providerInstance.refreshToken(userToken.token.refreshToken);\n await this.storage.updateToken(userToken.id, { token: newToken });\n finalToken = newToken;\n } catch (refreshError) {\n console.warn(\n `Failed to refresh token for provider ${userToken.provider}:`,\n refreshError,\n );\n continue; // Skip this token\n }\n }\n\n // Fetch OAuth provider profile if provider supports it\n let profile: UserProfile | undefined;\n const providerInstance = this.providers.get(userToken.provider);\n if (providerInstance && providerInstance.hasProfileFetcher()) {\n try {\n profile = await providerInstance.fetchProfile(finalToken.accessToken);\n } catch (profileError) {\n console.warn(\n `Failed to fetch profile for provider ${userToken.provider}:`,\n profileError,\n );\n // Continue without profile rather than skipping the token\n }\n }\n\n validTokens.push({\n scopeId: userToken.scopeId,\n token: finalToken,\n userToken: { ...userToken, token: finalToken },\n profile,\n });\n } catch (error) {\n console.warn(`Error processing token for provider ${userToken.provider}:`, error);\n continue; // Skip this token\n }\n }\n\n return validTokens;\n }\n\n /**\n * Get OAuth provider profile for a specific token\n * This fetches the actual email/profile from the OAuth provider using the access token\n */\n async getTokenProfile(token: OAuth2Token, provider: string): Promise<UserProfile | null> {\n const providerInstance = this.providers.get(provider);\n if (!providerInstance || !providerInstance.hasProfileFetcher()) {\n return null;\n }\n\n try {\n return await providerInstance.fetchProfile(token.accessToken);\n } catch (error) {\n console.warn(`Failed to fetch profile for provider ${provider}:`, error);\n return null;\n }\n }\n\n /**\n * Get OAuth provider profile for a specific user token\n * This fetches the actual email/profile from the OAuth provider using the access token\n */\n async getUserTokenProfile(userToken: UserToken): Promise<UserProfile | null> {\n return this.getTokenProfile(userToken.token, userToken.provider);\n }\n}\n","import { sealData, unsealData } from 'iron-session';\n\nexport const seal = <T>(d: T, key: string) => sealData(d, { password: key });\nexport const unseal = <T>(s: string, key: string) => unsealData<T>(s, { password: key });\n"]}
|