@kinde-oss/kinde-auth-react
Version:
Kinde React SDK for authentication
2 lines (1 loc) • 16.2 kB
JavaScript
;var O=(e=>(e.email="email",e.profile="profile",e.openid="openid",e.offline_access="offline",e))(O||{}),L=(e=>(e.none="none",e.create="create",e.login="login",e))(L||{}),A=(e=>(e.organizationDetails="organization_details",e.organizationMembers="organization_members",e.organizationPlanDetails="organization_plan_details",e.organizationPaymentDetails="organization_payment_details",e.organizationPlanSelection="organization_plan_selection",e.profile="profile",e))(A||{}),M=(e=>(e.organizationDetails="organization_details",e.organizationMembers="organization_members",e.organizationPlanDetails="organization_plan_details",e.organizationPaymentDetails="organization_payment_details",e.organizationPlanSelection="organization_plan_selection",e.profile="profile",e))(M||{}),v=(e=>(e.logout="logout",e.login="login",e.register="registration",e.token="token",e.profile="profile",e))(v||{}),p=(e=>(e[e.refreshToken=0]="refreshToken",e[e.cookie=1]="cookie",e))(p||{});const z=e=>{const r=t=>btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"");if(e instanceof ArrayBuffer){const t=new Uint8Array(e),u=String.fromCharCode(...t);return r(u)}const n=new TextEncoder().encode(e),o=String.fromCharCode(...n);return r(o)},x=(e=28)=>{if(crypto){const r=new Uint8Array(e/2);return crypto.getRandomValues(r),Array.from(r,G).join("")}else return J(e)};function G(e){return e.toString(16).padStart(2,"0")}function J(e=28){const r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let n="";const o=r.length;for(let t=0;t<e;t++)n+=r.charAt(Math.floor(Math.random()*o));return n}const W=e=>{e=e.split("?")[1];const r=new URLSearchParams(e);return{accessToken:r.get("access_token"),idToken:r.get("id_token"),expiresIn:+(r.get("expires_in")||0)}},P=e=>e.replace(/\/$/,""),q=(e,r=!1)=>{const n=Array.isArray(e.audience)?e.audience.join(" "):e.audience||"",o={login_hint:e.loginHint,is_create_org:e.isCreateOrg?.toString(),connection_id:e.connectionId,redirect_uri:e.redirectURL?r?e.redirectURL:P(e.redirectURL):void 0,audience:n,scope:e.scope?.join(" ")||"email profile openid offline",prompt:e.prompt,lang:e.lang,org_code:e.orgCode,org_name:e.orgName,has_success_page:e.hasSuccessPage?.toString(),workflow_deployment_id:e.workflowDeploymentId,supports_reauth:e.supportsReauth?.toString(),plan_interest:e.planInterest};return Object.keys(o).forEach(t=>o[t]===void 0&&delete o[t]),o},E=e=>typeof e!="object"||e===null?e:Array.isArray(e)?e.map(r=>E(r)):Object.fromEntries(Object.entries(e).map(([r,n])=>[r.replace(/_([a-z])/g,(o,t)=>t.toUpperCase()),E(n)])),Z=["utm_source","utm_medium","utm_campaign","utm_content","utm_term","gclid","click_id","hsa_acc","hsa_cam","hsa_grp","hsa_ad","hsa_src","hsa_tgt","hsa_kw","hsa_mt","hsa_net","hsa_ver","match_type","keyword","device","ad_group_id","campaign_id","creative","network","ad_position","fbclid","li_fat_id","msclkid","twclid","ttclid"],Q=async(e,r=v.login,n,o)=>{const t=`${e}/oauth2/auth`,u=I();if(n.reauthState)try{const l=E(JSON.parse(atob(n.reauthState)));n={...n,...l},delete n.reauthState}catch(l){const h=l instanceof Error?l.message:"Unknown error";throw new Error(`Error handing reauth state: ${h}`)}if(!n.clientId)throw new Error("Error generating auth URL: Client ID missing");const i={client_id:n.clientId,response_type:n.responseType||"code",...q(n,o?.disableUrlSanitization)};n.state||(n.state=x(32)),u&&u.setSessionItem(s.state,n.state),i.state=n.state,n.nonce||(n.nonce=x(16)),i.nonce=n.nonce,u&&u.setSessionItem(s.nonce,n.nonce);let d="";if(n.codeChallenge)i.code_challenge=n.codeChallenge;else{const{codeVerifier:l,codeChallenge:h}=await X();d=l,u&&u.setSessionItem(s.codeVerifier,l),i.code_challenge=h}i.code_challenge_method="S256",n.codeChallengeMethod&&(i.code_challenge_method=n.codeChallengeMethod),!n.prompt&&r===v.register&&(i.prompt=L.create),n.properties&&Object.keys(n.properties).forEach(l=>{if(!Z.includes(l)){console.warn("Unsupported Property for url generation: ",l);return}const h=n.properties?.[l];h!==void 0&&(i[l]=h)});const c=new URLSearchParams(i).toString();return{url:new URL(`${t}?${c}`),state:i.state,nonce:i.nonce,codeChallenge:i.code_challenge,codeVerifier:d}};async function X(){const e=x(52),r=new TextEncoder().encode(e);let n="";if(!crypto)n=z(btoa(e));else{const o=await crypto.subtle.digest("SHA-256",r);n=z(o)}return{codeVerifier:e,codeChallenge:n}}let T;function N(e,r){if(C(),typeof window>"u")throw new Error("setRefreshTimer requires a browser environment");if(e<=0)throw new Error("Timer duration must be positive");T=window.setTimeout(r,Math.min(e*1e3-1e4,864e5))}function C(){T!==void 0&&(window.clearTimeout(T),T=void 0)}const w={framework:"",frameworkVersion:"",sdkVersion:""},F=async()=>{await I()?.removeItems(s.state,s.nonce,s.codeVerifier)},Y=async({urlParams:e,domain:r,clientId:n,redirectURL:o,autoRefresh:t=!1,onRefresh:u})=>{const i=e.get("state"),d=e.get("code");if(!i||!d)return console.error("Invalid state or code"),{success:!1,error:"Invalid state or code"};const c=I();if(!c)return console.error("No active storage found"),{success:!1,error:"Authentication storage is not initialized"};(!w.framework||!w.frameworkVersion)&&console.warn("Framework and version not set. Please set the framework and version in the config object");const l=await c.getSessionItem(s.state);if(i!==l)return console.error("Invalid state"),{success:!1,error:`Invalid state; supplied ${i}, expected ${l}`};const h=await c.getSessionItem(s.codeVerifier);if(h===null)return console.error("Code verifier not found"),{success:!1,error:"Code verifier not found"};const j={"Content-type":"application/x-www-form-urlencoded; charset=UTF-8"};w.framework&&(j["Kinde-SDK"]=`${w.framework}/${w.sdkVersion}/${w.frameworkVersion}/Javascript`);const H={method:"POST",...!a.useInsecureForRefreshToken&&S(r)?{credentials:"include"}:{},headers:new Headers(j),body:new URLSearchParams({client_id:n,code:d,code_verifier:h,grant_type:"authorization_code",redirect_uri:o})};let _;C();try{if(_=await fetch(`${r}/oauth2/token`,H),!_?.ok){const k=await _.text();return console.error("Token exchange failed:",_.status,k),{success:!1,error:`Token exchange failed: ${_.status} - ${k}`}}}catch(k){return F(),console.error("Token exchange failed:",k),{success:!1,error:`Token exchange failed: ${k}`}}const f=await _.json(),D=y();D&&D.setItems({[s.accessToken]:f.access_token,[s.idToken]:f.id_token,[s.refreshToken]:f.refresh_token}),(a.useInsecureForRefreshToken||!S(r))&&c.setSessionItem(s.refreshToken,f.refresh_token),t&&N(f.expires_in,async()=>{$({domain:r,clientId:n,onRefresh:u})}),F();const B=(k=>(k.search="",k))(new URL(window.location.toString()));return window.history.replaceState(window.history.state,"",B),!f.access_token||!f.id_token||!f.refresh_token?{success:!1,error:"No access token received"}:{success:!0,[s.accessToken]:f.access_token,[s.idToken]:f.id_token,[s.refreshToken]:f.refresh_token}};function ee(e){const r=document.cookie.split("; ").find(n=>n.startsWith(`${e}=`));if(!r)return null;try{const n=r.split("=")[1];return n?decodeURIComponent(n):null}catch(n){return console.error(`Error parsing cookie ${e}:`,n),null}}const re="_kbrte",ne=async({domain:e,clientId:r})=>{if(!e)return{success:!1,error:"Domain is required for authentication check"};if(!r)return{success:!1,error:"Client ID is required for authentication check"};const n=S(e),o=a.useInsecureForRefreshToken;let t=null;return n&&!o&&(t=ee(re)),await $({domain:e,clientId:r,refreshType:t?p.cookie:p.refreshToken})},S=e=>!e.match(/^(?:https?:\/\/)?[a-zA-Z0-9][.-a-zA-Z0-9]*\.kinde\.com$/i);function R(e,r){return r<=0?[]:e.match(new RegExp(`.{1,${r}}`,"g"))||[]}var s=(e=>(e.accessToken="accessToken",e.idToken="idToken",e.refreshToken="refreshToken",e.state="state",e.nonce="nonce",e.codeVerifier="codeVerifier",e))(s||{});class b{async setItems(r){await Promise.all(Object.entries(r).map(([n,o])=>this.setSessionItem(n,o)))}async removeItems(...r){await Promise.all(r.map(n=>this.removeSessionItem(n)))}}class oe extends b{memCache={};async destroySession(){this.memCache={}}async setSessionItem(r,n){if(await this.removeSessionItem(r),typeof n=="string"){R(n,a.maxLength).forEach((o,t)=>{this.memCache[`${a.keyPrefix}${r}${t}`]=o});return}this.memCache[`${a.keyPrefix}${String(r)}0`]=n}async getSessionItem(r){if(this.memCache[`${a.keyPrefix}${String(r)}0`]===void 0)return null;let n="",o=0,t=`${a.keyPrefix}${String(r)}${o}`;for(;this.memCache[t]!==void 0;)n+=this.memCache[t],o++,t=`${a.keyPrefix}${String(r)}${o}`;return n}async removeSessionItem(r){for(const n in this.memCache)n.startsWith(`${a.keyPrefix}${String(r)}`)&&delete this.memCache[n]}}function U(e){return new Promise((r,n)=>{chrome.storage.local.get([e],function(o){chrome.runtime.lastError?n(void 0):r(o[e])})})}class te extends b{async destroySession(){await chrome.storage.local.clear()}async setSessionItem(r,n){if(await this.removeSessionItem(r),typeof n=="string"){R(n,a.maxLength).forEach(async(o,t)=>{await chrome.storage.local.set({[`${a.keyPrefix}${r}${t}`]:o})});return}await chrome.storage.local.set({[`${a.keyPrefix}${r}0`]:n})}async getSessionItem(r){let n="",o=0,t=`${a.keyPrefix}${String(r)}${o}`;for(;await U(`${a.keyPrefix}${String(r)}${o}`)!==void 0;)n+=await U(t),o++,t=`${a.keyPrefix}${String(r)}${o}`;return n}async removeSessionItem(r){let n=0;for(;await U(`${a.keyPrefix}${String(r)}${n}`)!==void 0;)await chrome.storage.local.remove(`${a.keyPrefix}${String(r)}${n}`),n++}}class se extends b{constructor(){super(),a.useInsecureForRefreshToken&&console.warn("LocalStorage store should not be used in production")}internalItems=new Set;async destroySession(){this.internalItems.forEach(r=>{this.removeSessionItem(r)})}async setSessionItem(r,n){if(await this.removeSessionItem(r),this.internalItems.add(r),typeof n=="string"){R(n,a.maxLength).forEach((o,t)=>{localStorage.setItem(`${a.keyPrefix}${r}${t}`,o)});return}localStorage.setItem(`${a.keyPrefix}${r}0`,n)}async getSessionItem(r){if(localStorage.getItem(`${a.keyPrefix}${r}0`)===null)return null;let n="",o=0,t=`${a.keyPrefix}${String(r)}${o}`;for(;localStorage.getItem(t)!==null;)n+=localStorage.getItem(t),o++,t=`${a.keyPrefix}${String(r)}${o}`;return n}async removeSessionItem(r){let n=0;for(;localStorage.getItem(`${a.keyPrefix}${String(r)}${n}`)!==null;)localStorage.removeItem(`${a.keyPrefix}${String(r)}${n}`),n++;this.internalItems.delete(r)}}const a={keyPrefix:"kinde-",maxLength:2e3,useInsecureForRefreshToken:!1};function ae(e,r){if(!e)return null;const n=e.split(".");if(n.length!==3)return null;const o=n[1].replace(/-/g,"+").replace(/_/g,"/"),t=decodeURIComponent(atob(o).split("").map(u=>"%"+("00"+u.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(t)}const g=async(e=s.accessToken)=>{const r=y();if(!r)return null;const n=await r.getSessionItem(e==="accessToken"?s.accessToken:s.idToken);if(!n)return null;const o=ae(n);return o||console.warn("No decoded token found"),o},V=async(e="accessToken")=>g(e),ie=async(e,r="accessToken")=>{const n=await V(r);return n?{name:e,value:n[e]}:null},ce=async()=>{const e=await g();return e?e.org_code||e["x-hasura-org-code"]:null},le=async(e=s.accessToken)=>{const r=y();return r&&await r.getSessionItem(e==="accessToken"?s.accessToken:s.idToken)||null},ue=async e=>{const r=await g();if(!r)return null;const n=r.feature_flags||r["x-hasura-feature-flags"];return n?n[e]?.v??null:null},de=async()=>{const e=await V("idToken");if(!e)return null;const{sub:r}=e;return r?{id:e.sub,givenName:e.given_name,familyName:e.family_name,email:e.email,picture:e.picture}:(console.error("No sub in idToken"),null)},fe=async e=>{const r=await g();if(!r)return{permissionKey:e,orgCode:null,isGranted:!1};const n=r.permissions||[];return{permissionKey:e,orgCode:r.org_code,isGranted:!!n.includes(e)}},he=async()=>{const e=await g();if(!e)return{orgCode:null,permissions:[]};const r=e.permissions||e["x-hasura-permissions"]||[];return{orgCode:e.org_code||e["x-hasura-org-code"],permissions:r}},me=async()=>{const e=await g("idToken");return e?!e.org_codes&&!e["x-hasura-org-codes"]?(console.warn("Org codes not found in token, ensure org codes have been included in the token customisation within the application settings"),null):e.org_codes||e["x-hasura-org-codes"]:null},ge=async()=>{const e=await g();return e?!e.roles&&!e["x-hasura-roles"]?(console.warn("No roles found in token, ensure roles have been included in the token customisation within the application settings"),[]):e.roles||e["x-hasura-roles"]:[]},ke=async e=>{try{const r=await g("accessToken");if(!r)return!1;if(!r.exp)return console.error("Token does not have an expiry"),!1;const n=r.exp<Math.floor(Date.now()/1e3);return n&&e?.useRefreshToken?(await $({domain:e.domain,clientId:e.clientId})).success:!n}catch(r){return console.error("Error checking authentication:",r),!1}},$=async({domain:e,clientId:r,refreshType:n=p.refreshToken,onRefresh:o})=>{const t=d=>(o&&o(d),d);if(!e)return t({success:!1,error:"Domain is required for token refresh"});if(!r)return t({success:!1,error:"Client ID is required for token refresh"});let u="",i;if(a.useInsecureForRefreshToken||!S(e)?i=I():i=y(),n===p.refreshToken){if(!i)return t({success:!1,error:"No active storage found"});if(u=await i.getSessionItem(s.refreshToken),!u)return t({success:!1,error:"No refresh token found"})}C();try{const d=await fetch(`${P(e)}/oauth2/token`,{method:"POST",...n===p.cookie&&{credentials:"include"},headers:{"Content-type":"application/x-www-form-urlencoded; charset=UTF-8"},body:new URLSearchParams({...n===p.refreshToken&&{refresh_token:u},grant_type:"refresh_token",client_id:r}).toString()});if(!d.ok)return t({success:!1,error:"Failed to refresh token"});const c=await d.json();if(c.access_token){const l=y();return l?(N(c.expires_in,async()=>{$({domain:e,clientId:r,refreshType:n,onRefresh:o})}),i&&(await l.setSessionItem(s.accessToken,c.access_token),c.id_token&&await l.setSessionItem(s.idToken,c.id_token),c.refresh_token&&await i.setSessionItem(s.refreshToken,c.refresh_token)),t({success:!0,[s.accessToken]:c.access_token,[s.idToken]:c.id_token,[s.refreshToken]:c.refresh_token})):t({success:!1,error:"No active storage found"})}}catch(d){return t({success:!1,error:`No access token received: ${d}`})}return t({success:!1,error:"No access token received"})},m={secure:null,insecure:null},pe=e=>{m.secure=e},y=()=>m.secure||null,we=()=>m.secure!==null,ye=()=>{m.secure=null},_e=e=>{m.insecure=e},I=()=>m.insecure||m.secure||null,Se=()=>m.insecure!==null,$e=()=>{m.insecure=null},Ie=async e=>(console.warn("Warning: generateProfileUrl is deprecated. Please use generatePortalUrl instead."),K({domain:e.domain,returnUrl:e.returnUrl,subNav:e.subNav})),K=async({domain:e,returnUrl:r,subNav:n})=>{const o=y();if(!o)throw new Error("generatePortalUrl: Active storage not found");const t=await o.getSessionItem(s.accessToken);if(!t)throw new Error("generatePortalUrl: Access Token not found");const u=new URLSearchParams({sub_nav:n||A.profile,return_url:r}),i=await fetch(`${P(e)}/account_api/v1/portal_link?${u.toString()}`,{headers:{Authorization:`Bearer ${t}`}});if(!i.ok)throw new Error(`Failed to fetch profile URL: ${i.status} ${i.statusText}`);const d=await i.json();if(!d.url||typeof d.url!="string")throw new Error("Invalid URL received from API");try{return{url:new URL(d.url)}}catch(c){throw console.error(c),new Error(`Invalid URL format received from API: ${d.url}`)}},Te={__esModule:!0,default:async()=>(await Promise.resolve().then(()=>require("./expoSecureStore-XvKE_bbE-kpuFfoHQ.cjs"))).ExpoSecureStore};exports.$=$;exports.$e=Se;exports.A=b;exports.B=M;exports.C=x;exports.F=N;exports.G=q;exports.H=O;exports.I=v;exports.Ie=Te;exports.K=K;exports.L=z;exports.M=V;exports.N=L;exports.P=P;exports.R=C;exports.Se=ke;exports.T=I;exports.Te=$e;exports.V=A;exports._=w;exports._e=pe;exports.a=s;exports.ae=oe;exports.b=R;exports.c=a;exports.ce=te;exports.de=le;exports.fe=ue;exports.ge=fe;exports.he=de;exports.ie=se;exports.k=g;exports.ke=me;exports.le=ie;exports.me=he;exports.ne=Q;exports.oe=Y;exports.p=y;exports.pe=we;exports.se=ne;exports.te=W;exports.ue=ce;exports.ve=ye;exports.w=p;exports.we=ge;exports.xe=Ie;exports.y=S;exports.ye=_e;