1import{W as e}from"./admin-components-Cjgks34q.js";import"./react-vendor-DLyJhTBa.js";import"./ui-vendor-DgRdf4fM.js";class t extends e{constructor(){super()}parseJwt(e){const t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),o=decodeURIComponent(atob(t).split("").map(e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(o)}async loadScript(e){return new Promise((t,o)=>{const r=document.createElement("script");r.src=e,r.async=!0,r.onload=()=>{t()},r.onerror=o,document.body.appendChild(r)})}}t.OAUTH_STATE_KEY="social_login_oauth_pending";class o extends t{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,o=!1){this.clientId=e,this.redirectUrl=t||null,this.useProperTokenExchange=o,e&&await this.loadAppleScript()}async login(e){if(!this.clientId)throw new Error("Apple Client ID not set. Call initialize() first.");if(!this.scriptLoaded)throw new Error("Apple Sign-In script not loaded.");return new Promise((t,o)=>{var r,i;AppleID.auth.init({clientId:null!==(r=this.clientId)&&void 0!==r?r:"",scope:(null===(i=e.scopes)||void 0===i?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 o,r,i,n,s;let a=null;a=this.useProperTokenExchange?null:{token:e.authorization.code||""};const l=Object.assign({profile:{user:e.user||"",email:(null===(o=e.user)||void 0===o?void 0:o.email)||null,givenName:(null===(i=null===(r=e.user)||void 0===r?void 0:r.name)||void 0===i?void 0:i.firstName)||null,familyName:(null===(s=null===(n=e.user)||void 0===n?void 0:n.name)||void 0===s?void 0:s.lastName)||null},accessToken:a,idToken:e.authorization.id_token||null},this.useProperTokenExchange&&{authorizationCode:e.authorization.code});t({provider:"apple",result:l})}).catch(e=>{o(e)})})}async logout(){}async isLoggedIn(){return{isLoggedIn:!1}}async getAuthorizationCode(){throw new Error("Apple authorization code not available")}async refresh(){}async loadAppleScript(){if(!this.scriptLoaded)return this.loadScript(this.scriptUrl).then(()=>{this.scriptLoaded=!0})}}class r extends t{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 new Error("Facebook App ID not set. Call initialize() first.");return new Promise((t,o)=>{FB.login(e=>{"connected"===e.status?FB.api("/me",{fields:"id,name,email,picture"},o=>{var r,i;const n={accessToken:{token:e.authResponse.accessToken,userId:e.authResponse.userID},profile:{userID:o.id,name:o.name,email:o.email||null,imageURL:(null===(i=null===(r=o.picture)||void 0===r?void 0:r.data)||void 0===i?void 0:i.url)||null,friendIDs:[],birthday:null,ageRange:null,gender:null,location:null,hometown:null,profileURL:null},idToken:null};t({provider:"facebook",result:n})}):o(new 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(o=>{var r;"connected"===o.status?e({accessToken:(null===(r=o.authResponse)||void 0===r?void 0:r.accessToken)||""}):t(new Error("No Facebook authorization code available"))})})}async refresh(e){await this.login(e)}async loadFacebookScript(e){if(this.scriptLoaded)return;const 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 i extends t{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,o,r){this.clientId=e,t&&(this.loginType=t),this.hostedDomain=o,this.redirectUrl=r}async login(e){if(!this.clientId)throw new 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"];const o=e.nonce||Math.random().toString(36).substring(2);return this.traditionalOAuth({scopes:t,nonce:o,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");const 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");const e=this.getGoogleState();if(!e)return{isLoggedIn:!1};try{const o=await this.accessTokenIsValid(e.accessToken),r=this.idTokenValid(e.idToken);if(o&&r)return{isLoggedIn:!0};try{await this.rawLogoutGoogle(e.accessToken,!1)}catch(t){}return{isLoggedIn:!1}}catch(t){return Promise.reject(t)}}async getAuthorizationCode(){if("offline"===this.loginType)return Promise.reject("Offline login doesn't store tokens. getAuthorizationCode is not available");const e=this.getGoogleState();if(!e)throw new Error("No Google authorization code available");try{const o=await this.accessTokenIsValid(e.accessToken),r=this.idTokenValid(e.idToken);if(o&&r)return{accessToken:e.accessToken,jwt:e.idToken};try{await this.rawLogoutGoogle(e.accessToken,!1)}catch(t){}throw new Error("No Google authorization code available")}catch(t){return Promise.reject(t)}}async refresh(){return Promise.reject("Not implemented")}handleOAuthRedirect(e){const o=e.searchParams,r=o.get("error");
1if(r){localStorage.removeItem(t.OAUTH_STATE_KEY);return{error:o.get("error_description")||r}}const i=o.get("code");if(i&&o.has("scope"))return{provider:"google",result:{serverAuthCode:i,responseType:"offline"}};const n=e.hash.substring(1);if(!n)return null;const s=new URLSearchParams(n),a=s.get("error");if(a){localStorage.removeItem(t.OAUTH_STATE_KEY);return{error:s.get("error_description")||a}}const l=s.get("access_token"),c=s.get("id_token");if(l&&c){localStorage.removeItem(t.OAUTH_STATE_KEY);const 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){const t=`${this.GOOGLE_TOKEN_REQUEST_URL}?access_token=${encodeURIComponent(e)}`;try{const e=await fetch(t);if(!e.ok)return!1;const r=await e.text();if(!r)throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);let i;try{i=JSON.parse(r)}catch(o){throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${o}`)}const n=i.expires_in;if(null==n)throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`);let s;try{if(s=parseInt(n,10),isNaN(s))throw new Error("'expires_in' is not a valid integer")}catch(o){throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${n} is not a valid integer. Error: ${o}`)}return s>5}catch(r){throw r}}idTokenValid(e){try{const t=this.parseJwt(e),o=Math.ceil(Date.now()/1e3)+5;return t.exp&&o<t.exp}catch(t){return!1}}async rawLogoutGoogle(e,t=null){if(null===t&&(t=await this.accessTokenIsValid(e)),!0!==t)this.clearStateGoogle();else try{await fetch(`https://accounts.google.com/o/oauth2/revoke?token=${encodeURIComponent(e)}`),this.clearStateGoogle()}catch(o){}}persistStateGoogle(e,t){try{window.localStorage.setItem(this.GOOGLE_STATE_KEY,JSON.stringify({accessToken:e,idToken:t}))}catch(o){}}clearStateGoogle(){try{window.localStorage.removeItem(this.GOOGLE_STATE_KEY)}catch(e){}}getGoogleState(){try{const e=window.localStorage.getItem(this.GOOGLE_STATE_KEY);if(!e)return null;const{accessToken:t,idToken:o}=JSON.parse(e);return{accessToken:t,idToken:o}}catch(e){return null}}async traditionalOAuth({scopes:e,hostedDomain:o,nonce:r,prompt:i}){var n;const s=[...new Set([...e||[],"openid"])],a=new URLSearchParams(Object.assign(Object.assign({client_id:null!==(n=this.clientId)&&void 0!==n?n:"",redirect_uri:this.redirectUrl||window.location.origin+window.location.pathname,response_type:"offline"===this.loginType?"code":"token id_token",scope:s.join(" ")},r&&{nonce:r}),{include_granted_scopes:"true",state:"popup"}));void 0!==o&&a.append("hd",o),void 0!==i&&a.append("prompt",i);const l=`https://accounts.google.com/o/oauth2/v2/auth?${a.toString()}`,c=window.screenX+(window.outerWidth-500)/2,d=window.screenY+(window.outerHeight-600)/2;localStorage.setItem(t.OAUTH_STATE_KEY,JSON.stringify({provider:"google",loginType:this.loginType,nonce:r}));const u=window.open(l,"Google Sign In",`width=500,height=600,left=${c},top=${d},popup=1`);let h,p;const g=`google_oauth_${r||Date.now()}`;let w=null;try{w=new BroadcastChannel(g)}catch(f){}return new Promise((e,t)=>{if(!u)return void t(new Error("Failed to open popup"));const o=()=>{window.removeEventListener("message",i),clearInterval(h),clearTimeout(p),w&&w.close()},r=o=>{if("online"===this.loginType){const{accessToken:r,idToken:i}=o;if(r&&i){const t=this.parseJwt(i);this.persistStateGoogle(r.token,i),e({provider:"google",result:{accessToken:{token:r.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(new Error("Invalid OAuth response: missing accessToken or idToken"))}else{const{serverAuthCode:r}=o;if(!r)return void t(new Error("Invalid OAuth response: missing serverAuthCode"));e({provider:"google",result:{responseType:"offline",serverAuthCode:r}})}},i=e=>{var i,n,s,a;if(e.origin===window.location.origin&&!(null===(n=null===(i=e.data)||void 0===i?void 0:i.source)||void 0===n?void 0:n.startsWith("angular")))if("oauth-response"===(null===(s=e.data)||void 0===s?void 0:s.type))o(),r(e.data);else if("oauth-error"===(null===(a=e.data)||void 0===a?void 0:a.type)){o();const r=e.data.error||"User cancelled the OAuth flow";t(new Error(r))}};w&&(w.onmessage=e=>{var i;const n=e.data;if(!(null===(i=null==n?void 0:n.source)||void 0===i?void 0:i.toString().startsWith("angular")))if("oauth-response"===(null==n?void 0:n.type))o(),r(n);else if("oauth-error"===(null==n?void 0:n.type)){o();const e=n.error||"User cancelled the OAuth flow";t(new Error(e))}}),window.addEventListener("message",i),p=setTimeout(()=>{o();try{u.close()}catch(e){}t(new Error("OAuth timeout"))},3e5),h=setInterval(()=>{try{u.closed&&(o(),t(new Error("Popup closed")))}catch(e){clearInterval(h)}},1e3)})}}class n extends t{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 o,r,i,n,s,a,l,c;const d=null!==(o=t.appId)&&void 0!==o?o:t.clientId,u=null!==(r=t.authorizationBaseUrl)&&void 0!==r?r:t.authorizationEndpoint,h=null!==(i=t.accessTokenEndpoint)&&void 0!==i?i:t.tokenEndpoint,p=null!==(n=t.logoutUrl)&&void 0!==n?n:t.endSessionEndpoint,g=null!==(s=t.scope)&&void 0!==s?s:t.scopes;if(!d)throw new Error(`OAuth2 provider '${e}' requires appId (or clientId).`);if(!t.redirectUrl)throw new Error(`OAuth2 provider '${e}' requires redirectUrl.`);if(!u&&!t.issuerUrl)throw new 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)&&void 0!==a?a:"code",pkceEnabled:null===(l=t.pkce
1Enabled)||void 0===l||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)&&void 0!==c&&c}}async ensureDiscovered(e){const t=this.providers.get(e);if(!(null==t?void 0:t.issuerUrl))return;if(t.authorizationBaseUrl&&t.accessTokenEndpoint)return;const o=`${t.issuerUrl.replace(/\/+$/,"")}/.well-known/openid-configuration`,r=await fetch(o);if(!r.ok){const e=await r.text().catch(()=>"");throw new Error(`OAuth2 discovery failed (${r.status}): ${e||o}`)}const i=await r.json(),n=i.authorization_endpoint,s=i.token_endpoint,a=i.end_session_endpoint;t.authorizationBaseUrl||"string"!=typeof n||(t.authorizationBaseUrl=n),t.accessTokenEndpoint||"string"!=typeof s||(t.accessTokenEndpoint=s),t.logoutUrl||"string"!=typeof a||(t.logoutUrl=a),t.logsEnabled}async initializeProviders(e){for(const[t,o]of Object.entries(e)){const e=this.normalizeConfig(t,o);this.providers.set(t,e),e.logsEnabled,await this.ensureDiscovered(t)}}getProvider(e){const t=this.providers.get(e);if(!t)throw new Error(`OAuth2 provider '${e}' not configured. Call initialize() first.`);return t}getTokensKey(e){return`${this.TOKENS_KEY_PREFIX}${e}`}async login(e){var o,r,i,n,s,a,l,c,d;const{providerId:u}=e,h=this.getProvider(u);await this.ensureDiscovered(u);const p=null!==(o=e.redirectUrl)&&void 0!==o?o:h.redirectUrl,g=this.normalizeScopeValue(null!==(i=null!==(r=e.scope)&&void 0!==r?r:e.scopes)&&void 0!==i?i:h.scope),w=null!==(n=e.state)&&void 0!==n?n:this.generateState(),f=null!==(s=e.codeVerifier)&&void 0!==s?s:this.generateCodeVerifier(),v=new URLSearchParams({response_type:h.responseType,client_id:h.appId,redirect_uri:p,state:w});g&&v.set("scope",g);const m=Object.assign(Object.assign({},null!==(a=h.additionalParameters)&&void 0!==a?a:{}),null!==(l=e.additionalParameters)&&void 0!==l?l:{}),T=null!==(c=e.loginHint)&&void 0!==c?c:h.loginHint,k=null!==(d=e.prompt)&&void 0!==d?d:h.prompt;if(T&&!("login_hint"in m)&&(m.login_hint=T),k&&!("prompt"in m)&&(m.prompt=k),"code"===h.responseType&&h.pkceEnabled){const e=await this.generateCodeChallenge(f);v.set("code_challenge",e),v.set("code_challenge_method","S256")}for(const[t,I]of Object.entries(m))void 0!==I&&v.set(t,I);if(this.persistPendingLogin(w,{providerId:u,codeVerifier:f,redirectUri:p,scope:g}),localStorage.setItem(t.OAUTH_STATE_KEY,JSON.stringify({provider:"oauth2",providerId:u,state:w})),!h.authorizationBaseUrl)throw new Error(`OAuth2 provider '${u}' is missing authorizationBaseUrl (discovery may have failed).`);const _=`${h.authorizationBaseUrl}?${v.toString()}`;if(h.logsEnabled,"redirect"===e.flow)return window.location.assign(_),new Promise(()=>{});const E=window.screenX+(window.outerWidth-500)/2,y=window.screenY+(window.outerHeight-650)/2,S=window.open(_,"OAuth2Login",`width=500,height=650,left=${E},top=${y},popup=1`);return new Promise((e,t)=>{if(!S)return void t(new Error("Unable to open login window. Please allow popups."));const o=`oauth2_${w}`;let r=null;try{r=new BroadcastChannel(o)}catch(c){h.logsEnabled}const i=(e,t,o)=>{window.removeEventListener("message",e),clearTimeout(t),clearInterval(o),r&&r.close()},n=o=>{if("oauth-response"===(null==o?void 0:o.type)){if((null==o?void 0:o.provider)&&"oauth2"!==o.provider)return!1;if((null==o?void 0:o.providerId)&&o.providerId!==u)return!1;i(s,a,l);const t=o,{provider:r,type:n}=t,c=function(e,t){var o={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(o[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i<r.length;i++)t.indexOf(r[i])<0&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(o[r[i]]=e[r[i]])}return o}(t,["provider","type"]);return e({provider:"oauth2",result:c}),!0}return"oauth-error"===(null==o?void 0:o.type)&&((!(null==o?void 0:o.provider)||"oauth2"===o.provider)&&(i(s,a,l),t(new Error(o.error||"OAuth2 login
1was cancelled.")),!0))};r&&(r.onmessage=e=>{n(e.data)});const s=e=>{e.origin===window.location.origin&&n(e.data)};window.addEventListener("message",s);const a=window.setTimeout(()=>{i(s,a,l);try{S.close()}catch(c){}t(new Error("OAuth2 login timed out."))},3e5),l=window.setInterval(()=>{try{S.closed&&(i(s,a,l),t(new Error("OAuth2 login window was closed.")))}catch(c){clearInterval(l),h.logsEnabled}},1e3)})}async logout(e){await this.ensureDiscovered(e);const t=this.providers.get(e),o=this.getStoredTokens(e);if(localStorage.removeItem(this.getTokensKey(e)),null==t?void 0:t.logoutUrl)try{const e=new URL(t.logoutUrl);(null==o?void 0:o.idToken)&&e.searchParams.set("id_token_hint",o.idToken);const r=t.postLogoutRedirectUrl;if(r&&e.searchParams.set("post_logout_redirect_uri",r),t.additionalLogoutParameters)for(const[o,i]of Object.entries(t.additionalLogoutParameters))e.searchParams.set(o,i);window.open(e.toString(),"_blank")}catch(r){window.open(t.logoutUrl,"_blank")}}async isLoggedIn(e){const t=this.getStoredTokens(e);if(!t)return{isLoggedIn:!1};const o=t.expiresAt>Date.now();return o||localStorage.removeItem(this.getTokensKey(e)),{isLoggedIn:o}}async getAuthorizationCode(e){const t=this.getStoredTokens(e);if(!t)throw new 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,o){var r,i,n,s,a,l;await this.ensureDiscovered(e);const c=this.getProvider(e),d=this.getStoredTokens(e),u=null!=t?t:null==d?void 0:d.refreshToken;if(!u)throw new Error(`No OAuth2 refresh token is available for provider '${e}'. Include offline_access scope to receive one.`);if(!c.accessTokenEndpoint)throw new Error(`No accessTokenEndpoint configured for provider '${e}'.`);const h=await this.refreshWithRefreshToken(e,u,o),p=h.expires_in?Date.now()+1e3*h.expires_in:Date.now()+36e5,g=null!==(n=null!==(i=null===(r=h.scope)||void 0===r?void 0:r.split(" ").filter(Boolean))&&void 0!==i?i:null==d?void 0:d.scope)&&void 0!==n?n:[];let w=null;c.resourceUrl&&(w=await this.fetchResource(e,h.access_token));const f=null!==(s=h.refresh_token)&&void 0!==s?s:u;return this.persistTokens(e,{accessToken:h.access_token,refreshToken:f,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:f},idToken:null!==(a=h.id_token)&&void 0!==a?a:null,refreshToken:null!=f?f:null,resourceData:w,scope:g,tokenType:h.token_type,expiresIn:null!==(l=h.expires_in)&&void 0!==l?l:null}}async handleOAuthRedirect(e,o){var r,i,n,s,a;const l=new URLSearchParams(e.search);new URLSearchParams(e.hash.slice(1)).forEach((e,t)=>{l.set(t,e)});const c=null!=o?o:l.get("state");if(!c)return null;const d=this.consumePendingLogin(c);if(!d)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:"OAuth2 login session expired or state mismatch."};const{providerId:u}=d;await this.ensureDiscovered(u);const h=this.providers.get(u);if(!h)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:`OAuth2 provider '${u}' configuration not found.`};const p=l.get("error");if(p)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:l.get("error_description")||p};try{let e;if(l.has("code")){const o=l.get("code");if(!o)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:"OAuth2 authorization code missing from redirect."};e=await this.exchangeAuthorizationCode(u,o,d)}else{if(!l.has("access_token"))return localStorage.removeItem(t.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}}const o=e.expires_in?Date.now()+1e3*e.expires_in:Date.now()+36e5,c=null!==(i=null===(r=e.scope)||void 0===r?void 0:r.split(" ").filter(Boolean))&&void 0!==i?i:[];let 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:o,scope:c,tokenType:e.token_type}),{provider:"oauth2",result:{providerId:u,accessToken:{token:e.access_token,tokenType:e.token_type,expires:new Date(o).toISOString(),refreshToken:e.refresh_token},idToken:null!==(n=e.id_token)&&void 0!==n?n:null,refreshToken:null!==(s=e.refresh_token)&&void 0!==s?s:null,resourceData:p,scope:c,tokenType:e.token_type,expires
1In:null!==(a=e.expires_in)&&void 0!==a?a:null}}}catch(g){return g instanceof Error?{error:g.message}:{error:"OAuth2 login failed unexpectedly."}}finally{localStorage.removeItem(t.OAUTH_STATE_KEY)}}async exchangeAuthorizationCode(e,t,o){const r=this.getProvider(e);if(!r.accessTokenEndpoint)throw new Error(`No accessTokenEndpoint configured for provider '${e}'.`);const i=new URLSearchParams({grant_type:"authorization_code",client_id:r.appId,code:t,redirect_uri:o.redirectUri});if(r.pkceEnabled&&i.set("code_verifier",o.codeVerifier),r.additionalTokenParameters)for(const[s,a]of Object.entries(r.additionalTokenParameters))i.set(s,a);r.logsEnabled;const n=await fetch(r.accessTokenEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!n.ok){const e=await n.text();throw new Error(`OAuth2 token exchange failed (${n.status}): ${e}`)}return await n.json()}async refreshWithRefreshToken(e,t,o){const r=this.getProvider(e);if(!r.accessTokenEndpoint)throw new Error(`No accessTokenEndpoint configured for provider '${e}'.`);const i=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:r.appId});if(r.additionalTokenParameters)for(const[s,a]of Object.entries(r.additionalTokenParameters))i.set(s,a);if(o)for(const[s,a]of Object.entries(o))i.set(s,a);const n=await fetch(r.accessTokenEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!n.ok){const e=await n.text();throw new Error(`OAuth2 refresh failed (${n.status}): ${e}`)}return await n.json()}async fetchResource(e,t){const o=this.getProvider(e);if(!o.resourceUrl)throw new Error(`No resourceUrl configured for provider '${e}'.`);const r={Authorization:`Bearer ${t}`};o.additionalResourceHeaders&&Object.assign(r,o.additionalResourceHeaders);const i=await fetch(o.resourceUrl,{headers:r});if(!i.ok){const e=await i.text();throw new 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){const t=localStorage.getItem(this.getTokensKey(e));if(!t)return null;try{return JSON.parse(t)}catch(o){return null}}persistPendingLogin(e,t){localStorage.setItem(`${this.STATE_PREFIX}${e}`,JSON.stringify(t))}consumePendingLogin(e){const t=`${this.STATE_PREFIX}${e}`,o=localStorage.getItem(t);if(localStorage.removeItem(t),!o)return null;try{return JSON.parse(o)}catch(r){return null}}generateState(){return[...crypto.getRandomValues(new Uint8Array(16))].map(e=>e.toString(16).padStart(2,"0")).join("")}generateCodeVerifier(){const e=new Uint8Array(64);return crypto.getRandomValues(e),Array.from(e).map(e=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"[e%66]).join("")}async generateCodeChallenge(e){const t=(new TextEncoder).encode(e),o=await crypto.subtle.digest("SHA-256",t);return this.base64UrlEncode(new Uint8Array(o))}base64UrlEncode(e){let t="";return e.forEach(e=>t+=String.fromCharCode(e)),btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}decodeIdToken(e){const t=e.split(".");if(t.length<2)throw new Error("Invalid JWT: missing parts");const o=t[1].replace(/-/g,"+").replace(/_/g,"/"),r=o+"=".repeat((4-o.length%4)%4),i=atob(r);return JSON.parse(i)}getAccessTokenExpirationDate(e){const t=this.getStoredTokens(e);return(null==t?void 0:t.expiresAt)?{expirationDate:new Date(t.expiresAt).toISOString()}:{expirationDate:null}}isAccessTokenAvailable(e){const t=this.getStoredTokens(e);return{isAvailable:!!(null==t?void 0:t.accessToken)}}isAccessTokenExpired(e){const t=this.getStoredTokens(e);return(null==t?void 0:t.expiresAt)?{isExpired:t.expiresAt<=Date.now()}:{isExpired:!0}}isRefreshTokenAvailable(e){const t=this.getStoredTokens(e);return{isAvailable:!!(null==t?void 0:t.refreshToken)}}}class s extends t{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,o,r,i){this.clientId=e,this.redirectUrl=null!=t?t:null,(null==o?void 0:o.length)&&(this.defaultScopes=o),this.forceLogin=null!=r&&r,this.audience=null!=i?i:void 0}async login(e){var o,r,i,n,s,a;if(!this.clientId)throw new Error("Twitter Client ID not configured. Call initialize() first.");const l=null!==(r=null!==(o=e.redirectUrl)&&void 0!==o?o:this.redirectUrl)&&void 0!==r?r:window.location.origin+window.location.pathname,c=(null===(i=e.scopes)||void 0===i?void 0:i.length)?e.scopes:this.defaultScopes,d=null!==(n=e.state)&&void 0!==n?n:this.generateState(),u=null!==(s=e.codeVerifier)&&void 0!==s?s:this.generateCodeVerifier(),h=await this.generateCodeChallenge(u);this.persistPendingLogin(d,{codeVerifier:u,redirectUri:l,scopes:c}),localStorage.setItem(t.OAUTH_STATE_KEY,JSON.stringify({provider:"twitter",state:d}));const p=new URLSearchParams({response_type:"code",client_id:this.clientId,redirect_uri:l,scope:c.join(" "),state:d,code_challenge:h,code_challenge_method:"S256"});!0===(null!==(a=e.forceLogin)&&void 0!==a?a:this.forceLogin)&&p.set("force_login","true"),this.audience&&p.set("audience",this.audience);const g=`https://x.com/i/oauth2/authorize?${p.toString()}`,w=window.screenX+(window.outerWidth-500)/2,f=window.screenY+(window.outerHeight-650)/2,v=window.open(g,"XLogin",`width=500,height=650,left=${w},top=${f},popup=1`);return new Promise((e,t)=>
1{if(!v)return void t(new Error("Unable to open login window. Please allow popups."));const o=`twitter_oauth_${d}`;let r=null;try{r=new BroadcastChannel(o)}catch(c){}const i=(e,t,o)=>{window.removeEventListener("message",e),clearTimeout(t),clearInterval(o),r&&r.close()},n=o=>{if("oauth-response"===(null==o?void 0:o.type)){if((null==o?void 0:o.provider)&&"twitter"!==o.provider)return!1;i(s,a,l);const t=o,{provider:r,type:n}=t,c=function(e,t){var o={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(o[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i<r.length;i++)t.indexOf(r[i])<0&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(o[r[i]]=e[r[i]])}return o}(t,["provider","type"]);return e({provider:"twitter",result:c}),!0}return"oauth-error"===(null==o?void 0:o.type)&&((!(null==o?void 0:o.provider)||"twitter"===o.provider)&&(i(s,a,l),t(new Error(o.error||"Twitter login was cancelled.")),!0))};r&&(r.onmessage=e=>{n(e.data)});const s=e=>{e.origin===window.location.origin&&n(e.data)};window.addEventListener("message",s);const a=window.setTimeout(()=>{i(s,a,l);try{v.close()}catch(c){}t(new Error("Twitter login timed out."))},3e5),l=window.setInterval(()=>{try{v.closed&&(i(s,a,l),t(new Error("Twitter login window was closed.")))}catch(c){clearInterval(l)}},1e3)})}async logout(){localStorage.removeItem(this.TOKENS_KEY)}async isLoggedIn(){const e=this.getStoredTokens();if(!e)return{isLoggedIn:!1};const t=e.expiresAt>Date.now();return t||localStorage.removeItem(this.TOKENS_KEY),{isLoggedIn:t}}async getAuthorizationCode(){const e=this.getStoredTokens();if(!e)throw new Error("Twitter access token is not available.");return{accessToken:e.accessToken}}async refresh(){const e=this.getStoredTokens();if(!(null==e?void 0:e.refreshToken))throw new Error("No Twitter refresh token is available. Include offline.access scope to receive one.");await this.refreshWithRefreshToken(e.refreshToken)}async handleOAuthRedirect(e,o){const r=e.searchParams,i=null!=o?o:r.get("state");if(!i)return null;const n=this.consumePendingLogin(i);if(!n)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:"Twitter login session expired or state mismatch."};const s=r.get("error");if(s)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:r.get("error_description")||s};const a=r.get("code");if(!a)return localStorage.removeItem(t.OAUTH_STATE_KEY),{error:"Twitter authorization code missing from redirect."};try{const e=await this.exchangeAuthorizationCode(a,n),t=await this.fetchProfile(e.access_token),o=Date.now()+1e3*e.expires_in,r=e.scope.split(" ").filter(Boolean);return this.persistTokens({accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:o,scope:r,tokenType:e.token_type,userId:t.id,profile:t}),{provider:"twitter",result:{accessToken:{token:e.access_token,tokenType:e.token_type,expires:new Date(o).toISOString(),userId:t.id},refreshToken:e.refresh_token,scope:r,tokenType:e.token_type,expiresIn:e.expires_in,profile:t}}}catch(l){return l instanceof Error?{error:l.message}:{error:"Twitter login failed unexpectedly."}}finally{localStorage.removeItem(t.OAUTH_STATE_KEY)}}async exchangeAuthorizationCode(e,t){var o;const r=new URLSearchParams({grant_type:"authorization_code",client_id:null!==(o=this.clientId)&&void 0!==o?o:"",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:r.toString()});if(!i.ok){const e=await i.text();throw new Error(`Twitter token exchange failed (${i.status}): ${e}`)}return await i.json()}async refreshWithRefreshToken(e){var t,o;const r=new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:null!==(t=this.clientId)&&void 0!==t?t:""}),i=await fetch("https://api.x.com/2/oauth2/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()});if(!i.ok){const e=await i.text();throw new Error(`Twitter refresh failed (${i.status}): ${e}`)}const n=await i.json(),s=await this.fetchProfile(n.access_token),a=Date.now()+1e3*n.expires_in,l=n.scope.split(" ").filter(
1Boolean);this.persistTokens({accessToken:n.access_token,refreshToken:null!==(o=n.refresh_token)&&void 0!==o?o:e,expiresAt:a,scope:l,tokenType:n.token_type,userId:s.id,profile:s})}async fetchProfile(e){var t,o,r,i;const n=await fetch(`https://api.x.com/2/users/me?user.fields=${["profile_image_url","verified","name","username"].join(",")}`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok){const e=await n.text();throw new Error(`Unable to fetch Twitter profile (${n.status}): ${e}`)}const s=await n.json();if(!s.data)throw new Error("Twitter profile payload is missing data.");return{id:s.data.id,username:s.data.username,name:null!==(t=s.data.name)&&void 0!==t?t:null,profileImageUrl:null!==(o=s.data.profile_image_url)&&void 0!==o?o:null,verified:null!==(r=s.data.verified)&&void 0!==r&&r,email:null!==(i=s.data.email)&&void 0!==i?i:null}}persistTokens(e){localStorage.setItem(this.TOKENS_KEY,JSON.stringify(e))}getStoredTokens(){const e=localStorage.getItem(this.TOKENS_KEY);if(!e)return null;try{return JSON.parse(e)}catch(t){return null}}persistPendingLogin(e,t){localStorage.setItem(`${this.STATE_PREFIX}${e}`,JSON.stringify(t))}consumePendingLogin(e){const t=`${this.STATE_PREFIX}${e}`,o=localStorage.getItem(t);if(localStorage.removeItem(t),!o)return null;try{return JSON.parse(o)}catch(r){return null}}generateState(){return[...crypto.getRandomValues(new Uint8Array(16))].map(e=>e.toString(16).padStart(2,"0")).join("")}generateCodeVerifier(){const e=new Uint8Array(64);return crypto.getRandomValues(e),Array.from(e).map(e=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"[e%66]).join("")}async generateCodeChallenge(e){const t=(new TextEncoder).encode(e),o=await crypto.subtle.digest("SHA-256",t);return this.base64UrlEncode(new Uint8Array(o))}base64UrlEncode(e){let t="";return e.forEach(e=>t+=String.fromCharCode(e)),btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}class a extends e{constructor(){super(),this.googleProvider=new i,this.appleProvider=new o,this.facebookProvider=new r,this.twitterProvider=new s,this.oauth2Provider=new n;const e=!!localStorage.getItem(a.OAUTH_STATE_KEY),t=!!window.opener||a.POPUP_WINDOW_NAMES.has(window.name);e&&t&&this.finishOAuthRedirectInPopup().catch(e=>{try{window.close()}catch(t){}})}async parseRedirectResult(){var e;const t=new URL(window.location.href),o=localStorage.getItem(a.OAUTH_STATE_KEY);let r,i,n=null;if(o)try{const t=JSON.parse(o);n=null!==(e=t.provider)&&void 0!==e?e:null,r=t.state,i=t.nonce}catch(l){n="true"===o?"google":null}let s=null;switch(n){case"twitter":s=await this.twitterProvider.handleOAuthRedirect(t,r);break;case"oauth2":s=await this.oauth2Provider.handleOAuthRedirect(t,r);break;default:s=this.googleProvider.handleOAuthRedirect(t)}return{provider:n,state:r,nonce:i,result:s}}async finishOAuthRedirectInPopup(){var e;const t=await this.parseRedirectResult(),o=t.result;if(!o)return;let r;if("error"in o){r={type:"oauth-error",provider:null!==(e=t.provider)&&void 0!==e?e:null,error:o.error}}else r=Object.assign({type:"oauth-response",provider:o.provider},o.result);try{window.opener&&window.opener.postMessage(r,window.location.origin)}catch(i){}try{let e=null;if("oauth2"===t.provider&&t.state?e=`oauth2_${t.state}`:"twitter"===t.provider&&t.state?e=`twitter_oauth_${t.state}`:"google"===t.provider&&t.nonce&&(e=`google_oauth_${t.nonce}`),e){const t=new BroadcastChannel(e);t.postMessage(r),t.close()}}catch(n){}window.close()}async initialize(e){var t,o,r,i;const n=[];(null===(t=e.google)||void 0===t?void 0:t.webClientId)&&n.push(this.googleProvider.initialize(e.google.webClientId,e.google.mode,e.google.hostedDomain,e.google.redirectUrl)),(null===(o=e.apple)||void 0===o?void 0:o.clientId)&&n.push(this.appleProvider.initialize(e.apple.clientId,e.apple.redirectUrl,e.apple.useProperTokenExchange)),(null===(r=e.facebook)||void 0===r?void 0:r.appId)&&n.push(this.facebookProvider.initialize(e.facebook.appId,e.facebook.locale)),(null===(i=e.twitter)||void 0===i?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 new 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 new Error("providerId is required for oauth2 logout");return this.oauth2Provider.logout(e.providerId);default:throw new 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 new Error("providerId is required for oauth2 isLoggedIn");return this.oauth2Provider.isLoggedIn(e.providerId);default:throw new 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 new Error("providerId is required for oauth2 getAuthorizationCode");return this.oauth2Provider.getAuthorizationCode(e.providerId);default:throw new 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":{const t=e.options;if(!(null==t?void 0:t.providerId))throw new Error("providerId is required for oauth2 refresh");return this.oauth2Provider.refresh(t.providerId)}default:throw new Error(`Refresh for ${e.provider} is not implemented`)}}async providerSpecificCall(e){throw new Error(`Provider specific call for ${e.call} is not implemented`)}async refreshToken(e){if("oauth2"!==e.provider)throw new Error("refreshToken is only implemented for oauth2 on web");return this.oauth2Provider.refreshToken(e.providerId,e.refreshToken,e.additionalParameters)}async handleRedirectCallback(){const e=(await this.parseRedirectResult()).result;if(!e)return null;if("error"in e)throw new Error(e.error);return e}async decodeIdToken(e){var t;const o=null!==(t=null==e?void 0:e.idToken)&&void 0!==t?t:null==e?void 0:e.token;if(!o)throw new Error("idToken (or token) is required");return{claims:this.oauth2Provider.decodeIdToken(o)}}async getAccessTokenExpirationDate(e){if("number"!=typeof(null==e?void 0:e.accessTokenExpirationDate))throw new Error("accessTokenExpirationDate is required");return{date:new Date(e.accessTokenExpirationDate).toISOString()}}async isAccessTokenAvailable(e){var t;const o=null!==(t=null==e?void 0:e.accessToken)&&void 0!==t?t:null;return{isAvailable:"string"==typeof o&&o.length>0}}async isAccessTokenExpired(e){if("number"!=typeof(null==e?void 0:e.accessTokenExpirationDate))throw new Error("accessTokenExpirationDate is required");return{isExpired:e.accessTokenExpirationDate<=Date.now()}}async isRefreshTokenAvailable(e){var t;const o=null!==(t=null==e?void 0:e.refreshToken)&&void 0!==t?t:null;return{isAvailable:"string"==typeof o&&o.length>0}}async getPluginVersion(){return{version:"web"}}async openSecureWindow(e){const t=600,o=550,r=[["width",t],["height",o],["left",screen.width/2-t/2],["top",screen.height/2-o/2]].map(e=>e.join("=")).join(","),i=window.open(e.authEndpoint,"Authorization",r);return"function"==typeof i.focus&&i.focus(),new Promise((t,o)=>{const r=new BroadcastChannel(e.broadcastChannelName||"oauth-channel");r.addEventListener("message",i=>{i.data.startsWith(e.redirectUri)?(r.close(),t({redirectedUri:i.data})):(r.close(),o(new Error("Redirect URI does not match, expected "+e.redirectUri+" but got "+i.data)))}),setTimeout(()=>{r.close(),o(new Error("The sign-in flow timed out"))},3e5)})}}a.OAUTH_STATE_KEY="social_login_oauth_pending",a.POPUP_WINDOW_NAMES=new Set(["OAuth2Login","XLogin","Google Sign In","Authorization"]);export{a as SocialLoginWeb};
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.