1try{!function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="40e921ea-edf0-4b1c-9fb0-38310d2af1ee",e._sentryDebugIdIdentifier="sentry-dbid-40e921ea-edf0-4b1c-9fb0-38310d2af1ee")}()}catch(e){}"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[72060],{72060:(e,t,r)=>{r.r(t),r.d(t,{SocialLoginWeb:()=>h});var o=r(77805);class i extends o.E_{constructor(){super()}parseJwt(e){return JSON.parse(decodeURIComponent(atob(e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/")).split("").map(e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)).join("")))}async loadScript(e){return new Promise((t,r)=>{let o=document.createElement("script");o.src=e,o.async=!0,o.onload=()=>{t()},o.onerror=r,document.body.appendChild(o)})}}i.OAUTH_STATE_KEY="social_login_oauth_pending";class n extends i{constructor(){super(...arguments),this.clientId=null,this.redirectUrl=null,this.scriptLoaded=!1,this.scriptUrl="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js",this.useProperTokenExchange=!1}async initialize(e,t,r=!1){this.clientId=e,this.redirectUrl=t||null,this.useProperTokenExchange=r,e&&await this.loadAppleScript()}async login(e){if(!this.clientId)throw Error("Apple Client ID not set. Call initialize() first.");if(!this.scriptLoaded)throw Error("Apple Sign-In script not loaded.");return new Promise((t,r)=>{var o,i;AppleID.auth.init({clientId:null!=(o=this.clientId)?o:"",scope:(null==(i=e.scopes)?void 0:i.join(" "))||"name email",redirectURI:this.redirectUrl||window.location.href,state:e.state,nonce:e.nonce,usePopup:!0}),AppleID.auth.signIn().then(e=>{var r,o,i,n,s;let a=null;a=this.useProperTokenExchange?null:{token:e.authorization.code||""},t({provider:"apple",result:Object.assign({profile:{user:e.user||"",email:(null==(r=e.user)?void 0:r.email)||null,givenName:(null==(i=null==(o=e.user)?void 0:o.name)?void 0:i.firstName)||null,familyName:(null==(s=null==(n=e.user)?void 0:n.name)?void 0:s.lastName)||null},accessToken:a,idToken:e.authorization.id_token||null},this.useProperTokenExchange&&{authorizationCode:e.authorization.code})})}).catch(e=>{r(e)})})}async logout(){console.log("Apple logout: Session should be managed on the client side")}async isLoggedIn(){return console.log("Apple login status should be managed on the client side"),{isLoggedIn:!1}}async getAuthorizationCode(){throw console.log("Apple authorization code should be stored during login"),Error("Apple authorization code not available")}async refresh(){console.log("Apple refresh not available on web")}async loadAppleScript(){if(!this.scriptLoaded)return this.loadScript(this.scriptUrl).then(()=>{this.scriptLoaded=!0})}}class s extends i{constructor(){super(...arguments),this.appId=null,this.scriptLoaded=!1,this.locale="en_US"}async initialize(e,t){this.appId=e,t&&(this.locale=t),e&&(await this.loadFacebookScript(this.locale),FB.init({appId:this.appId,version:"v17.0",xfbml:!0,cookie:!0}))}async login(e){if(!this.appId)throw Error("Facebook App ID not set. Call initialize() first.");return new Promise((t,r)=>{FB.login(e=>{"connected"===e.status?FB.api("/me",{fields:"id,name,email,picture"},r=>{var o,i;t({provider:"facebook",result:{accessToken:{token:e.authResponse.accessToken,userId:e.authResponse.userID},profile:{userID:r.id,name:r.name,email:r.email||null,imageURL:(null==(i=null==(o=r.picture)?void 0:o.data)?void 0:i.url)||null,friendIDs:[],birthday:null,ageRange:null,gender:null,location:null,hometown:null,profileURL:null},idToken:null}})}):r(Error("Facebook login failed"))},{scope:e.permissions.join(",")})})}async logout(){return new Promise(e=>{FB.logout(()=>e())})}async isLoggedIn(){return new Promise(e=>{FB.getLoginStatus(t=>{e({isLoggedIn:"connected"===t.status})})})}async getAuthorizationCode(){return new Promise((e,t)=>{FB.getLoginStatus(r=>{var o;"connected"===r.status?e({accessToken:(null==(o=r.authResponse)?void 0:o.accessToken)||""}):t(Error("No Facebook authorization code available"))})})}async refresh(e){await this.login(e)}async loadFacebookScript(e){if(this.scriptLoaded)return;let t=document.querySelector('script[src*="connect.facebook.net"]');return t&&t.remove(),this.loadScript(`https://connect.facebook.net/${e}/sdk.js`).then(()=>{this.scriptLoaded=!0})}}class a extends i{constructor(){super(...arguments),this.clientId=null,this.loginType="online",this.GOOGLE_TOKEN_REQUEST_URL="https://www.googleapis.com/oauth2/v3/tokeninfo",this.GOOGLE_STATE_KEY="capgo_social_login_google_state"}async initialize(e,t,r,o){this.clientId=e,t&&(this.loginType=t),this.hostedDomain=r,this.redirectUrl=o}async login(e){if(!this.clientId)throw Error("Google Client ID not set. Call initialize() first.");let t=e.scopes||[];t.length>0?(t.includes("https://www.googleapis.com/auth/userinfo.email")||t.push("https://www.googleapis.com/auth/userinfo.email"),t.includes("https://www.googleapis.com/auth/userinfo.profile")||t.push("https://www.googleapis.com/auth/userinfo.profile"),t.includes("openid")||t.push("openid")):t=["https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","openid"];let r=e.nonce||Math.random().toString(36).substring(2);return this.traditionalOAuth({scopes:t,nonce:r,hostedDomain:this.hostedDomain,prompt:e.prompt})}async logout(){if("offline"===this.loginType)return Promise.reject("Offline login doesn't store tokens. logout is not available");let e=this.getGoogleState();e&&await this.rawLogoutGoogle(e.accessToken)}async isLoggedIn(){if("offline"===this.loginType)return Promise.reject("Offline login doesn't store tokens. isLoggedIn is not available");let e=this.getGoogleState();if(!e)return{isLoggedIn:!1};try{let t=await this.accessTokenIsValid(e.accessToken),r=this.idTokenValid(e.idToken);if(t&&r)return{isLoggedIn:!0};try{await this.rawLogoutGoogle(e.accessToken,!1)}
1catch(e){console.error("Access token is not valid, but cannot logout",e)}return{isLoggedIn:!1}}catch(e){return Promise.reject(e)}}async getAuthorizationCode(){if("offline"===this.loginType)return Promise.reject("Offline login doesn't store tokens. getAuthorizationCode is not available");let e=this.getGoogleState();if(!e)throw Error("No Google authorization code available");try{let t=await this.accessTokenIsValid(e.accessToken),r=this.idTokenValid(e.idToken);if(t&&r)return{accessToken:e.accessToken,jwt:e.idToken};try{await this.rawLogoutGoogle(e.accessToken,!1)}catch(e){console.error("Access token is not valid, but cannot logout",e)}throw Error("No Google authorization code available")}catch(e){return Promise.reject(e)}}async refresh(){return Promise.reject("Not implemented")}handleOAuthRedirect(e){let t=e.searchParams,r=t.get("error");if(r)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:t.get("error_description")||r};let o=t.get("code");if(o&&t.has("scope"))return{provider:"google",result:{serverAuthCode:o,responseType:"offline"}};let n=e.hash.substring(1);if(console.log("handleOAuthRedirect",e.hash),!n)return null;let s=new URLSearchParams(n),a=s.get("error");if(a)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:s.get("error_description")||a};console.log("handleOAuthRedirect ok");let l=s.get("access_token"),c=s.get("id_token");if(l&&c){localStorage.removeItem(i.OAUTH_STATE_KEY);let e=this.parseJwt(c);return{provider:"google",result:{accessToken:{token:l},idToken:c,profile:{email:e.email||null,familyName:e.family_name||null,givenName:e.given_name||null,id:e.sub||null,name:e.name||null,imageUrl:e.picture||null},responseType:"online"}}}return null}async accessTokenIsValid(e){let t=`${this.GOOGLE_TOKEN_REQUEST_URL}?access_token=${encodeURIComponent(e)}`;try{let e,r,o=await fetch(t);if(!o.ok)return console.log(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response not successful. Status code: ${o.status}. Assuming that the token is not valid`),!1;let i=await o.text();if(!i)throw console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`),Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);try{e=JSON.parse(i)}catch(e){throw console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`),Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`)}let n=e.expires_in;if(null==n)throw console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`),Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`);try{if(r=parseInt(n,10),isNaN(r))throw Error("'expires_in' is not a valid integer")}catch(e){throw console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${n} is not a valid integer. Error: ${e}`),Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${n} is not a valid integer. Error: ${e}`)}return r>5}catch(e){throw console.error(e),e}}idTokenValid(e){try{let t=this.parseJwt(e),r=Math.ceil(Date.now()/1e3)+5;return t.exp&&r<t.exp}catch(e){return!1}}async rawLogoutGoogle(e,t=null){if(null===t&&(t=await this.accessTokenIsValid(e)),!0!==t)return void this.clearStateGoogle();try{await fetch(`https://accounts.google.com/o/oauth2/revoke?token=${encodeURIComponent(e)}`),this.clearStateGoogle()}catch(e){}}persistStateGoogle(e,t){try{window.localStorage.setItem(this.GOOGLE_STATE_KEY,JSON.stringify({accessToken:e,idToken:t}))}catch(e){console.error("Cannot persist state google",e)}}clearStateGoogle(){try{window.localStorage.removeItem(this.GOOGLE_STATE_KEY)}catch(e){console.error("Cannot clear state google",e)}}getGoogleState(){try{let e=window.localStorage.getItem(this.GOOGLE_STATE_KEY);if(!e)return null;let{accessToken:t,idToken:r}=JSON.parse(e);return{accessToken:t,idToken:r}}catch(e){return console.error("Cannot get state google",e),null}}async traditionalOAuth({scopes:e,hostedDomain:t,nonce:r,prompt:o}){var n;let s,a,l=[...new Set([...e||[],"openid"])],c=new URLSearchParams(Object.assign(Object.assign({client_id:null!=(n=this.clientId)?n:"",redirect_uri:this.redirectUrl||window.location.origin+window.location.pathname,response_type:"offline"===this.loginType?"code":"token id_token",scope:l.join(" ")},r&&{nonce:r}),{include_granted_scopes:"true",state:"popup"}));void 0!==t&&c.append("hd",t),void 0!==o&&c.append("prompt",o);let d=`https://accounts.google.com/o/oauth2/v2/auth?${c.toString()}`,u=window.screenX+(window.outerWidth-500)/2,h=window.screenY+(window.outerHeight-600)/2;localStorage.setItem(i.OAUTH_STATE_KEY,JSON.stringify({provider:"google",loginType:this.loginType,nonce:r}));let p=window.open(d,"Google Sign In",`width=500,height=600,left=${u},top=${h},popup=1`),g=`google_oauth_${r||Date.now()}`,f=null;try{f=new BroadcastChannel(g)}catch(e){}return new Promise((e,t)=>
1{if(!p)return void t(Error("Failed to open popup"));let r=()=>{window.removeEventListener("message",i),clearInterval(s),clearTimeout(a),f&&f.close()},o=r=>{if("online"===this.loginType){let{accessToken:o,idToken:i}=r;if(o&&i){let t=this.parseJwt(i);this.persistStateGoogle(o.token,i),e({provider:"google",result:{accessToken:{token:o.token},idToken:i,profile:{email:t.email||null,familyName:t.family_name||null,givenName:t.given_name||null,id:t.sub||null,name:t.name||null,imageUrl:t.picture||null},responseType:"online"}})}else t(Error("Invalid OAuth response: missing accessToken or idToken"))}else{let{serverAuthCode:o}=r;if(!o)return void t(Error("Invalid OAuth response: missing serverAuthCode"));e({provider:"google",result:{responseType:"offline",serverAuthCode:o}})}},i=e=>{var i,n,s,a;e.origin!==window.location.origin||(null==(n=null==(i=e.data)?void 0:i.source)?void 0:n.startsWith("angular"))||((null==(s=e.data)?void 0:s.type)==="oauth-response"?(r(),o(e.data)):(null==(a=e.data)?void 0:a.type)==="oauth-error"&&(r(),t(Error(e.data.error||"User cancelled the OAuth flow"))))};f&&(f.onmessage=e=>{var i;let n=e.data;null!=(i=null==n?void 0:n.source)&&i.toString().startsWith("angular")||((null==n?void 0:n.type)==="oauth-response"?(r(),o(n)):(null==n?void 0:n.type)==="oauth-error"&&(r(),t(Error(n.error||"User cancelled the OAuth flow"))))}),window.addEventListener("message",i),a=setTimeout(()=>{r();try{p.close()}catch(e){}t(Error("OAuth timeout"))},3e5),s=setInterval(()=>{try{p.closed&&(r(),t(Error("Popup closed")))}catch(e){clearInterval(s)}},1e3)})}}var l=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,o=Object.getOwnPropertySymbols(e);i<o.length;i++)0>t.indexOf(o[i])&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(r[o[i]]=e[o[i]]);return r};class c extends i{constructor(){super(...arguments),this.providers=new Map,this.TOKENS_KEY_PREFIX="capgo_social_login_oauth2_tokens_",this.STATE_PREFIX="capgo_social_login_oauth2_state_"}normalizeScopeValue(e){return e?"string"==typeof e?e:Array.isArray(e)?e.filter(Boolean).join(" "):"":""}normalizeConfig(e,t){var r,o,i,n,s,a,l,c;let d=null!=(r=t.appId)?r:t.clientId,u=null!=(o=t.authorizationBaseUrl)?o:t.authorizationEndpoint,h=null!=(i=t.accessTokenEndpoint)?i:t.tokenEndpoint,p=null!=(n=t.logoutUrl)?n:t.endSessionEndpoint,g=null!=(s=t.scope)?s:t.scopes;if(!d)throw Error(`OAuth2 provider '${e}' requires appId (or clientId).`);if(!t.redirectUrl)throw Error(`OAuth2 provider '${e}' requires redirectUrl.`);if(!u&&!t.issuerUrl)throw Error(`OAuth2 provider '${e}' requires authorizationBaseUrl (or authorizationEndpoint) or issuerUrl.`);return{appId:d,issuerUrl:t.issuerUrl,authorizationBaseUrl:u,accessTokenEndpoint:h,redirectUrl:t.redirectUrl,resourceUrl:t.resourceUrl,responseType:null!=(a=t.responseType)?a:"code",pkceEnabled:null==(l=t.pkceEnabled)||l,scope:this.normalizeScopeValue(g),additionalParameters:t.additionalParameters,loginHint:t.loginHint,prompt:t.prompt,additionalTokenParameters:t.additionalTokenParameters,additionalResourceHeaders:t.additionalResourceHeaders,logoutUrl:p,postLogoutRedirectUrl:t.postLogoutRedirectUrl,additionalLogoutParameters:t.additionalLogoutParameters,logsEnabled:null!=(c=t.logsEnabled)&&c}}async ensureDiscovered(e){let t=this.providers.get(e);if(!(null==t?void 0:t.issuerUrl)||t.authorizationBaseUrl&&t.accessTokenEndpoint)return;let r=t.issuerUrl.replace(/\/+$/,""),o=`${r}/.well-known/openid-configuration`,i=await fetch(o);if(!i.ok){let e=await i.text().catch(()=>"");throw Error(`OAuth2 discovery failed (${i.status}): ${e||o}`)}let n=await i.json(),s=n.authorization_endpoint,a=n.token_endpoint,l=n.end_session_endpoint;t.authorizationBaseUrl||"string"!=typeof s||(t.authorizationBaseUrl=s),t.accessTokenEndpoint||"string"!=typeof a||(t.accessTokenEndpoint=a),t.logoutUrl||"string"!=typeof l||(t.logoutUrl=l),t.logsEnabled&&console.log(`[OAuth2:${e}] Discovery resolved`,{authorizationBaseUrl:t.authorizationBaseUrl,accessTokenEndpoint:t.accessTokenEndpoint,logoutUrl:t.logoutUrl})}async initializeProviders(e){for(let[t,r]of Object.entries(e)){let e=this.normalizeConfig(t,r);this.providers.set(t,e),e.logsEnabled&&console.log(`[OAuth2:${t}] Initialized with config:`,{appId:e.appId,issuerUrl:e.issuerUrl,authorizationBaseUrl:e.authorizationBaseUrl,redirectUrl:e.redirectUrl,responseType:e.responseType,pkceEnabled:e.pkceEnabled}),await this.ensureDiscovered(t)}}getProvider(e){let t=this.providers.get(e);if(!t)throw Error(`OAuth2 provider '${e}' not configured. Call initialize() first.`);return t}getTokensKey(e){return`${this.TOKENS_KEY_PREFIX}${e}`}async login(e){var t,r,o,n,s,a,c,d,u;let{providerId:h}=e,p=this.getProvider(h);await this.ensureDiscovered(h);let g=null!=(t=e.redirectUrl)?t:p.redirectUrl,f=this.normalizeScopeValue(null!=(o=null!=(r=e.scope)?r:e.scopes)?o:p.scope),w=null!=(n=e.state)?n:this.generateState(),v=null!=(s=e.codeVerifier)?s:this.generateCodeVerifier(),m=new URLSearchParams({response_type:p.responseType,client_id:p.appId,redirect_uri:g,state:w});f&&m.set("scope",f);let T=Object.assign(Object.assign({},null!=(a=p.additionalParameters)?a:{}),null!=(c=e.additionalParameters)?c:{}),_=null!=(d=e.loginHint)?d:p.loginHint,k=null!=(u=e.prompt)?u:p.prompt;if(!_||"login_hint"in T||(T.login_hint=_),!k||"prompt"in T||(T.prompt=k),"code"===p.responseType&&p.pkceEnabled){let e=await this.generateCodeChallenge(v);m.set("code_challenge",e),m.set("code_challenge_method","S256")}for(let[e,t]of Object.entries(T))void 0!==t&&m.set(e,t);if(this.persistPendingLogin(w,{providerId:h,codeVerifier:v,redirectUri:g,scope:f}),localStorage.setItem(i.OAUTH_STATE_KEY,JSON.stringify({provider:"oauth2",providerId:h,state:w})),!p.authorizationBaseUrl)throw Error(`OAuth2 provider '${h}' is missing authorizationBaseUrl (discovery may have failed).`);let E=`${p.authorizationBaseUrl}?${m.toString()}`;if(p.logsEnabled&&console.log(`[OAuth2:${h}] Opening authorization URL:`,E),"redirect"===e.flow)return window.location.assign(E),new Promise(()=>{});let y=window.screenX+(window.outerWidth-500)/2,S=window.screenY+(window.outerHeight-650)/2,I=window.open(E,"OAuth2Login",`width=500,height=650,left=${y},top=${S},popup=1`);return new Promise((e,t)=>
1{if(!I)return void t(Error("Unable to open login window. Please allow popups."));let r=`oauth2_${w}`,o=null;try{o=new BroadcastChannel(r)}catch(e){p.logsEnabled&&console.log(`[OAuth2:${h}] BroadcastChannel not supported, using postMessage only`)}let i=(e,t,r)=>{window.removeEventListener("message",e),clearTimeout(t),clearInterval(r),o&&o.close()},n=r=>{if((null==r?void 0:r.type)==="oauth-response"){if((null==r?void 0:r.provider)&&"oauth2"!==r.provider||(null==r?void 0:r.providerId)&&r.providerId!==h)return!1;i(s,a,c);let{provider:t,type:o}=r;return e({provider:"oauth2",result:l(r,["provider","type"])}),!0}return(null==r?void 0:r.type)==="oauth-error"&&(null==r||!r.provider||"oauth2"===r.provider)&&(i(s,a,c),t(Error(r.error||"OAuth2 login was cancelled.")),!0)};o&&(o.onmessage=e=>{n(e.data)});let s=e=>{e.origin===window.location.origin&&n(e.data)};window.addEventListener("message",s);let a=window.setTimeout(()=>{i(s,a,c);try{I.close()}catch(e){}t(Error("OAuth2 login timed out."))},3e5),c=window.setInterval(()=>{try{I.closed&&(i(s,a,c),t(Error("OAuth2 login window was closed.")))}catch(e){clearInterval(c),p.logsEnabled&&console.log(`[OAuth2:${h}] Cannot check popup.closed due to cross-origin restrictions. Relying on message handlers and timeout.`)}},1e3)})}async logout(e){await this.ensureDiscovered(e);let t=this.providers.get(e),r=this.getStoredTokens(e);if(localStorage.removeItem(this.getTokensKey(e)),null==t?void 0:t.logoutUrl)try{let e=new URL(t.logoutUrl);(null==r?void 0:r.idToken)&&e.searchParams.set("id_token_hint",r.idToken);let o=t.postLogoutRedirectUrl;if(o&&e.searchParams.set("post_logout_redirect_uri",o),t.additionalLogoutParameters)for(let[r,o]of Object.entries(t.additionalLogoutParameters))e.searchParams.set(r,o);window.open(e.toString(),"_blank")}catch(e){window.open(t.logoutUrl,"_blank")}}async isLoggedIn(e){let t=this.getStoredTokens(e);if(!t)return{isLoggedIn:!1};let r=t.expiresAt>Date.now();return r||localStorage.removeItem(this.getTokensKey(e)),{isLoggedIn:r}}async getAuthorizationCode(e){let t=this.getStoredTokens(e);if(!t)throw Error(`OAuth2 access token is not available for provider '${e}'.`);return{accessToken:t.accessToken,jwt:t.idToken}}async refresh(e){await this.refreshToken(e)}async refreshToken(e,t,r){var o,i,n,s,a,l;await this.ensureDiscovered(e);let c=this.getProvider(e),d=this.getStoredTokens(e),u=null!=t?t:null==d?void 0:d.refreshToken;if(!u)throw Error(`No OAuth2 refresh token is available for provider '${e}'. Include offline_access scope to receive one.`);if(!c.accessTokenEndpoint)throw Error(`No accessTokenEndpoint configured for provider '${e}'.`);let h=await this.refreshWithRefreshToken(e,u,r),p=h.expires_in?Date.now()+1e3*h.expires_in:Date.now()+36e5,g=null!=(n=null!=(i=null==(o=h.scope)?void 0:o.split(" ").filter(Boolean))?i:null==d?void 0:d.scope)?n:[],f=null;c.resourceUrl&&(f=await this.fetchResource(e,h.access_token));let w=null!=(s=h.refresh_token)?s:u;return this.persistTokens(e,{accessToken:h.access_token,refreshToken:w,idToken:h.id_token,expiresAt:p,scope:g,tokenType:h.token_type}),{providerId:e,accessToken:{token:h.access_token,tokenType:h.token_type,expires:new Date(p).toISOString(),refreshToken:w},idToken:null!=(a=h.id_token)?a:null,refreshToken:null!=w?w:null,resourceData:f,scope:g,tokenType:h.token_type,expiresIn:null!=(l=h.expires_in)?l:null}}async handleOAuthRedirect(e,t){var r,o,n,s,a;let l=new URLSearchParams(e.search);new URLSearchParams(e.hash.slice(1)).forEach((e,t)=>{l.set(t,e)});let c=null!=t?t:l.get("state");if(!c)return null;let d=this.consumePendingLogin(c);if(!d)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:"OAuth2 login session expired or state mismatch."};let{providerId:u}=d;await this.ensureDiscovered(u);let h=this.providers.get(u);if(!h)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:`OAuth2 provider '${u}' configuration not found.`};let p=l.get("error");if(p)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:l.get("error_description")||p};try{let e;if(l.has("code")){let t=l.get("code");if(!t)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:"OAuth2 authorization code missing from redirect."};e=await this.exchangeAuthorizationCode(u,t,d)}else{if(!l.has("access_token"))return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:"No authorization code or access token in redirect."};e={access_token:l.get("access_token"),token_type:l.get("token_type")||"bearer",expires_in:l.has("expires_in")?parseInt(l.get("expires_in"),10):void 0,scope:l.get("scope")||void 0,id_token:l.get("id_token")||void 0}}let t=e.expires_in?Date.now()+1e3*e.expires_in:Date.now()+36e5,c=null!=(o=null==(r=e.scope)?void 0:r.split(" ").filter(
1Boolean))?o:[],p=null;return h.resourceUrl&&(p=await this.fetchResource(u,e.access_token)),this.persistTokens(u,{accessToken:e.access_token,refreshToken:e.refresh_token,idToken:e.id_token,expiresAt:t,scope:c,tokenType:e.token_type}),{provider:"oauth2",result:{providerId:u,accessToken:{token:e.access_token,tokenType:e.token_type,expires:new Date(t).toISOString(),refreshToken:e.refresh_token},idToken:null!=(n=e.id_token)?n:null,refreshToken:null!=(s=e.refresh_token)?s:null,resourceData:p,scope:c,tokenType:e.token_type,expiresIn:null!=(a=e.expires_in)?a:null}}}catch(e){if(e instanceof Error)return{error:e.message};return{error:"OAuth2 login failed unexpectedly."}}finally{localStorage.removeItem(i.OAUTH_STATE_KEY)}}async exchangeAuthorizationCode(e,t,r){let o=this.getProvider(e);if(!o.accessTokenEndpoint)throw Error(`No accessTokenEndpoint configured for provider '${e}'.`);let i=new URLSearchParams({grant_type:"authorization_code",client_id:o.appId,code:t,redirect_uri:r.redirectUri});if(o.pkceEnabled&&i.set("code_verifier",r.codeVerifier),o.additionalTokenParameters)for(let[e,t]of Object.entries(o.additionalTokenParameters))i.set(e,t);o.logsEnabled&&console.log(`[OAuth2:${e}] Exchanging code at:`,o.accessTokenEndpoint);let n=await fetch(o.accessTokenEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!n.ok){let e=await n.text();throw Error(`OAuth2 token exchange failed (${n.status}): ${e}`)}return await n.json()}async refreshWithRefreshToken(e,t,r){let o=this.getProvider(e);if(!o.accessTokenEndpoint)throw Error(`No accessTokenEndpoint configured for provider '${e}'.`);let i=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:o.appId});if(o.additionalTokenParameters)for(let[e,t]of Object.entries(o.additionalTokenParameters))i.set(e,t);if(r)for(let[e,t]of Object.entries(r))i.set(e,t);let n=await fetch(o.accessTokenEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!n.ok){let e=await n.text();throw Error(`OAuth2 refresh failed (${n.status}): ${e}`)}return await n.json()}async fetchResource(e,t){let r=this.getProvider(e);if(!r.resourceUrl)throw Error(`No resourceUrl configured for provider '${e}'.`);let o={Authorization:`Bearer ${t}`};r.additionalResourceHeaders&&Object.assign(o,r.additionalResourceHeaders);let i=await fetch(r.resourceUrl,{headers:o});if(!i.ok){let e=await i.text();throw Error(`Unable to fetch OAuth2 resource (${i.status}): ${e}`)}return await i.json()}persistTokens(e,t){localStorage.setItem(this.getTokensKey(e),JSON.stringify(t))}getStoredTokens(e){let t=localStorage.getItem(this.getTokensKey(e));if(!t)return null;try{return JSON.parse(t)}catch(t){return console.warn(`Failed to parse stored OAuth2 tokens for provider '${e}'`,t),null}}persistPendingLogin(e,t){localStorage.setItem(`${this.STATE_PREFIX}${e}`,JSON.stringify(t))}consumePendingLogin(e){let t=`${this.STATE_PREFIX}${e}`,r=localStorage.getItem(t);if(localStorage.removeItem(t),!r)return null;try{return JSON.parse(r)}catch(e){return console.warn("Failed to parse pending OAuth2 login payload",e),null}}generateState(){return[...crypto.getRandomValues(new Uint8Array(16))].map(e=>e.toString(16).padStart(2,"0")).join("")}generateCodeVerifier(){let e=new Uint8Array(64);return crypto.getRandomValues(e),Array.from(e).map(e=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"[e%66]).join("")}async generateCodeChallenge(e){let t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return this.base64UrlEncode(new Uint8Array(r))}base64UrlEncode(e){let t="";return e.forEach(e=>t+=String.fromCharCode(e)),btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}decodeIdToken(e){let t=e.split(".");if(t.length<2)throw Error("Invalid JWT: missing parts");let r=t[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(atob(r+"=".repeat((4-r.length%4)%4)))}getAccessTokenExpirationDate(e){let t=this.getStoredTokens(e);return(null==t?void 0:t.expiresAt)?{expirationDate:new Date(t.expiresAt).toISOString()}:{expirationDate:null}}isAccessTokenAvailable(e){let t=this.getStoredTokens(e);return{isAvailable:!!(null==t?void 0:t.accessToken)}}isAccessTokenExpired(e){let t=this.getStoredTokens(e);return(null==t?void 0:t.expiresAt)?{isExpired:t.expiresAt<=Date.now()}:{isExpired:!0}}isRefreshTokenAvailable(e){let t=this.getStoredTokens(e);return{isAvailable:!!(null==t?void 0:t.refreshToken)}}}var d=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,o=Object.getOwnPropertySymbols(e);i<o.length;i++)0>t.indexOf(o[i])&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(r[o[i]]=e[o[i]]);return r};class u extends i{constructor(){super(...arguments),this.clientId=null,this.redirectUrl=null,this.defaultScopes=["tweet.read","users.read"],this.forceLogin=!1,this.TOKENS_KEY="capgo_social_login_twitter_tokens_v1",this.STATE_PREFIX="capgo_social_login_twitter_state_"}async initialize(e,t,r,o,i){this.clientId=e,this.redirectUrl=null!=t?t:null,(null==r?void 0:r.length)&&(this.defaultScopes=r),this.forceLogin=null!=o&&o,this.audience=null!=i?i:void 0}async login(e){var t,r,o,n,s,a;if(!this.clientId)throw Error("Twitter Client ID not configured. Call initialize() first.");let l=null!=(r=null!=(t=e.redirectUrl)?t:this.redirectUrl)?r:window.location.origin+window.location.pathname,c=(null==(o=e.scopes)?void 0:o.length)?e.scopes:this.defaultScopes,u=null!=(n=e.state)?n:this.generateState(),h=null!=(s=e.codeVerifier)?s:this.generateCodeVerifier(),p=await this.generateCodeChallenge(h);this.persistPendingLogin(u,{codeVerifier:h,redirectUri:l,scopes:c}),localStorage.setItem(i.OAUTH_STATE_KEY,JSON.stringify({provider:"twitter",state:u}));let g=new URLSearchParams({response_type:"code",client_id:this.clientId,redirect_uri:l,scope:c.join(" "),state:u,code_challenge:p,code_challenge_method:"S256"});(null!=(a=e.forceLogin)?a:this.forceLogin)===!0&&g.set("force_login","true"),this.audience&&g.set("audience",this.audience);let f=`https://x.com/i/oauth2/authorize?${g.toString()}`,w=window.screenX+(window.outerWidth-500)/2,v=window.screenY+(window.outerHeight-650)/2,m=window.open(f,"XLogin",`width=500,height=650,left=${w},top=${v},popup=1`);return new Promise((e,t)=>
1{if(!m)return void t(Error("Unable to open login window. Please allow popups."));let r=`twitter_oauth_${u}`,o=null;try{o=new BroadcastChannel(r)}catch(e){}let i=(e,t,r)=>{window.removeEventListener("message",e),clearTimeout(t),clearInterval(r),o&&o.close()},n=r=>{if((null==r?void 0:r.type)==="oauth-response"){if((null==r?void 0:r.provider)&&"twitter"!==r.provider)return!1;i(s,a,l);let{provider:t,type:o}=r;return e({provider:"twitter",result:d(r,["provider","type"])}),!0}return(null==r?void 0:r.type)==="oauth-error"&&(null==r||!r.provider||"twitter"===r.provider)&&(i(s,a,l),t(Error(r.error||"Twitter login was cancelled.")),!0)};o&&(o.onmessage=e=>{n(e.data)});let s=e=>{e.origin===window.location.origin&&n(e.data)};window.addEventListener("message",s);let a=window.setTimeout(()=>{i(s,a,l);try{m.close()}catch(e){}t(Error("Twitter login timed out."))},3e5),l=window.setInterval(()=>{try{m.closed&&(i(s,a,l),t(Error("Twitter login window was closed.")))}catch(e){clearInterval(l)}},1e3)})}async logout(){localStorage.removeItem(this.TOKENS_KEY)}async isLoggedIn(){let e=this.getStoredTokens();if(!e)return{isLoggedIn:!1};let t=e.expiresAt>Date.now();return t||localStorage.removeItem(this.TOKENS_KEY),{isLoggedIn:t}}async getAuthorizationCode(){let e=this.getStoredTokens();if(!e)throw Error("Twitter access token is not available.");return{accessToken:e.accessToken}}async refresh(){let e=this.getStoredTokens();if(!(null==e?void 0:e.refreshToken))throw Error("No Twitter refresh token is available. Include offline.access scope to receive one.");await this.refreshWithRefreshToken(e.refreshToken)}async handleOAuthRedirect(e,t){let r=e.searchParams,o=null!=t?t:r.get("state");if(!o)return null;let n=this.consumePendingLogin(o);if(!n)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:"Twitter login session expired or state mismatch."};let s=r.get("error");if(s)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:r.get("error_description")||s};let a=r.get("code");if(!a)return localStorage.removeItem(i.OAUTH_STATE_KEY),{error:"Twitter authorization code missing from redirect."};try{let e=await this.exchangeAuthorizationCode(a,n),t=await this.fetchProfile(e.access_token),r=Date.now()+1e3*e.expires_in,o=e.scope.split(" ").filter(Boolean);return this.persistTokens({accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:r,scope:o,tokenType:e.token_type,userId:t.id,profile:t}),{provider:"twitter",result:{accessToken:{token:e.access_token,tokenType:e.token_type,expires:new Date(r).toISOString(),userId:t.id},refreshToken:e.refresh_token,scope:o,tokenType:e.token_type,expiresIn:e.expires_in,profile:t}}}catch(e){if(e instanceof Error)return{error:e.message};return{error:"Twitter login failed unexpectedly."}}finally{localStorage.removeItem(i.OAUTH_STATE_KEY)}}async exchangeAuthorizationCode(e,t){var r;let o=new URLSearchParams({grant_type:"authorization_code",client_id:null!=(r=this.clientId)?r:"",code:e,redirect_uri:t.redirectUri,code_verifier:t.codeVerifier}),i=await fetch("https://api.x.com/2/oauth2/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()});if(!i.ok){let e=await i.text();throw Error(`Twitter token exchange failed (${i.status}): ${e}`)}return await i.json()}async refreshWithRefreshToken(e){var t,r;let o=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:null!=(t=this.clientId)?t:""}),i=await fetch("https://api.x.com/2/oauth2/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()});if(!i.ok){let e=await i.text();throw Error(`Twitter refresh failed (${i.status}): ${e}`)}let n=await i.json(),s=await this.fetchProfile(n.access_token),a=Date.now()+1e3*n.expires_in,l=n.scope.split(" ").filter(Boolean);this.persistTokens({accessToken:n.access_token,refreshToken:null!=(r=n.refresh_token)?r:e,expiresAt:a,scope:l,tokenType:n.token_type,userId:s.id,profile:s})}async fetchProfile(e){var t,r,o,i;let n=await fetch("https://api.x.com/2/users/me?user.fields=profile_image_url,verified,name,username",{headers:{Authorization:`Bearer ${e}`}});if(!n.ok){let e=await n.text();throw Error(`Unable to fetch Twitter profile (${n.status}): ${e}`)}let s=await n.json();if(!s.data)throw Error("Twitter profile payload is missing data.");return{id:s.data.id,username:s.data.username,name:null!=(t=s.data.name)?t:null,profileImageUrl:null!=(r=s.data.profile_image_url)?r:null,verified:null!=(o=s.data.verified)&&o,email:null!=(i=s.data.email)?i:null}}persistTokens(e){localStorage.setItem(this.TOKENS_KEY,JSON.stringify(e))}getStoredTokens(){let e=localStorage.getItem(this.TOKENS_KEY);if(!e)return null;try{return JSON.parse(e)}catch(e){return console.warn("Failed to parse stored Twitter tokens",e),null}}persistPendingLogin(e,t){localStorage.setItem(`${this.STATE_PREFIX}${e}`,JSON.stringify(t))}consumePendingLogin(e){let t=`${this.STATE_PREFIX}${e}`,r=localStorage.getItem(t);if(localStorage.removeItem(t),!r)return null;try{return JSON.parse(r)}catch(e){return console.warn("Failed to parse pending Twitter login payload",e),null}}generateState(){return[...crypto.getRandomValues(new Uint8Array(16))].map(e=>e.toString(16).padStart(2,"0")).join("")}generateCodeVerifier(){let e=new Uint8Array(64);return crypto.getRandomValues(e),Array.from(e).map(e=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"[e%66]).join("")}async generateCodeChallenge(e){let t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return this.base64UrlEncode(new Uint8Array(r))}base64UrlEncode(e){let t="";
1return e.forEach(e=>t+=String.fromCharCode(e)),btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}class h extends o.E_{constructor(){super(),this.googleProvider=new a,this.appleProvider=new n,this.facebookProvider=new s,this.twitterProvider=new u,this.oauth2Provider=new c;let e=!!localStorage.getItem(h.OAUTH_STATE_KEY),t=!!window.opener||h.POPUP_WINDOW_NAMES.has(window.name);e&&t&&this.finishOAuthRedirectInPopup().catch(e=>{console.error("Failed to finish OAuth redirect",e);try{window.close()}catch(e){}})}async parseRedirectResult(){var e;let t,r,o=new URL(window.location.href),i=localStorage.getItem(h.OAUTH_STATE_KEY),n=null;if(i)try{let o=JSON.parse(i);n=null!=(e=o.provider)?e:null,t=o.state,r=o.nonce}catch(e){n="true"===i?"google":null}let s=null;switch(n){case"twitter":s=await this.twitterProvider.handleOAuthRedirect(o,t);break;case"oauth2":s=await this.oauth2Provider.handleOAuthRedirect(o,t);break;default:s=this.googleProvider.handleOAuthRedirect(o)}return{provider:n,state:t,nonce:r,result:s}}async finishOAuthRedirectInPopup(){var e;let t,r=await this.parseRedirectResult(),o=r.result;if(o){t="error"in o?{type:"oauth-error",provider:null!=(e=r.provider)?e:null,error:o.error}:Object.assign({type:"oauth-response",provider:o.provider},o.result);try{window.opener&&window.opener.postMessage(t,window.location.origin)}catch(e){console.log("postMessage to opener failed, using BroadcastChannel")}try{let e=null;if("oauth2"===r.provider&&r.state?e=`oauth2_${r.state}`:"twitter"===r.provider&&r.state?e=`twitter_oauth_${r.state}`:"google"===r.provider&&r.nonce&&(e=`google_oauth_${r.nonce}`),e){let r=new BroadcastChannel(e);r.postMessage(t),r.close()}}catch(e){console.log("BroadcastChannel not available")}window.close()}}async initialize(e){var t,r,o,i;let n=[];(null==(t=e.google)?void 0:t.webClientId)&&n.push(this.googleProvider.initialize(e.google.webClientId,e.google.mode,e.google.hostedDomain,e.google.redirectUrl)),(null==(r=e.apple)?void 0:r.clientId)&&n.push(this.appleProvider.initialize(e.apple.clientId,e.apple.redirectUrl,e.apple.useProperTokenExchange)),(null==(o=e.facebook)?void 0:o.appId)&&n.push(this.facebookProvider.initialize(e.facebook.appId,e.facebook.locale)),(null==(i=e.twitter)?void 0:i.clientId)&&n.push(this.twitterProvider.initialize(e.twitter.clientId,e.twitter.redirectUrl,e.twitter.defaultScopes,e.twitter.forceLogin,e.twitter.audience)),e.oauth2&&Object.keys(e.oauth2).length>0&&n.push(this.oauth2Provider.initializeProviders(e.oauth2)),await Promise.all(n)}async login(e){switch(e.provider){case"google":return this.googleProvider.login(e.options);case"apple":return this.appleProvider.login(e.options);case"facebook":return this.facebookProvider.login(e.options);case"twitter":return this.twitterProvider.login(e.options);case"oauth2":return this.oauth2Provider.login(e.options);default:throw Error(`Login for ${e.provider} is not implemented on web`)}}async logout(e){switch(e.provider){case"google":return this.googleProvider.logout();case"apple":return this.appleProvider.logout();case"facebook":return this.facebookProvider.logout();case"twitter":return this.twitterProvider.logout();case"oauth2":if(!e.providerId)throw Error("providerId is required for oauth2 logout");return this.oauth2Provider.logout(e.providerId);default:throw Error(`Logout for ${e.provider} is not implemented`)}}async isLoggedIn(e){switch(e.provider){case"google":return this.googleProvider.isLoggedIn();case"apple":return this.appleProvider.isLoggedIn();case"facebook":return this.facebookProvider.isLoggedIn();case"twitter":return this.twitterProvider.isLoggedIn();case"oauth2":if(!e.providerId)throw Error("providerId is required for oauth2 isLoggedIn");return this.oauth2Provider.isLoggedIn(e.providerId);default:throw Error(`isLoggedIn for ${e.provider} is not implemented`)}}async getAuthorizationCode(e){switch(e.provider){case"google":return this.googleProvider.getAuthorizationCode();case"apple":return this.appleProvider.getAuthorizationCode();case"facebook":return this.facebookProvider.getAuthorizationCode();case"twitter":return this.twitterProvider.getAuthorizationCode();case"oauth2":if(!e.providerId)throw Error("providerId is required for oauth2 getAuthorizationCode");return this.oauth2Provider.getAuthorizationCode(e.providerId);default:throw Error(`getAuthorizationCode for ${e.provider} is not implemented`)}}async refresh(e){switch(e.provider){case"google":return this.googleProvider.refresh();case"apple":return this.appleProvider.refresh();case"facebook":return this.facebookProvider.refresh(e.options);case"twitter":return this.twitterProvider.refresh();case"oauth2":{let t=e.options;if(!(null==t?void 0:t.providerId))throw Error("providerId is required for oauth2 refresh");return this.oauth2Provider.refresh(t.providerId)}default:throw Error(`Refresh for ${e.provider} is not implemented`)}}async providerSpecificCall(e){throw Error(`Provider specific call for ${e.call} is not implemented`)}async refreshToken(e){if("oauth2"!==e.provider)throw Error("refreshToken is only implemented for oauth2 on web");return this.oauth2Provider.refreshToken(e.providerId,e.refreshToken,e.additionalParameters)}async handleRedirectCallback(){let e=(await this.parseRedirectResult()).result;if(!e)return null;if("error"in e)throw Error(e.error);return e}async decodeIdToken(e){var t;let r=null!=(t=null==e?void 0:e.idToken)?t:null==e?void 0:e.token;if(!r)throw Error("idToken (or token) is required");return{claims:this.oauth2Provider.decodeIdToken(r)}}async getAccessTokenExpirationDate(e){if("number"!=typeof(null==e?void 0:e.accessTokenExpirationDate))throw Error("accessTokenExpirationDate is required");return{date:new Date(e.accessTokenExpirationDate).toISOString()}}async isAccessTokenAvailable(e){var t;let r=null!=(t=null==e?void 0:e.accessToken)?t:null;return{isAvailable:"string"==typeof r&&r.length>0}}async isAccessTokenExpired(e){if("number"!=typeof(null==e?void 0:e.accessTokenExpirationDate))throw Error("accessTokenExpirationDate is required");return{isExpired:e.accessTokenExpirationDate<=Date.now()}}async isRefreshTokenAvailable(e){var t;let r=null!=(t=null==e?void 0:e.refreshToken)?t:null;return{isAvailable:"string"==typeof r&&r.length>0}}async getPluginVersion(){return{version:"web"}}
1async openSecureWindow(e){let t=[["width",600],["height",550],["left",screen.width/2-300],["top",screen.height/2-275]].map(e=>e.join("=")).join(","),r=window.open(e.authEndpoint,"Authorization",t);return"function"==typeof r.focus&&r.focus(),new Promise((t,r)=>{let o=new BroadcastChannel(e.broadcastChannelName||"oauth-channel");o.addEventListener("message",i=>{i.data.startsWith(e.redirectUri)?(o.close(),t({redirectedUri:i.data})):(o.close(),r(Error("Redirect URI does not match, expected "+e.redirectUri+" but got "+i.data)))}),setTimeout(()=>{o.close(),r(Error("The sign-in flow timed out"))},3e5)})}}h.OAUTH_STATE_KEY="social_login_oauth_pending",h.POPUP_WINDOW_NAMES=new Set(["OAuth2Login","XLogin","Google Sign In","Authorization"])}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.