@yboard/auth-mobile 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/client/http-client.ts +2 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var ve=Object.create;var W=Object.defineProperty;var _e=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var ze=Object.getPrototypeOf,Ee=Object.prototype.hasOwnProperty;var ie=r=>{throw TypeError(r)};var Ne=(r,e)=>{for(var t in e)W(r,t,{get:e[t],enumerable:!0})},ae=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Pe(e))!Ee.call(r,o)&&o!==t&&W(r,o,{get:()=>e[o],enumerable:!(n=_e(e,o))||n.enumerable});return r};var b=(r,e,t)=>(t=r!=null?ve(ze(r)):{},ae(e||!r||!r.__esModule?W(t,"default",{value:r,enumerable:!0}):t,r)),Le=r=>ae(W({},"__esModule",{value:!0}),r);var F=(r,e,t)=>e.has(r)||ie("Cannot "+t);var i=(r,e,t)=>(F(r,e,"read from private field"),t?t.call(r):e.get(r)),p=(r,e,t)=>e.has(r)?ie("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),d=(r,e,t,n)=>(F(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),u=(r,e,t)=>(F(r,e,"access private method"),t);var Ye={};Ne(Ye,{AuthKitError:()=>_,LoginRequiredError:()=>P,YboardAuthProvider:()=>Ae,createClient:()=>D,getClaims:()=>ne,memoryStorage:()=>N,useYboardAuth:()=>Re});module.exports=Le(Ye);var pe=b(require("expo-auth-session"),1),A=b(require("expo-secure-store"),1),de=b(require("expo-web-browser"),1),I=require("react-native");function $e(r){let e=new Map;return r.split(", ").forEach(n=>{let[o,...s]=n.split("; "),[a,l]=o.split("="),h={value:l};s.forEach(f=>{let[w,O]=f.split("=");h[w.toLowerCase()]=O}),e.set(a,h)}),e}function ce(r,e){let t=$e(r),n={};if(t.forEach((o,s)=>{let a=o.expires,l=o["max-age"],h=a?new Date(String(a)):l?new Date(Date.now()+Number(l)):null;n[s]={value:o.value,expires:h}}),e)try{n={...JSON.parse(e),...n}}catch{}return JSON.stringify(n)}function M(r){let e={};try{e=JSON.parse(r)}catch{}return Object.entries(e).reduce((n,[o,s])=>s.expires&&s.expires<new Date?n:`${n}; ${o}=${s.value}`,"")}var _=class extends Error{};var L=class extends _{},P=class extends _{constructor(){super(...arguments);this.message="No access token available"}};var k=({baseUrl:r,organizationId:e,cookie:t,path:n,method:o,options:s,body:a={}})=>{let l={method:o,headers:{Accept:"application/json, text/plain, */*","Content-Type":"application/json","X-Organization-Id":e,cookie:t||""},credentials:"include",...s};return o!=="GET"&&a&&(l.body=JSON.stringify(a)),fetch(`${r}${n}`,l)};var Z=r=>({object:r.object,id:r.id,email:r.email,emailVerified:r.email_verified,firstName:r.first_name,profilePictureUrl:r.profile_picture_url,lastName:r.last_name,lastSignInAt:r.last_sign_in_at,externalId:r.external_id,createdAt:r.created_at,updatedAt:r.updated_at});var ee=r=>{let{user:e,organization_id:t,access_token:n,refresh_token:o,impersonator:s,...a}=r;return{user:Z(e),organizationId:t,accessToken:n,refreshToken:o,impersonator:s,...a}};var y,z,S,Y=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,y);p(this,z);p(this,S);d(this,y,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,z,e),d(this,S,o)}async authenticateWithCode({code:e}){let t=await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/authenticate",method:"POST",body:{code:e,client_id:i(this,z),grant_type:"authorization_code"}});if(t.ok){let o=await t.json();return ee(o)}let n=await t.json();throw new L(n.error_description)}async getAuthorizationUrl({redirectUri:e}){let t=new URLSearchParams(e?{redirectUri:e,authorizationCallbackUri:`${i(this,y)}/api/user_management/auth/callback`,clientId:i(this,z),organizationId:i(this,S)}:{}),n=new URL("api/user_management/signIn",i(this,y));return n.search=t.toString(),n.toString()}async getUser(){let t=await(await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/getUser",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.user?n.user:null}async getAccessToken(){let t=await(await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/getAccessToken",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.accessToken?n.accessToken:null}async getLogoutUrl({returnTo:e}){let t=await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/getLogOutUrl",method:"POST",body:{returnTo:e,client_id:i(this,z)}}),{url:n}=await t.json();return n}};y=new WeakMap,z=new WeakMap,S=new WeakMap;var j=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoClientIdProvidedException";this.message='Missing Client ID. Pass it to the constructor (createClient("client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7"))'}},B=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoOrganizationIdProvidedException";this.message="Missing Organization ID. Pass it to the constructor"}};var le=b(require("expo-auth-session"),1),ue=b(require("expo-web-browser"),1);var x,E,U,G,ge,J=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,G);p(this,x);p(this,E);p(this,U);d(this,x,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,E,e),d(this,U,o)}async startAuthorizationFlow({codeChallenge:e,codeChallengeMethod:t}){let n=le.makeRedirectUri({native:"yboardstarter:"}).toString(),o=u(this,G,ge).call(this,{redirectUri:n,codeChallenge:e,codeChallengeMethod:t,clientId:i(this,E),organizationId:i(this,U)}),s,a=await ue.openAuthSessionAsync(o,n);switch(a.type){case"success":if(a.url){let l=a.url.split("?");if(l.length>1){let f=l[1].split("&");for(let w of f){let[O,C]=w.split("=");if(O==="code"){s=decodeURIComponent(C);break}}}}break;case"cancel":throw new Error("Authentication cancelled.");case"dismiss":throw new Error("Authentication dismissed.");case"locked":throw new Error("Authentication session already active.");default:throw new Error(`Unhandled auth session result: ${a.type}`)}if(!s)throw new Error("No authorization code found in redirect URL.");return{code:s}}async authenticateWithCode({code:e,codeVerifier:t,redirectUri:n}){let o=await fetch(`${i(this,x)}/api/user_management/mobile/authenticate`,{method:"POST",headers:{"Content-Type":"application/json","X-Organization-Id":i(this,U)},body:JSON.stringify({code:e,client_id:i(this,E),grant_type:"authorization_code",code_verifier:t,redirect_uri:n})});if(!o.ok){let a=await o.json();throw new L(a.error_description)}return o.headers.get("set-cookie")}async getUser({cookie:e}={}){let t=await k({baseUrl:i(this,x),organizationId:i(this,U),cookie:e,path:"/api/user_management/mobile/getUser",method:"GET"});if(!t.ok)return null;let{user:n}=await t.json();return n}async getAccessToken({cookie:e}={}){let t=await k({baseUrl:i(this,x),organizationId:i(this,U),cookie:e,path:"/api/user_management/mobile/getAccessToken",method:"GET"}),{accessToken:n}=await t.json();return n}async getLogoutUrl({returnTo:e,cookie:t}={}){let n=await k({baseUrl:i(this,x),organizationId:i(this,U),cookie:t,path:"/api/user_management/mobile/getLogOutUrl",method:"POST",body:{client_id:i(this,E),returnTo:e||""}}),{url:o}=await n.json();return o}};x=new WeakMap,E=new WeakMap,U=new WeakMap,G=new WeakSet,ge=function({redirectUri:e,codeChallenge:t,codeChallengeMethod:n,clientId:o,organizationId:s}){let a=new URLSearchParams({response_type:"code",clientId:o,redirectUri:e,codeChallenge:t,codeChallengeMethod:n,organizationId:s});return`${i(this,x)}/api/user_management/mobile/signIn?${a.toString()}`};function te(r,e,t){if(!(typeof e=="object"&&"code"in e))return!1;let o;if(t){let s=new URL(t);o=`${s.protocol}//${s.host}${s.pathname}`}else return!1;return o===r||o===`${r}/`}function He(){let r={};function e(s,a){r[s]=a}function t(s){return r[s]}function n(s){delete r[s]}function o(){r={}}return{setItem:e,getItem:t,removeItem:n,reset:o}}var N=He();var T=b(require("expo-crypto"),1);async function re(){let r=await je(),e=await De(r);return{codeVerifier:r,codeChallenge:e}}async function je(){let r=await T.getRandomBytesAsync(32);return Ve(r)}async function De(r){return(await T.digestStringAsync(T.CryptoDigestAlgorithm.SHA256,r,{encoding:T.CryptoEncoding.BASE64})).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function Ve(r){let e="";for(let n=0;n<r.length;n++)e+=String.fromCharCode(r[n]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var We=null;try{We=require("@react-native-async-storage/async-storage").default}catch{}var q={codeVerifier:"code-verifier",user:"user",accessToken:"access-token",refreshToken:"refresh-token",expiresAt:"expires-at"};function ne(r){return JSON.parse(atob(r.split(".")[1]))}var g,R,c,se,me,he,fe,ye,we,Ce,be,ke,Se,xe,oe=class{constructor(e,{apiHostname:t,https:n,port:o,organizationId:s,redirectUri:a,devMode:l}){p(this,c);p(this,g);p(this,R);if(!e)throw new j;if(!s)throw new B;I.Platform.OS==="web"?(a=a??window.origin,l=l??(location.hostname==="localhost"||location.hostname==="127.0.0.1")):(a=a??"",l=l??!1),I.Platform.OS==="web"?d(this,g,new Y({clientId:e,hostname:t,port:o,organizationId:s,https:n})):d(this,g,new J({clientId:e,hostname:t,port:o,organizationId:s,https:n})),d(this,R,a)}async getAccessToken(){return I.Platform.OS==="web"?u(this,c,be).call(this):u(this,c,he).call(this)}async getUser(){return I.Platform.OS==="web"?u(this,c,ke).call(this):u(this,c,fe).call(this)}async initialize(){let e=new URLSearchParams(window.location.search);te(i(this,R),e)&&await u(this,c,Se).call(this)}async signIn(e={}){return u(this,c,se).call(this,{...e,type:"sign-in"})}async signUp(e={}){return u(this,c,se).call(this,{...e,type:"sign-up"})}async signOut(e){return I.Platform.OS==="web"?u(this,c,Ce).call(this,e):u(this,c,me).call(this,e)}async getCookieDomain(e){let t=new URL(e),n=t.hostname.split(".");return n.length>1?"."+n.slice(-2).join("."):t.hostname}};g=new WeakMap,R=new WeakMap,c=new WeakSet,se=async function(e){return I.Platform.OS==="web"?u(this,c,xe).call(this,e):u(this,c,ye).call(this,e)},me=async function(e){let t=e?.returnTo||pe.makeRedirectUri({native:"yboardstarter:"}),n=await A.getItemAsync("yboard-session"),o=M(n||"{}"),s=await i(this,g).getLogoutUrl({returnTo:t,cookie:o});if(s)try{(await de.openAuthSessionAsync(s,t)).type==="success"&&await A.deleteItemAsync("yboard-session")}catch{}},he=async function(){let e=await A.getItemAsync("yboard-session"),t=M(e||"{}");return await i(this,g).getAccessToken({cookie:t})||null},fe=async function(){let e=await A.getItemAsync("yboard-session"),t=M(e||"{}"),n=await i(this,g).getUser({cookie:t});return n||null},ye=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a}){let{codeVerifier:l,codeChallenge:h}=await re();N.setItem(q.codeVerifier,l);let{code:f}=await i(this,g).startAuthorizationFlow({codeChallenge:h,codeChallengeMethod:"S256"});if(f){let w=await u(this,c,we).call(this,{code:f,codeVerifier:l});if(w&&typeof w=="string"){let O=await A.getItemAsync("yboard-session"),C=ce(w,O||void 0);await A.setItemAsync("yboard-session",C)}}},we=async function({code:e,codeVerifier:t}){return typeof t!="string"?null:await i(this,g).authenticateWithCode({code:e,codeVerifier:t,redirectUri:i(this,R)})},Ce=async function(e){let t=await i(this,g).getLogoutUrl({returnTo:e?.returnTo});if(t){let n=await this.getCookieDomain(i(this,R));document.cookie=`yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${n}`,window.location.assign(t)}},be=async function(){return await i(this,g).getAccessToken()},ke=async function(){return await i(this,g).getUser()},Se=async function(){let e=new URL(window.location.toString());e.search="",window.history.replaceState({},"",e)},xe=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a,type:l,provider:h}){let f=await i(this,g).getAuthorizationUrl({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,redirectUri:i(this,R),state:a?JSON.stringify(a):void 0});window.location.assign(f)};async function D(r,e){let t=new oe(r,e);return I.Platform.OS==="web"&&await t.initialize(),t}var V=b(require("react"),1);var Ue=b(require("react"),1);var $={isLoading:!0,user:null,role:null,organizationId:null,permissions:[]};var K=Ue.createContext($);var Te=require("react/jsx-runtime");function Ae(r){let{clientId:e,apiHostname:t,https:n,port:o,redirectUri:s,children:a,organizationId:l,refreshBufferInterval:h}=r,[f,w]=(0,V.useState)(Me),[O,C]=V.default.useState($);return V.default.useEffect(()=>{async function Oe(){try{let m=await D(e,{apiHostname:t,port:o,organizationId:l,https:n,redirectUri:s,refreshBufferInterval:h}),X=await m.getUser();w({getAccessToken:m.getAccessToken.bind(m),getUser:m.getUser.bind(m),signIn:async(...v)=>{await m.signIn(...v);let H=await m.getUser();C(Q=>({...Q,user:H}))},signUp:async(...v)=>{await m.signUp(...v);let H=await m.getUser();C(Q=>({...Q,user:H}))},signOut:async(...v)=>{await m.signOut(...v),C(H=>({...H,user:null}))}}),C(v=>({...v,isLoading:!1,user:X}))}catch{C(X=>({...X,isLoading:!1,user:null}))}}Oe()},[]),(0,Te.jsx)(K.Provider,{value:{...f,...O},children:a})}var Me={signIn:async()=>{},signUp:async()=>{},getUser:()=>Promise.resolve(null),getAccessToken:()=>Promise.reject(new P),signOut:async()=>Promise.resolve()};var Ie=b(require("react"),1);function Re(){let r=Ie.useContext(K);if(r===$)throw new Error("useYboardAuth must be used within a YboardAuthProvider");return r}0&&(module.exports={AuthKitError,LoginRequiredError,YboardAuthProvider,createClient,getClaims,memoryStorage,useYboardAuth});
|
|
1
|
+
"use strict";var ve=Object.create;var W=Object.defineProperty;var _e=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var ze=Object.getPrototypeOf,Ee=Object.prototype.hasOwnProperty;var ie=r=>{throw TypeError(r)};var Ne=(r,e)=>{for(var t in e)W(r,t,{get:e[t],enumerable:!0})},ae=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Pe(e))!Ee.call(r,o)&&o!==t&&W(r,o,{get:()=>e[o],enumerable:!(n=_e(e,o))||n.enumerable});return r};var b=(r,e,t)=>(t=r!=null?ve(ze(r)):{},ae(e||!r||!r.__esModule?W(t,"default",{value:r,enumerable:!0}):t,r)),Le=r=>ae(W({},"__esModule",{value:!0}),r);var F=(r,e,t)=>e.has(r)||ie("Cannot "+t);var i=(r,e,t)=>(F(r,e,"read from private field"),t?t.call(r):e.get(r)),p=(r,e,t)=>e.has(r)?ie("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),d=(r,e,t,n)=>(F(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),u=(r,e,t)=>(F(r,e,"access private method"),t);var Ye={};Ne(Ye,{AuthKitError:()=>_,LoginRequiredError:()=>P,YboardAuthProvider:()=>Ae,createClient:()=>D,getClaims:()=>ne,memoryStorage:()=>N,useYboardAuth:()=>Re});module.exports=Le(Ye);var pe=b(require("expo-auth-session"),1),A=b(require("expo-secure-store"),1),de=b(require("expo-web-browser"),1),I=require("react-native");function $e(r){let e=new Map;return r.split(", ").forEach(n=>{let[o,...s]=n.split("; "),[a,l]=o.split("="),h={value:l};s.forEach(f=>{let[w,O]=f.split("=");h[w.toLowerCase()]=O}),e.set(a,h)}),e}function ce(r,e){let t=$e(r),n={};if(t.forEach((o,s)=>{let a=o.expires,l=o["max-age"],h=a?new Date(String(a)):l?new Date(Date.now()+Number(l)):null;n[s]={value:o.value,expires:h}}),e)try{n={...JSON.parse(e),...n}}catch{}return JSON.stringify(n)}function M(r){let e={};try{e=JSON.parse(r)}catch{}return Object.entries(e).reduce((n,[o,s])=>s.expires&&s.expires<new Date?n:`${n}; ${o}=${s.value}`,"")}var _=class extends Error{};var L=class extends _{},P=class extends _{constructor(){super(...arguments);this.message="No access token available"}};var k=({baseUrl:r,organizationId:e,cookie:t,path:n,method:o,options:s,body:a={}})=>{let l={method:o,headers:{Accept:"application/json, text/plain, */*","Content-Type":"application/json","X-Organization-Id":e,cookie:t||""},credentials:"include",...s};return o!=="GET"&&a&&(l.body=JSON.stringify(a)),fetch(`${r}${n}`,l)};var Z=r=>({object:r.object,id:r.id,email:r.email,emailVerified:r.email_verified,firstName:r.first_name,profilePictureUrl:r.profile_picture_url,lastName:r.last_name,lastSignInAt:r.last_sign_in_at,externalId:r.external_id,createdAt:r.created_at,updatedAt:r.updated_at});var ee=r=>{let{user:e,organization_id:t,access_token:n,refresh_token:o,impersonator:s,...a}=r;return{user:Z(e),organizationId:t,accessToken:n,refreshToken:o,impersonator:s,...a}};var y,z,S,Y=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,y);p(this,z);p(this,S);d(this,y,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,z,e),d(this,S,o)}async authenticateWithCode({code:e}){let t=await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/authenticate",method:"POST",body:{code:e,client_id:i(this,z),grant_type:"authorization_code"}});if(t.ok){let o=await t.json();return ee(o)}let n=await t.json();throw new L(n.error_description)}async getAuthorizationUrl({redirectUri:e}){let t=new URLSearchParams(e?{redirectUri:e,authorizationCallbackUri:`${i(this,y)}/api/user_management/auth/callback`,clientId:i(this,z),organizationId:i(this,S)}:{}),n=new URL("api/user_management/signIn",i(this,y));return n.search=t.toString(),n.toString()}async getUser(){let t=await(await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/getUser",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.user?n.user:null}async getAccessToken(){let t=await(await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/getAccessToken",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.accessToken?n.accessToken:null}async getLogoutUrl({returnTo:e}){let t=await k({baseUrl:i(this,y),organizationId:i(this,S),path:"/api/user_management/getLogOutUrl",method:"POST",body:{returnTo:e,client_id:i(this,z)}}),{url:n}=await t.json();return n}};y=new WeakMap,z=new WeakMap,S=new WeakMap;var j=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoClientIdProvidedException";this.message='Missing Client ID. Pass it to the constructor (createClient("client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7"))'}},B=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoOrganizationIdProvidedException";this.message="Missing Organization ID. Pass it to the constructor"}};var le=b(require("expo-auth-session"),1),ue=b(require("expo-web-browser"),1);var x,E,U,G,ge,J=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,G);p(this,x);p(this,E);p(this,U);d(this,x,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,E,e),d(this,U,o)}async startAuthorizationFlow({codeChallenge:e,codeChallengeMethod:t}){let n=le.makeRedirectUri({native:"yboardstarter:"}).toString(),o=u(this,G,ge).call(this,{redirectUri:n,codeChallenge:e,codeChallengeMethod:t,clientId:i(this,E),organizationId:i(this,U)}),s,a=await ue.openAuthSessionAsync(o,n);switch(a.type){case"success":if(a.url){let l=a.url.split("?");if(l.length>1){let f=l[1].split("&");for(let w of f){let[O,C]=w.split("=");if(O==="code"){s=decodeURIComponent(C).split("#")[0];break}}}}break;case"cancel":throw new Error("Authentication cancelled.");case"dismiss":throw new Error("Authentication dismissed.");case"locked":throw new Error("Authentication session already active.");default:throw new Error(`Unhandled auth session result: ${a.type}`)}if(!s)throw new Error("No authorization code found in redirect URL.");return{code:s}}async authenticateWithCode({code:e,codeVerifier:t,redirectUri:n}){let o=await fetch(`${i(this,x)}/api/user_management/mobile/authenticate`,{method:"POST",headers:{"Content-Type":"application/json","X-Organization-Id":i(this,U)},body:JSON.stringify({code:e,client_id:i(this,E),grant_type:"authorization_code",code_verifier:t,redirect_uri:n})});if(!o.ok){let a=await o.json();throw new L(a.error_description)}return o.headers.get("set-cookie")}async getUser({cookie:e}={}){let t=await k({baseUrl:i(this,x),organizationId:i(this,U),cookie:e,path:"/api/user_management/mobile/getUser",method:"GET"});if(!t.ok)return null;let{user:n}=await t.json();return n}async getAccessToken({cookie:e}={}){let t=await k({baseUrl:i(this,x),organizationId:i(this,U),cookie:e,path:"/api/user_management/mobile/getAccessToken",method:"GET"}),{accessToken:n}=await t.json();return n}async getLogoutUrl({returnTo:e,cookie:t}={}){let n=await k({baseUrl:i(this,x),organizationId:i(this,U),cookie:t,path:"/api/user_management/mobile/getLogOutUrl",method:"POST",body:{client_id:i(this,E),returnTo:e||""}}),{url:o}=await n.json();return o}};x=new WeakMap,E=new WeakMap,U=new WeakMap,G=new WeakSet,ge=function({redirectUri:e,codeChallenge:t,codeChallengeMethod:n,clientId:o,organizationId:s}){let a=new URLSearchParams({response_type:"code",clientId:o,redirectUri:e,codeChallenge:t,codeChallengeMethod:n,organizationId:s});return`${i(this,x)}/api/user_management/mobile/signIn?${a.toString()}`};function te(r,e,t){if(!(typeof e=="object"&&"code"in e))return!1;let o;if(t){let s=new URL(t);o=`${s.protocol}//${s.host}${s.pathname}`}else return!1;return o===r||o===`${r}/`}function He(){let r={};function e(s,a){r[s]=a}function t(s){return r[s]}function n(s){delete r[s]}function o(){r={}}return{setItem:e,getItem:t,removeItem:n,reset:o}}var N=He();var T=b(require("expo-crypto"),1);async function re(){let r=await je(),e=await De(r);return{codeVerifier:r,codeChallenge:e}}async function je(){let r=await T.getRandomBytesAsync(32);return Ve(r)}async function De(r){return(await T.digestStringAsync(T.CryptoDigestAlgorithm.SHA256,r,{encoding:T.CryptoEncoding.BASE64})).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function Ve(r){let e="";for(let n=0;n<r.length;n++)e+=String.fromCharCode(r[n]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var We=null;try{We=require("@react-native-async-storage/async-storage").default}catch{}var q={codeVerifier:"code-verifier",user:"user",accessToken:"access-token",refreshToken:"refresh-token",expiresAt:"expires-at"};function ne(r){return JSON.parse(atob(r.split(".")[1]))}var g,R,c,se,me,he,fe,ye,we,Ce,be,ke,Se,xe,oe=class{constructor(e,{apiHostname:t,https:n,port:o,organizationId:s,redirectUri:a,devMode:l}){p(this,c);p(this,g);p(this,R);if(!e)throw new j;if(!s)throw new B;I.Platform.OS==="web"?(a=a??window.origin,l=l??(location.hostname==="localhost"||location.hostname==="127.0.0.1")):(a=a??"",l=l??!1),I.Platform.OS==="web"?d(this,g,new Y({clientId:e,hostname:t,port:o,organizationId:s,https:n})):d(this,g,new J({clientId:e,hostname:t,port:o,organizationId:s,https:n})),d(this,R,a)}async getAccessToken(){return I.Platform.OS==="web"?u(this,c,be).call(this):u(this,c,he).call(this)}async getUser(){return I.Platform.OS==="web"?u(this,c,ke).call(this):u(this,c,fe).call(this)}async initialize(){let e=new URLSearchParams(window.location.search);te(i(this,R),e)&&await u(this,c,Se).call(this)}async signIn(e={}){return u(this,c,se).call(this,{...e,type:"sign-in"})}async signUp(e={}){return u(this,c,se).call(this,{...e,type:"sign-up"})}async signOut(e){return I.Platform.OS==="web"?u(this,c,Ce).call(this,e):u(this,c,me).call(this,e)}async getCookieDomain(e){let t=new URL(e),n=t.hostname.split(".");return n.length>1?"."+n.slice(-2).join("."):t.hostname}};g=new WeakMap,R=new WeakMap,c=new WeakSet,se=async function(e){return I.Platform.OS==="web"?u(this,c,xe).call(this,e):u(this,c,ye).call(this,e)},me=async function(e){let t=e?.returnTo||pe.makeRedirectUri({native:"yboardstarter:"}),n=await A.getItemAsync("yboard-session"),o=M(n||"{}"),s=await i(this,g).getLogoutUrl({returnTo:t,cookie:o});if(s)try{(await de.openAuthSessionAsync(s,t)).type==="success"&&await A.deleteItemAsync("yboard-session")}catch{}},he=async function(){let e=await A.getItemAsync("yboard-session"),t=M(e||"{}");return await i(this,g).getAccessToken({cookie:t})||null},fe=async function(){let e=await A.getItemAsync("yboard-session"),t=M(e||"{}"),n=await i(this,g).getUser({cookie:t});return n||null},ye=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a}){let{codeVerifier:l,codeChallenge:h}=await re();N.setItem(q.codeVerifier,l);let{code:f}=await i(this,g).startAuthorizationFlow({codeChallenge:h,codeChallengeMethod:"S256"});if(f){let w=await u(this,c,we).call(this,{code:f,codeVerifier:l});if(w&&typeof w=="string"){let O=await A.getItemAsync("yboard-session"),C=ce(w,O||void 0);await A.setItemAsync("yboard-session",C)}}},we=async function({code:e,codeVerifier:t}){return typeof t!="string"?null:await i(this,g).authenticateWithCode({code:e,codeVerifier:t,redirectUri:i(this,R)})},Ce=async function(e){let t=await i(this,g).getLogoutUrl({returnTo:e?.returnTo});if(t){let n=await this.getCookieDomain(i(this,R));document.cookie=`yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${n}`,window.location.assign(t)}},be=async function(){return await i(this,g).getAccessToken()},ke=async function(){return await i(this,g).getUser()},Se=async function(){let e=new URL(window.location.toString());e.search="",window.history.replaceState({},"",e)},xe=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a,type:l,provider:h}){let f=await i(this,g).getAuthorizationUrl({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,redirectUri:i(this,R),state:a?JSON.stringify(a):void 0});window.location.assign(f)};async function D(r,e){let t=new oe(r,e);return I.Platform.OS==="web"&&await t.initialize(),t}var V=b(require("react"),1);var Ue=b(require("react"),1);var $={isLoading:!0,user:null,role:null,organizationId:null,permissions:[]};var K=Ue.createContext($);var Te=require("react/jsx-runtime");function Ae(r){let{clientId:e,apiHostname:t,https:n,port:o,redirectUri:s,children:a,organizationId:l,refreshBufferInterval:h}=r,[f,w]=(0,V.useState)(Me),[O,C]=V.default.useState($);return V.default.useEffect(()=>{async function Oe(){try{let m=await D(e,{apiHostname:t,port:o,organizationId:l,https:n,redirectUri:s,refreshBufferInterval:h}),X=await m.getUser();w({getAccessToken:m.getAccessToken.bind(m),getUser:m.getUser.bind(m),signIn:async(...v)=>{await m.signIn(...v);let H=await m.getUser();C(Q=>({...Q,user:H}))},signUp:async(...v)=>{await m.signUp(...v);let H=await m.getUser();C(Q=>({...Q,user:H}))},signOut:async(...v)=>{await m.signOut(...v),C(H=>({...H,user:null}))}}),C(v=>({...v,isLoading:!1,user:X}))}catch{C(X=>({...X,isLoading:!1,user:null}))}}Oe()},[]),(0,Te.jsx)(K.Provider,{value:{...f,...O},children:a})}var Me={signIn:async()=>{},signUp:async()=>{},getUser:()=>Promise.resolve(null),getAccessToken:()=>Promise.reject(new P),signOut:async()=>Promise.resolve()};var Ie=b(require("react"),1);function Re(){let r=Ie.useContext(K);if(r===$)throw new Error("useYboardAuth must be used within a YboardAuthProvider");return r}0&&(module.exports={AuthKitError,LoginRequiredError,YboardAuthProvider,createClient,getClaims,memoryStorage,useYboardAuth});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client/create-client.ts","../src/client/cookie.ts","../src/client/errors.ts","../src/client/globalFetch.ts","../src/client/serializers/user.serializer.ts","../src/client/serializers/authentication-response.serializer.ts","../src/client/cookie-http-client.ts","../src/client/exceptions/no-client-id-provided.exception.ts","../src/client/http-client.ts","../src/client/utils/is-redirect-callback.ts","../src/client/utils/memory-storage.ts","../src/client/utils/pkce.ts","../src/client/utils/native-storage.ts","../src/client/utils/storage-keys.ts","../src/client/utils/session-data.ts","../src/provider/authProvider.tsx","../src/provider/context.ts","../src/provider/state.ts","../src/provider/hook.ts"],"sourcesContent":["// Client exports\nexport { createClient } from \"./client/create-client\";\nexport type { RedirectOptions } from \"./client/create-client\";\nexport { getClaims } from \"./client/utils/session-data\";\nexport type { User, AuthenticationResponse } from \"./client/interfaces\";\nexport { AuthKitError, LoginRequiredError } from \"./client/errors\";\nexport { memoryStorage } from \"./client/utils/memory-storage\";\n\n// Provider exports\nexport { YboardAuthProvider } from \"./provider/authProvider\";\nexport { useYboardAuth } from \"./provider/hook\";\n","import * as AuthSession from \"expo-auth-session\";\nimport * as SecureStore from \"expo-secure-store\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { Platform } from \"react-native\";\nimport { getCookie, getSetCookie } from \"./cookie\";\nimport { CookieHttpClient } from \"./cookie-http-client\";\nimport { NoClientIdProvidedException } from \"./exceptions\";\nimport { NoOrganizationIdProvidedException } from \"./exceptions/no-client-id-provided.exception\";\nimport { HttpClient } from \"./http-client\";\nimport type { CreateClientOptions, User } from \"./interfaces\";\nimport {\n createPkceChallenge,\n isRedirectCallback,\n memoryStorage,\n storageKeys,\n} from \"./utils\";\n\nexport interface RedirectOptions {\n provider?: string;\n context?: string;\n invitationToken?: string;\n loginHint?: string;\n organizationId?: string;\n passwordResetToken?: string;\n state?: any;\n type: \"sign-in\" | \"sign-up\";\n}\n\nexport class Client {\n readonly #httpClient: HttpClient | CookieHttpClient;\n #redirectUri: string;\n\n constructor(\n clientId: string,\n {\n apiHostname: hostname,\n https,\n port,\n organizationId,\n redirectUri,\n devMode,\n }: CreateClientOptions,\n ) {\n if (!clientId) {\n throw new NoClientIdProvidedException();\n }\n if (!organizationId) {\n throw new NoOrganizationIdProvidedException();\n }\n\n // Platform-specific defaults\n if (Platform.OS === \"web\") {\n // --- Web defaults ---\n redirectUri = redirectUri ?? window.origin;\n devMode =\n devMode ??\n (location.hostname === \"localhost\" ||\n location.hostname === \"127.0.0.1\");\n } else {\n // --- Native defaults ---\n redirectUri = redirectUri ?? \"\";\n devMode = devMode ?? false;\n }\n\n // Use CookieHttpClient for web (cookie-based), HttpClient for native (token-based)\n if (Platform.OS === \"web\") {\n this.#httpClient = new CookieHttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n } else {\n this.#httpClient = new HttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n }\n\n this.#redirectUri = redirectUri;\n }\n\n // ============================================================\n // Cross-platform methods\n // ============================================================\n\n async getAccessToken(): Promise<string | null> {\n if (Platform.OS === \"web\") {\n return this.#getAccessTokenWeb();\n } else {\n return this.#getAccessTokenNative();\n }\n }\n\n async getUser(): Promise<User | null> {\n if (Platform.OS === \"web\") {\n return this.#getUserWeb();\n } else {\n return this.#getUserNative();\n }\n }\n\n async #redirect(options: RedirectOptions) {\n if (Platform.OS === \"web\") {\n return this.#redirectWeb(options);\n } else {\n return this.#redirectNative(options);\n }\n }\n\n async initialize() {\n const searchParams = new URLSearchParams(window.location.search);\n if (isRedirectCallback(this.#redirectUri, searchParams)) {\n await this.#handleCallback();\n }\n }\n\n async signIn(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-in\" });\n }\n\n async signUp(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-up\" });\n }\n\n async signOut(options?: { returnTo: string }) {\n if (Platform.OS === \"web\") {\n return this.#signOutWeb(options);\n } else {\n return this.#signOutNative(options);\n }\n }\n\n // Native methods\n async #signOutNative(options?: { returnTo: string }) {\n const redirectUri =\n options?.returnTo ||\n AuthSession.makeRedirectUri({ native: \"yboardstarter:\" });\n\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n\n const logoutUrl = await (this.#httpClient as HttpClient).getLogoutUrl({\n returnTo: redirectUri,\n cookie,\n });\n\n if (logoutUrl) {\n try {\n const result = await WebBrowser.openAuthSessionAsync(\n logoutUrl,\n redirectUri,\n );\n\n if (result.type === \"success\") {\n await SecureStore.deleteItemAsync(\"yboard-session\");\n } else {\n console.warn(\"User cancelled or dismissed logout:\", result.type);\n }\n } catch (error) {\n console.error(\"Error during sign out:\", error);\n }\n }\n }\n\n async #getAccessTokenNative(): Promise<string | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const accessToken = await (this.#httpClient as HttpClient).getAccessToken({\n cookie,\n });\n return (accessToken as string) || null;\n }\n\n async #getUserNative(): Promise<User | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const user = await (this.#httpClient as HttpClient).getUser({ cookie });\n if (!user) {\n return null;\n }\n return user as User;\n }\n\n async #redirectNative({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n }: RedirectOptions) {\n const { codeVerifier, codeChallenge } = await createPkceChallenge();\n memoryStorage.setItem(storageKeys.codeVerifier, codeVerifier);\n\n const { code } = await (\n this.#httpClient as HttpClient\n ).startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod: \"S256\",\n });\n\n if (code) {\n const cookie = await this.#authenticate({\n code,\n codeVerifier,\n });\n if (cookie && typeof cookie === \"string\") {\n const prev = await SecureStore.getItemAsync(\"yboard-session\");\n const updated = getSetCookie(cookie, prev || undefined);\n await SecureStore.setItemAsync(\"yboard-session\", updated);\n }\n }\n }\n\n async #authenticate({\n code,\n codeVerifier,\n }: {\n code: string;\n codeVerifier: string;\n }): Promise<string | null> {\n if (typeof codeVerifier !== \"string\") return null;\n\n const cookie = await (this.#httpClient as HttpClient).authenticateWithCode({\n code,\n codeVerifier: codeVerifier,\n redirectUri: this.#redirectUri,\n });\n\n return cookie;\n }\n\n // Web methods\n async getCookieDomain(origin: string) {\n const url = new URL(origin);\n const domainParts = url.hostname.split(\".\");\n if (domainParts.length > 1) {\n return \".\" + domainParts.slice(-2).join(\".\");\n }\n return url.hostname;\n }\n\n async #signOutWeb(options?: { returnTo: string }) {\n const url = await (this.#httpClient as CookieHttpClient).getLogoutUrl({\n returnTo: options?.returnTo,\n });\n\n if (url) {\n const domain = await this.getCookieDomain(this.#redirectUri);\n document.cookie = `yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}`;\n window.location.assign(url);\n }\n }\n\n async #getAccessTokenWeb(): Promise<string | null> {\n const accessToken = await (\n this.#httpClient as CookieHttpClient\n ).getAccessToken();\n return accessToken as string | null;\n }\n\n async #getUserWeb(): Promise<User | null> {\n const user = await (this.#httpClient as CookieHttpClient).getUser();\n return user as User | null;\n }\n\n async #handleCallback() {\n const cleanUrl = new URL(window.location.toString());\n cleanUrl.search = \"\";\n window.history.replaceState({}, \"\", cleanUrl);\n }\n\n async #redirectWeb({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n type,\n provider,\n }: RedirectOptions) {\n const url = await (\n this.#httpClient as CookieHttpClient\n ).getAuthorizationUrl({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n redirectUri: this.#redirectUri,\n state: state ? JSON.stringify(state) : undefined,\n });\n window.location.assign(url);\n }\n}\n\nexport async function createClient(\n clientId: string,\n options: CreateClientOptions,\n) {\n const client = new Client(clientId, options);\n\n // Only initialize for web platform\n if (Platform.OS === \"web\") {\n await client.initialize();\n }\n\n return client;\n}\n","interface CookieAttributes {\n\tvalue: string;\n\texpires?: Date;\n\t\"max-age\"?: number;\n\tdomain?: string;\n\tpath?: string;\n\tsecure?: boolean;\n\thttpOnly?: boolean;\n\tsameSite?: \"Strict\" | \"Lax\" | \"None\";\n}\n\ninterface StoredCookie {\n\tvalue: string;\n\texpires: Date | null;\n}\n\nexport function parseSetCookieHeader(\n header: string,\n): Map<string, CookieAttributes> {\n const cookieMap = new Map<string, CookieAttributes>();\n const cookies = header.split(\", \");\n cookies.forEach((cookie) => {\n const [nameValue, ...attributes] = cookie.split(\"; \");\n const [name, value] = nameValue.split(\"=\");\n\n const cookieObj: CookieAttributes = { value };\n\n attributes.forEach((attr) => {\n const [attrName, attrValue] = attr.split(\"=\");\n cookieObj[attrName.toLowerCase() as \"value\"] = attrValue;\n });\n\n cookieMap.set(name, cookieObj);\n });\n\n return cookieMap;\n}\n\nexport function getSetCookie(header: string, prevCookie?: string) {\n const parsed = parseSetCookieHeader(header);\n let toSetCookie: Record<string, StoredCookie> = {};\n parsed.forEach((cookie, key) => {\n const expiresAt = cookie[\"expires\"];\n const maxAge = cookie[\"max-age\"];\n const expires = expiresAt\n ? new Date(String(expiresAt))\n : maxAge\n ? new Date(Date.now() + Number(maxAge))\n : null;\n toSetCookie[key] = {\n value: cookie[\"value\"],\n expires,\n };\n });\n if (prevCookie) {\n try {\n const prevCookieParsed = JSON.parse(prevCookie);\n toSetCookie = {\n ...prevCookieParsed,\n ...toSetCookie,\n };\n } catch {\n //\n }\n }\n return JSON.stringify(toSetCookie);\n}\n\n\nexport function getCookie(cookie: string) {\n\tlet parsed = {} as Record<string, StoredCookie>;\n\ttry {\n\t\tparsed = JSON.parse(cookie) as Record<string, StoredCookie>;\n\t} catch (e) {}\n\tconst toSend = Object.entries(parsed).reduce((acc, [key, value]) => {\n\t\tif (value.expires && value.expires < new Date()) {\n\t\t\treturn acc;\n\t\t}\n\t\treturn `${acc}; ${key}=${value.value}`;\n\t}, \"\");\n\treturn toSend;\n}\n","export class AuthKitError extends Error {}\nexport class RefreshError extends AuthKitError {}\nexport class CodeExchangeError extends AuthKitError {}\nexport class LoginRequiredError extends AuthKitError {\n readonly message: string = \"No access token available\";\n}\n","export const fetchWithOrganizationIdAndCookie = ({\n baseUrl,\n organizationId,\n cookie,\n path,\n method,\n options,\n body = {},\n}: {\n baseUrl: string;\n organizationId: string;\n cookie?: string;\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n options?: RequestInit;\n body?: Record<string, unknown>;\n}) => {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"Accept\": \"application/json, text/plain, */*\",\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": organizationId,\n \"cookie\": cookie || \"\",\n },\n credentials: \"include\",\n ...options,\n };\n\n if (method !== \"GET\" && body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n return fetch(`${baseUrl}${path}`, fetchOptions);\n};\n","import type { User, UserRaw } from \"../interfaces\";\n\nexport const deserializeUser = (user: UserRaw): User => ({\n object: user.object,\n id: user.id,\n email: user.email,\n emailVerified: user.email_verified,\n firstName: user.first_name,\n profilePictureUrl: user.profile_picture_url,\n lastName: user.last_name,\n lastSignInAt: user.last_sign_in_at,\n externalId: user.external_id,\n createdAt: user.created_at,\n updatedAt: user.updated_at,\n});\n","import type {\n AuthenticationResponse,\n AuthenticationResponseRaw,\n} from \"../interfaces\";\nimport { deserializeUser } from \"./user.serializer\";\n\nexport const deserializeAuthenticationResponse = (\n authenticationResponse: AuthenticationResponseRaw,\n): AuthenticationResponse => {\n const {\n user,\n organization_id,\n access_token,\n refresh_token,\n impersonator,\n ...rest\n } = authenticationResponse;\n\n return {\n user: deserializeUser(user),\n organizationId: organization_id,\n accessToken: access_token,\n refreshToken: refresh_token,\n impersonator,\n ...rest,\n };\n};\n","import { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport {\n AuthenticationResponseRaw,\n GetAuthorizationUrlOptions,\n User,\n} from \"./interfaces\";\nimport { deserializeAuthenticationResponse } from \"./serializers\";\n\nexport class CookieHttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n async authenticateWithCode({ code }: { code: string }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/authenticate\",\n method: \"POST\",\n body: {\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n },\n });\n\n if (response.ok) {\n const data = (await response.json()) as AuthenticationResponseRaw;\n return deserializeAuthenticationResponse(data);\n }\n\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n async getAuthorizationUrl({ redirectUri }: GetAuthorizationUrlOptions) {\n const params = new URLSearchParams(\n redirectUri\n ? {\n redirectUri: redirectUri,\n authorizationCallbackUri: `${this.#baseUrl}/api/user_management/auth/callback`,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n }\n : {},\n );\n\n const url = new URL(\"api/user_management/signIn\", this.#baseUrl);\n url.search = params.toString();\n return url.toString();\n }\n\n async getUser() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getUser\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { user: User };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.user) {\n return null;\n }\n\n return parsed.user as User;\n }\n\n async getAccessToken() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getAccessToken\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { accessToken: string };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.accessToken) {\n return null;\n }\n\n return parsed.accessToken as string;\n }\n\n async getLogoutUrl({ returnTo }: { returnTo: string | undefined }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getLogOutUrl\",\n method: \"POST\",\n body: {\n returnTo,\n client_id: this.#clientId,\n },\n });\n\n const { url: logoutUrl } = (await response.json()) as { url: string };\n return logoutUrl;\n }\n}\n","export class NoClientIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoClientIdProvidedException\";\n readonly message: string = `Missing Client ID. Pass it to the constructor (createClient(\"client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7\"))`;\n}\n\nexport class NoOrganizationIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoOrganizationIdProvidedException\";\n readonly message: string = `Missing Organization ID. Pass it to the constructor`;\n}\n","import * as AuthSession from \"expo-auth-session\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport { User } from \"./interfaces\";\n\nexport class HttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n #buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId,\n organizationId,\n }: {\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n clientId: string;\n organizationId: string;\n }) {\n const params = new URLSearchParams({\n response_type: \"code\",\n clientId,\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n organizationId,\n });\n\n return `${this.#baseUrl}/api/user_management/mobile/signIn?${params.toString()}`;\n }\n\n async startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod,\n }: {\n codeChallenge: string;\n codeChallengeMethod: \"S256\";\n }) {\n const redirectUri = AuthSession.makeRedirectUri({\n native: \"yboardstarter:\",\n }).toString();\n const authUrl = this.#buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n });\n\n let code: string | undefined;\n\n const webResult = await WebBrowser.openAuthSessionAsync(\n authUrl,\n redirectUri,\n );\n\n switch (webResult.type) {\n case \"success\":\n if (webResult.url) {\n const urlParts = webResult.url.split(\"?\");\n if (urlParts.length > 1) {\n const queryString = urlParts[1];\n const params = queryString.split(\"&\");\n for (const param of params) {\n const [key, value] = param.split(\"=\");\n if (key === \"code\") {\n code = decodeURIComponent(value);\n break;\n }\n }\n }\n } else {\n console.warn(\"Success result but no URL returned\");\n }\n break;\n\n case \"cancel\":\n console.warn(\"User cancelled the auth flow.\");\n throw new Error(\"Authentication cancelled.\");\n\n case \"dismiss\":\n console.warn(\n \"Auth flow was dismissed (possibly due to backgrounding).\",\n );\n throw new Error(\"Authentication dismissed.\");\n\n case \"locked\":\n console.warn(\"Another auth session is already in progress.\");\n throw new Error(\"Authentication session already active.\");\n\n default:\n console.error(\"Unhandled web result type:\", webResult.type);\n throw new Error(`Unhandled auth session result: ${webResult.type}`);\n }\n\n if (!code) {\n throw new Error(\"No authorization code found in redirect URL.\");\n }\n\n return { code };\n }\n\n async authenticateWithCode({\n code,\n codeVerifier,\n redirectUri,\n }: {\n code: string;\n codeVerifier: string;\n redirectUri: string;\n }): Promise<string | null> {\n const response = await fetch(\n `${this.#baseUrl}/api/user_management/mobile/authenticate`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": this.#organizationId,\n },\n body: JSON.stringify({\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n }),\n },\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n const setCookie = response.headers.get(\"set-cookie\");\n return setCookie;\n }\n\n async getUser({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getUser\",\n method: \"GET\",\n });\n\n if (!response.ok) {\n return null;\n }\n const { user } = (await response.json()) as { user: User };\n return user;\n }\n\n async getAccessToken({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getAccessToken\",\n method: \"GET\",\n });\n\n const { accessToken } = (await response.json()) as { accessToken: string };\n return accessToken;\n }\n\n async getLogoutUrl({\n returnTo,\n cookie,\n }: { returnTo?: string; cookie?: string } = {}): Promise<string | null> {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getLogOutUrl\",\n method: \"POST\",\n body: { client_id: this.#clientId, returnTo: returnTo || \"\" },\n });\n\n const { url } = await response.json();\n return url;\n }\n}\n","/**\n * Checks if the current URL is a redirect callback from the auth server.\n *\n * In React Native, you must pass the current URL explicitly (since window.location is not available).\n */\nexport function isRedirectCallback(\n redirectUri: string,\n searchParams: Record<string, any>,\n currentUrl?: string // Pass the current URL explicitly in React Native\n) {\n // Only support the object returned by query-string\n const hasCode = typeof searchParams === \"object\" && \"code\" in searchParams;\n\n if (!hasCode) return false;\n\n // If currentUrl is provided (React Native), use it.\n let currentUri: string;\n if (currentUrl) {\n // Remove query and hash from currentUrl\n const urlObj = new URL(currentUrl);\n currentUri = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;\n } else {\n // Can't determine current URI\n return false;\n }\n\n return currentUri === redirectUri || currentUri === `${redirectUri}/`;\n}\n","function createMemoryStorage() {\n let _store: { [key: string]: unknown } = {};\n\n function setItem(key: string, value: unknown): void {\n _store[key] = value;\n }\n\n function getItem(key: string): unknown {\n return _store[key];\n }\n\n function removeItem(key: string): void {\n delete _store[key];\n }\n\n function reset(): void {\n _store = {};\n }\n\n return {\n setItem,\n getItem,\n removeItem,\n reset,\n };\n}\n\nconst memoryStorage = createMemoryStorage();\n\nexport { memoryStorage };\n","import * as Crypto from \"expo-crypto\";\n\nexport async function createPkceChallenge() {\n const codeVerifier = await generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n return { codeVerifier, codeChallenge };\n}\n\nasync function generateCodeVerifier(): Promise<string> {\n // Generate 32 random bytes and encode as base64url\n const randomBytes = await Crypto.getRandomBytesAsync(32);\n return base64urlEncode(randomBytes);\n}\n\nasync function generateCodeChallenge(codeVerifier: string): Promise<string> {\n // Hash the code verifier using SHA-256 and encode as base64url\n const hash = await Crypto.digestStringAsync(\n Crypto.CryptoDigestAlgorithm.SHA256,\n codeVerifier,\n { encoding: Crypto.CryptoEncoding.BASE64 },\n );\n // Convert base64 to base64url\n return hash.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nfunction base64urlEncode(uint8Array: Uint8Array): string {\n // Convert Uint8Array to base64\n let binary = \"\";\n for (let i = 0; i < uint8Array.length; i++) {\n binary += String.fromCharCode(uint8Array[i]);\n }\n const base64 = btoa(binary);\n\n // Convert base64 to base64url\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n","let AsyncStorage: any = null;\ntry {\n AsyncStorage = require(\"@react-native-async-storage/async-storage\").default;\n} catch (e) {\n // Not in React Native, ignore\n}\n\nfunction isReactNative() {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.product === \"ReactNative\"\n );\n}\n\nconst nativeStorage = {\n async setItem(key: string, value: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.setItem(key, value);\n } else {\n // fallback to in-memory for web\n (globalThis as any).__nativeMemoryStore = (globalThis as any).__nativeMemoryStore || {};\n (globalThis as any).__nativeMemoryStore[key] = value;\n }\n },\n async getItem(key: string): Promise<string | null> {\n if (isReactNative() && AsyncStorage) {\n return await AsyncStorage.getItem(key);\n } else {\n return (globalThis as any).__nativeMemoryStore?.[key] ?? null;\n }\n },\n async removeItem(key: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.removeItem(key);\n } else {\n if ((globalThis as any).__nativeMemoryStore) {\n delete (globalThis as any).__nativeMemoryStore[key];\n }\n }\n }\n};\n\nexport { nativeStorage };\n","export const storageKeys = {\n codeVerifier: \"code-verifier\",\n user: \"user\",\n accessToken: \"access-token\",\n refreshToken: \"refresh-token\",\n expiresAt: \"expires-at\",\n} as const;\n","import type { AuthenticationResponse } from \"../interfaces\";\nimport { memoryStorage } from \"./memory-storage\";\nimport { nativeStorage } from \"./native-storage\";\nimport { storageKeys } from \"./storage-keys\";\n\ninterface AccessToken {\n exp: number;\n iat: number;\n iss: string;\n jti: string;\n sid: string;\n sub: string;\n org_id?: string;\n role?: string;\n permissions?: string[];\n}\n\n// should replace this with jose if we ever need to verify the JWT\nexport function getClaims(accessToken: string) {\n return JSON.parse(atob(accessToken.split(\".\")[1])) as AccessToken;\n}\n\nexport function setSessionData(\n data: AuthenticationResponse,\n { devMode = false } = {},\n) {\n const { user, accessToken, refreshToken } = data;\n memoryStorage.setItem(storageKeys.user, user);\n memoryStorage.setItem(storageKeys.accessToken, accessToken);\n if (devMode) {\n nativeStorage.setItem(storageKeys.refreshToken, refreshToken);\n } else {\n memoryStorage.setItem(storageKeys.refreshToken, refreshToken);\n }\n\n // compute a local time version of expires at (should avoid issues with slightly-wrong clocks)\n const { exp, iat } = getClaims(accessToken);\n const expiresIn = exp - iat;\n const expiresAt = Date.now() + expiresIn * 1000;\n memoryStorage.setItem(storageKeys.expiresAt, expiresAt);\n}\n\nexport function removeSessionData({ devMode = false } = {}) {\n memoryStorage.removeItem(storageKeys.user);\n memoryStorage.removeItem(storageKeys.accessToken);\n if (devMode) {\n nativeStorage.removeItem(storageKeys.refreshToken);\n } else {\n memoryStorage.removeItem(storageKeys.refreshToken);\n }\n}\n\nexport async function getRefreshToken({ devMode = false } = {}) {\n if (devMode) {\n return await nativeStorage.getItem(storageKeys.refreshToken);\n } else {\n return memoryStorage.getItem(storageKeys.refreshToken) as string | undefined;\n }\n}\n","import { createClient, LoginRequiredError } from \"../client\";\nimport type { RedirectOptions } from \"../client/create-client\";\nimport type { State } from \"./state\";\nimport React, { useState } from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport type Client = Pick<\n Awaited<ReturnType<typeof createClient>>,\n \"signIn\" | \"signUp\" | \"getUser\" | \"getAccessToken\" | \"signOut\"\n>;\n\nexport type CreateClientOptions = NonNullable<\n Parameters<typeof createClient>[1]\n>;\n\ntype YboardAuthProviderProps = CreateClientOptions & {\n clientId: string;\n organizationId: string;\n children: React.ReactNode;\n};\n\nexport function YboardAuthProvider(props: YboardAuthProviderProps) {\n const {\n clientId,\n apiHostname,\n https,\n port,\n redirectUri,\n children,\n organizationId,\n refreshBufferInterval,\n } = props;\n const [client, setClient] = useState<Client>(NOOP_CLIENT);\n const [state, setState] = React.useState(initialState);\n\n React.useEffect(() => {\n async function initialize() {\n try {\n const client = await createClient(clientId, {\n apiHostname,\n port,\n organizationId,\n https,\n redirectUri,\n refreshBufferInterval,\n });\n const user = await client.getUser();\n\n setClient({\n getAccessToken: client.getAccessToken.bind(client),\n getUser: client.getUser.bind(client),\n signIn: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signIn(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signUp: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signUp(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signOut: async (...args: [{ returnTo: string }?]) => {\n await client.signOut(...args);\n setState((prev: State) => ({ ...prev, user: null }));\n },\n });\n setState((prev: State) => ({ ...prev, isLoading: false, user }));\n } catch (err) {\n console.error(\"Error initializing auth client:\", err);\n setState((prev: State) => ({ ...prev, isLoading: false, user: null }));\n }\n }\n\n initialize();\n }, []);\n\n return (\n <YboardAuthContext.Provider value={{ ...client, ...state }}>\n {children}\n </YboardAuthContext.Provider>\n );\n}\n\nconst NOOP_CLIENT: Client = {\n signIn: async () => {},\n signUp: async () => {},\n getUser: () => Promise.resolve(null),\n getAccessToken: () => Promise.reject(new LoginRequiredError()),\n signOut: async () => Promise.resolve(),\n};\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { type State, initialState } from \"./state\";\nimport type { Client } from \"./authProvider\";\n\nexport interface ContextValue extends Client, State { }\n\nexport const YboardAuthContext = React.createContext<ContextValue>(\n initialState as ContextValue,\n);\n","import type { User } from \"../client/interfaces\";\n\nexport interface State {\n isLoading: boolean;\n user: User | null;\n role: string | null;\n organizationId: string | null;\n permissions: string[];\n}\n\nexport const initialState: State = {\n isLoading: true,\n user: null,\n role: null,\n organizationId: null,\n permissions: [],\n};\n","import * as React from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport function useYboardAuth() {\n const context = React.useContext(YboardAuthContext);\n\n if (context === initialState) {\n throw new Error(\"useYboardAuth must be used within a YboardAuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["index_exports","__export","AuthKitError","LoginRequiredError","YboardAuthProvider","createClient","getClaims","memoryStorage","useYboardAuth","__toCommonJS","AuthSession","SecureStore","WebBrowser","import_react_native","parseSetCookieHeader","header","cookieMap","cookie","nameValue","attributes","name","value","cookieObj","attr","attrName","attrValue","getSetCookie","prevCookie","parsed","toSetCookie","key","expiresAt","maxAge","expires","getCookie","acc","AuthKitError","CodeExchangeError","AuthKitError","LoginRequiredError","fetchWithOrganizationIdAndCookie","baseUrl","organizationId","cookie","path","method","options","body","fetchOptions","deserializeUser","user","deserializeAuthenticationResponse","authenticationResponse","user","organization_id","access_token","refresh_token","impersonator","rest","deserializeUser","_baseUrl","_clientId","_organizationId","CookieHttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","code","response","fetchWithOrganizationIdAndCookie","__privateGet","data","deserializeAuthenticationResponse","error","CodeExchangeError","redirectUri","params","url","text","parsed","returnTo","logoutUrl","NoClientIdProvidedException","NoOrganizationIdProvidedException","AuthSession","WebBrowser","_baseUrl","_clientId","_organizationId","_HttpClient_instances","buildAuthUrl_fn","HttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","codeChallenge","codeChallengeMethod","redirectUri","authUrl","__privateMethod","__privateGet","code","webResult","urlParts","params","param","key","value","codeVerifier","response","error","CodeExchangeError","cookie","fetchWithOrganizationIdAndCookie","user","accessToken","returnTo","url","isRedirectCallback","redirectUri","searchParams","currentUrl","currentUri","urlObj","createMemoryStorage","_store","setItem","key","value","getItem","removeItem","reset","memoryStorage","Crypto","createPkceChallenge","codeVerifier","generateCodeVerifier","codeChallenge","generateCodeChallenge","randomBytes","base64urlEncode","uint8Array","binary","i","AsyncStorage","storageKeys","getClaims","accessToken","_httpClient","_redirectUri","_Client_instances","redirect_fn","signOutNative_fn","getAccessTokenNative_fn","getUserNative_fn","redirectNative_fn","authenticate_fn","signOutWeb_fn","getAccessTokenWeb_fn","getUserWeb_fn","handleCallback_fn","redirectWeb_fn","Client","clientId","hostname","https","port","organizationId","redirectUri","devMode","__privateAdd","NoClientIdProvidedException","NoOrganizationIdProvidedException","__privateSet","CookieHttpClient","HttpClient","__privateMethod","searchParams","isRedirectCallback","__privateGet","opts","options","origin","url","domainParts","stored","cookie","getCookie","logoutUrl","user","context","invitationToken","loginHint","passwordResetToken","state","codeVerifier","codeChallenge","createPkceChallenge","memoryStorage","storageKeys","code","prev","updated","getSetCookie","domain","cleanUrl","type","provider","createClient","client","import_react","React","initialState","YboardAuthContext","initialState","import_jsx_runtime","YboardAuthProvider","props","clientId","apiHostname","https","port","redirectUri","children","organizationId","refreshBufferInterval","client","setClient","NOOP_CLIENT","state","setState","React","initialState","initialize","createClient","user","args","prev","YboardAuthContext","LoginRequiredError","React","useYboardAuth","context","YboardAuthContext","initialState"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client/create-client.ts","../src/client/cookie.ts","../src/client/errors.ts","../src/client/globalFetch.ts","../src/client/serializers/user.serializer.ts","../src/client/serializers/authentication-response.serializer.ts","../src/client/cookie-http-client.ts","../src/client/exceptions/no-client-id-provided.exception.ts","../src/client/http-client.ts","../src/client/utils/is-redirect-callback.ts","../src/client/utils/memory-storage.ts","../src/client/utils/pkce.ts","../src/client/utils/native-storage.ts","../src/client/utils/storage-keys.ts","../src/client/utils/session-data.ts","../src/provider/authProvider.tsx","../src/provider/context.ts","../src/provider/state.ts","../src/provider/hook.ts"],"sourcesContent":["// Client exports\nexport { createClient } from \"./client/create-client\";\nexport type { RedirectOptions } from \"./client/create-client\";\nexport { getClaims } from \"./client/utils/session-data\";\nexport type { User, AuthenticationResponse } from \"./client/interfaces\";\nexport { AuthKitError, LoginRequiredError } from \"./client/errors\";\nexport { memoryStorage } from \"./client/utils/memory-storage\";\n\n// Provider exports\nexport { YboardAuthProvider } from \"./provider/authProvider\";\nexport { useYboardAuth } from \"./provider/hook\";\n","import * as AuthSession from \"expo-auth-session\";\nimport * as SecureStore from \"expo-secure-store\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { Platform } from \"react-native\";\nimport { getCookie, getSetCookie } from \"./cookie\";\nimport { CookieHttpClient } from \"./cookie-http-client\";\nimport { NoClientIdProvidedException } from \"./exceptions\";\nimport { NoOrganizationIdProvidedException } from \"./exceptions/no-client-id-provided.exception\";\nimport { HttpClient } from \"./http-client\";\nimport type { CreateClientOptions, User } from \"./interfaces\";\nimport {\n createPkceChallenge,\n isRedirectCallback,\n memoryStorage,\n storageKeys,\n} from \"./utils\";\n\nexport interface RedirectOptions {\n provider?: string;\n context?: string;\n invitationToken?: string;\n loginHint?: string;\n organizationId?: string;\n passwordResetToken?: string;\n state?: any;\n type: \"sign-in\" | \"sign-up\";\n}\n\nexport class Client {\n readonly #httpClient: HttpClient | CookieHttpClient;\n #redirectUri: string;\n\n constructor(\n clientId: string,\n {\n apiHostname: hostname,\n https,\n port,\n organizationId,\n redirectUri,\n devMode,\n }: CreateClientOptions,\n ) {\n if (!clientId) {\n throw new NoClientIdProvidedException();\n }\n if (!organizationId) {\n throw new NoOrganizationIdProvidedException();\n }\n\n // Platform-specific defaults\n if (Platform.OS === \"web\") {\n // --- Web defaults ---\n redirectUri = redirectUri ?? window.origin;\n devMode =\n devMode ??\n (location.hostname === \"localhost\" ||\n location.hostname === \"127.0.0.1\");\n } else {\n // --- Native defaults ---\n redirectUri = redirectUri ?? \"\";\n devMode = devMode ?? false;\n }\n\n // Use CookieHttpClient for web (cookie-based), HttpClient for native (token-based)\n if (Platform.OS === \"web\") {\n this.#httpClient = new CookieHttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n } else {\n this.#httpClient = new HttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n }\n\n this.#redirectUri = redirectUri;\n }\n\n // ============================================================\n // Cross-platform methods\n // ============================================================\n\n async getAccessToken(): Promise<string | null> {\n if (Platform.OS === \"web\") {\n return this.#getAccessTokenWeb();\n } else {\n return this.#getAccessTokenNative();\n }\n }\n\n async getUser(): Promise<User | null> {\n if (Platform.OS === \"web\") {\n return this.#getUserWeb();\n } else {\n return this.#getUserNative();\n }\n }\n\n async #redirect(options: RedirectOptions) {\n if (Platform.OS === \"web\") {\n return this.#redirectWeb(options);\n } else {\n return this.#redirectNative(options);\n }\n }\n\n async initialize() {\n const searchParams = new URLSearchParams(window.location.search);\n if (isRedirectCallback(this.#redirectUri, searchParams)) {\n await this.#handleCallback();\n }\n }\n\n async signIn(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-in\" });\n }\n\n async signUp(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-up\" });\n }\n\n async signOut(options?: { returnTo: string }) {\n if (Platform.OS === \"web\") {\n return this.#signOutWeb(options);\n } else {\n return this.#signOutNative(options);\n }\n }\n\n // Native methods\n async #signOutNative(options?: { returnTo: string }) {\n const redirectUri =\n options?.returnTo ||\n AuthSession.makeRedirectUri({ native: \"yboardstarter:\" });\n\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n\n const logoutUrl = await (this.#httpClient as HttpClient).getLogoutUrl({\n returnTo: redirectUri,\n cookie,\n });\n\n if (logoutUrl) {\n try {\n const result = await WebBrowser.openAuthSessionAsync(\n logoutUrl,\n redirectUri,\n );\n\n if (result.type === \"success\") {\n await SecureStore.deleteItemAsync(\"yboard-session\");\n } else {\n console.warn(\"User cancelled or dismissed logout:\", result.type);\n }\n } catch (error) {\n console.error(\"Error during sign out:\", error);\n }\n }\n }\n\n async #getAccessTokenNative(): Promise<string | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const accessToken = await (this.#httpClient as HttpClient).getAccessToken({\n cookie,\n });\n return (accessToken as string) || null;\n }\n\n async #getUserNative(): Promise<User | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const user = await (this.#httpClient as HttpClient).getUser({ cookie });\n if (!user) {\n return null;\n }\n return user as User;\n }\n\n async #redirectNative({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n }: RedirectOptions) {\n const { codeVerifier, codeChallenge } = await createPkceChallenge();\n memoryStorage.setItem(storageKeys.codeVerifier, codeVerifier);\n\n const { code } = await (\n this.#httpClient as HttpClient\n ).startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod: \"S256\",\n });\n\n if (code) {\n const cookie = await this.#authenticate({\n code,\n codeVerifier,\n });\n if (cookie && typeof cookie === \"string\") {\n const prev = await SecureStore.getItemAsync(\"yboard-session\");\n const updated = getSetCookie(cookie, prev || undefined);\n await SecureStore.setItemAsync(\"yboard-session\", updated);\n }\n }\n }\n\n async #authenticate({\n code,\n codeVerifier,\n }: {\n code: string;\n codeVerifier: string;\n }): Promise<string | null> {\n if (typeof codeVerifier !== \"string\") return null;\n\n const cookie = await (this.#httpClient as HttpClient).authenticateWithCode({\n code,\n codeVerifier: codeVerifier,\n redirectUri: this.#redirectUri,\n });\n\n return cookie;\n }\n\n // Web methods\n async getCookieDomain(origin: string) {\n const url = new URL(origin);\n const domainParts = url.hostname.split(\".\");\n if (domainParts.length > 1) {\n return \".\" + domainParts.slice(-2).join(\".\");\n }\n return url.hostname;\n }\n\n async #signOutWeb(options?: { returnTo: string }) {\n const url = await (this.#httpClient as CookieHttpClient).getLogoutUrl({\n returnTo: options?.returnTo,\n });\n\n if (url) {\n const domain = await this.getCookieDomain(this.#redirectUri);\n document.cookie = `yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}`;\n window.location.assign(url);\n }\n }\n\n async #getAccessTokenWeb(): Promise<string | null> {\n const accessToken = await (\n this.#httpClient as CookieHttpClient\n ).getAccessToken();\n return accessToken as string | null;\n }\n\n async #getUserWeb(): Promise<User | null> {\n const user = await (this.#httpClient as CookieHttpClient).getUser();\n return user as User | null;\n }\n\n async #handleCallback() {\n const cleanUrl = new URL(window.location.toString());\n cleanUrl.search = \"\";\n window.history.replaceState({}, \"\", cleanUrl);\n }\n\n async #redirectWeb({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n type,\n provider,\n }: RedirectOptions) {\n const url = await (\n this.#httpClient as CookieHttpClient\n ).getAuthorizationUrl({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n redirectUri: this.#redirectUri,\n state: state ? JSON.stringify(state) : undefined,\n });\n window.location.assign(url);\n }\n}\n\nexport async function createClient(\n clientId: string,\n options: CreateClientOptions,\n) {\n const client = new Client(clientId, options);\n\n // Only initialize for web platform\n if (Platform.OS === \"web\") {\n await client.initialize();\n }\n\n return client;\n}\n","interface CookieAttributes {\n\tvalue: string;\n\texpires?: Date;\n\t\"max-age\"?: number;\n\tdomain?: string;\n\tpath?: string;\n\tsecure?: boolean;\n\thttpOnly?: boolean;\n\tsameSite?: \"Strict\" | \"Lax\" | \"None\";\n}\n\ninterface StoredCookie {\n\tvalue: string;\n\texpires: Date | null;\n}\n\nexport function parseSetCookieHeader(\n header: string,\n): Map<string, CookieAttributes> {\n const cookieMap = new Map<string, CookieAttributes>();\n const cookies = header.split(\", \");\n cookies.forEach((cookie) => {\n const [nameValue, ...attributes] = cookie.split(\"; \");\n const [name, value] = nameValue.split(\"=\");\n\n const cookieObj: CookieAttributes = { value };\n\n attributes.forEach((attr) => {\n const [attrName, attrValue] = attr.split(\"=\");\n cookieObj[attrName.toLowerCase() as \"value\"] = attrValue;\n });\n\n cookieMap.set(name, cookieObj);\n });\n\n return cookieMap;\n}\n\nexport function getSetCookie(header: string, prevCookie?: string) {\n const parsed = parseSetCookieHeader(header);\n let toSetCookie: Record<string, StoredCookie> = {};\n parsed.forEach((cookie, key) => {\n const expiresAt = cookie[\"expires\"];\n const maxAge = cookie[\"max-age\"];\n const expires = expiresAt\n ? new Date(String(expiresAt))\n : maxAge\n ? new Date(Date.now() + Number(maxAge))\n : null;\n toSetCookie[key] = {\n value: cookie[\"value\"],\n expires,\n };\n });\n if (prevCookie) {\n try {\n const prevCookieParsed = JSON.parse(prevCookie);\n toSetCookie = {\n ...prevCookieParsed,\n ...toSetCookie,\n };\n } catch {\n //\n }\n }\n return JSON.stringify(toSetCookie);\n}\n\n\nexport function getCookie(cookie: string) {\n\tlet parsed = {} as Record<string, StoredCookie>;\n\ttry {\n\t\tparsed = JSON.parse(cookie) as Record<string, StoredCookie>;\n\t} catch (e) {}\n\tconst toSend = Object.entries(parsed).reduce((acc, [key, value]) => {\n\t\tif (value.expires && value.expires < new Date()) {\n\t\t\treturn acc;\n\t\t}\n\t\treturn `${acc}; ${key}=${value.value}`;\n\t}, \"\");\n\treturn toSend;\n}\n","export class AuthKitError extends Error {}\nexport class RefreshError extends AuthKitError {}\nexport class CodeExchangeError extends AuthKitError {}\nexport class LoginRequiredError extends AuthKitError {\n readonly message: string = \"No access token available\";\n}\n","export const fetchWithOrganizationIdAndCookie = ({\n baseUrl,\n organizationId,\n cookie,\n path,\n method,\n options,\n body = {},\n}: {\n baseUrl: string;\n organizationId: string;\n cookie?: string;\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n options?: RequestInit;\n body?: Record<string, unknown>;\n}) => {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"Accept\": \"application/json, text/plain, */*\",\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": organizationId,\n \"cookie\": cookie || \"\",\n },\n credentials: \"include\",\n ...options,\n };\n\n if (method !== \"GET\" && body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n return fetch(`${baseUrl}${path}`, fetchOptions);\n};\n","import type { User, UserRaw } from \"../interfaces\";\n\nexport const deserializeUser = (user: UserRaw): User => ({\n object: user.object,\n id: user.id,\n email: user.email,\n emailVerified: user.email_verified,\n firstName: user.first_name,\n profilePictureUrl: user.profile_picture_url,\n lastName: user.last_name,\n lastSignInAt: user.last_sign_in_at,\n externalId: user.external_id,\n createdAt: user.created_at,\n updatedAt: user.updated_at,\n});\n","import type {\n AuthenticationResponse,\n AuthenticationResponseRaw,\n} from \"../interfaces\";\nimport { deserializeUser } from \"./user.serializer\";\n\nexport const deserializeAuthenticationResponse = (\n authenticationResponse: AuthenticationResponseRaw,\n): AuthenticationResponse => {\n const {\n user,\n organization_id,\n access_token,\n refresh_token,\n impersonator,\n ...rest\n } = authenticationResponse;\n\n return {\n user: deserializeUser(user),\n organizationId: organization_id,\n accessToken: access_token,\n refreshToken: refresh_token,\n impersonator,\n ...rest,\n };\n};\n","import { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport {\n AuthenticationResponseRaw,\n GetAuthorizationUrlOptions,\n User,\n} from \"./interfaces\";\nimport { deserializeAuthenticationResponse } from \"./serializers\";\n\nexport class CookieHttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n async authenticateWithCode({ code }: { code: string }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/authenticate\",\n method: \"POST\",\n body: {\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n },\n });\n\n if (response.ok) {\n const data = (await response.json()) as AuthenticationResponseRaw;\n return deserializeAuthenticationResponse(data);\n }\n\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n async getAuthorizationUrl({ redirectUri }: GetAuthorizationUrlOptions) {\n const params = new URLSearchParams(\n redirectUri\n ? {\n redirectUri: redirectUri,\n authorizationCallbackUri: `${this.#baseUrl}/api/user_management/auth/callback`,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n }\n : {},\n );\n\n const url = new URL(\"api/user_management/signIn\", this.#baseUrl);\n url.search = params.toString();\n return url.toString();\n }\n\n async getUser() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getUser\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { user: User };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.user) {\n return null;\n }\n\n return parsed.user as User;\n }\n\n async getAccessToken() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getAccessToken\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { accessToken: string };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.accessToken) {\n return null;\n }\n\n return parsed.accessToken as string;\n }\n\n async getLogoutUrl({ returnTo }: { returnTo: string | undefined }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getLogOutUrl\",\n method: \"POST\",\n body: {\n returnTo,\n client_id: this.#clientId,\n },\n });\n\n const { url: logoutUrl } = (await response.json()) as { url: string };\n return logoutUrl;\n }\n}\n","export class NoClientIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoClientIdProvidedException\";\n readonly message: string = `Missing Client ID. Pass it to the constructor (createClient(\"client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7\"))`;\n}\n\nexport class NoOrganizationIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoOrganizationIdProvidedException\";\n readonly message: string = `Missing Organization ID. Pass it to the constructor`;\n}\n","import * as AuthSession from \"expo-auth-session\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport { User } from \"./interfaces\";\n\nexport class HttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n #buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId,\n organizationId,\n }: {\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n clientId: string;\n organizationId: string;\n }) {\n const params = new URLSearchParams({\n response_type: \"code\",\n clientId,\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n organizationId,\n });\n\n return `${this.#baseUrl}/api/user_management/mobile/signIn?${params.toString()}`;\n }\n\n async startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod,\n }: {\n codeChallenge: string;\n codeChallengeMethod: \"S256\";\n }) {\n const redirectUri = AuthSession.makeRedirectUri({\n native: \"yboardstarter:\",\n }).toString();\n const authUrl = this.#buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n });\n\n let code: string | undefined;\n\n const webResult = await WebBrowser.openAuthSessionAsync(\n authUrl,\n redirectUri,\n );\n\n switch (webResult.type) {\n case \"success\":\n if (webResult.url) {\n const urlParts = webResult.url.split(\"?\");\n if (urlParts.length > 1) {\n const queryString = urlParts[1];\n const params = queryString.split(\"&\");\n for (const param of params) {\n const [key, value] = param.split(\"=\");\n if (key === \"code\") {\n // Strip URL fragment (#) — iOS includes it in the redirect URL\n code = decodeURIComponent(value).split(\"#\")[0];\n break;\n }\n }\n }\n } else {\n console.warn(\"Success result but no URL returned\");\n }\n break;\n\n case \"cancel\":\n console.warn(\"User cancelled the auth flow.\");\n throw new Error(\"Authentication cancelled.\");\n\n case \"dismiss\":\n console.warn(\n \"Auth flow was dismissed (possibly due to backgrounding).\",\n );\n throw new Error(\"Authentication dismissed.\");\n\n case \"locked\":\n console.warn(\"Another auth session is already in progress.\");\n throw new Error(\"Authentication session already active.\");\n\n default:\n console.error(\"Unhandled web result type:\", webResult.type);\n throw new Error(`Unhandled auth session result: ${webResult.type}`);\n }\n\n if (!code) {\n throw new Error(\"No authorization code found in redirect URL.\");\n }\n\n return { code };\n }\n\n async authenticateWithCode({\n code,\n codeVerifier,\n redirectUri,\n }: {\n code: string;\n codeVerifier: string;\n redirectUri: string;\n }): Promise<string | null> {\n const response = await fetch(\n `${this.#baseUrl}/api/user_management/mobile/authenticate`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": this.#organizationId,\n },\n body: JSON.stringify({\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n }),\n },\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n const setCookie = response.headers.get(\"set-cookie\");\n return setCookie;\n }\n\n async getUser({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getUser\",\n method: \"GET\",\n });\n\n if (!response.ok) {\n return null;\n }\n const { user } = (await response.json()) as { user: User };\n return user;\n }\n\n async getAccessToken({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getAccessToken\",\n method: \"GET\",\n });\n\n const { accessToken } = (await response.json()) as { accessToken: string };\n return accessToken;\n }\n\n async getLogoutUrl({\n returnTo,\n cookie,\n }: { returnTo?: string; cookie?: string } = {}): Promise<string | null> {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getLogOutUrl\",\n method: \"POST\",\n body: { client_id: this.#clientId, returnTo: returnTo || \"\" },\n });\n\n const { url } = await response.json();\n return url;\n }\n}\n","/**\n * Checks if the current URL is a redirect callback from the auth server.\n *\n * In React Native, you must pass the current URL explicitly (since window.location is not available).\n */\nexport function isRedirectCallback(\n redirectUri: string,\n searchParams: Record<string, any>,\n currentUrl?: string // Pass the current URL explicitly in React Native\n) {\n // Only support the object returned by query-string\n const hasCode = typeof searchParams === \"object\" && \"code\" in searchParams;\n\n if (!hasCode) return false;\n\n // If currentUrl is provided (React Native), use it.\n let currentUri: string;\n if (currentUrl) {\n // Remove query and hash from currentUrl\n const urlObj = new URL(currentUrl);\n currentUri = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;\n } else {\n // Can't determine current URI\n return false;\n }\n\n return currentUri === redirectUri || currentUri === `${redirectUri}/`;\n}\n","function createMemoryStorage() {\n let _store: { [key: string]: unknown } = {};\n\n function setItem(key: string, value: unknown): void {\n _store[key] = value;\n }\n\n function getItem(key: string): unknown {\n return _store[key];\n }\n\n function removeItem(key: string): void {\n delete _store[key];\n }\n\n function reset(): void {\n _store = {};\n }\n\n return {\n setItem,\n getItem,\n removeItem,\n reset,\n };\n}\n\nconst memoryStorage = createMemoryStorage();\n\nexport { memoryStorage };\n","import * as Crypto from \"expo-crypto\";\n\nexport async function createPkceChallenge() {\n const codeVerifier = await generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n return { codeVerifier, codeChallenge };\n}\n\nasync function generateCodeVerifier(): Promise<string> {\n // Generate 32 random bytes and encode as base64url\n const randomBytes = await Crypto.getRandomBytesAsync(32);\n return base64urlEncode(randomBytes);\n}\n\nasync function generateCodeChallenge(codeVerifier: string): Promise<string> {\n // Hash the code verifier using SHA-256 and encode as base64url\n const hash = await Crypto.digestStringAsync(\n Crypto.CryptoDigestAlgorithm.SHA256,\n codeVerifier,\n { encoding: Crypto.CryptoEncoding.BASE64 },\n );\n // Convert base64 to base64url\n return hash.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nfunction base64urlEncode(uint8Array: Uint8Array): string {\n // Convert Uint8Array to base64\n let binary = \"\";\n for (let i = 0; i < uint8Array.length; i++) {\n binary += String.fromCharCode(uint8Array[i]);\n }\n const base64 = btoa(binary);\n\n // Convert base64 to base64url\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n","let AsyncStorage: any = null;\ntry {\n AsyncStorage = require(\"@react-native-async-storage/async-storage\").default;\n} catch (e) {\n // Not in React Native, ignore\n}\n\nfunction isReactNative() {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.product === \"ReactNative\"\n );\n}\n\nconst nativeStorage = {\n async setItem(key: string, value: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.setItem(key, value);\n } else {\n // fallback to in-memory for web\n (globalThis as any).__nativeMemoryStore = (globalThis as any).__nativeMemoryStore || {};\n (globalThis as any).__nativeMemoryStore[key] = value;\n }\n },\n async getItem(key: string): Promise<string | null> {\n if (isReactNative() && AsyncStorage) {\n return await AsyncStorage.getItem(key);\n } else {\n return (globalThis as any).__nativeMemoryStore?.[key] ?? null;\n }\n },\n async removeItem(key: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.removeItem(key);\n } else {\n if ((globalThis as any).__nativeMemoryStore) {\n delete (globalThis as any).__nativeMemoryStore[key];\n }\n }\n }\n};\n\nexport { nativeStorage };\n","export const storageKeys = {\n codeVerifier: \"code-verifier\",\n user: \"user\",\n accessToken: \"access-token\",\n refreshToken: \"refresh-token\",\n expiresAt: \"expires-at\",\n} as const;\n","import type { AuthenticationResponse } from \"../interfaces\";\nimport { memoryStorage } from \"./memory-storage\";\nimport { nativeStorage } from \"./native-storage\";\nimport { storageKeys } from \"./storage-keys\";\n\ninterface AccessToken {\n exp: number;\n iat: number;\n iss: string;\n jti: string;\n sid: string;\n sub: string;\n org_id?: string;\n role?: string;\n permissions?: string[];\n}\n\n// should replace this with jose if we ever need to verify the JWT\nexport function getClaims(accessToken: string) {\n return JSON.parse(atob(accessToken.split(\".\")[1])) as AccessToken;\n}\n\nexport function setSessionData(\n data: AuthenticationResponse,\n { devMode = false } = {},\n) {\n const { user, accessToken, refreshToken } = data;\n memoryStorage.setItem(storageKeys.user, user);\n memoryStorage.setItem(storageKeys.accessToken, accessToken);\n if (devMode) {\n nativeStorage.setItem(storageKeys.refreshToken, refreshToken);\n } else {\n memoryStorage.setItem(storageKeys.refreshToken, refreshToken);\n }\n\n // compute a local time version of expires at (should avoid issues with slightly-wrong clocks)\n const { exp, iat } = getClaims(accessToken);\n const expiresIn = exp - iat;\n const expiresAt = Date.now() + expiresIn * 1000;\n memoryStorage.setItem(storageKeys.expiresAt, expiresAt);\n}\n\nexport function removeSessionData({ devMode = false } = {}) {\n memoryStorage.removeItem(storageKeys.user);\n memoryStorage.removeItem(storageKeys.accessToken);\n if (devMode) {\n nativeStorage.removeItem(storageKeys.refreshToken);\n } else {\n memoryStorage.removeItem(storageKeys.refreshToken);\n }\n}\n\nexport async function getRefreshToken({ devMode = false } = {}) {\n if (devMode) {\n return await nativeStorage.getItem(storageKeys.refreshToken);\n } else {\n return memoryStorage.getItem(storageKeys.refreshToken) as string | undefined;\n }\n}\n","import { createClient, LoginRequiredError } from \"../client\";\nimport type { RedirectOptions } from \"../client/create-client\";\nimport type { State } from \"./state\";\nimport React, { useState } from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport type Client = Pick<\n Awaited<ReturnType<typeof createClient>>,\n \"signIn\" | \"signUp\" | \"getUser\" | \"getAccessToken\" | \"signOut\"\n>;\n\nexport type CreateClientOptions = NonNullable<\n Parameters<typeof createClient>[1]\n>;\n\ntype YboardAuthProviderProps = CreateClientOptions & {\n clientId: string;\n organizationId: string;\n children: React.ReactNode;\n};\n\nexport function YboardAuthProvider(props: YboardAuthProviderProps) {\n const {\n clientId,\n apiHostname,\n https,\n port,\n redirectUri,\n children,\n organizationId,\n refreshBufferInterval,\n } = props;\n const [client, setClient] = useState<Client>(NOOP_CLIENT);\n const [state, setState] = React.useState(initialState);\n\n React.useEffect(() => {\n async function initialize() {\n try {\n const client = await createClient(clientId, {\n apiHostname,\n port,\n organizationId,\n https,\n redirectUri,\n refreshBufferInterval,\n });\n const user = await client.getUser();\n\n setClient({\n getAccessToken: client.getAccessToken.bind(client),\n getUser: client.getUser.bind(client),\n signIn: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signIn(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signUp: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signUp(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signOut: async (...args: [{ returnTo: string }?]) => {\n await client.signOut(...args);\n setState((prev: State) => ({ ...prev, user: null }));\n },\n });\n setState((prev: State) => ({ ...prev, isLoading: false, user }));\n } catch (err) {\n console.error(\"Error initializing auth client:\", err);\n setState((prev: State) => ({ ...prev, isLoading: false, user: null }));\n }\n }\n\n initialize();\n }, []);\n\n return (\n <YboardAuthContext.Provider value={{ ...client, ...state }}>\n {children}\n </YboardAuthContext.Provider>\n );\n}\n\nconst NOOP_CLIENT: Client = {\n signIn: async () => {},\n signUp: async () => {},\n getUser: () => Promise.resolve(null),\n getAccessToken: () => Promise.reject(new LoginRequiredError()),\n signOut: async () => Promise.resolve(),\n};\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { type State, initialState } from \"./state\";\nimport type { Client } from \"./authProvider\";\n\nexport interface ContextValue extends Client, State { }\n\nexport const YboardAuthContext = React.createContext<ContextValue>(\n initialState as ContextValue,\n);\n","import type { User } from \"../client/interfaces\";\n\nexport interface State {\n isLoading: boolean;\n user: User | null;\n role: string | null;\n organizationId: string | null;\n permissions: string[];\n}\n\nexport const initialState: State = {\n isLoading: true,\n user: null,\n role: null,\n organizationId: null,\n permissions: [],\n};\n","import * as React from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport function useYboardAuth() {\n const context = React.useContext(YboardAuthContext);\n\n if (context === initialState) {\n throw new Error(\"useYboardAuth must be used within a YboardAuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["index_exports","__export","AuthKitError","LoginRequiredError","YboardAuthProvider","createClient","getClaims","memoryStorage","useYboardAuth","__toCommonJS","AuthSession","SecureStore","WebBrowser","import_react_native","parseSetCookieHeader","header","cookieMap","cookie","nameValue","attributes","name","value","cookieObj","attr","attrName","attrValue","getSetCookie","prevCookie","parsed","toSetCookie","key","expiresAt","maxAge","expires","getCookie","acc","AuthKitError","CodeExchangeError","AuthKitError","LoginRequiredError","fetchWithOrganizationIdAndCookie","baseUrl","organizationId","cookie","path","method","options","body","fetchOptions","deserializeUser","user","deserializeAuthenticationResponse","authenticationResponse","user","organization_id","access_token","refresh_token","impersonator","rest","deserializeUser","_baseUrl","_clientId","_organizationId","CookieHttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","code","response","fetchWithOrganizationIdAndCookie","__privateGet","data","deserializeAuthenticationResponse","error","CodeExchangeError","redirectUri","params","url","text","parsed","returnTo","logoutUrl","NoClientIdProvidedException","NoOrganizationIdProvidedException","AuthSession","WebBrowser","_baseUrl","_clientId","_organizationId","_HttpClient_instances","buildAuthUrl_fn","HttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","codeChallenge","codeChallengeMethod","redirectUri","authUrl","__privateMethod","__privateGet","code","webResult","urlParts","params","param","key","value","codeVerifier","response","error","CodeExchangeError","cookie","fetchWithOrganizationIdAndCookie","user","accessToken","returnTo","url","isRedirectCallback","redirectUri","searchParams","currentUrl","currentUri","urlObj","createMemoryStorage","_store","setItem","key","value","getItem","removeItem","reset","memoryStorage","Crypto","createPkceChallenge","codeVerifier","generateCodeVerifier","codeChallenge","generateCodeChallenge","randomBytes","base64urlEncode","uint8Array","binary","i","AsyncStorage","storageKeys","getClaims","accessToken","_httpClient","_redirectUri","_Client_instances","redirect_fn","signOutNative_fn","getAccessTokenNative_fn","getUserNative_fn","redirectNative_fn","authenticate_fn","signOutWeb_fn","getAccessTokenWeb_fn","getUserWeb_fn","handleCallback_fn","redirectWeb_fn","Client","clientId","hostname","https","port","organizationId","redirectUri","devMode","__privateAdd","NoClientIdProvidedException","NoOrganizationIdProvidedException","__privateSet","CookieHttpClient","HttpClient","__privateMethod","searchParams","isRedirectCallback","__privateGet","opts","options","origin","url","domainParts","stored","cookie","getCookie","logoutUrl","user","context","invitationToken","loginHint","passwordResetToken","state","codeVerifier","codeChallenge","createPkceChallenge","memoryStorage","storageKeys","code","prev","updated","getSetCookie","domain","cleanUrl","type","provider","createClient","client","import_react","React","initialState","YboardAuthContext","initialState","import_jsx_runtime","YboardAuthProvider","props","clientId","apiHostname","https","port","redirectUri","children","organizationId","refreshBufferInterval","client","setClient","NOOP_CLIENT","state","setState","React","initialState","initialize","createClient","user","args","prev","YboardAuthContext","LoginRequiredError","React","useYboardAuth","context","YboardAuthContext","initialState"]}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var re=r=>{throw TypeError(r)};var Ue=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var K=(r,e,t)=>e.has(r)||re("Cannot "+t);var i=(r,e,t)=>(K(r,e,"read from private field"),t?t.call(r):e.get(r)),p=(r,e,t)=>e.has(r)?re("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),d=(r,e,t,n)=>(K(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),u=(r,e,t)=>(K(r,e,"access private method"),t);import*as ce from"expo-auth-session";import*as U from"expo-secure-store";import*as le from"expo-web-browser";import{Platform as _}from"react-native";function Ae(r){let e=new Map;return r.split(", ").forEach(n=>{let[o,...s]=n.split("; "),[a,l]=o.split("="),h={value:l};s.forEach(f=>{let[w,I]=f.split("=");h[w.toLowerCase()]=I}),e.set(a,h)}),e}function ne(r,e){let t=Ae(r),n={};if(t.forEach((o,s)=>{let a=o.expires,l=o["max-age"],h=a?new Date(String(a)):l?new Date(Date.now()+Number(l)):null;n[s]={value:o.value,expires:h}}),e)try{n={...JSON.parse(e),...n}}catch{}return JSON.stringify(n)}function j(r){let e={};try{e=JSON.parse(r)}catch{}return Object.entries(e).reduce((n,[o,s])=>s.expires&&s.expires<new Date?n:`${n}; ${o}=${s.value}`,"")}var P=class extends Error{};var z=class extends P{},E=class extends P{constructor(){super(...arguments);this.message="No access token available"}};var b=({baseUrl:r,organizationId:e,cookie:t,path:n,method:o,options:s,body:a={}})=>{let l={method:o,headers:{Accept:"application/json, text/plain, */*","Content-Type":"application/json","X-Organization-Id":e,cookie:t||""},credentials:"include",...s};return o!=="GET"&&a&&(l.body=JSON.stringify(a)),fetch(`${r}${n}`,l)};var X=r=>({object:r.object,id:r.id,email:r.email,emailVerified:r.email_verified,firstName:r.first_name,profilePictureUrl:r.profile_picture_url,lastName:r.last_name,lastSignInAt:r.last_sign_in_at,externalId:r.external_id,createdAt:r.created_at,updatedAt:r.updated_at});var Q=r=>{let{user:e,organization_id:t,access_token:n,refresh_token:o,impersonator:s,...a}=r;return{user:X(e),organizationId:t,accessToken:n,refreshToken:o,impersonator:s,...a}};var y,O,k,D=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,y);p(this,O);p(this,k);d(this,y,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,O,e),d(this,k,o)}async authenticateWithCode({code:e}){let t=await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/authenticate",method:"POST",body:{code:e,client_id:i(this,O),grant_type:"authorization_code"}});if(t.ok){let o=await t.json();return Q(o)}let n=await t.json();throw new z(n.error_description)}async getAuthorizationUrl({redirectUri:e}){let t=new URLSearchParams(e?{redirectUri:e,authorizationCallbackUri:`${i(this,y)}/api/user_management/auth/callback`,clientId:i(this,O),organizationId:i(this,k)}:{}),n=new URL("api/user_management/signIn",i(this,y));return n.search=t.toString(),n.toString()}async getUser(){let t=await(await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/getUser",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.user?n.user:null}async getAccessToken(){let t=await(await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/getAccessToken",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.accessToken?n.accessToken:null}async getLogoutUrl({returnTo:e}){let t=await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/getLogOutUrl",method:"POST",body:{returnTo:e,client_id:i(this,O)}}),{url:n}=await t.json();return n}};y=new WeakMap,O=new WeakMap,k=new WeakMap;var H=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoClientIdProvidedException";this.message='Missing Client ID. Pass it to the constructor (createClient("client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7"))'}},V=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoOrganizationIdProvidedException";this.message="Missing Organization ID. Pass it to the constructor"}};import*as oe from"expo-auth-session";import*as se from"expo-web-browser";var S,v,x,M,ie,W=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,M);p(this,S);p(this,v);p(this,x);d(this,S,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,v,e),d(this,x,o)}async startAuthorizationFlow({codeChallenge:e,codeChallengeMethod:t}){let n=oe.makeRedirectUri({native:"yboardstarter:"}).toString(),o=u(this,M,ie).call(this,{redirectUri:n,codeChallenge:e,codeChallengeMethod:t,clientId:i(this,v),organizationId:i(this,x)}),s,a=await se.openAuthSessionAsync(o,n);switch(a.type){case"success":if(a.url){let l=a.url.split("?");if(l.length>1){let f=l[1].split("&");for(let w of f){let[I,C]=w.split("=");if(I==="code"){s=decodeURIComponent(C);break}}}}break;case"cancel":throw new Error("Authentication cancelled.");case"dismiss":throw new Error("Authentication dismissed.");case"locked":throw new Error("Authentication session already active.");default:throw new Error(`Unhandled auth session result: ${a.type}`)}if(!s)throw new Error("No authorization code found in redirect URL.");return{code:s}}async authenticateWithCode({code:e,codeVerifier:t,redirectUri:n}){let o=await fetch(`${i(this,S)}/api/user_management/mobile/authenticate`,{method:"POST",headers:{"Content-Type":"application/json","X-Organization-Id":i(this,x)},body:JSON.stringify({code:e,client_id:i(this,v),grant_type:"authorization_code",code_verifier:t,redirect_uri:n})});if(!o.ok){let a=await o.json();throw new z(a.error_description)}return o.headers.get("set-cookie")}async getUser({cookie:e}={}){let t=await b({baseUrl:i(this,S),organizationId:i(this,x),cookie:e,path:"/api/user_management/mobile/getUser",method:"GET"});if(!t.ok)return null;let{user:n}=await t.json();return n}async getAccessToken({cookie:e}={}){let t=await b({baseUrl:i(this,S),organizationId:i(this,x),cookie:e,path:"/api/user_management/mobile/getAccessToken",method:"GET"}),{accessToken:n}=await t.json();return n}async getLogoutUrl({returnTo:e,cookie:t}={}){let n=await b({baseUrl:i(this,S),organizationId:i(this,x),cookie:t,path:"/api/user_management/mobile/getLogOutUrl",method:"POST",body:{client_id:i(this,v),returnTo:e||""}}),{url:o}=await n.json();return o}};S=new WeakMap,v=new WeakMap,x=new WeakMap,M=new WeakSet,ie=function({redirectUri:e,codeChallenge:t,codeChallengeMethod:n,clientId:o,organizationId:s}){let a=new URLSearchParams({response_type:"code",clientId:o,redirectUri:e,codeChallenge:t,codeChallengeMethod:n,organizationId:s});return`${i(this,S)}/api/user_management/mobile/signIn?${a.toString()}`};function F(r,e,t){if(!(typeof e=="object"&&"code"in e))return!1;let o;if(t){let s=new URL(t);o=`${s.protocol}//${s.host}${s.pathname}`}else return!1;return o===r||o===`${r}/`}function Te(){let r={};function e(s,a){r[s]=a}function t(s){return r[s]}function n(s){delete r[s]}function o(){r={}}return{setItem:e,getItem:t,removeItem:n,reset:o}}var N=Te();import*as A from"expo-crypto";async function Z(){let r=await Ie(),e=await Re(r);return{codeVerifier:r,codeChallenge:e}}async function Ie(){let r=await A.getRandomBytesAsync(32);return Oe(r)}async function Re(r){return(await A.digestStringAsync(A.CryptoDigestAlgorithm.SHA256,r,{encoding:A.CryptoEncoding.BASE64})).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function Oe(r){let e="";for(let n=0;n<r.length;n++)e+=String.fromCharCode(r[n]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var ve=null;try{ve=Ue("@react-native-async-storage/async-storage").default}catch{}var Y={codeVerifier:"code-verifier",user:"user",accessToken:"access-token",refreshToken:"refresh-token",expiresAt:"expires-at"};function ae(r){return JSON.parse(atob(r.split(".")[1]))}var g,T,c,te,ue,ge,pe,de,me,he,fe,ye,we,Ce,ee=class{constructor(e,{apiHostname:t,https:n,port:o,organizationId:s,redirectUri:a,devMode:l}){p(this,c);p(this,g);p(this,T);if(!e)throw new H;if(!s)throw new V;_.OS==="web"?(a=a??window.origin,l=l??(location.hostname==="localhost"||location.hostname==="127.0.0.1")):(a=a??"",l=l??!1),_.OS==="web"?d(this,g,new D({clientId:e,hostname:t,port:o,organizationId:s,https:n})):d(this,g,new W({clientId:e,hostname:t,port:o,organizationId:s,https:n})),d(this,T,a)}async getAccessToken(){return _.OS==="web"?u(this,c,fe).call(this):u(this,c,ge).call(this)}async getUser(){return _.OS==="web"?u(this,c,ye).call(this):u(this,c,pe).call(this)}async initialize(){let e=new URLSearchParams(window.location.search);F(i(this,T),e)&&await u(this,c,we).call(this)}async signIn(e={}){return u(this,c,te).call(this,{...e,type:"sign-in"})}async signUp(e={}){return u(this,c,te).call(this,{...e,type:"sign-up"})}async signOut(e){return _.OS==="web"?u(this,c,he).call(this,e):u(this,c,ue).call(this,e)}async getCookieDomain(e){let t=new URL(e),n=t.hostname.split(".");return n.length>1?"."+n.slice(-2).join("."):t.hostname}};g=new WeakMap,T=new WeakMap,c=new WeakSet,te=async function(e){return _.OS==="web"?u(this,c,Ce).call(this,e):u(this,c,de).call(this,e)},ue=async function(e){let t=e?.returnTo||ce.makeRedirectUri({native:"yboardstarter:"}),n=await U.getItemAsync("yboard-session"),o=j(n||"{}"),s=await i(this,g).getLogoutUrl({returnTo:t,cookie:o});if(s)try{(await le.openAuthSessionAsync(s,t)).type==="success"&&await U.deleteItemAsync("yboard-session")}catch{}},ge=async function(){let e=await U.getItemAsync("yboard-session"),t=j(e||"{}");return await i(this,g).getAccessToken({cookie:t})||null},pe=async function(){let e=await U.getItemAsync("yboard-session"),t=j(e||"{}"),n=await i(this,g).getUser({cookie:t});return n||null},de=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a}){let{codeVerifier:l,codeChallenge:h}=await Z();N.setItem(Y.codeVerifier,l);let{code:f}=await i(this,g).startAuthorizationFlow({codeChallenge:h,codeChallengeMethod:"S256"});if(f){let w=await u(this,c,me).call(this,{code:f,codeVerifier:l});if(w&&typeof w=="string"){let I=await U.getItemAsync("yboard-session"),C=ne(w,I||void 0);await U.setItemAsync("yboard-session",C)}}},me=async function({code:e,codeVerifier:t}){return typeof t!="string"?null:await i(this,g).authenticateWithCode({code:e,codeVerifier:t,redirectUri:i(this,T)})},he=async function(e){let t=await i(this,g).getLogoutUrl({returnTo:e?.returnTo});if(t){let n=await this.getCookieDomain(i(this,T));document.cookie=`yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${n}`,window.location.assign(t)}},fe=async function(){return await i(this,g).getAccessToken()},ye=async function(){return await i(this,g).getUser()},we=async function(){let e=new URL(window.location.toString());e.search="",window.history.replaceState({},"",e)},Ce=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a,type:l,provider:h}){let f=await i(this,g).getAuthorizationUrl({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,redirectUri:i(this,T),state:a?JSON.stringify(a):void 0});window.location.assign(f)};async function B(r,e){let t=new ee(r,e);return _.OS==="web"&&await t.initialize(),t}import ke,{useState as _e}from"react";import*as be from"react";var L={isLoading:!0,user:null,role:null,organizationId:null,permissions:[]};var J=be.createContext(L);import{jsx as Ee}from"react/jsx-runtime";function Pe(r){let{clientId:e,apiHostname:t,https:n,port:o,redirectUri:s,children:a,organizationId:l,refreshBufferInterval:h}=r,[f,w]=_e(ze),[I,C]=ke.useState(L);return ke.useEffect(()=>{async function xe(){try{let m=await B(e,{apiHostname:t,port:o,organizationId:l,https:n,redirectUri:s,refreshBufferInterval:h}),G=await m.getUser();w({getAccessToken:m.getAccessToken.bind(m),getUser:m.getUser.bind(m),signIn:async(...R)=>{await m.signIn(...R);let $=await m.getUser();C(q=>({...q,user:$}))},signUp:async(...R)=>{await m.signUp(...R);let $=await m.getUser();C(q=>({...q,user:$}))},signOut:async(...R)=>{await m.signOut(...R),C($=>({...$,user:null}))}}),C(R=>({...R,isLoading:!1,user:G}))}catch{C(G=>({...G,isLoading:!1,user:null}))}}xe()},[]),Ee(J.Provider,{value:{...f,...I},children:a})}var ze={signIn:async()=>{},signUp:async()=>{},getUser:()=>Promise.resolve(null),getAccessToken:()=>Promise.reject(new E),signOut:async()=>Promise.resolve()};import*as Se from"react";function Ne(){let r=Se.useContext(J);if(r===L)throw new Error("useYboardAuth must be used within a YboardAuthProvider");return r}export{P as AuthKitError,E as LoginRequiredError,Pe as YboardAuthProvider,B as createClient,ae as getClaims,N as memoryStorage,Ne as useYboardAuth};
|
|
1
|
+
var re=r=>{throw TypeError(r)};var Ue=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var K=(r,e,t)=>e.has(r)||re("Cannot "+t);var i=(r,e,t)=>(K(r,e,"read from private field"),t?t.call(r):e.get(r)),p=(r,e,t)=>e.has(r)?re("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),d=(r,e,t,n)=>(K(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),u=(r,e,t)=>(K(r,e,"access private method"),t);import*as ce from"expo-auth-session";import*as U from"expo-secure-store";import*as le from"expo-web-browser";import{Platform as _}from"react-native";function Ae(r){let e=new Map;return r.split(", ").forEach(n=>{let[o,...s]=n.split("; "),[a,l]=o.split("="),h={value:l};s.forEach(f=>{let[w,I]=f.split("=");h[w.toLowerCase()]=I}),e.set(a,h)}),e}function ne(r,e){let t=Ae(r),n={};if(t.forEach((o,s)=>{let a=o.expires,l=o["max-age"],h=a?new Date(String(a)):l?new Date(Date.now()+Number(l)):null;n[s]={value:o.value,expires:h}}),e)try{n={...JSON.parse(e),...n}}catch{}return JSON.stringify(n)}function j(r){let e={};try{e=JSON.parse(r)}catch{}return Object.entries(e).reduce((n,[o,s])=>s.expires&&s.expires<new Date?n:`${n}; ${o}=${s.value}`,"")}var P=class extends Error{};var z=class extends P{},E=class extends P{constructor(){super(...arguments);this.message="No access token available"}};var b=({baseUrl:r,organizationId:e,cookie:t,path:n,method:o,options:s,body:a={}})=>{let l={method:o,headers:{Accept:"application/json, text/plain, */*","Content-Type":"application/json","X-Organization-Id":e,cookie:t||""},credentials:"include",...s};return o!=="GET"&&a&&(l.body=JSON.stringify(a)),fetch(`${r}${n}`,l)};var X=r=>({object:r.object,id:r.id,email:r.email,emailVerified:r.email_verified,firstName:r.first_name,profilePictureUrl:r.profile_picture_url,lastName:r.last_name,lastSignInAt:r.last_sign_in_at,externalId:r.external_id,createdAt:r.created_at,updatedAt:r.updated_at});var Q=r=>{let{user:e,organization_id:t,access_token:n,refresh_token:o,impersonator:s,...a}=r;return{user:X(e),organizationId:t,accessToken:n,refreshToken:o,impersonator:s,...a}};var y,O,k,D=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,y);p(this,O);p(this,k);d(this,y,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,O,e),d(this,k,o)}async authenticateWithCode({code:e}){let t=await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/authenticate",method:"POST",body:{code:e,client_id:i(this,O),grant_type:"authorization_code"}});if(t.ok){let o=await t.json();return Q(o)}let n=await t.json();throw new z(n.error_description)}async getAuthorizationUrl({redirectUri:e}){let t=new URLSearchParams(e?{redirectUri:e,authorizationCallbackUri:`${i(this,y)}/api/user_management/auth/callback`,clientId:i(this,O),organizationId:i(this,k)}:{}),n=new URL("api/user_management/signIn",i(this,y));return n.search=t.toString(),n.toString()}async getUser(){let t=await(await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/getUser",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.user?n.user:null}async getAccessToken(){let t=await(await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/getAccessToken",method:"GET"})).text(),n;try{n=JSON.parse(t)}catch{return null}return n?.accessToken?n.accessToken:null}async getLogoutUrl({returnTo:e}){let t=await b({baseUrl:i(this,y),organizationId:i(this,k),path:"/api/user_management/getLogOutUrl",method:"POST",body:{returnTo:e,client_id:i(this,O)}}),{url:n}=await t.json();return n}};y=new WeakMap,O=new WeakMap,k=new WeakMap;var H=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoClientIdProvidedException";this.message='Missing Client ID. Pass it to the constructor (createClient("client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7"))'}},V=class extends Error{constructor(){super(...arguments);this.status=500;this.name="NoOrganizationIdProvidedException";this.message="Missing Organization ID. Pass it to the constructor"}};import*as oe from"expo-auth-session";import*as se from"expo-web-browser";var S,v,x,M,ie,W=class{constructor({clientId:e,hostname:t,port:n,organizationId:o,https:s=!0}){p(this,M);p(this,S);p(this,v);p(this,x);d(this,S,`${s?"https":"http"}://${t}${n?`:${n}`:""}`),d(this,v,e),d(this,x,o)}async startAuthorizationFlow({codeChallenge:e,codeChallengeMethod:t}){let n=oe.makeRedirectUri({native:"yboardstarter:"}).toString(),o=u(this,M,ie).call(this,{redirectUri:n,codeChallenge:e,codeChallengeMethod:t,clientId:i(this,v),organizationId:i(this,x)}),s,a=await se.openAuthSessionAsync(o,n);switch(a.type){case"success":if(a.url){let l=a.url.split("?");if(l.length>1){let f=l[1].split("&");for(let w of f){let[I,C]=w.split("=");if(I==="code"){s=decodeURIComponent(C).split("#")[0];break}}}}break;case"cancel":throw new Error("Authentication cancelled.");case"dismiss":throw new Error("Authentication dismissed.");case"locked":throw new Error("Authentication session already active.");default:throw new Error(`Unhandled auth session result: ${a.type}`)}if(!s)throw new Error("No authorization code found in redirect URL.");return{code:s}}async authenticateWithCode({code:e,codeVerifier:t,redirectUri:n}){let o=await fetch(`${i(this,S)}/api/user_management/mobile/authenticate`,{method:"POST",headers:{"Content-Type":"application/json","X-Organization-Id":i(this,x)},body:JSON.stringify({code:e,client_id:i(this,v),grant_type:"authorization_code",code_verifier:t,redirect_uri:n})});if(!o.ok){let a=await o.json();throw new z(a.error_description)}return o.headers.get("set-cookie")}async getUser({cookie:e}={}){let t=await b({baseUrl:i(this,S),organizationId:i(this,x),cookie:e,path:"/api/user_management/mobile/getUser",method:"GET"});if(!t.ok)return null;let{user:n}=await t.json();return n}async getAccessToken({cookie:e}={}){let t=await b({baseUrl:i(this,S),organizationId:i(this,x),cookie:e,path:"/api/user_management/mobile/getAccessToken",method:"GET"}),{accessToken:n}=await t.json();return n}async getLogoutUrl({returnTo:e,cookie:t}={}){let n=await b({baseUrl:i(this,S),organizationId:i(this,x),cookie:t,path:"/api/user_management/mobile/getLogOutUrl",method:"POST",body:{client_id:i(this,v),returnTo:e||""}}),{url:o}=await n.json();return o}};S=new WeakMap,v=new WeakMap,x=new WeakMap,M=new WeakSet,ie=function({redirectUri:e,codeChallenge:t,codeChallengeMethod:n,clientId:o,organizationId:s}){let a=new URLSearchParams({response_type:"code",clientId:o,redirectUri:e,codeChallenge:t,codeChallengeMethod:n,organizationId:s});return`${i(this,S)}/api/user_management/mobile/signIn?${a.toString()}`};function F(r,e,t){if(!(typeof e=="object"&&"code"in e))return!1;let o;if(t){let s=new URL(t);o=`${s.protocol}//${s.host}${s.pathname}`}else return!1;return o===r||o===`${r}/`}function Te(){let r={};function e(s,a){r[s]=a}function t(s){return r[s]}function n(s){delete r[s]}function o(){r={}}return{setItem:e,getItem:t,removeItem:n,reset:o}}var N=Te();import*as A from"expo-crypto";async function Z(){let r=await Ie(),e=await Re(r);return{codeVerifier:r,codeChallenge:e}}async function Ie(){let r=await A.getRandomBytesAsync(32);return Oe(r)}async function Re(r){return(await A.digestStringAsync(A.CryptoDigestAlgorithm.SHA256,r,{encoding:A.CryptoEncoding.BASE64})).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function Oe(r){let e="";for(let n=0;n<r.length;n++)e+=String.fromCharCode(r[n]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var ve=null;try{ve=Ue("@react-native-async-storage/async-storage").default}catch{}var Y={codeVerifier:"code-verifier",user:"user",accessToken:"access-token",refreshToken:"refresh-token",expiresAt:"expires-at"};function ae(r){return JSON.parse(atob(r.split(".")[1]))}var g,T,c,te,ue,ge,pe,de,me,he,fe,ye,we,Ce,ee=class{constructor(e,{apiHostname:t,https:n,port:o,organizationId:s,redirectUri:a,devMode:l}){p(this,c);p(this,g);p(this,T);if(!e)throw new H;if(!s)throw new V;_.OS==="web"?(a=a??window.origin,l=l??(location.hostname==="localhost"||location.hostname==="127.0.0.1")):(a=a??"",l=l??!1),_.OS==="web"?d(this,g,new D({clientId:e,hostname:t,port:o,organizationId:s,https:n})):d(this,g,new W({clientId:e,hostname:t,port:o,organizationId:s,https:n})),d(this,T,a)}async getAccessToken(){return _.OS==="web"?u(this,c,fe).call(this):u(this,c,ge).call(this)}async getUser(){return _.OS==="web"?u(this,c,ye).call(this):u(this,c,pe).call(this)}async initialize(){let e=new URLSearchParams(window.location.search);F(i(this,T),e)&&await u(this,c,we).call(this)}async signIn(e={}){return u(this,c,te).call(this,{...e,type:"sign-in"})}async signUp(e={}){return u(this,c,te).call(this,{...e,type:"sign-up"})}async signOut(e){return _.OS==="web"?u(this,c,he).call(this,e):u(this,c,ue).call(this,e)}async getCookieDomain(e){let t=new URL(e),n=t.hostname.split(".");return n.length>1?"."+n.slice(-2).join("."):t.hostname}};g=new WeakMap,T=new WeakMap,c=new WeakSet,te=async function(e){return _.OS==="web"?u(this,c,Ce).call(this,e):u(this,c,de).call(this,e)},ue=async function(e){let t=e?.returnTo||ce.makeRedirectUri({native:"yboardstarter:"}),n=await U.getItemAsync("yboard-session"),o=j(n||"{}"),s=await i(this,g).getLogoutUrl({returnTo:t,cookie:o});if(s)try{(await le.openAuthSessionAsync(s,t)).type==="success"&&await U.deleteItemAsync("yboard-session")}catch{}},ge=async function(){let e=await U.getItemAsync("yboard-session"),t=j(e||"{}");return await i(this,g).getAccessToken({cookie:t})||null},pe=async function(){let e=await U.getItemAsync("yboard-session"),t=j(e||"{}"),n=await i(this,g).getUser({cookie:t});return n||null},de=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a}){let{codeVerifier:l,codeChallenge:h}=await Z();N.setItem(Y.codeVerifier,l);let{code:f}=await i(this,g).startAuthorizationFlow({codeChallenge:h,codeChallengeMethod:"S256"});if(f){let w=await u(this,c,me).call(this,{code:f,codeVerifier:l});if(w&&typeof w=="string"){let I=await U.getItemAsync("yboard-session"),C=ne(w,I||void 0);await U.setItemAsync("yboard-session",C)}}},me=async function({code:e,codeVerifier:t}){return typeof t!="string"?null:await i(this,g).authenticateWithCode({code:e,codeVerifier:t,redirectUri:i(this,T)})},he=async function(e){let t=await i(this,g).getLogoutUrl({returnTo:e?.returnTo});if(t){let n=await this.getCookieDomain(i(this,T));document.cookie=`yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${n}`,window.location.assign(t)}},fe=async function(){return await i(this,g).getAccessToken()},ye=async function(){return await i(this,g).getUser()},we=async function(){let e=new URL(window.location.toString());e.search="",window.history.replaceState({},"",e)},Ce=async function({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,state:a,type:l,provider:h}){let f=await i(this,g).getAuthorizationUrl({context:e,invitationToken:t,loginHint:n,organizationId:o,passwordResetToken:s,redirectUri:i(this,T),state:a?JSON.stringify(a):void 0});window.location.assign(f)};async function B(r,e){let t=new ee(r,e);return _.OS==="web"&&await t.initialize(),t}import ke,{useState as _e}from"react";import*as be from"react";var L={isLoading:!0,user:null,role:null,organizationId:null,permissions:[]};var J=be.createContext(L);import{jsx as Ee}from"react/jsx-runtime";function Pe(r){let{clientId:e,apiHostname:t,https:n,port:o,redirectUri:s,children:a,organizationId:l,refreshBufferInterval:h}=r,[f,w]=_e(ze),[I,C]=ke.useState(L);return ke.useEffect(()=>{async function xe(){try{let m=await B(e,{apiHostname:t,port:o,organizationId:l,https:n,redirectUri:s,refreshBufferInterval:h}),G=await m.getUser();w({getAccessToken:m.getAccessToken.bind(m),getUser:m.getUser.bind(m),signIn:async(...R)=>{await m.signIn(...R);let $=await m.getUser();C(q=>({...q,user:$}))},signUp:async(...R)=>{await m.signUp(...R);let $=await m.getUser();C(q=>({...q,user:$}))},signOut:async(...R)=>{await m.signOut(...R),C($=>({...$,user:null}))}}),C(R=>({...R,isLoading:!1,user:G}))}catch{C(G=>({...G,isLoading:!1,user:null}))}}xe()},[]),Ee(J.Provider,{value:{...f,...I},children:a})}var ze={signIn:async()=>{},signUp:async()=>{},getUser:()=>Promise.resolve(null),getAccessToken:()=>Promise.reject(new E),signOut:async()=>Promise.resolve()};import*as Se from"react";function Ne(){let r=Se.useContext(J);if(r===L)throw new Error("useYboardAuth must be used within a YboardAuthProvider");return r}export{P as AuthKitError,E as LoginRequiredError,Pe as YboardAuthProvider,B as createClient,ae as getClaims,N as memoryStorage,Ne as useYboardAuth};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/create-client.ts","../src/client/cookie.ts","../src/client/errors.ts","../src/client/globalFetch.ts","../src/client/serializers/user.serializer.ts","../src/client/serializers/authentication-response.serializer.ts","../src/client/cookie-http-client.ts","../src/client/exceptions/no-client-id-provided.exception.ts","../src/client/http-client.ts","../src/client/utils/is-redirect-callback.ts","../src/client/utils/memory-storage.ts","../src/client/utils/pkce.ts","../src/client/utils/native-storage.ts","../src/client/utils/storage-keys.ts","../src/client/utils/session-data.ts","../src/provider/authProvider.tsx","../src/provider/context.ts","../src/provider/state.ts","../src/provider/hook.ts"],"sourcesContent":["import * as AuthSession from \"expo-auth-session\";\nimport * as SecureStore from \"expo-secure-store\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { Platform } from \"react-native\";\nimport { getCookie, getSetCookie } from \"./cookie\";\nimport { CookieHttpClient } from \"./cookie-http-client\";\nimport { NoClientIdProvidedException } from \"./exceptions\";\nimport { NoOrganizationIdProvidedException } from \"./exceptions/no-client-id-provided.exception\";\nimport { HttpClient } from \"./http-client\";\nimport type { CreateClientOptions, User } from \"./interfaces\";\nimport {\n createPkceChallenge,\n isRedirectCallback,\n memoryStorage,\n storageKeys,\n} from \"./utils\";\n\nexport interface RedirectOptions {\n provider?: string;\n context?: string;\n invitationToken?: string;\n loginHint?: string;\n organizationId?: string;\n passwordResetToken?: string;\n state?: any;\n type: \"sign-in\" | \"sign-up\";\n}\n\nexport class Client {\n readonly #httpClient: HttpClient | CookieHttpClient;\n #redirectUri: string;\n\n constructor(\n clientId: string,\n {\n apiHostname: hostname,\n https,\n port,\n organizationId,\n redirectUri,\n devMode,\n }: CreateClientOptions,\n ) {\n if (!clientId) {\n throw new NoClientIdProvidedException();\n }\n if (!organizationId) {\n throw new NoOrganizationIdProvidedException();\n }\n\n // Platform-specific defaults\n if (Platform.OS === \"web\") {\n // --- Web defaults ---\n redirectUri = redirectUri ?? window.origin;\n devMode =\n devMode ??\n (location.hostname === \"localhost\" ||\n location.hostname === \"127.0.0.1\");\n } else {\n // --- Native defaults ---\n redirectUri = redirectUri ?? \"\";\n devMode = devMode ?? false;\n }\n\n // Use CookieHttpClient for web (cookie-based), HttpClient for native (token-based)\n if (Platform.OS === \"web\") {\n this.#httpClient = new CookieHttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n } else {\n this.#httpClient = new HttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n }\n\n this.#redirectUri = redirectUri;\n }\n\n // ============================================================\n // Cross-platform methods\n // ============================================================\n\n async getAccessToken(): Promise<string | null> {\n if (Platform.OS === \"web\") {\n return this.#getAccessTokenWeb();\n } else {\n return this.#getAccessTokenNative();\n }\n }\n\n async getUser(): Promise<User | null> {\n if (Platform.OS === \"web\") {\n return this.#getUserWeb();\n } else {\n return this.#getUserNative();\n }\n }\n\n async #redirect(options: RedirectOptions) {\n if (Platform.OS === \"web\") {\n return this.#redirectWeb(options);\n } else {\n return this.#redirectNative(options);\n }\n }\n\n async initialize() {\n const searchParams = new URLSearchParams(window.location.search);\n if (isRedirectCallback(this.#redirectUri, searchParams)) {\n await this.#handleCallback();\n }\n }\n\n async signIn(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-in\" });\n }\n\n async signUp(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-up\" });\n }\n\n async signOut(options?: { returnTo: string }) {\n if (Platform.OS === \"web\") {\n return this.#signOutWeb(options);\n } else {\n return this.#signOutNative(options);\n }\n }\n\n // Native methods\n async #signOutNative(options?: { returnTo: string }) {\n const redirectUri =\n options?.returnTo ||\n AuthSession.makeRedirectUri({ native: \"yboardstarter:\" });\n\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n\n const logoutUrl = await (this.#httpClient as HttpClient).getLogoutUrl({\n returnTo: redirectUri,\n cookie,\n });\n\n if (logoutUrl) {\n try {\n const result = await WebBrowser.openAuthSessionAsync(\n logoutUrl,\n redirectUri,\n );\n\n if (result.type === \"success\") {\n await SecureStore.deleteItemAsync(\"yboard-session\");\n } else {\n console.warn(\"User cancelled or dismissed logout:\", result.type);\n }\n } catch (error) {\n console.error(\"Error during sign out:\", error);\n }\n }\n }\n\n async #getAccessTokenNative(): Promise<string | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const accessToken = await (this.#httpClient as HttpClient).getAccessToken({\n cookie,\n });\n return (accessToken as string) || null;\n }\n\n async #getUserNative(): Promise<User | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const user = await (this.#httpClient as HttpClient).getUser({ cookie });\n if (!user) {\n return null;\n }\n return user as User;\n }\n\n async #redirectNative({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n }: RedirectOptions) {\n const { codeVerifier, codeChallenge } = await createPkceChallenge();\n memoryStorage.setItem(storageKeys.codeVerifier, codeVerifier);\n\n const { code } = await (\n this.#httpClient as HttpClient\n ).startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod: \"S256\",\n });\n\n if (code) {\n const cookie = await this.#authenticate({\n code,\n codeVerifier,\n });\n if (cookie && typeof cookie === \"string\") {\n const prev = await SecureStore.getItemAsync(\"yboard-session\");\n const updated = getSetCookie(cookie, prev || undefined);\n await SecureStore.setItemAsync(\"yboard-session\", updated);\n }\n }\n }\n\n async #authenticate({\n code,\n codeVerifier,\n }: {\n code: string;\n codeVerifier: string;\n }): Promise<string | null> {\n if (typeof codeVerifier !== \"string\") return null;\n\n const cookie = await (this.#httpClient as HttpClient).authenticateWithCode({\n code,\n codeVerifier: codeVerifier,\n redirectUri: this.#redirectUri,\n });\n\n return cookie;\n }\n\n // Web methods\n async getCookieDomain(origin: string) {\n const url = new URL(origin);\n const domainParts = url.hostname.split(\".\");\n if (domainParts.length > 1) {\n return \".\" + domainParts.slice(-2).join(\".\");\n }\n return url.hostname;\n }\n\n async #signOutWeb(options?: { returnTo: string }) {\n const url = await (this.#httpClient as CookieHttpClient).getLogoutUrl({\n returnTo: options?.returnTo,\n });\n\n if (url) {\n const domain = await this.getCookieDomain(this.#redirectUri);\n document.cookie = `yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}`;\n window.location.assign(url);\n }\n }\n\n async #getAccessTokenWeb(): Promise<string | null> {\n const accessToken = await (\n this.#httpClient as CookieHttpClient\n ).getAccessToken();\n return accessToken as string | null;\n }\n\n async #getUserWeb(): Promise<User | null> {\n const user = await (this.#httpClient as CookieHttpClient).getUser();\n return user as User | null;\n }\n\n async #handleCallback() {\n const cleanUrl = new URL(window.location.toString());\n cleanUrl.search = \"\";\n window.history.replaceState({}, \"\", cleanUrl);\n }\n\n async #redirectWeb({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n type,\n provider,\n }: RedirectOptions) {\n const url = await (\n this.#httpClient as CookieHttpClient\n ).getAuthorizationUrl({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n redirectUri: this.#redirectUri,\n state: state ? JSON.stringify(state) : undefined,\n });\n window.location.assign(url);\n }\n}\n\nexport async function createClient(\n clientId: string,\n options: CreateClientOptions,\n) {\n const client = new Client(clientId, options);\n\n // Only initialize for web platform\n if (Platform.OS === \"web\") {\n await client.initialize();\n }\n\n return client;\n}\n","interface CookieAttributes {\n\tvalue: string;\n\texpires?: Date;\n\t\"max-age\"?: number;\n\tdomain?: string;\n\tpath?: string;\n\tsecure?: boolean;\n\thttpOnly?: boolean;\n\tsameSite?: \"Strict\" | \"Lax\" | \"None\";\n}\n\ninterface StoredCookie {\n\tvalue: string;\n\texpires: Date | null;\n}\n\nexport function parseSetCookieHeader(\n header: string,\n): Map<string, CookieAttributes> {\n const cookieMap = new Map<string, CookieAttributes>();\n const cookies = header.split(\", \");\n cookies.forEach((cookie) => {\n const [nameValue, ...attributes] = cookie.split(\"; \");\n const [name, value] = nameValue.split(\"=\");\n\n const cookieObj: CookieAttributes = { value };\n\n attributes.forEach((attr) => {\n const [attrName, attrValue] = attr.split(\"=\");\n cookieObj[attrName.toLowerCase() as \"value\"] = attrValue;\n });\n\n cookieMap.set(name, cookieObj);\n });\n\n return cookieMap;\n}\n\nexport function getSetCookie(header: string, prevCookie?: string) {\n const parsed = parseSetCookieHeader(header);\n let toSetCookie: Record<string, StoredCookie> = {};\n parsed.forEach((cookie, key) => {\n const expiresAt = cookie[\"expires\"];\n const maxAge = cookie[\"max-age\"];\n const expires = expiresAt\n ? new Date(String(expiresAt))\n : maxAge\n ? new Date(Date.now() + Number(maxAge))\n : null;\n toSetCookie[key] = {\n value: cookie[\"value\"],\n expires,\n };\n });\n if (prevCookie) {\n try {\n const prevCookieParsed = JSON.parse(prevCookie);\n toSetCookie = {\n ...prevCookieParsed,\n ...toSetCookie,\n };\n } catch {\n //\n }\n }\n return JSON.stringify(toSetCookie);\n}\n\n\nexport function getCookie(cookie: string) {\n\tlet parsed = {} as Record<string, StoredCookie>;\n\ttry {\n\t\tparsed = JSON.parse(cookie) as Record<string, StoredCookie>;\n\t} catch (e) {}\n\tconst toSend = Object.entries(parsed).reduce((acc, [key, value]) => {\n\t\tif (value.expires && value.expires < new Date()) {\n\t\t\treturn acc;\n\t\t}\n\t\treturn `${acc}; ${key}=${value.value}`;\n\t}, \"\");\n\treturn toSend;\n}\n","export class AuthKitError extends Error {}\nexport class RefreshError extends AuthKitError {}\nexport class CodeExchangeError extends AuthKitError {}\nexport class LoginRequiredError extends AuthKitError {\n readonly message: string = \"No access token available\";\n}\n","export const fetchWithOrganizationIdAndCookie = ({\n baseUrl,\n organizationId,\n cookie,\n path,\n method,\n options,\n body = {},\n}: {\n baseUrl: string;\n organizationId: string;\n cookie?: string;\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n options?: RequestInit;\n body?: Record<string, unknown>;\n}) => {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"Accept\": \"application/json, text/plain, */*\",\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": organizationId,\n \"cookie\": cookie || \"\",\n },\n credentials: \"include\",\n ...options,\n };\n\n if (method !== \"GET\" && body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n return fetch(`${baseUrl}${path}`, fetchOptions);\n};\n","import type { User, UserRaw } from \"../interfaces\";\n\nexport const deserializeUser = (user: UserRaw): User => ({\n object: user.object,\n id: user.id,\n email: user.email,\n emailVerified: user.email_verified,\n firstName: user.first_name,\n profilePictureUrl: user.profile_picture_url,\n lastName: user.last_name,\n lastSignInAt: user.last_sign_in_at,\n externalId: user.external_id,\n createdAt: user.created_at,\n updatedAt: user.updated_at,\n});\n","import type {\n AuthenticationResponse,\n AuthenticationResponseRaw,\n} from \"../interfaces\";\nimport { deserializeUser } from \"./user.serializer\";\n\nexport const deserializeAuthenticationResponse = (\n authenticationResponse: AuthenticationResponseRaw,\n): AuthenticationResponse => {\n const {\n user,\n organization_id,\n access_token,\n refresh_token,\n impersonator,\n ...rest\n } = authenticationResponse;\n\n return {\n user: deserializeUser(user),\n organizationId: organization_id,\n accessToken: access_token,\n refreshToken: refresh_token,\n impersonator,\n ...rest,\n };\n};\n","import { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport {\n AuthenticationResponseRaw,\n GetAuthorizationUrlOptions,\n User,\n} from \"./interfaces\";\nimport { deserializeAuthenticationResponse } from \"./serializers\";\n\nexport class CookieHttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n async authenticateWithCode({ code }: { code: string }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/authenticate\",\n method: \"POST\",\n body: {\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n },\n });\n\n if (response.ok) {\n const data = (await response.json()) as AuthenticationResponseRaw;\n return deserializeAuthenticationResponse(data);\n }\n\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n async getAuthorizationUrl({ redirectUri }: GetAuthorizationUrlOptions) {\n const params = new URLSearchParams(\n redirectUri\n ? {\n redirectUri: redirectUri,\n authorizationCallbackUri: `${this.#baseUrl}/api/user_management/auth/callback`,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n }\n : {},\n );\n\n const url = new URL(\"api/user_management/signIn\", this.#baseUrl);\n url.search = params.toString();\n return url.toString();\n }\n\n async getUser() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getUser\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { user: User };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.user) {\n return null;\n }\n\n return parsed.user as User;\n }\n\n async getAccessToken() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getAccessToken\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { accessToken: string };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.accessToken) {\n return null;\n }\n\n return parsed.accessToken as string;\n }\n\n async getLogoutUrl({ returnTo }: { returnTo: string | undefined }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getLogOutUrl\",\n method: \"POST\",\n body: {\n returnTo,\n client_id: this.#clientId,\n },\n });\n\n const { url: logoutUrl } = (await response.json()) as { url: string };\n return logoutUrl;\n }\n}\n","export class NoClientIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoClientIdProvidedException\";\n readonly message: string = `Missing Client ID. Pass it to the constructor (createClient(\"client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7\"))`;\n}\n\nexport class NoOrganizationIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoOrganizationIdProvidedException\";\n readonly message: string = `Missing Organization ID. Pass it to the constructor`;\n}\n","import * as AuthSession from \"expo-auth-session\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport { User } from \"./interfaces\";\n\nexport class HttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n #buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId,\n organizationId,\n }: {\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n clientId: string;\n organizationId: string;\n }) {\n const params = new URLSearchParams({\n response_type: \"code\",\n clientId,\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n organizationId,\n });\n\n return `${this.#baseUrl}/api/user_management/mobile/signIn?${params.toString()}`;\n }\n\n async startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod,\n }: {\n codeChallenge: string;\n codeChallengeMethod: \"S256\";\n }) {\n const redirectUri = AuthSession.makeRedirectUri({\n native: \"yboardstarter:\",\n }).toString();\n const authUrl = this.#buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n });\n\n let code: string | undefined;\n\n const webResult = await WebBrowser.openAuthSessionAsync(\n authUrl,\n redirectUri,\n );\n\n switch (webResult.type) {\n case \"success\":\n if (webResult.url) {\n const urlParts = webResult.url.split(\"?\");\n if (urlParts.length > 1) {\n const queryString = urlParts[1];\n const params = queryString.split(\"&\");\n for (const param of params) {\n const [key, value] = param.split(\"=\");\n if (key === \"code\") {\n code = decodeURIComponent(value);\n break;\n }\n }\n }\n } else {\n console.warn(\"Success result but no URL returned\");\n }\n break;\n\n case \"cancel\":\n console.warn(\"User cancelled the auth flow.\");\n throw new Error(\"Authentication cancelled.\");\n\n case \"dismiss\":\n console.warn(\n \"Auth flow was dismissed (possibly due to backgrounding).\",\n );\n throw new Error(\"Authentication dismissed.\");\n\n case \"locked\":\n console.warn(\"Another auth session is already in progress.\");\n throw new Error(\"Authentication session already active.\");\n\n default:\n console.error(\"Unhandled web result type:\", webResult.type);\n throw new Error(`Unhandled auth session result: ${webResult.type}`);\n }\n\n if (!code) {\n throw new Error(\"No authorization code found in redirect URL.\");\n }\n\n return { code };\n }\n\n async authenticateWithCode({\n code,\n codeVerifier,\n redirectUri,\n }: {\n code: string;\n codeVerifier: string;\n redirectUri: string;\n }): Promise<string | null> {\n const response = await fetch(\n `${this.#baseUrl}/api/user_management/mobile/authenticate`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": this.#organizationId,\n },\n body: JSON.stringify({\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n }),\n },\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n const setCookie = response.headers.get(\"set-cookie\");\n return setCookie;\n }\n\n async getUser({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getUser\",\n method: \"GET\",\n });\n\n if (!response.ok) {\n return null;\n }\n const { user } = (await response.json()) as { user: User };\n return user;\n }\n\n async getAccessToken({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getAccessToken\",\n method: \"GET\",\n });\n\n const { accessToken } = (await response.json()) as { accessToken: string };\n return accessToken;\n }\n\n async getLogoutUrl({\n returnTo,\n cookie,\n }: { returnTo?: string; cookie?: string } = {}): Promise<string | null> {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getLogOutUrl\",\n method: \"POST\",\n body: { client_id: this.#clientId, returnTo: returnTo || \"\" },\n });\n\n const { url } = await response.json();\n return url;\n }\n}\n","/**\n * Checks if the current URL is a redirect callback from the auth server.\n *\n * In React Native, you must pass the current URL explicitly (since window.location is not available).\n */\nexport function isRedirectCallback(\n redirectUri: string,\n searchParams: Record<string, any>,\n currentUrl?: string // Pass the current URL explicitly in React Native\n) {\n // Only support the object returned by query-string\n const hasCode = typeof searchParams === \"object\" && \"code\" in searchParams;\n\n if (!hasCode) return false;\n\n // If currentUrl is provided (React Native), use it.\n let currentUri: string;\n if (currentUrl) {\n // Remove query and hash from currentUrl\n const urlObj = new URL(currentUrl);\n currentUri = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;\n } else {\n // Can't determine current URI\n return false;\n }\n\n return currentUri === redirectUri || currentUri === `${redirectUri}/`;\n}\n","function createMemoryStorage() {\n let _store: { [key: string]: unknown } = {};\n\n function setItem(key: string, value: unknown): void {\n _store[key] = value;\n }\n\n function getItem(key: string): unknown {\n return _store[key];\n }\n\n function removeItem(key: string): void {\n delete _store[key];\n }\n\n function reset(): void {\n _store = {};\n }\n\n return {\n setItem,\n getItem,\n removeItem,\n reset,\n };\n}\n\nconst memoryStorage = createMemoryStorage();\n\nexport { memoryStorage };\n","import * as Crypto from \"expo-crypto\";\n\nexport async function createPkceChallenge() {\n const codeVerifier = await generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n return { codeVerifier, codeChallenge };\n}\n\nasync function generateCodeVerifier(): Promise<string> {\n // Generate 32 random bytes and encode as base64url\n const randomBytes = await Crypto.getRandomBytesAsync(32);\n return base64urlEncode(randomBytes);\n}\n\nasync function generateCodeChallenge(codeVerifier: string): Promise<string> {\n // Hash the code verifier using SHA-256 and encode as base64url\n const hash = await Crypto.digestStringAsync(\n Crypto.CryptoDigestAlgorithm.SHA256,\n codeVerifier,\n { encoding: Crypto.CryptoEncoding.BASE64 },\n );\n // Convert base64 to base64url\n return hash.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nfunction base64urlEncode(uint8Array: Uint8Array): string {\n // Convert Uint8Array to base64\n let binary = \"\";\n for (let i = 0; i < uint8Array.length; i++) {\n binary += String.fromCharCode(uint8Array[i]);\n }\n const base64 = btoa(binary);\n\n // Convert base64 to base64url\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n","let AsyncStorage: any = null;\ntry {\n AsyncStorage = require(\"@react-native-async-storage/async-storage\").default;\n} catch (e) {\n // Not in React Native, ignore\n}\n\nfunction isReactNative() {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.product === \"ReactNative\"\n );\n}\n\nconst nativeStorage = {\n async setItem(key: string, value: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.setItem(key, value);\n } else {\n // fallback to in-memory for web\n (globalThis as any).__nativeMemoryStore = (globalThis as any).__nativeMemoryStore || {};\n (globalThis as any).__nativeMemoryStore[key] = value;\n }\n },\n async getItem(key: string): Promise<string | null> {\n if (isReactNative() && AsyncStorage) {\n return await AsyncStorage.getItem(key);\n } else {\n return (globalThis as any).__nativeMemoryStore?.[key] ?? null;\n }\n },\n async removeItem(key: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.removeItem(key);\n } else {\n if ((globalThis as any).__nativeMemoryStore) {\n delete (globalThis as any).__nativeMemoryStore[key];\n }\n }\n }\n};\n\nexport { nativeStorage };\n","export const storageKeys = {\n codeVerifier: \"code-verifier\",\n user: \"user\",\n accessToken: \"access-token\",\n refreshToken: \"refresh-token\",\n expiresAt: \"expires-at\",\n} as const;\n","import type { AuthenticationResponse } from \"../interfaces\";\nimport { memoryStorage } from \"./memory-storage\";\nimport { nativeStorage } from \"./native-storage\";\nimport { storageKeys } from \"./storage-keys\";\n\ninterface AccessToken {\n exp: number;\n iat: number;\n iss: string;\n jti: string;\n sid: string;\n sub: string;\n org_id?: string;\n role?: string;\n permissions?: string[];\n}\n\n// should replace this with jose if we ever need to verify the JWT\nexport function getClaims(accessToken: string) {\n return JSON.parse(atob(accessToken.split(\".\")[1])) as AccessToken;\n}\n\nexport function setSessionData(\n data: AuthenticationResponse,\n { devMode = false } = {},\n) {\n const { user, accessToken, refreshToken } = data;\n memoryStorage.setItem(storageKeys.user, user);\n memoryStorage.setItem(storageKeys.accessToken, accessToken);\n if (devMode) {\n nativeStorage.setItem(storageKeys.refreshToken, refreshToken);\n } else {\n memoryStorage.setItem(storageKeys.refreshToken, refreshToken);\n }\n\n // compute a local time version of expires at (should avoid issues with slightly-wrong clocks)\n const { exp, iat } = getClaims(accessToken);\n const expiresIn = exp - iat;\n const expiresAt = Date.now() + expiresIn * 1000;\n memoryStorage.setItem(storageKeys.expiresAt, expiresAt);\n}\n\nexport function removeSessionData({ devMode = false } = {}) {\n memoryStorage.removeItem(storageKeys.user);\n memoryStorage.removeItem(storageKeys.accessToken);\n if (devMode) {\n nativeStorage.removeItem(storageKeys.refreshToken);\n } else {\n memoryStorage.removeItem(storageKeys.refreshToken);\n }\n}\n\nexport async function getRefreshToken({ devMode = false } = {}) {\n if (devMode) {\n return await nativeStorage.getItem(storageKeys.refreshToken);\n } else {\n return memoryStorage.getItem(storageKeys.refreshToken) as string | undefined;\n }\n}\n","import { createClient, LoginRequiredError } from \"../client\";\nimport type { RedirectOptions } from \"../client/create-client\";\nimport type { State } from \"./state\";\nimport React, { useState } from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport type Client = Pick<\n Awaited<ReturnType<typeof createClient>>,\n \"signIn\" | \"signUp\" | \"getUser\" | \"getAccessToken\" | \"signOut\"\n>;\n\nexport type CreateClientOptions = NonNullable<\n Parameters<typeof createClient>[1]\n>;\n\ntype YboardAuthProviderProps = CreateClientOptions & {\n clientId: string;\n organizationId: string;\n children: React.ReactNode;\n};\n\nexport function YboardAuthProvider(props: YboardAuthProviderProps) {\n const {\n clientId,\n apiHostname,\n https,\n port,\n redirectUri,\n children,\n organizationId,\n refreshBufferInterval,\n } = props;\n const [client, setClient] = useState<Client>(NOOP_CLIENT);\n const [state, setState] = React.useState(initialState);\n\n React.useEffect(() => {\n async function initialize() {\n try {\n const client = await createClient(clientId, {\n apiHostname,\n port,\n organizationId,\n https,\n redirectUri,\n refreshBufferInterval,\n });\n const user = await client.getUser();\n\n setClient({\n getAccessToken: client.getAccessToken.bind(client),\n getUser: client.getUser.bind(client),\n signIn: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signIn(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signUp: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signUp(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signOut: async (...args: [{ returnTo: string }?]) => {\n await client.signOut(...args);\n setState((prev: State) => ({ ...prev, user: null }));\n },\n });\n setState((prev: State) => ({ ...prev, isLoading: false, user }));\n } catch (err) {\n console.error(\"Error initializing auth client:\", err);\n setState((prev: State) => ({ ...prev, isLoading: false, user: null }));\n }\n }\n\n initialize();\n }, []);\n\n return (\n <YboardAuthContext.Provider value={{ ...client, ...state }}>\n {children}\n </YboardAuthContext.Provider>\n );\n}\n\nconst NOOP_CLIENT: Client = {\n signIn: async () => {},\n signUp: async () => {},\n getUser: () => Promise.resolve(null),\n getAccessToken: () => Promise.reject(new LoginRequiredError()),\n signOut: async () => Promise.resolve(),\n};\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { type State, initialState } from \"./state\";\nimport type { Client } from \"./authProvider\";\n\nexport interface ContextValue extends Client, State { }\n\nexport const YboardAuthContext = React.createContext<ContextValue>(\n initialState as ContextValue,\n);\n","import type { User } from \"../client/interfaces\";\n\nexport interface State {\n isLoading: boolean;\n user: User | null;\n role: string | null;\n organizationId: string | null;\n permissions: string[];\n}\n\nexport const initialState: State = {\n isLoading: true,\n user: null,\n role: null,\n organizationId: null,\n permissions: [],\n};\n","import * as React from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport function useYboardAuth() {\n const context = React.useContext(YboardAuthContext);\n\n if (context === initialState) {\n throw new Error(\"useYboardAuth must be used within a YboardAuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["AuthSession","SecureStore","WebBrowser","Platform","parseSetCookieHeader","header","cookieMap","cookie","nameValue","attributes","name","value","cookieObj","attr","attrName","attrValue","getSetCookie","prevCookie","parsed","toSetCookie","key","expiresAt","maxAge","expires","getCookie","acc","AuthKitError","CodeExchangeError","AuthKitError","LoginRequiredError","fetchWithOrganizationIdAndCookie","baseUrl","organizationId","cookie","path","method","options","body","fetchOptions","deserializeUser","user","deserializeAuthenticationResponse","authenticationResponse","user","organization_id","access_token","refresh_token","impersonator","rest","deserializeUser","_baseUrl","_clientId","_organizationId","CookieHttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","code","response","fetchWithOrganizationIdAndCookie","__privateGet","data","deserializeAuthenticationResponse","error","CodeExchangeError","redirectUri","params","url","text","parsed","returnTo","logoutUrl","NoClientIdProvidedException","NoOrganizationIdProvidedException","AuthSession","WebBrowser","_baseUrl","_clientId","_organizationId","_HttpClient_instances","buildAuthUrl_fn","HttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","codeChallenge","codeChallengeMethod","redirectUri","authUrl","__privateMethod","__privateGet","code","webResult","urlParts","params","param","key","value","codeVerifier","response","error","CodeExchangeError","cookie","fetchWithOrganizationIdAndCookie","user","accessToken","returnTo","url","isRedirectCallback","redirectUri","searchParams","currentUrl","currentUri","urlObj","createMemoryStorage","_store","setItem","key","value","getItem","removeItem","reset","memoryStorage","Crypto","createPkceChallenge","codeVerifier","generateCodeVerifier","codeChallenge","generateCodeChallenge","randomBytes","base64urlEncode","uint8Array","binary","i","AsyncStorage","storageKeys","getClaims","accessToken","_httpClient","_redirectUri","_Client_instances","redirect_fn","signOutNative_fn","getAccessTokenNative_fn","getUserNative_fn","redirectNative_fn","authenticate_fn","signOutWeb_fn","getAccessTokenWeb_fn","getUserWeb_fn","handleCallback_fn","redirectWeb_fn","Client","clientId","hostname","https","port","organizationId","redirectUri","devMode","__privateAdd","NoClientIdProvidedException","NoOrganizationIdProvidedException","Platform","__privateSet","CookieHttpClient","HttpClient","__privateMethod","searchParams","isRedirectCallback","__privateGet","opts","options","origin","url","domainParts","stored","cookie","getCookie","logoutUrl","user","context","invitationToken","loginHint","passwordResetToken","state","codeVerifier","codeChallenge","createPkceChallenge","memoryStorage","storageKeys","code","prev","updated","getSetCookie","domain","cleanUrl","type","provider","createClient","client","React","useState","React","initialState","YboardAuthContext","initialState","jsx","YboardAuthProvider","props","clientId","apiHostname","https","port","redirectUri","children","organizationId","refreshBufferInterval","client","setClient","useState","NOOP_CLIENT","state","setState","React","initialState","initialize","createClient","user","args","prev","YboardAuthContext","LoginRequiredError","React","useYboardAuth","context","YboardAuthContext","initialState"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/create-client.ts","../src/client/cookie.ts","../src/client/errors.ts","../src/client/globalFetch.ts","../src/client/serializers/user.serializer.ts","../src/client/serializers/authentication-response.serializer.ts","../src/client/cookie-http-client.ts","../src/client/exceptions/no-client-id-provided.exception.ts","../src/client/http-client.ts","../src/client/utils/is-redirect-callback.ts","../src/client/utils/memory-storage.ts","../src/client/utils/pkce.ts","../src/client/utils/native-storage.ts","../src/client/utils/storage-keys.ts","../src/client/utils/session-data.ts","../src/provider/authProvider.tsx","../src/provider/context.ts","../src/provider/state.ts","../src/provider/hook.ts"],"sourcesContent":["import * as AuthSession from \"expo-auth-session\";\nimport * as SecureStore from \"expo-secure-store\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { Platform } from \"react-native\";\nimport { getCookie, getSetCookie } from \"./cookie\";\nimport { CookieHttpClient } from \"./cookie-http-client\";\nimport { NoClientIdProvidedException } from \"./exceptions\";\nimport { NoOrganizationIdProvidedException } from \"./exceptions/no-client-id-provided.exception\";\nimport { HttpClient } from \"./http-client\";\nimport type { CreateClientOptions, User } from \"./interfaces\";\nimport {\n createPkceChallenge,\n isRedirectCallback,\n memoryStorage,\n storageKeys,\n} from \"./utils\";\n\nexport interface RedirectOptions {\n provider?: string;\n context?: string;\n invitationToken?: string;\n loginHint?: string;\n organizationId?: string;\n passwordResetToken?: string;\n state?: any;\n type: \"sign-in\" | \"sign-up\";\n}\n\nexport class Client {\n readonly #httpClient: HttpClient | CookieHttpClient;\n #redirectUri: string;\n\n constructor(\n clientId: string,\n {\n apiHostname: hostname,\n https,\n port,\n organizationId,\n redirectUri,\n devMode,\n }: CreateClientOptions,\n ) {\n if (!clientId) {\n throw new NoClientIdProvidedException();\n }\n if (!organizationId) {\n throw new NoOrganizationIdProvidedException();\n }\n\n // Platform-specific defaults\n if (Platform.OS === \"web\") {\n // --- Web defaults ---\n redirectUri = redirectUri ?? window.origin;\n devMode =\n devMode ??\n (location.hostname === \"localhost\" ||\n location.hostname === \"127.0.0.1\");\n } else {\n // --- Native defaults ---\n redirectUri = redirectUri ?? \"\";\n devMode = devMode ?? false;\n }\n\n // Use CookieHttpClient for web (cookie-based), HttpClient for native (token-based)\n if (Platform.OS === \"web\") {\n this.#httpClient = new CookieHttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n } else {\n this.#httpClient = new HttpClient({\n clientId,\n hostname,\n port,\n organizationId,\n https,\n });\n }\n\n this.#redirectUri = redirectUri;\n }\n\n // ============================================================\n // Cross-platform methods\n // ============================================================\n\n async getAccessToken(): Promise<string | null> {\n if (Platform.OS === \"web\") {\n return this.#getAccessTokenWeb();\n } else {\n return this.#getAccessTokenNative();\n }\n }\n\n async getUser(): Promise<User | null> {\n if (Platform.OS === \"web\") {\n return this.#getUserWeb();\n } else {\n return this.#getUserNative();\n }\n }\n\n async #redirect(options: RedirectOptions) {\n if (Platform.OS === \"web\") {\n return this.#redirectWeb(options);\n } else {\n return this.#redirectNative(options);\n }\n }\n\n async initialize() {\n const searchParams = new URLSearchParams(window.location.search);\n if (isRedirectCallback(this.#redirectUri, searchParams)) {\n await this.#handleCallback();\n }\n }\n\n async signIn(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-in\" });\n }\n\n async signUp(opts: Omit<RedirectOptions, \"type\"> = {}) {\n return this.#redirect({ ...opts, type: \"sign-up\" });\n }\n\n async signOut(options?: { returnTo: string }) {\n if (Platform.OS === \"web\") {\n return this.#signOutWeb(options);\n } else {\n return this.#signOutNative(options);\n }\n }\n\n // Native methods\n async #signOutNative(options?: { returnTo: string }) {\n const redirectUri =\n options?.returnTo ||\n AuthSession.makeRedirectUri({ native: \"yboardstarter:\" });\n\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n\n const logoutUrl = await (this.#httpClient as HttpClient).getLogoutUrl({\n returnTo: redirectUri,\n cookie,\n });\n\n if (logoutUrl) {\n try {\n const result = await WebBrowser.openAuthSessionAsync(\n logoutUrl,\n redirectUri,\n );\n\n if (result.type === \"success\") {\n await SecureStore.deleteItemAsync(\"yboard-session\");\n } else {\n console.warn(\"User cancelled or dismissed logout:\", result.type);\n }\n } catch (error) {\n console.error(\"Error during sign out:\", error);\n }\n }\n }\n\n async #getAccessTokenNative(): Promise<string | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const accessToken = await (this.#httpClient as HttpClient).getAccessToken({\n cookie,\n });\n return (accessToken as string) || null;\n }\n\n async #getUserNative(): Promise<User | null> {\n const stored = await SecureStore.getItemAsync(\"yboard-session\");\n const cookie = getCookie(stored || \"{}\");\n const user = await (this.#httpClient as HttpClient).getUser({ cookie });\n if (!user) {\n return null;\n }\n return user as User;\n }\n\n async #redirectNative({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n }: RedirectOptions) {\n const { codeVerifier, codeChallenge } = await createPkceChallenge();\n memoryStorage.setItem(storageKeys.codeVerifier, codeVerifier);\n\n const { code } = await (\n this.#httpClient as HttpClient\n ).startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod: \"S256\",\n });\n\n if (code) {\n const cookie = await this.#authenticate({\n code,\n codeVerifier,\n });\n if (cookie && typeof cookie === \"string\") {\n const prev = await SecureStore.getItemAsync(\"yboard-session\");\n const updated = getSetCookie(cookie, prev || undefined);\n await SecureStore.setItemAsync(\"yboard-session\", updated);\n }\n }\n }\n\n async #authenticate({\n code,\n codeVerifier,\n }: {\n code: string;\n codeVerifier: string;\n }): Promise<string | null> {\n if (typeof codeVerifier !== \"string\") return null;\n\n const cookie = await (this.#httpClient as HttpClient).authenticateWithCode({\n code,\n codeVerifier: codeVerifier,\n redirectUri: this.#redirectUri,\n });\n\n return cookie;\n }\n\n // Web methods\n async getCookieDomain(origin: string) {\n const url = new URL(origin);\n const domainParts = url.hostname.split(\".\");\n if (domainParts.length > 1) {\n return \".\" + domainParts.slice(-2).join(\".\");\n }\n return url.hostname;\n }\n\n async #signOutWeb(options?: { returnTo: string }) {\n const url = await (this.#httpClient as CookieHttpClient).getLogoutUrl({\n returnTo: options?.returnTo,\n });\n\n if (url) {\n const domain = await this.getCookieDomain(this.#redirectUri);\n document.cookie = `yboard-session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}`;\n window.location.assign(url);\n }\n }\n\n async #getAccessTokenWeb(): Promise<string | null> {\n const accessToken = await (\n this.#httpClient as CookieHttpClient\n ).getAccessToken();\n return accessToken as string | null;\n }\n\n async #getUserWeb(): Promise<User | null> {\n const user = await (this.#httpClient as CookieHttpClient).getUser();\n return user as User | null;\n }\n\n async #handleCallback() {\n const cleanUrl = new URL(window.location.toString());\n cleanUrl.search = \"\";\n window.history.replaceState({}, \"\", cleanUrl);\n }\n\n async #redirectWeb({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n state,\n type,\n provider,\n }: RedirectOptions) {\n const url = await (\n this.#httpClient as CookieHttpClient\n ).getAuthorizationUrl({\n context,\n invitationToken,\n loginHint,\n organizationId,\n passwordResetToken,\n redirectUri: this.#redirectUri,\n state: state ? JSON.stringify(state) : undefined,\n });\n window.location.assign(url);\n }\n}\n\nexport async function createClient(\n clientId: string,\n options: CreateClientOptions,\n) {\n const client = new Client(clientId, options);\n\n // Only initialize for web platform\n if (Platform.OS === \"web\") {\n await client.initialize();\n }\n\n return client;\n}\n","interface CookieAttributes {\n\tvalue: string;\n\texpires?: Date;\n\t\"max-age\"?: number;\n\tdomain?: string;\n\tpath?: string;\n\tsecure?: boolean;\n\thttpOnly?: boolean;\n\tsameSite?: \"Strict\" | \"Lax\" | \"None\";\n}\n\ninterface StoredCookie {\n\tvalue: string;\n\texpires: Date | null;\n}\n\nexport function parseSetCookieHeader(\n header: string,\n): Map<string, CookieAttributes> {\n const cookieMap = new Map<string, CookieAttributes>();\n const cookies = header.split(\", \");\n cookies.forEach((cookie) => {\n const [nameValue, ...attributes] = cookie.split(\"; \");\n const [name, value] = nameValue.split(\"=\");\n\n const cookieObj: CookieAttributes = { value };\n\n attributes.forEach((attr) => {\n const [attrName, attrValue] = attr.split(\"=\");\n cookieObj[attrName.toLowerCase() as \"value\"] = attrValue;\n });\n\n cookieMap.set(name, cookieObj);\n });\n\n return cookieMap;\n}\n\nexport function getSetCookie(header: string, prevCookie?: string) {\n const parsed = parseSetCookieHeader(header);\n let toSetCookie: Record<string, StoredCookie> = {};\n parsed.forEach((cookie, key) => {\n const expiresAt = cookie[\"expires\"];\n const maxAge = cookie[\"max-age\"];\n const expires = expiresAt\n ? new Date(String(expiresAt))\n : maxAge\n ? new Date(Date.now() + Number(maxAge))\n : null;\n toSetCookie[key] = {\n value: cookie[\"value\"],\n expires,\n };\n });\n if (prevCookie) {\n try {\n const prevCookieParsed = JSON.parse(prevCookie);\n toSetCookie = {\n ...prevCookieParsed,\n ...toSetCookie,\n };\n } catch {\n //\n }\n }\n return JSON.stringify(toSetCookie);\n}\n\n\nexport function getCookie(cookie: string) {\n\tlet parsed = {} as Record<string, StoredCookie>;\n\ttry {\n\t\tparsed = JSON.parse(cookie) as Record<string, StoredCookie>;\n\t} catch (e) {}\n\tconst toSend = Object.entries(parsed).reduce((acc, [key, value]) => {\n\t\tif (value.expires && value.expires < new Date()) {\n\t\t\treturn acc;\n\t\t}\n\t\treturn `${acc}; ${key}=${value.value}`;\n\t}, \"\");\n\treturn toSend;\n}\n","export class AuthKitError extends Error {}\nexport class RefreshError extends AuthKitError {}\nexport class CodeExchangeError extends AuthKitError {}\nexport class LoginRequiredError extends AuthKitError {\n readonly message: string = \"No access token available\";\n}\n","export const fetchWithOrganizationIdAndCookie = ({\n baseUrl,\n organizationId,\n cookie,\n path,\n method,\n options,\n body = {},\n}: {\n baseUrl: string;\n organizationId: string;\n cookie?: string;\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n options?: RequestInit;\n body?: Record<string, unknown>;\n}) => {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"Accept\": \"application/json, text/plain, */*\",\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": organizationId,\n \"cookie\": cookie || \"\",\n },\n credentials: \"include\",\n ...options,\n };\n\n if (method !== \"GET\" && body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n return fetch(`${baseUrl}${path}`, fetchOptions);\n};\n","import type { User, UserRaw } from \"../interfaces\";\n\nexport const deserializeUser = (user: UserRaw): User => ({\n object: user.object,\n id: user.id,\n email: user.email,\n emailVerified: user.email_verified,\n firstName: user.first_name,\n profilePictureUrl: user.profile_picture_url,\n lastName: user.last_name,\n lastSignInAt: user.last_sign_in_at,\n externalId: user.external_id,\n createdAt: user.created_at,\n updatedAt: user.updated_at,\n});\n","import type {\n AuthenticationResponse,\n AuthenticationResponseRaw,\n} from \"../interfaces\";\nimport { deserializeUser } from \"./user.serializer\";\n\nexport const deserializeAuthenticationResponse = (\n authenticationResponse: AuthenticationResponseRaw,\n): AuthenticationResponse => {\n const {\n user,\n organization_id,\n access_token,\n refresh_token,\n impersonator,\n ...rest\n } = authenticationResponse;\n\n return {\n user: deserializeUser(user),\n organizationId: organization_id,\n accessToken: access_token,\n refreshToken: refresh_token,\n impersonator,\n ...rest,\n };\n};\n","import { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport {\n AuthenticationResponseRaw,\n GetAuthorizationUrlOptions,\n User,\n} from \"./interfaces\";\nimport { deserializeAuthenticationResponse } from \"./serializers\";\n\nexport class CookieHttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n async authenticateWithCode({ code }: { code: string }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/authenticate\",\n method: \"POST\",\n body: {\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n },\n });\n\n if (response.ok) {\n const data = (await response.json()) as AuthenticationResponseRaw;\n return deserializeAuthenticationResponse(data);\n }\n\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n async getAuthorizationUrl({ redirectUri }: GetAuthorizationUrlOptions) {\n const params = new URLSearchParams(\n redirectUri\n ? {\n redirectUri: redirectUri,\n authorizationCallbackUri: `${this.#baseUrl}/api/user_management/auth/callback`,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n }\n : {},\n );\n\n const url = new URL(\"api/user_management/signIn\", this.#baseUrl);\n url.search = params.toString();\n return url.toString();\n }\n\n async getUser() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getUser\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { user: User };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.user) {\n return null;\n }\n\n return parsed.user as User;\n }\n\n async getAccessToken() {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getAccessToken\",\n method: \"GET\",\n });\n\n const text = await response.text();\n\n // Ensure that JSON.parse doesn't return error\n let parsed: { accessToken: string };\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n\n if (!parsed?.accessToken) {\n return null;\n }\n\n return parsed.accessToken as string;\n }\n\n async getLogoutUrl({ returnTo }: { returnTo: string | undefined }) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n path: \"/api/user_management/getLogOutUrl\",\n method: \"POST\",\n body: {\n returnTo,\n client_id: this.#clientId,\n },\n });\n\n const { url: logoutUrl } = (await response.json()) as { url: string };\n return logoutUrl;\n }\n}\n","export class NoClientIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoClientIdProvidedException\";\n readonly message: string = `Missing Client ID. Pass it to the constructor (createClient(\"client_01HXRMBQ9BJ3E7QSTQ9X2PHVB7\"))`;\n}\n\nexport class NoOrganizationIdProvidedException extends Error {\n readonly status: number = 500;\n readonly name: string = \"NoOrganizationIdProvidedException\";\n readonly message: string = `Missing Organization ID. Pass it to the constructor`;\n}\n","import * as AuthSession from \"expo-auth-session\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport { CodeExchangeError } from \"./errors\";\nimport { fetchWithOrganizationIdAndCookie } from \"./globalFetch\";\nimport { User } from \"./interfaces\";\n\nexport class HttpClient {\n readonly #baseUrl: string;\n readonly #clientId: string;\n readonly #organizationId: string;\n\n constructor({\n clientId,\n hostname,\n port,\n organizationId,\n https = true,\n }: {\n clientId: string;\n hostname?: string;\n organizationId: string;\n port?: number;\n https?: boolean;\n }) {\n this.#baseUrl = `${https ? \"https\" : \"http\"}://${hostname}${port ? `:${port}` : \"\"}`;\n this.#clientId = clientId;\n this.#organizationId = organizationId;\n }\n\n #buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId,\n organizationId,\n }: {\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n clientId: string;\n organizationId: string;\n }) {\n const params = new URLSearchParams({\n response_type: \"code\",\n clientId,\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n organizationId,\n });\n\n return `${this.#baseUrl}/api/user_management/mobile/signIn?${params.toString()}`;\n }\n\n async startAuthorizationFlow({\n codeChallenge,\n codeChallengeMethod,\n }: {\n codeChallenge: string;\n codeChallengeMethod: \"S256\";\n }) {\n const redirectUri = AuthSession.makeRedirectUri({\n native: \"yboardstarter:\",\n }).toString();\n const authUrl = this.#buildAuthUrl({\n redirectUri,\n codeChallenge,\n codeChallengeMethod,\n clientId: this.#clientId,\n organizationId: this.#organizationId,\n });\n\n let code: string | undefined;\n\n const webResult = await WebBrowser.openAuthSessionAsync(\n authUrl,\n redirectUri,\n );\n\n switch (webResult.type) {\n case \"success\":\n if (webResult.url) {\n const urlParts = webResult.url.split(\"?\");\n if (urlParts.length > 1) {\n const queryString = urlParts[1];\n const params = queryString.split(\"&\");\n for (const param of params) {\n const [key, value] = param.split(\"=\");\n if (key === \"code\") {\n // Strip URL fragment (#) — iOS includes it in the redirect URL\n code = decodeURIComponent(value).split(\"#\")[0];\n break;\n }\n }\n }\n } else {\n console.warn(\"Success result but no URL returned\");\n }\n break;\n\n case \"cancel\":\n console.warn(\"User cancelled the auth flow.\");\n throw new Error(\"Authentication cancelled.\");\n\n case \"dismiss\":\n console.warn(\n \"Auth flow was dismissed (possibly due to backgrounding).\",\n );\n throw new Error(\"Authentication dismissed.\");\n\n case \"locked\":\n console.warn(\"Another auth session is already in progress.\");\n throw new Error(\"Authentication session already active.\");\n\n default:\n console.error(\"Unhandled web result type:\", webResult.type);\n throw new Error(`Unhandled auth session result: ${webResult.type}`);\n }\n\n if (!code) {\n throw new Error(\"No authorization code found in redirect URL.\");\n }\n\n return { code };\n }\n\n async authenticateWithCode({\n code,\n codeVerifier,\n redirectUri,\n }: {\n code: string;\n codeVerifier: string;\n redirectUri: string;\n }): Promise<string | null> {\n const response = await fetch(\n `${this.#baseUrl}/api/user_management/mobile/authenticate`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Organization-Id\": this.#organizationId,\n },\n body: JSON.stringify({\n code,\n client_id: this.#clientId,\n grant_type: \"authorization_code\",\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n }),\n },\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new CodeExchangeError(error.error_description);\n }\n\n const setCookie = response.headers.get(\"set-cookie\");\n return setCookie;\n }\n\n async getUser({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getUser\",\n method: \"GET\",\n });\n\n if (!response.ok) {\n return null;\n }\n const { user } = (await response.json()) as { user: User };\n return user;\n }\n\n async getAccessToken({ cookie }: { cookie?: string } = {}) {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getAccessToken\",\n method: \"GET\",\n });\n\n const { accessToken } = (await response.json()) as { accessToken: string };\n return accessToken;\n }\n\n async getLogoutUrl({\n returnTo,\n cookie,\n }: { returnTo?: string; cookie?: string } = {}): Promise<string | null> {\n const response = await fetchWithOrganizationIdAndCookie({\n baseUrl: this.#baseUrl,\n organizationId: this.#organizationId,\n cookie,\n path: \"/api/user_management/mobile/getLogOutUrl\",\n method: \"POST\",\n body: { client_id: this.#clientId, returnTo: returnTo || \"\" },\n });\n\n const { url } = await response.json();\n return url;\n }\n}\n","/**\n * Checks if the current URL is a redirect callback from the auth server.\n *\n * In React Native, you must pass the current URL explicitly (since window.location is not available).\n */\nexport function isRedirectCallback(\n redirectUri: string,\n searchParams: Record<string, any>,\n currentUrl?: string // Pass the current URL explicitly in React Native\n) {\n // Only support the object returned by query-string\n const hasCode = typeof searchParams === \"object\" && \"code\" in searchParams;\n\n if (!hasCode) return false;\n\n // If currentUrl is provided (React Native), use it.\n let currentUri: string;\n if (currentUrl) {\n // Remove query and hash from currentUrl\n const urlObj = new URL(currentUrl);\n currentUri = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;\n } else {\n // Can't determine current URI\n return false;\n }\n\n return currentUri === redirectUri || currentUri === `${redirectUri}/`;\n}\n","function createMemoryStorage() {\n let _store: { [key: string]: unknown } = {};\n\n function setItem(key: string, value: unknown): void {\n _store[key] = value;\n }\n\n function getItem(key: string): unknown {\n return _store[key];\n }\n\n function removeItem(key: string): void {\n delete _store[key];\n }\n\n function reset(): void {\n _store = {};\n }\n\n return {\n setItem,\n getItem,\n removeItem,\n reset,\n };\n}\n\nconst memoryStorage = createMemoryStorage();\n\nexport { memoryStorage };\n","import * as Crypto from \"expo-crypto\";\n\nexport async function createPkceChallenge() {\n const codeVerifier = await generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n return { codeVerifier, codeChallenge };\n}\n\nasync function generateCodeVerifier(): Promise<string> {\n // Generate 32 random bytes and encode as base64url\n const randomBytes = await Crypto.getRandomBytesAsync(32);\n return base64urlEncode(randomBytes);\n}\n\nasync function generateCodeChallenge(codeVerifier: string): Promise<string> {\n // Hash the code verifier using SHA-256 and encode as base64url\n const hash = await Crypto.digestStringAsync(\n Crypto.CryptoDigestAlgorithm.SHA256,\n codeVerifier,\n { encoding: Crypto.CryptoEncoding.BASE64 },\n );\n // Convert base64 to base64url\n return hash.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nfunction base64urlEncode(uint8Array: Uint8Array): string {\n // Convert Uint8Array to base64\n let binary = \"\";\n for (let i = 0; i < uint8Array.length; i++) {\n binary += String.fromCharCode(uint8Array[i]);\n }\n const base64 = btoa(binary);\n\n // Convert base64 to base64url\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n","let AsyncStorage: any = null;\ntry {\n AsyncStorage = require(\"@react-native-async-storage/async-storage\").default;\n} catch (e) {\n // Not in React Native, ignore\n}\n\nfunction isReactNative() {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.product === \"ReactNative\"\n );\n}\n\nconst nativeStorage = {\n async setItem(key: string, value: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.setItem(key, value);\n } else {\n // fallback to in-memory for web\n (globalThis as any).__nativeMemoryStore = (globalThis as any).__nativeMemoryStore || {};\n (globalThis as any).__nativeMemoryStore[key] = value;\n }\n },\n async getItem(key: string): Promise<string | null> {\n if (isReactNative() && AsyncStorage) {\n return await AsyncStorage.getItem(key);\n } else {\n return (globalThis as any).__nativeMemoryStore?.[key] ?? null;\n }\n },\n async removeItem(key: string) {\n if (isReactNative() && AsyncStorage) {\n await AsyncStorage.removeItem(key);\n } else {\n if ((globalThis as any).__nativeMemoryStore) {\n delete (globalThis as any).__nativeMemoryStore[key];\n }\n }\n }\n};\n\nexport { nativeStorage };\n","export const storageKeys = {\n codeVerifier: \"code-verifier\",\n user: \"user\",\n accessToken: \"access-token\",\n refreshToken: \"refresh-token\",\n expiresAt: \"expires-at\",\n} as const;\n","import type { AuthenticationResponse } from \"../interfaces\";\nimport { memoryStorage } from \"./memory-storage\";\nimport { nativeStorage } from \"./native-storage\";\nimport { storageKeys } from \"./storage-keys\";\n\ninterface AccessToken {\n exp: number;\n iat: number;\n iss: string;\n jti: string;\n sid: string;\n sub: string;\n org_id?: string;\n role?: string;\n permissions?: string[];\n}\n\n// should replace this with jose if we ever need to verify the JWT\nexport function getClaims(accessToken: string) {\n return JSON.parse(atob(accessToken.split(\".\")[1])) as AccessToken;\n}\n\nexport function setSessionData(\n data: AuthenticationResponse,\n { devMode = false } = {},\n) {\n const { user, accessToken, refreshToken } = data;\n memoryStorage.setItem(storageKeys.user, user);\n memoryStorage.setItem(storageKeys.accessToken, accessToken);\n if (devMode) {\n nativeStorage.setItem(storageKeys.refreshToken, refreshToken);\n } else {\n memoryStorage.setItem(storageKeys.refreshToken, refreshToken);\n }\n\n // compute a local time version of expires at (should avoid issues with slightly-wrong clocks)\n const { exp, iat } = getClaims(accessToken);\n const expiresIn = exp - iat;\n const expiresAt = Date.now() + expiresIn * 1000;\n memoryStorage.setItem(storageKeys.expiresAt, expiresAt);\n}\n\nexport function removeSessionData({ devMode = false } = {}) {\n memoryStorage.removeItem(storageKeys.user);\n memoryStorage.removeItem(storageKeys.accessToken);\n if (devMode) {\n nativeStorage.removeItem(storageKeys.refreshToken);\n } else {\n memoryStorage.removeItem(storageKeys.refreshToken);\n }\n}\n\nexport async function getRefreshToken({ devMode = false } = {}) {\n if (devMode) {\n return await nativeStorage.getItem(storageKeys.refreshToken);\n } else {\n return memoryStorage.getItem(storageKeys.refreshToken) as string | undefined;\n }\n}\n","import { createClient, LoginRequiredError } from \"../client\";\nimport type { RedirectOptions } from \"../client/create-client\";\nimport type { State } from \"./state\";\nimport React, { useState } from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport type Client = Pick<\n Awaited<ReturnType<typeof createClient>>,\n \"signIn\" | \"signUp\" | \"getUser\" | \"getAccessToken\" | \"signOut\"\n>;\n\nexport type CreateClientOptions = NonNullable<\n Parameters<typeof createClient>[1]\n>;\n\ntype YboardAuthProviderProps = CreateClientOptions & {\n clientId: string;\n organizationId: string;\n children: React.ReactNode;\n};\n\nexport function YboardAuthProvider(props: YboardAuthProviderProps) {\n const {\n clientId,\n apiHostname,\n https,\n port,\n redirectUri,\n children,\n organizationId,\n refreshBufferInterval,\n } = props;\n const [client, setClient] = useState<Client>(NOOP_CLIENT);\n const [state, setState] = React.useState(initialState);\n\n React.useEffect(() => {\n async function initialize() {\n try {\n const client = await createClient(clientId, {\n apiHostname,\n port,\n organizationId,\n https,\n redirectUri,\n refreshBufferInterval,\n });\n const user = await client.getUser();\n\n setClient({\n getAccessToken: client.getAccessToken.bind(client),\n getUser: client.getUser.bind(client),\n signIn: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signIn(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signUp: async (...args: [Omit<RedirectOptions, \"type\">?]) => {\n await client.signUp(...args);\n const user = await client.getUser();\n setState((prev: State) => ({ ...prev, user }));\n },\n signOut: async (...args: [{ returnTo: string }?]) => {\n await client.signOut(...args);\n setState((prev: State) => ({ ...prev, user: null }));\n },\n });\n setState((prev: State) => ({ ...prev, isLoading: false, user }));\n } catch (err) {\n console.error(\"Error initializing auth client:\", err);\n setState((prev: State) => ({ ...prev, isLoading: false, user: null }));\n }\n }\n\n initialize();\n }, []);\n\n return (\n <YboardAuthContext.Provider value={{ ...client, ...state }}>\n {children}\n </YboardAuthContext.Provider>\n );\n}\n\nconst NOOP_CLIENT: Client = {\n signIn: async () => {},\n signUp: async () => {},\n getUser: () => Promise.resolve(null),\n getAccessToken: () => Promise.reject(new LoginRequiredError()),\n signOut: async () => Promise.resolve(),\n};\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { type State, initialState } from \"./state\";\nimport type { Client } from \"./authProvider\";\n\nexport interface ContextValue extends Client, State { }\n\nexport const YboardAuthContext = React.createContext<ContextValue>(\n initialState as ContextValue,\n);\n","import type { User } from \"../client/interfaces\";\n\nexport interface State {\n isLoading: boolean;\n user: User | null;\n role: string | null;\n organizationId: string | null;\n permissions: string[];\n}\n\nexport const initialState: State = {\n isLoading: true,\n user: null,\n role: null,\n organizationId: null,\n permissions: [],\n};\n","import * as React from \"react\";\nimport { YboardAuthContext } from \"./context\";\nimport { initialState } from \"./state\";\n\nexport function useYboardAuth() {\n const context = React.useContext(YboardAuthContext);\n\n if (context === initialState) {\n throw new Error(\"useYboardAuth must be used within a YboardAuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["AuthSession","SecureStore","WebBrowser","Platform","parseSetCookieHeader","header","cookieMap","cookie","nameValue","attributes","name","value","cookieObj","attr","attrName","attrValue","getSetCookie","prevCookie","parsed","toSetCookie","key","expiresAt","maxAge","expires","getCookie","acc","AuthKitError","CodeExchangeError","AuthKitError","LoginRequiredError","fetchWithOrganizationIdAndCookie","baseUrl","organizationId","cookie","path","method","options","body","fetchOptions","deserializeUser","user","deserializeAuthenticationResponse","authenticationResponse","user","organization_id","access_token","refresh_token","impersonator","rest","deserializeUser","_baseUrl","_clientId","_organizationId","CookieHttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","code","response","fetchWithOrganizationIdAndCookie","__privateGet","data","deserializeAuthenticationResponse","error","CodeExchangeError","redirectUri","params","url","text","parsed","returnTo","logoutUrl","NoClientIdProvidedException","NoOrganizationIdProvidedException","AuthSession","WebBrowser","_baseUrl","_clientId","_organizationId","_HttpClient_instances","buildAuthUrl_fn","HttpClient","clientId","hostname","port","organizationId","https","__privateAdd","__privateSet","codeChallenge","codeChallengeMethod","redirectUri","authUrl","__privateMethod","__privateGet","code","webResult","urlParts","params","param","key","value","codeVerifier","response","error","CodeExchangeError","cookie","fetchWithOrganizationIdAndCookie","user","accessToken","returnTo","url","isRedirectCallback","redirectUri","searchParams","currentUrl","currentUri","urlObj","createMemoryStorage","_store","setItem","key","value","getItem","removeItem","reset","memoryStorage","Crypto","createPkceChallenge","codeVerifier","generateCodeVerifier","codeChallenge","generateCodeChallenge","randomBytes","base64urlEncode","uint8Array","binary","i","AsyncStorage","storageKeys","getClaims","accessToken","_httpClient","_redirectUri","_Client_instances","redirect_fn","signOutNative_fn","getAccessTokenNative_fn","getUserNative_fn","redirectNative_fn","authenticate_fn","signOutWeb_fn","getAccessTokenWeb_fn","getUserWeb_fn","handleCallback_fn","redirectWeb_fn","Client","clientId","hostname","https","port","organizationId","redirectUri","devMode","__privateAdd","NoClientIdProvidedException","NoOrganizationIdProvidedException","Platform","__privateSet","CookieHttpClient","HttpClient","__privateMethod","searchParams","isRedirectCallback","__privateGet","opts","options","origin","url","domainParts","stored","cookie","getCookie","logoutUrl","user","context","invitationToken","loginHint","passwordResetToken","state","codeVerifier","codeChallenge","createPkceChallenge","memoryStorage","storageKeys","code","prev","updated","getSetCookie","domain","cleanUrl","type","provider","createClient","client","React","useState","React","initialState","YboardAuthContext","initialState","jsx","YboardAuthProvider","props","clientId","apiHostname","https","port","redirectUri","children","organizationId","refreshBufferInterval","client","setClient","useState","NOOP_CLIENT","state","setState","React","initialState","initialize","createClient","user","args","prev","YboardAuthContext","LoginRequiredError","React","useYboardAuth","context","YboardAuthContext","initialState"]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yboard/auth-mobile",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
|
-
"module": "./dist/index.
|
|
5
|
+
"module": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"description": "YBoard mobile authentication SDK",
|
|
8
8
|
"type": "module",
|
|
@@ -87,7 +87,8 @@ export class HttpClient {
|
|
|
87
87
|
for (const param of params) {
|
|
88
88
|
const [key, value] = param.split("=");
|
|
89
89
|
if (key === "code") {
|
|
90
|
-
|
|
90
|
+
// Strip URL fragment (#) — iOS includes it in the redirect URL
|
|
91
|
+
code = decodeURIComponent(value).split("#")[0];
|
|
91
92
|
break;
|
|
92
93
|
}
|
|
93
94
|
}
|