@imtbl/auth 2.12.5-alpha.9 → 2.12.6-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -0
- package/dist/browser/index.js +79 -27
- package/dist/node/index.cjs +97 -40
- package/dist/node/index.js +80 -28
- package/dist/types/index.d.ts +3 -2
- package/dist/types/login/standalone.d.ts +141 -0
- package/dist/types/types.d.ts +26 -5
- package/package.json +6 -6
- package/src/Auth.test.ts +99 -18
- package/src/Auth.ts +21 -36
- package/src/index.ts +22 -1
- package/src/login/standalone.ts +745 -0
- package/src/types.ts +30 -5
package/dist/node/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { UserManager, User, ErrorTimeout, ErrorResponse, InMemoryWebStorage, WebStorageStateStore } from 'oidc-client-ts';
|
|
2
|
-
import
|
|
2
|
+
import Ve from 'localforage';
|
|
3
3
|
import { track, identify, getDetail, Detail, trackFlow, trackError } from '@imtbl/metrics';
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var I=(p=>(p.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",p.INVALID_CONFIGURATION="INVALID_CONFIGURATION",p.WALLET_CONNECTION_ERROR="WALLET_CONNECTION_ERROR",p.NOT_LOGGED_IN_ERROR="NOT_LOGGED_IN_ERROR",p.SILENT_LOGIN_ERROR="SILENT_LOGIN_ERROR",p.REFRESH_TOKEN_ERROR="REFRESH_TOKEN_ERROR",p.USER_REGISTRATION_ERROR="USER_REGISTRATION_ERROR",p.USER_NOT_REGISTERED_ERROR="USER_NOT_REGISTERED_ERROR",p.LOGOUT_ERROR="LOGOUT_ERROR",p.TRANSFER_ERROR="TRANSFER_ERROR",p.CREATE_ORDER_ERROR="CREATE_ORDER_ERROR",p.CANCEL_ORDER_ERROR="CANCEL_ORDER_ERROR",p.EXCHANGE_TRANSFER_ERROR="EXCHANGE_TRANSFER_ERROR",p.CREATE_TRADE_ERROR="CREATE_TRADE_ERROR",p.OPERATION_NOT_SUPPORTED_ERROR="OPERATION_NOT_SUPPORTED_ERROR",p.LINK_WALLET_ALREADY_LINKED_ERROR="LINK_WALLET_ALREADY_LINKED_ERROR",p.LINK_WALLET_MAX_WALLETS_LINKED_ERROR="LINK_WALLET_MAX_WALLETS_LINKED_ERROR",p.LINK_WALLET_VALIDATION_ERROR="LINK_WALLET_VALIDATION_ERROR",p.LINK_WALLET_DUPLICATE_NONCE_ERROR="LINK_WALLET_DUPLICATE_NONCE_ERROR",p.LINK_WALLET_GENERIC_ERROR="LINK_WALLET_GENERIC_ERROR",p.SERVICE_UNAVAILABLE_ERROR="SERVICE_UNAVAILABLE_ERROR",p.TRANSACTION_REJECTED="TRANSACTION_REJECTED",p))(I||{});function H(n){return typeof n=="object"&&n!==null&&"code"in n&&"message"in n}var ve=n=>{if(H(n))return n;if(typeof n=="object"&&n!==null&&"response"in n){let{response:e}=n;if(e?.data&&H(e.data))return e.data}},f=class extends Error{type;constructor(e,t){super(e),this.type=t;}},h=async(n,e)=>{try{return await n()}catch(t){let r;if(t instanceof f&&t.type==="SERVICE_UNAVAILABLE_ERROR")throw new f(t.message,t.type);let o=ve(t);throw o?r=o.message:r=t.message,new f(r,e)}};var Te=(n,e,t)=>{let r=e.map(o=>!n[o]&&o).filter(o=>o).join(", ");if(r!==""){let o=`${r} cannot be null`;throw new f(o,"INVALID_CONFIGURATION")}},T=class{authenticationDomain;passportDomain;oidcConfiguration;crossSdkBridgeEnabled;popupOverlayOptions;constructor({authenticationDomain:e,passportDomain:t,crossSdkBridgeEnabled:r,popupOverlayOptions:o,...i}){Te(i,["clientId","redirectUri"]),this.oidcConfiguration=i,this.crossSdkBridgeEnabled=r||!1,this.popupOverlayOptions=o,this.authenticationDomain=e||"https://auth.immutable.com",this.passportDomain=t||"https://passport.immutable.com";}};var Y=(e=>(e.ZKEVM="zkEvm",e))(Y||{}),A=(t=>(t.ZKEVM="zkevm",t.ARBITRUM_ONE="arbitrum_one",t))(A||{}),F=n=>!!n.zkEvm,J=(r=>(r.OptedIn="opted_in",r.Unsubscribed="unsubscribed",r.Subscribed="subscribed",r))(J||{}),V=(o=>(o.LOGGED_OUT="loggedOut",o.LOGGED_IN="loggedIn",o.TOKEN_REFRESHED="tokenRefreshed",o.USER_REMOVED="userRemoved",o))(V||{});var Q="im_passport_embedded_login_prompt";var C="passport-overlay",_="passport-overlay-contents",b=`${C}-close`,x=`${C}-try-again`,q=`
|
|
6
6
|
<svg
|
|
7
7
|
viewBox="0 0 20 20"
|
|
8
8
|
fill="none"
|
|
@@ -14,7 +14,7 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
14
14
|
fill="#F3F3F3"
|
|
15
15
|
/>
|
|
16
16
|
</svg>
|
|
17
|
-
`,
|
|
17
|
+
`,X=`
|
|
18
18
|
<svg
|
|
19
19
|
viewBox="0 0 17 16"
|
|
20
20
|
fill="none"
|
|
@@ -28,7 +28,7 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
28
28
|
fill="#E01A3D"
|
|
29
29
|
/>
|
|
30
30
|
</svg>
|
|
31
|
-
`,
|
|
31
|
+
`,G=`
|
|
32
32
|
<svg
|
|
33
33
|
style="
|
|
34
34
|
max-width: 123px !important;
|
|
@@ -211,9 +211,9 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
211
211
|
</clipPath>
|
|
212
212
|
</defs>
|
|
213
213
|
</svg>
|
|
214
|
-
`;var
|
|
214
|
+
`;var Oe=()=>`
|
|
215
215
|
<button
|
|
216
|
-
id="${
|
|
216
|
+
id="${b}"
|
|
217
217
|
style="
|
|
218
218
|
background: #f3f3f326 !important;
|
|
219
219
|
border: none !important;
|
|
@@ -229,11 +229,11 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
229
229
|
justify-content: center !important;
|
|
230
230
|
"
|
|
231
231
|
>
|
|
232
|
-
${
|
|
232
|
+
${q}
|
|
233
233
|
</button>
|
|
234
|
-
`,
|
|
234
|
+
`,j=()=>`
|
|
235
235
|
<button
|
|
236
|
-
id="${
|
|
236
|
+
id="${x}"
|
|
237
237
|
style="
|
|
238
238
|
margin-top: 27px !important;
|
|
239
239
|
color: #f3f3f3 !important;
|
|
@@ -248,8 +248,8 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
248
248
|
>
|
|
249
249
|
Try again
|
|
250
250
|
</button>
|
|
251
|
-
`,
|
|
252
|
-
${
|
|
251
|
+
`,Le=()=>`
|
|
252
|
+
${G}
|
|
253
253
|
<div
|
|
254
254
|
style="
|
|
255
255
|
color: #e01a3d !important;
|
|
@@ -259,7 +259,7 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
259
259
|
margin-bottom: 10px !important;
|
|
260
260
|
"
|
|
261
261
|
>
|
|
262
|
-
${
|
|
262
|
+
${X}
|
|
263
263
|
Pop-up blocked
|
|
264
264
|
</div>
|
|
265
265
|
<p style="
|
|
@@ -272,9 +272,9 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
272
272
|
If the problem continues, adjust your<br />
|
|
273
273
|
browser settings.
|
|
274
274
|
</p>
|
|
275
|
-
${
|
|
276
|
-
`,
|
|
277
|
-
${
|
|
275
|
+
${j()}
|
|
276
|
+
`,Pe=()=>`
|
|
277
|
+
${G}
|
|
278
278
|
<p style="
|
|
279
279
|
color: #b6b6b6 !important;
|
|
280
280
|
text-align: center !important;
|
|
@@ -283,10 +283,10 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
283
283
|
>
|
|
284
284
|
Secure pop-up not showing?<br />We'll help you re-launch
|
|
285
285
|
</p>
|
|
286
|
-
${
|
|
287
|
-
`,
|
|
286
|
+
${j()}
|
|
287
|
+
`,ee=n=>`
|
|
288
288
|
<div
|
|
289
|
-
id="${
|
|
289
|
+
id="${C}"
|
|
290
290
|
style="
|
|
291
291
|
position: fixed !important;
|
|
292
292
|
top: 0 !important;
|
|
@@ -309,9 +309,9 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
309
309
|
z-index: 2147483647 !important;
|
|
310
310
|
"
|
|
311
311
|
>
|
|
312
|
-
${
|
|
312
|
+
${Oe()}
|
|
313
313
|
<div
|
|
314
|
-
id="${
|
|
314
|
+
id="${_}"
|
|
315
315
|
style="
|
|
316
316
|
display: flex !important;
|
|
317
317
|
flex-direction: column !important;
|
|
@@ -319,12 +319,12 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
319
319
|
max-width: 400px !important;
|
|
320
320
|
"
|
|
321
321
|
>
|
|
322
|
-
${
|
|
322
|
+
${n??""}
|
|
323
323
|
</div>
|
|
324
324
|
</div>
|
|
325
|
-
`,
|
|
325
|
+
`,te=()=>`
|
|
326
326
|
<div
|
|
327
|
-
id="${
|
|
327
|
+
id="${C}"
|
|
328
328
|
style="
|
|
329
329
|
position: fixed;
|
|
330
330
|
top: 0;
|
|
@@ -342,7 +342,7 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
342
342
|
"
|
|
343
343
|
>
|
|
344
344
|
<div
|
|
345
|
-
id="${
|
|
345
|
+
id="${_}"
|
|
346
346
|
style="
|
|
347
347
|
display: flex;
|
|
348
348
|
flex-direction: column;
|
|
@@ -351,7 +351,7 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
351
351
|
"
|
|
352
352
|
/>
|
|
353
353
|
</div>
|
|
354
|
-
`;function
|
|
354
|
+
`;function U({id:n,href:e,rel:t,crossOrigin:r}){let o=`${C}-${n}`;if(!document.getElementById(o)){let i=document.createElement("link");i.id=o,i.href=e,t&&(i.rel=t),r&&(i.crossOrigin=r),document.head.appendChild(i);}}var re=()=>ee(Le()),ne=()=>ee(Pe());var E=class{static overlay;static onCloseListener;static closeButton;static remove(){this.onCloseListener&&this.closeButton?.removeEventListener?.("click",this.onCloseListener),this.overlay?.remove(),this.closeButton=void 0,this.onCloseListener=void 0,this.overlay=void 0;}static appendOverlay(e,t){if(!this.overlay){let r=document.createElement("div");r.innerHTML=te(),document.body.insertAdjacentElement("beforeend",r);let o=document.querySelector(`#${_}`);o&&o.appendChild(e),r.addEventListener("click",t),this.overlay=r;}}};var Ie=660,Ae=440,be="16px",oe="passport-embedded-login-keyframes",ie="passport-embedded-login-iframe",O=class n{config;constructor(e){this.config=e;}getHref=()=>`${this.config.authenticationDomain}/im-embedded-login-prompt?client_id=${this.config.oidcConfiguration.clientId}&rid=${getDetail(Detail.RUNTIME_ID)}`;static appendIFrameStylesIfNeeded=()=>{if(document.getElementById(oe))return;let e=document.createElement("style");e.id=oe,e.textContent=`
|
|
355
355
|
@keyframes passportEmbeddedLoginPromptPopBounceIn {
|
|
356
356
|
0% {
|
|
357
357
|
opacity: 0.5;
|
|
@@ -370,7 +370,7 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
370
370
|
}
|
|
371
371
|
|
|
372
372
|
@media (max-height: 400px) {
|
|
373
|
-
#${
|
|
373
|
+
#${ie} {
|
|
374
374
|
width: 100% !important;
|
|
375
375
|
max-width: none !important;
|
|
376
376
|
}
|
|
@@ -384,6 +384,58 @@ var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION
|
|
|
384
384
|
opacity: 1;
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
|
-
`,document.head.appendChild(e);};getEmbeddedLoginIFrame=()=>{let e=document.createElement("iframe");return e.id=z,e.src=this.getHref(),e.style.height="100vh",e.style.width="100vw",e.style.maxHeight=`${se}px`,e.style.maxWidth=`${ae}px`,e.style.borderRadius=le,e.style.opacity="0",e.style.transform="scale(0.6)",e.style.animation="passportEmbeddedLoginPromptPopBounceIn 1s ease forwards",o.appendIFrameStylesIfNeeded(),e};displayEmbeddedLoginPrompt(){return new Promise((e,t)=>{let r=this.getEmbeddedLoginIFrame(),n=({data:i,origin:l})=>{if(!(l!==this.config.authenticationDomain||i.eventType!==H))switch(i.messageType){case"login_method_selected":{let d=i.payload;window.removeEventListener("message",n),m.remove(),e(d);break}case"login_prompt_error":{window.removeEventListener("message",n),m.remove(),t(new Error("Error during embedded login prompt",{cause:i.payload}));break}case"login_prompt_closed":{window.removeEventListener("message",n),m.remove(),t(new Error("Popup closed by user"));break}default:window.removeEventListener("message",n),m.remove(),t(new Error(`Unsupported message type: ${i.messageType}`));break}};window.addEventListener("message",n),m.appendOverlay(r,()=>{window.removeEventListener("message",n),m.remove(),t(new Error("Popup closed by user"));});})}};var C=class{listeners=new Map;emit(e,...t){let r=this.listeners.get(e);!r||r.size===0||[...r].forEach(n=>{n(...t);});}on(e,t){let r=this.listeners.get(e)??new Set;r.add(t),this.listeners.set(e,r);}removeListener(e,t){let r=this.listeners.get(e);r&&(r.delete(t),r.size===0&&this.listeners.delete(e));}};var p=async(o,e,t=!0,r=!0)=>{let n=trackFlow("passport",e,t);try{return await o(n)}catch(i){throw i instanceof Error?trackError("passport",e,i,{flowId:n.details.flowId}):n.addEvent("errored"),i}finally{r&&n.addEvent("End");}};var pe=()=>typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{},ue=o=>{let e=o.replace(/-/g,"+").replace(/_/g,"/"),t=e.length%4===0?"":"=".repeat(4-e.length%4);return e+t},me=o=>{let e=pe();if(typeof e.atob!="function")return null;let t=e.atob(o),r=new Uint8Array(t.length);for(let i=0;i<t.length;i+=1)r[i]=t.charCodeAt(i);if(typeof e.TextDecoder=="function")return new e.TextDecoder("utf-8").decode(r);let n="";for(let i=0;i<r.length;i+=1)n+=String.fromCharCode(r[i]);return n},ge=o=>{if(typeof Buffer<"u")return Buffer.from(o,"base64").toString("utf-8");let e=me(o);if(e===null)throw new Error("Base64 decoding is not supported in this environment");return e},f=o=>{if(typeof o!="string")throw new Error("JWT must be a string");let e=o.split(".");if(e.length<2)throw new Error("Invalid JWT: payload segment is missing");let t=e[1],r=ge(ue(t));try{return JSON.parse(r)}catch{throw new Error("Invalid JWT payload: unable to parse JSON")}};var J="pkce_state",j="pkce_verifier",fe=3600,O=class{isTokenValid(e){try{let r=f(e).exp??0,n=Date.now()/1e3+fe;return r>n}catch{return !1}}savePKCEData(e){localStorage.setItem(J,e.state),localStorage.setItem(j,e.verifier);}getPKCEData(){let e=localStorage.getItem(J),t=localStorage.getItem(j);return e&&t?{state:e,verifier:t}:null}};var Ee=(...o)=>{if(typeof process>"u")return;process?.env?.JEST_WORKER_ID===void 0&&console.warn(...o);},_={warn:Ee};function Q(o){try{let e=f(o),t=Math.floor(Date.now()/1e3);return e.exp?e.exp<=t+30:!0}catch{return !0}}function q(o){let{id_token:e,access_token:t}=o;return !t||!e?!0:Q(t)||Q(e)}var T=class{disableGenericPopupOverlay;disableBlockedPopupOverlay;overlay;isBlockedOverlay;tryAgainListener;onCloseListener;constructor(e,t=!1){this.disableBlockedPopupOverlay=e.disableBlockedPopupOverlay||!1,this.disableGenericPopupOverlay=e.disableGenericPopupOverlay||!1,this.isBlockedOverlay=t;}append(e,t){this.shouldAppendOverlay()&&(this.appendOverlay(),this.updateTryAgainButton(e),this.updateCloseButton(t));}update(e){this.updateTryAgainButton(e);}remove(){this.overlay&&this.overlay.remove();}shouldAppendOverlay(){return !(this.disableGenericPopupOverlay&&this.disableBlockedPopupOverlay||this.disableGenericPopupOverlay&&!this.isBlockedOverlay||this.disableBlockedPopupOverlay&&this.isBlockedOverlay)}appendOverlay(){if(!this.overlay){A({id:"link-googleapis",href:"https://fonts.googleapis.com"}),A({id:"link-gstatic",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"}),A({id:"link-roboto",href:"https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap",rel:"stylesheet"});let t=document.createElement("div");t.innerHTML=this.isBlockedOverlay?W():$(),document.body.insertAdjacentElement("beforeend",t),this.overlay=t;}}updateTryAgainButton(e){let t=document.getElementById(w);t&&(this.tryAgainListener&&t.removeEventListener("click",this.tryAgainListener),this.tryAgainListener=e,t.addEventListener("click",e));}updateCloseButton(e){let t=document.getElementById(I);t&&(this.onCloseListener&&t.removeEventListener("click",this.onCloseListener),this.onCloseListener=e,t.addEventListener("click",e));}};var k=class{storage;constructor(e,t){this.storage=he.createInstance({name:e,driver:t});}get length(){return this.storage.length()}clear(){return this.storage.clear()}getItem(e){return this.storage.getItem(e)}key(e){return this.storage.key(e)}async removeItem(e){await this.storage.removeItem(e);}async setItem(e,t){await this.storage.setItem(e,t);}};var ke={"Content-Type":"application/x-www-form-urlencoded"},be=o=>{if(o)try{return JSON.parse(o)}catch{return}},Ue=(o,e,t)=>{if(o&&typeof o=="object"){let r=o,n=r.error_description??r.message??r.error;if(typeof n=="string"&&n.trim().length>0)return n}return e.trim().length>0?e:`Token request failed with status ${t}`},xe="/v2/logout",Se="/im-logged-out",De="/authorize",Me=o=>o?Se:xe,Ne=o=>{let{authenticationDomain:e,oidcConfiguration:t}=o,r;o.crossSdkBridgeEnabled?r=new k("ImmutableSDKPassport",he.INDEXEDDB):typeof window<"u"?r=window.localStorage:r=new InMemoryWebStorage;let n=new WebStorageStateStore({store:r}),i=new URL(Me(o.crossSdkBridgeEnabled),e.replace(/^(?:https?:\/\/)?(.*)/,"https://$1"));return i.searchParams.set("client_id",t.clientId),t.logoutRedirectUri&&i.searchParams.set("returnTo",t.logoutRedirectUri),{authority:e,redirect_uri:t.redirectUri,popup_redirect_uri:t.popupRedirectUri||t.redirectUri,client_id:t.clientId,metadata:{authorization_endpoint:`${e}/authorize`,token_endpoint:`${e}/oauth/token`,userinfo_endpoint:`${e}/userinfo`,end_session_endpoint:i.toString(),revocation_endpoint:`${e}/oauth/revoke`},automaticSilentRenew:!1,scope:t.scope,userStore:n,revokeTokenTypes:["refresh_token"],extraQueryParams:{...t.audience?{audience:t.audience}:{}}}};function D(o){return btoa(String.fromCharCode(...new Uint8Array(o))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function Fe(o){let t=new TextEncoder().encode(o);return window.crypto.subtle.digest("SHA-256",t)}var M=class o{config;userManager;deviceCredentialsManager;embeddedLoginPrompt;logoutMode;refreshingPromise=null;eventEmitter;constructor(e){this.config=new y(e),this.embeddedLoginPrompt=new v(this.config),this.userManager=new UserManager(Ne(this.config)),this.deviceCredentialsManager=new O,this.logoutMode=this.config.oidcConfiguration.logoutMode||"redirect",this.eventEmitter=new C,track("passport","initialise");}async login(e){return p(async()=>{let{useCachedSession:t=!1,useSilentLogin:r}=e||{},n=null;try{n=await this.getUserInternal();}catch(i){if(i instanceof Error&&!i.message.includes("Unknown or invalid refresh token")&&trackError("passport","login",i),t)throw i;_.warn("Failed to retrieve a cached user session",i);}if(!n&&r)n=await this.forceUserRefreshInternal();else if(!n&&!t){if(e?.useRedirectFlow)return await this.loginWithRedirectInternal(e?.directLoginOptions),null;n=await this.loginWithPopup(e?.directLoginOptions);}return n&&this.handleSuccessfulLogin(n),n},"login")}async loginWithRedirect(e){await this.loginWithRedirectInternal(e);}async loginCallback(){return p(async()=>{let e=await this.loginCallbackInternal();return e&&this.handleSuccessfulLogin(e),e},"loginCallback")}async logout(){await p(async()=>{await this.logoutInternal(),this.eventEmitter.emit("loggedOut");},"logout");}async getUser(){return this.getUserInternal()}async getUserOrLogin(){let e=null;try{e=await this.getUserInternal();}catch(r){_.warn("Failed to retrieve a cached user session",r);}if(e)return e;let t=await this.loginWithPopup();return this.handleSuccessfulLogin(t),t}async getUserZkEvm(){return this.getUserZkEvmInternal()}async getIdToken(){return p(async()=>(await this.getUserInternal())?.idToken,"getIdToken",!1)}async getAccessToken(){return p(async()=>(await this.getUserInternal())?.accessToken,"getAccessToken",!1,!1)}async isLoggedIn(){return await this.getUser()!==null}async forceUserRefresh(){return this.forceUserRefreshInternal()}forceUserRefreshInBackground(){this.forceUserRefreshInBackgroundInternal();}async loginWithPKCEFlow(e,t){return p(async()=>this.getPKCEAuthorizationUrl(e,t),"loginWithPKCEFlow")}async loginWithPKCEFlowCallback(e,t){return p(async()=>{let r=await this.loginWithPKCEFlowCallbackInternal(e,t);return this.handleSuccessfulLogin(r),r},"loginWithPKCEFlowCallback")}async storeTokens(e){return p(async()=>{let t=await this.storeTokensInternal(e);return this.handleSuccessfulLogin(t),t},"storeTokens")}async getLogoutUrl(){return p(async()=>(await this.userManager.removeUser(),this.eventEmitter.emit("loggedOut"),await this.getLogoutUrlInternal()||void 0),"getLogoutUrl")}async logoutSilentCallback(e){return p(()=>this.userManager.signoutSilentCallback(e),"logoutSilentCallback")}getConfig(){return this.config}async getClientId(){return this.config.oidcConfiguration.clientId}handleSuccessfulLogin(e){this.eventEmitter.emit("loggedIn",e),identify({passportId:e.profile.sub});}buildExtraQueryParams(e,t){let r={...this.userManager.settings?.extraQueryParams??{},rid:getDetail(Detail.RUNTIME_ID)||""};if(e){if(e.directLoginMethod==="email"){let n=e.email;n&&(r.direct=e.directLoginMethod,r.email=n);}else r.direct=e.directLoginMethod;e.marketingConsentStatus&&(r.marketingConsent=e.marketingConsentStatus);}return t&&(r.im_passport_trace_id=t),r}async loginWithRedirectInternal(e){await this.userManager.clearStaleState(),await g(async()=>{let t=this.buildExtraQueryParams(e);await this.userManager.signinRedirect({extraQueryParams:t});},"AUTHENTICATION_ERROR");}async loginWithPopup(e){return g(async()=>{let t,r;if(e)t=e;else if(!this.config.popupOverlayOptions?.disableHeadlessLoginPromptOverlay){let{imPassportTraceId:l,...d}=await this.embeddedLoginPrompt.displayEmbeddedLoginPrompt();t=d,r=l;}let n=window.crypto.randomUUID(),i=async()=>{let l=this.buildExtraQueryParams(t,r);return this.userManager.signinPopup({extraQueryParams:l,popupWindowFeatures:{width:410,height:450},popupWindowTarget:n,popupAbortOnClose:!0})};return new Promise((l,d)=>{i().then(c=>l(o.mapOidcUserToDomainModel(c))).catch(c=>{if(!(c instanceof Error)||c.message!=="Attempted to navigate on a disposed window"){d(c);return}let L=!1,a=new T(this.config.popupOverlayOptions||{},!0);a.append(async()=>{try{if(L)window.open("",n);else {L=!0;let E=await i();a.remove(),l(o.mapOidcUserToDomainModel(E));}}catch(E){a.remove(),d(E);}},()=>{a.remove(),d(new Error("Popup closed by user"));});});})},"AUTHENTICATION_ERROR")}static mapOidcUserToDomainModel=e=>{let t,r;if(e.id_token){let i=f(e.id_token);t=i?.passport,i?.username&&(r=i?.username);}let n={expired:e.expired,idToken:e.id_token,accessToken:e.access_token,refreshToken:e.refresh_token,profile:{sub:e.profile.sub,email:e.profile.email,nickname:e.profile.nickname,username:r}};return t?.zkevm_eth_address&&t?.zkevm_user_admin_address&&(n.zkEvm={ethAddress:t.zkevm_eth_address,userAdminAddress:t.zkevm_user_admin_address}),n};static mapDeviceTokenResponseToOidcUser=e=>{let t=f(e.id_token);return new User({id_token:e.id_token,access_token:e.access_token,refresh_token:e.refresh_token,token_type:e.token_type,profile:{sub:t.sub,iss:t.iss,aud:t.aud,exp:t.exp,iat:t.iat,email:t.email,nickname:t.nickname,passport:t.passport,...t.username?{username:t.username}:{}}})};async loginCallbackInternal(){return g(async()=>{let e=await this.userManager.signinCallback();if(e)return o.mapOidcUserToDomainModel(e)},"AUTHENTICATION_ERROR")}async getPKCEAuthorizationUrl(e,t){let r=D(window.crypto.getRandomValues(new Uint8Array(32))),n=D(await Fe(r)),i=D(window.crypto.getRandomValues(new Uint8Array(32))),{redirectUri:l,scope:d,audience:c,clientId:L}=this.config.oidcConfiguration;this.deviceCredentialsManager.savePKCEData({state:i,verifier:r});let a=new URL(De,this.config.authenticationDomain);if(a.searchParams.set("response_type","code"),a.searchParams.set("code_challenge",n),a.searchParams.set("code_challenge_method","S256"),a.searchParams.set("client_id",L),a.searchParams.set("redirect_uri",l),a.searchParams.set("state",i),d&&a.searchParams.set("scope",d),c&&a.searchParams.set("audience",c),e){if(e.directLoginMethod==="email"){let E=e.email;E&&(a.searchParams.set("direct",e.directLoginMethod),a.searchParams.set("email",E));}else a.searchParams.set("direct",e.directLoginMethod);e.marketingConsentStatus&&a.searchParams.set("marketingConsent",e.marketingConsentStatus);}return t&&a.searchParams.set("im_passport_trace_id",t),a.toString()}async loginWithPKCEFlowCallbackInternal(e,t){return g(async()=>{let r=this.deviceCredentialsManager.getPKCEData();if(!r)throw new Error("No code verifier or state for PKCE");if(t!==r.state)throw new Error("Provided state does not match stored state");let n=await this.getPKCEToken(e,r.verifier),i=o.mapDeviceTokenResponseToOidcUser(n),l=o.mapOidcUserToDomainModel(i);return await this.userManager.storeUser(i),l},"AUTHENTICATION_ERROR")}async getPKCEToken(e,t){let r=await fetch(`${this.config.authenticationDomain}/oauth/token`,{method:"POST",headers:ke,body:new URLSearchParams({client_id:this.config.oidcConfiguration.clientId,grant_type:"authorization_code",code_verifier:t,code:e,redirect_uri:this.config.oidcConfiguration.redirectUri})}),n=await r.text(),i=be(n);if(!r.ok)throw new Error(Ue(i,n,r.status));if(!i||typeof i!="object")throw new Error("Token endpoint returned an invalid response");return i}async storeTokensInternal(e){return g(async()=>{let t=o.mapDeviceTokenResponseToOidcUser(e),r=o.mapOidcUserToDomainModel(t);return await this.userManager.storeUser(t),r},"AUTHENTICATION_ERROR")}async logoutInternal(){await g(async()=>{await this.userManager.revokeTokens(["refresh_token"]),this.logoutMode==="silent"?await this.userManager.signoutSilent():await this.userManager.signoutRedirect();},"LOGOUT_ERROR");}async getLogoutUrlInternal(){let e=this.userManager.settings?.metadata?.end_session_endpoint;return e||(_.warn("Failed to get logout URL"),null)}forceUserRefreshInBackgroundInternal(){this.refreshTokenAndUpdatePromise().catch(e=>{_.warn("Failed to refresh user token",e);});}async forceUserRefreshInternal(){return this.refreshTokenAndUpdatePromise().catch(e=>(_.warn("Failed to refresh user token",e),null))}async refreshTokenAndUpdatePromise(){return this.refreshingPromise?this.refreshingPromise:(this.refreshingPromise=new Promise((e,t)=>{(async()=>{try{let r=await this.userManager.signinSilent();if(r){let n=o.mapOidcUserToDomainModel(r);this.eventEmitter.emit("tokenRefreshed",n),e(n);return}e(null);}catch(r){let n="AUTHENTICATION_ERROR",i="Failed to refresh token",l=!0,d="unknown";if(r instanceof ErrorTimeout)n="SILENT_LOGIN_ERROR",i=`${i}: ${r.message}`,l=!1;else if(r instanceof ErrorResponse){n="NOT_LOGGED_IN_ERROR",i=`${i}: ${r.message||r.error_description}`;let c=["server_error","temporarily_unavailable"];r.error&&c.includes(r.error)?(l=!1,d="refresh_failed"):d="refresh_token_invalid";}else r instanceof Error?(i=`${i}: ${r.message}`,r.message.toLowerCase().includes("network")||r.message.toLowerCase().includes("fetch")||r.message.toLowerCase().includes("failed to fetch")||r.message.toLowerCase().includes("networkerror")?l=!1:d="refresh_failed"):typeof r=="string"&&(i=`${i}: ${r}`,d="refresh_failed");if(l){this.eventEmitter.emit("userRemoved",{reason:d,error:i});try{await this.userManager.removeUser();}catch(c){c instanceof Error&&(i=`${i}: Failed to remove user: ${c.message}`);}}t(new u(i,n));}finally{this.refreshingPromise=null;}})();}),this.refreshingPromise)}async getUserInternal(e=t=>!0){if(this.refreshingPromise){let r=await this.refreshingPromise;return r&&e(r)?r:null}let t=await this.userManager.getUser();if(!t)return null;if(!q(t)){let r=o.mapOidcUserToDomainModel(t);if(r&&e(r))return r}if(t.refresh_token){let r=await this.refreshTokenAndUpdatePromise();if(r&&e(r))return r}return null}async getUserZkEvmInternal(){let e=await this.getUserInternal(U);if(!e)throw new Error("Failed to obtain a User with the required ZkEvm attributes");return e}};
|
|
387
|
+
`,document.head.appendChild(e);};getEmbeddedLoginIFrame=()=>{let e=document.createElement("iframe");return e.id=ie,e.src=this.getHref(),e.style.height="100vh",e.style.width="100vw",e.style.maxHeight=`${Ie}px`,e.style.maxWidth=`${Ae}px`,e.style.borderRadius=be,e.style.opacity="0",e.style.transform="scale(0.6)",e.style.animation="passportEmbeddedLoginPromptPopBounceIn 1s ease forwards",n.appendIFrameStylesIfNeeded(),e};displayEmbeddedLoginPrompt(){return new Promise((e,t)=>{let r=this.getEmbeddedLoginIFrame(),o=({data:i,origin:s})=>{if(!(s!==this.config.authenticationDomain||i.eventType!==Q))switch(i.messageType){case"login_method_selected":{let a=i.payload;window.removeEventListener("message",o),E.remove(),e(a);break}case"login_prompt_error":{window.removeEventListener("message",o),E.remove(),t(new Error("Error during embedded login prompt",{cause:i.payload}));break}case"login_prompt_closed":{window.removeEventListener("message",o),E.remove(),t(new Error("Popup closed by user"));break}default:window.removeEventListener("message",o),E.remove(),t(new Error(`Unsupported message type: ${i.messageType}`));break}};window.addEventListener("message",o),E.appendOverlay(r,()=>{window.removeEventListener("message",o),E.remove(),t(new Error("Popup closed by user"));});})}};var R=class{listeners=new Map;emit(e,...t){let r=this.listeners.get(e);!r||r.size===0||[...r].forEach(o=>{o(...t);});}on(e,t){let r=this.listeners.get(e)??new Set;r.add(t),this.listeners.set(e,r);}removeListener(e,t){let r=this.listeners.get(e);r&&(r.delete(t),r.size===0&&this.listeners.delete(e));}};var m=async(n,e,t=!0,r=!0)=>{let o=trackFlow("passport",e,t);try{return await n(o)}catch(i){throw i instanceof Error?trackError("passport",e,i,{flowId:o.details.flowId}):o.addEvent("errored"),i}finally{r&&o.addEvent("End");}};var Se=()=>typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{},De=n=>{let e=n.replace(/-/g,"+").replace(/_/g,"/"),t=e.length%4===0?"":"=".repeat(4-e.length%4);return e+t},Me=n=>{let e=Se();if(typeof e.atob!="function")return null;let t=e.atob(n),r=new Uint8Array(t.length);for(let i=0;i<t.length;i+=1)r[i]=t.charCodeAt(i);if(typeof e.TextDecoder=="function")return new e.TextDecoder("utf-8").decode(r);let o="";for(let i=0;i<r.length;i+=1)o+=String.fromCharCode(r[i]);return o},Ne=n=>{if(typeof Buffer<"u")return Buffer.from(n,"base64").toString("utf-8");let e=Me(n);if(e===null)throw new Error("Base64 decoding is not supported in this environment");return e},u=n=>{if(typeof n!="string")throw new Error("JWT must be a string");let e=n.split(".");if(e.length<2)throw new Error("Invalid JWT: payload segment is missing");let t=e[1],r=Ne(De(t));try{return JSON.parse(r)}catch{throw new Error("Invalid JWT payload: unable to parse JSON")}};var se="pkce_state",ae="pkce_verifier",He=3600,L=class{isTokenValid(e){try{let r=u(e).exp??0,o=Date.now()/1e3+He;return r>o}catch{return !1}}savePKCEData(e){localStorage.setItem(se,e.state),localStorage.setItem(ae,e.verifier);}getPKCEData(){let e=localStorage.getItem(se),t=localStorage.getItem(ae);return e&&t?{state:e,verifier:t}:null}};var Fe=(...n)=>{if(typeof process>"u")return;process?.env?.JEST_WORKER_ID===void 0&&console.warn(...n);},v={warn:Fe};function de(n){try{let e=u(n),t=Math.floor(Date.now()/1e3);return e.exp?e.exp<=t+30:!0}catch{return !0}}function le(n){let{id_token:e,access_token:t}=n;return !t||!e?!0:de(t)||de(e)}var P=class{disableGenericPopupOverlay;disableBlockedPopupOverlay;overlay;isBlockedOverlay;tryAgainListener;onCloseListener;constructor(e,t=!1){this.disableBlockedPopupOverlay=e.disableBlockedPopupOverlay||!1,this.disableGenericPopupOverlay=e.disableGenericPopupOverlay||!1,this.isBlockedOverlay=t;}append(e,t){this.shouldAppendOverlay()&&(this.appendOverlay(),this.updateTryAgainButton(e),this.updateCloseButton(t));}update(e){this.updateTryAgainButton(e);}remove(){this.overlay&&this.overlay.remove();}shouldAppendOverlay(){return !(this.disableGenericPopupOverlay&&this.disableBlockedPopupOverlay||this.disableGenericPopupOverlay&&!this.isBlockedOverlay||this.disableBlockedPopupOverlay&&this.isBlockedOverlay)}appendOverlay(){if(!this.overlay){U({id:"link-googleapis",href:"https://fonts.googleapis.com"}),U({id:"link-gstatic",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"}),U({id:"link-roboto",href:"https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap",rel:"stylesheet"});let t=document.createElement("div");t.innerHTML=this.isBlockedOverlay?re():ne(),document.body.insertAdjacentElement("beforeend",t),this.overlay=t;}}updateTryAgainButton(e){let t=document.getElementById(x);t&&(this.tryAgainListener&&t.removeEventListener("click",this.tryAgainListener),this.tryAgainListener=e,t.addEventListener("click",e));}updateCloseButton(e){let t=document.getElementById(b);t&&(this.onCloseListener&&t.removeEventListener("click",this.onCloseListener),this.onCloseListener=e,t.addEventListener("click",e));}};var S=class{storage;constructor(e,t){this.storage=Ve.createInstance({name:e,driver:t});}get length(){return this.storage.length()}clear(){return this.storage.clear()}getItem(e){return this.storage.getItem(e)}key(e){return this.storage.key(e)}async removeItem(e){await this.storage.removeItem(e);}async setItem(e,t){await this.storage.setItem(e,t);}};var je={"Content-Type":"application/x-www-form-urlencoded"},et=n=>{if(n)try{return JSON.parse(n)}catch{return}},tt=(n,e,t)=>{if(n&&typeof n=="object"){let r=n,o=r.error_description??r.message??r.error;if(typeof o=="string"&&o.trim().length>0)return o}return e.trim().length>0?e:`Token request failed with status ${t}`},ce=(n,e)=>({ethAddress:n,userAdminAddress:e}),rt="/v2/logout",nt="/im-logged-out",ot="/authorize",it=n=>n?nt:rt,st=n=>{let{authenticationDomain:e,oidcConfiguration:t}=n,r;n.crossSdkBridgeEnabled?r=new S("ImmutableSDKPassport",Ve.INDEXEDDB):typeof window<"u"?r=window.localStorage:r=new InMemoryWebStorage;let o=new WebStorageStateStore({store:r}),i=new URL(it(n.crossSdkBridgeEnabled),e.replace(/^(?:https?:\/\/)?(.*)/,"https://$1"));return i.searchParams.set("client_id",t.clientId),t.logoutRedirectUri&&i.searchParams.set("returnTo",t.logoutRedirectUri),{authority:e,redirect_uri:t.redirectUri,popup_redirect_uri:t.popupRedirectUri||t.redirectUri,client_id:t.clientId,metadata:{authorization_endpoint:`${e}/authorize`,token_endpoint:`${e}/oauth/token`,userinfo_endpoint:`${e}/userinfo`,end_session_endpoint:i.toString(),revocation_endpoint:`${e}/oauth/revoke`},automaticSilentRenew:!1,scope:t.scope,userStore:o,revokeTokenTypes:["refresh_token"],extraQueryParams:{...t.audience?{audience:t.audience}:{}}}};function B(n){return btoa(String.fromCharCode(...new Uint8Array(n))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function at(n){let t=new TextEncoder().encode(n);return window.crypto.subtle.digest("SHA-256",t)}var K=class n{config;userManager;deviceCredentialsManager;embeddedLoginPrompt;logoutMode;refreshingPromise=null;eventEmitter;constructor(e){this.config=new T(e),this.embeddedLoginPrompt=new O(this.config),this.userManager=new UserManager(st(this.config)),this.deviceCredentialsManager=new L,this.logoutMode=this.config.oidcConfiguration.logoutMode||"redirect",this.eventEmitter=new R,track("passport","initialise");}async login(e){return m(async()=>{let{useCachedSession:t=!1,useSilentLogin:r}=e||{},o=null;try{o=await this.getUserInternal();}catch(i){if(i instanceof Error&&!i.message.includes("Unknown or invalid refresh token")&&trackError("passport","login",i),t)throw i;v.warn("Failed to retrieve a cached user session",i);}if(!o&&r)o=await this.forceUserRefreshInternal();else if(!o&&!t){if(e?.useRedirectFlow)return await this.loginWithRedirectInternal(e?.directLoginOptions),null;o=await this.loginWithPopup(e?.directLoginOptions);}return o&&this.handleSuccessfulLogin(o),o},"login")}async loginWithRedirect(e){await this.loginWithRedirectInternal(e);}async loginCallback(){return m(async()=>{let e=await this.loginCallbackInternal();return e&&this.handleSuccessfulLogin(e),e},"loginCallback")}async logout(){await m(async()=>{await this.logoutInternal(),this.eventEmitter.emit("loggedOut");},"logout");}async getUser(){return this.getUserInternal()}async getUserOrLogin(){let e=null;try{e=await this.getUserInternal();}catch(r){v.warn("Failed to retrieve a cached user session",r);}if(e)return e;let t=await this.loginWithPopup();return this.handleSuccessfulLogin(t),t}async getUserZkEvm(){return this.getUserZkEvmInternal()}async getIdToken(){return m(async()=>(await this.getUserInternal())?.idToken,"getIdToken",!1)}async getAccessToken(){return m(async()=>(await this.getUserInternal())?.accessToken,"getAccessToken",!1,!1)}async isLoggedIn(){return await this.getUser()!==null}async forceUserRefresh(){return this.forceUserRefreshInternal()}forceUserRefreshInBackground(){this.forceUserRefreshInBackgroundInternal();}async loginWithPKCEFlow(e,t){return m(async()=>this.getPKCEAuthorizationUrl(e,t),"loginWithPKCEFlow")}async loginWithPKCEFlowCallback(e,t){return m(async()=>{let r=await this.loginWithPKCEFlowCallbackInternal(e,t);return this.handleSuccessfulLogin(r),r},"loginWithPKCEFlowCallback")}async storeTokens(e){return m(async()=>{let t=await this.storeTokensInternal(e);return this.handleSuccessfulLogin(t),t},"storeTokens")}async getLogoutUrl(){return m(async()=>(await this.userManager.removeUser(),this.eventEmitter.emit("loggedOut"),await this.getLogoutUrlInternal()||void 0),"getLogoutUrl")}async logoutSilentCallback(e){return m(()=>this.userManager.signoutSilentCallback(e),"logoutSilentCallback")}getConfig(){return this.config}async getClientId(){return this.config.oidcConfiguration.clientId}handleSuccessfulLogin(e){this.eventEmitter.emit("loggedIn",e),identify({passportId:e.profile.sub});}buildExtraQueryParams(e,t){let r={...this.userManager.settings?.extraQueryParams??{},rid:getDetail(Detail.RUNTIME_ID)||""};if(e){if(e.directLoginMethod==="email"){let o=e.email;o&&(r.direct=e.directLoginMethod,r.email=o);}else r.direct=e.directLoginMethod;e.marketingConsentStatus&&(r.marketingConsent=e.marketingConsentStatus);}return t&&(r.im_passport_trace_id=t),r}async loginWithRedirectInternal(e){await this.userManager.clearStaleState(),await h(async()=>{let t=this.buildExtraQueryParams(e);await this.userManager.signinRedirect({extraQueryParams:t});},"AUTHENTICATION_ERROR");}async loginWithPopup(e){return h(async()=>{let t,r;if(e)t=e;else if(!this.config.popupOverlayOptions?.disableHeadlessLoginPromptOverlay){let{imPassportTraceId:s,...a}=await this.embeddedLoginPrompt.displayEmbeddedLoginPrompt();t=a,r=s;}let o=window.crypto.randomUUID(),i=async()=>{let s=this.buildExtraQueryParams(t,r);return this.userManager.signinPopup({extraQueryParams:s,popupWindowFeatures:{width:410,height:450},popupWindowTarget:o,popupAbortOnClose:!0})};return new Promise((s,a)=>{i().then(l=>s(n.mapOidcUserToDomainModel(l))).catch(l=>{if(!(l instanceof Error)||l.message!=="Attempted to navigate on a disposed window"){a(l);return}let c=!1,d=new P(this.config.popupOverlayOptions||{},!0);d.append(async()=>{try{if(c)window.open("",o);else {c=!0;let g=await i();d.remove(),s(n.mapOidcUserToDomainModel(g));}}catch(g){d.remove(),a(g);}},()=>{d.remove(),a(new Error("Popup closed by user"));});});})},"AUTHENTICATION_ERROR")}static mapOidcUserToDomainModel=e=>{let t,r;if(e.id_token){let s=u(e.id_token);t=s?.passport,s?.username&&(r=s?.username);}let o={expired:e.expired,idToken:e.id_token,accessToken:e.access_token,refreshToken:e.refresh_token,profile:{sub:e.profile.sub,email:e.profile.email,nickname:e.profile.nickname,username:r}};t?.zkevm_eth_address&&t?.zkevm_user_admin_address&&(o.zkEvm=ce(t.zkevm_eth_address,t.zkevm_user_admin_address));let i=Object.values(A).filter(s=>s!=="zkevm");for(let s of i){let a=t?.[s];a?.eth_address&&a?.user_admin_address&&(o[s]=ce(a.eth_address,a.user_admin_address));}return o};static mapDeviceTokenResponseToOidcUser=e=>{let t=u(e.id_token);return new User({id_token:e.id_token,access_token:e.access_token,refresh_token:e.refresh_token,token_type:e.token_type,profile:{sub:t.sub,iss:t.iss,aud:t.aud,exp:t.exp,iat:t.iat,email:t.email,nickname:t.nickname,passport:t.passport,...t.username?{username:t.username}:{}}})};async loginCallbackInternal(){return h(async()=>{let e=await this.userManager.signinCallback();if(e)return n.mapOidcUserToDomainModel(e)},"AUTHENTICATION_ERROR")}async getPKCEAuthorizationUrl(e,t){let r=B(window.crypto.getRandomValues(new Uint8Array(32))),o=B(await at(r)),i=B(window.crypto.getRandomValues(new Uint8Array(32))),{redirectUri:s,scope:a,audience:l,clientId:c}=this.config.oidcConfiguration;this.deviceCredentialsManager.savePKCEData({state:i,verifier:r});let d=new URL(ot,this.config.authenticationDomain);if(d.searchParams.set("response_type","code"),d.searchParams.set("code_challenge",o),d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("client_id",c),d.searchParams.set("redirect_uri",s),d.searchParams.set("state",i),a&&d.searchParams.set("scope",a),l&&d.searchParams.set("audience",l),e){if(e.directLoginMethod==="email"){let g=e.email;g&&(d.searchParams.set("direct",e.directLoginMethod),d.searchParams.set("email",g));}else d.searchParams.set("direct",e.directLoginMethod);e.marketingConsentStatus&&d.searchParams.set("marketingConsent",e.marketingConsentStatus);}return t&&d.searchParams.set("im_passport_trace_id",t),d.toString()}async loginWithPKCEFlowCallbackInternal(e,t){return h(async()=>{let r=this.deviceCredentialsManager.getPKCEData();if(!r)throw new Error("No code verifier or state for PKCE");if(t!==r.state)throw new Error("Provided state does not match stored state");let o=await this.getPKCEToken(e,r.verifier),i=n.mapDeviceTokenResponseToOidcUser(o),s=n.mapOidcUserToDomainModel(i);return await this.userManager.storeUser(i),s},"AUTHENTICATION_ERROR")}async getPKCEToken(e,t){let r=await fetch(`${this.config.authenticationDomain}/oauth/token`,{method:"POST",headers:je,body:new URLSearchParams({client_id:this.config.oidcConfiguration.clientId,grant_type:"authorization_code",code_verifier:t,code:e,redirect_uri:this.config.oidcConfiguration.redirectUri})}),o=await r.text(),i=et(o);if(!r.ok)throw new Error(tt(i,o,r.status));if(!i||typeof i!="object")throw new Error("Token endpoint returned an invalid response");return i}async storeTokensInternal(e){return h(async()=>{let t=n.mapDeviceTokenResponseToOidcUser(e),r=n.mapOidcUserToDomainModel(t);return await this.userManager.storeUser(t),r},"AUTHENTICATION_ERROR")}async logoutInternal(){await h(async()=>{await this.userManager.revokeTokens(["refresh_token"]),this.logoutMode==="silent"?await this.userManager.signoutSilent():await this.userManager.signoutRedirect();},"LOGOUT_ERROR");}async getLogoutUrlInternal(){let e=this.userManager.settings?.metadata?.end_session_endpoint;return e||(v.warn("Failed to get logout URL"),null)}forceUserRefreshInBackgroundInternal(){this.refreshTokenAndUpdatePromise().catch(e=>{v.warn("Failed to refresh user token",e);});}async forceUserRefreshInternal(){return this.refreshTokenAndUpdatePromise().catch(e=>(v.warn("Failed to refresh user token",e),null))}async refreshTokenAndUpdatePromise(){return this.refreshingPromise?this.refreshingPromise:(this.refreshingPromise=new Promise((e,t)=>{(async()=>{try{let r=await this.userManager.signinSilent();if(r){let o=n.mapOidcUserToDomainModel(r);this.eventEmitter.emit("tokenRefreshed",o),e(o);return}e(null);}catch(r){let o="AUTHENTICATION_ERROR",i="Failed to refresh token",s=!0;if(r instanceof ErrorTimeout?(o="SILENT_LOGIN_ERROR",i=`${i}: ${r.message}`,s=!1):r instanceof ErrorResponse?(o="NOT_LOGGED_IN_ERROR",i=`${i}: ${r.message||r.error_description}`):r instanceof Error?i=`${i}: ${r.message}`:typeof r=="string"&&(i=`${i}: ${r}`),s){this.eventEmitter.emit("userRemoved",{reason:"refresh_failed",error:i});try{await this.userManager.removeUser();}catch(a){a instanceof Error&&(i=`${i}: Failed to remove user: ${a.message}`);}}t(new f(i,o));}finally{this.refreshingPromise=null;}})();}),this.refreshingPromise)}async getUserInternal(e=t=>!0){if(this.refreshingPromise){let r=await this.refreshingPromise;return r&&e(r)?r:null}let t=await this.userManager.getUser();if(!t)return null;if(!le(t)){let r=n.mapOidcUserToDomainModel(t);if(r&&e(r))return r}if(t.refresh_token){let r=await this.refreshTokenAndUpdatePromise();if(r&&e(r))return r}return null}async getUserZkEvmInternal(){let e=await this.getUserInternal(F);if(!e)throw new Error("Failed to obtain a User with the required ZkEvm attributes");return e}};var ct="im_passport_embedded_login_prompt",ue="passport-embedded-login-iframe",ge="passport-overlay";var pt="https://auth.immutable.com",mt="platform_api",ut="openid profile email offline_access transact",gt="/authorize",ft="/oauth/token",Z="imtbl_pkce_data";function fe(n){return btoa(String.fromCharCode(...new Uint8Array(n))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function Et(n){let t=new TextEncoder().encode(n);return window.crypto.subtle.digest("SHA-256",t)}function pe(){return fe(window.crypto.getRandomValues(new Uint8Array(32)))}function $(n){return n.authenticationDomain||pt}function ht(n){try{let e=u(n);if(e.exp)return e.exp*1e3}catch{}return Date.now()+3600*1e3}function _t(n){let{access_token:e,refresh_token:t,id_token:r}=n,o={sub:""},i;if(r)try{let{sub:s,email:a,nickname:l,passport:c}=u(r);o={sub:s,email:a,nickname:l},c?.zkevm_eth_address&&c?.zkevm_user_admin_address&&(i={ethAddress:c.zkevm_eth_address,userAdminAddress:c.zkevm_user_admin_address});}catch{}return {accessToken:e,refreshToken:t,idToken:r,accessTokenExpires:ht(e),profile:o,zkEvm:i}}function yt(n){typeof window<"u"&&window.sessionStorage&&window.sessionStorage.setItem(Z,JSON.stringify(n));}function Ct(){if(typeof window<"u"&&window.sessionStorage){let n=window.sessionStorage.getItem(Z);if(n)try{return JSON.parse(n)}catch{return null}}return null}function me(){typeof window<"u"&&window.sessionStorage&&window.sessionStorage.removeItem(Z);}function Rt(){let n="passport-embedded-login-keyframes";if(document.getElementById(n))return;let e=document.createElement("style");e.id=n,e.textContent=`
|
|
388
|
+
@keyframes passportEmbeddedLoginPromptPopBounceIn {
|
|
389
|
+
0% {
|
|
390
|
+
opacity: 0.5;
|
|
391
|
+
}
|
|
392
|
+
50% {
|
|
393
|
+
opacity: 1;
|
|
394
|
+
transform: scale(1.05);
|
|
395
|
+
}
|
|
396
|
+
75% {
|
|
397
|
+
transform: scale(0.98);
|
|
398
|
+
}
|
|
399
|
+
100% {
|
|
400
|
+
opacity: 1;
|
|
401
|
+
transform: scale(1);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
@media (max-height: 400px) {
|
|
406
|
+
#${ue} {
|
|
407
|
+
width: 100% !important;
|
|
408
|
+
max-width: none !important;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
@keyframes passportEmbeddedLoginPromptOverlayFadeIn {
|
|
413
|
+
from {
|
|
414
|
+
opacity: 0;
|
|
415
|
+
}
|
|
416
|
+
to {
|
|
417
|
+
opacity: 1;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
`,document.head.appendChild(e);}function vt(n,e){let t=getDetail(Detail.RUNTIME_ID),r=document.createElement("iframe");return r.id=ue,r.src=`${n}/im-embedded-login-prompt?client_id=${e}&rid=${t}`,r.style.height="100vh",r.style.width="100vw",r.style.maxHeight="660px",r.style.maxWidth="440px",r.style.borderRadius="16px",r.style.border="none",r.style.opacity="0",r.style.transform="scale(0.6)",r.style.animation="passportEmbeddedLoginPromptPopBounceIn 1s ease forwards",Rt(),r}function Tt(){let n=document.createElement("div");n.id=ge,n.style.cssText=`
|
|
421
|
+
position: fixed;
|
|
422
|
+
top: 0;
|
|
423
|
+
left: 0;
|
|
424
|
+
width: 100%;
|
|
425
|
+
height: 100%;
|
|
426
|
+
display: flex;
|
|
427
|
+
flex-direction: column;
|
|
428
|
+
justify-content: center;
|
|
429
|
+
align-items: center;
|
|
430
|
+
z-index: 2147483647;
|
|
431
|
+
background: rgba(247, 247, 247, 0.24);
|
|
432
|
+
animation-name: passportEmbeddedLoginPromptOverlayFadeIn;
|
|
433
|
+
animation-duration: 0.8s;
|
|
434
|
+
`;let e=document.createElement("div");return e.id=_,e.style.cssText=`
|
|
435
|
+
display: flex;
|
|
436
|
+
flex-direction: column;
|
|
437
|
+
align-items: center;
|
|
438
|
+
width: 100%;
|
|
439
|
+
`,n.appendChild(e),n}function w(){document.getElementById(ge)?.remove();}function Ot(n,e){return new Promise((t,r)=>{let o=vt(n,e),i=Tt(),s=({data:c,origin:d})=>{if(!(d!==n||c.eventType!==ct))switch(c.messageType){case"login_method_selected":{let g=c.payload;window.removeEventListener("message",s),w(),t(g);break}case"login_prompt_error":{window.removeEventListener("message",s),w(),r(new Error("Error during embedded login prompt",{cause:c.payload}));break}case"login_prompt_closed":{window.removeEventListener("message",s),w(),r(new Error("Login closed by user"));break}default:window.removeEventListener("message",s),w(),r(new Error(`Unsupported message type: ${c.messageType}`));break}},a=c=>{c.target===i&&(window.removeEventListener("message",s),i.removeEventListener("click",a),w(),r(new Error("Login closed by user")));};window.addEventListener("message",s),i.addEventListener("click",a);let l=i.querySelector(`#${_}`);l&&l.appendChild(o),document.body.appendChild(i);})}async function Ee(n,e){let t=$(n),r=pe(),o=fe(await Et(r)),i=pe(),s=new URL(gt,t);s.searchParams.set("response_type","code"),s.searchParams.set("code_challenge",o),s.searchParams.set("code_challenge_method","S256"),s.searchParams.set("client_id",n.clientId),s.searchParams.set("redirect_uri",n.redirectUri),s.searchParams.set("state",i),s.searchParams.set("scope",n.scope||ut),n.audience?s.searchParams.set("audience",n.audience):s.searchParams.set("audience",mt);let a=e?.directLoginOptions;return a&&(a.directLoginMethod==="email"?a.email&&(s.searchParams.set("direct","email"),s.searchParams.set("email",a.email)):s.searchParams.set("direct",a.directLoginMethod),a.marketingConsentStatus&&s.searchParams.set("marketingConsent",a.marketingConsentStatus)),{url:s.toString(),verifier:r,state:i}}async function he(n,e,t,r){let i=`${$(n)}${ft}`,s=await fetch(i,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",client_id:n.clientId,code_verifier:t,code:e,redirect_uri:r})});if(!s.ok){let l=await s.text(),c=`Token exchange failed with status ${s.status}`;try{let d=JSON.parse(l);d.error_description?c=d.error_description:d.error&&(c=d.error);}catch{l&&(c=l);}throw new Error(c)}let a=await s.json();return _t(a)}async function _e(n,e){track("passport","standaloneLoginWithPopup");let t=n.popupRedirectUri||n.redirectUri,r={...n,redirectUri:t},{url:o,verifier:i,state:s}=await Ee(r,e);return new Promise((a,l)=>{let g=window.screenX+(window.outerWidth-500)/2,ye=window.screenY+(window.outerHeight-600)/2,y=window.open(o,"immutable_login",`width=500,height=600,left=${g},top=${ye},toolbar=no,menubar=no`);if(!y){l(new Error("Popup was blocked. Please allow popups for this site."));return}let M=setInterval(()=>{try{if(y.closed){clearInterval(M),l(new Error("Login popup was closed"));return}let N=y.location.href;if(N&&N.startsWith(t)){clearInterval(M),y.close();let k=new URL(N),W=k.searchParams.get("code"),Ce=k.searchParams.get("state"),z=k.searchParams.get("error"),Re=k.searchParams.get("error_description");if(z){l(new Error(Re||z));return}if(!W){l(new Error("No authorization code received"));return}if(Ce!==s){l(new Error("State mismatch - possible CSRF attack"));return}he(r,W,i,t).then(a).catch(l);}}catch{}},100);setTimeout(()=>{clearInterval(M),y.closed||y.close(),l(new Error("Login timed out"));},5*60*1e3);})}async function Lt(n){track("passport","standaloneLoginWithEmbedded");let e=$(n),t=await Ot(e,n.clientId),r={directLoginOptions:{directLoginMethod:t.directLoginMethod,marketingConsentStatus:t.marketingConsentStatus,...t.directLoginMethod==="email"&&t.email?{email:t.email}:{}}};return _e(n,r)}async function Pt(n,e){track("passport","standaloneLoginWithRedirect");let{url:t,verifier:r,state:o}=await Ee(n,e);yt({state:o,verifier:r,redirectUri:n.redirectUri}),window.location.href=t;}async function wt(n){if(track("passport","standaloneHandleCallback"),typeof window>"u")return;let e=new URLSearchParams(window.location.search),t=e.get("code"),r=e.get("state"),o=e.get("error"),i=e.get("error_description");if(o)throw new Error(i||o);if(!t)return;let s=Ct();if(!s)throw new Error("No PKCE data found. Login may have been initiated in a different session.");if(r!==s.state)throw me(),new Error("State mismatch - possible CSRF attack");let a=await he(n,t,s.verifier,s.redirectUri);return me(),a}
|
|
388
440
|
|
|
389
|
-
export {
|
|
441
|
+
export { K as Auth, T as AuthConfiguration, V as AuthEvents, A as EvmChain, J as MarketingConsentStatus, f as PassportError, I as PassportErrorType, Y as RollupType, R as TypedEventEmitter, u as decodeJwtPayload, wt as handleLoginCallback, H as isAPIError, F as isUserZkEvm, Lt as loginWithEmbedded, _e as loginWithPopup, Pt as loginWithRedirect, h as withPassportError };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { Auth } from './Auth';
|
|
2
2
|
export { AuthConfiguration, type IAuthConfiguration } from './config';
|
|
3
|
-
export type { User, UserProfile, UserZkEvm, DirectLoginMethod, DirectLoginOptions, LoginOptions, DeviceTokenResponse, OidcConfiguration, AuthModuleConfiguration, PopupOverlayOptions, PassportMetadata, IdTokenPayload, PKCEData, AuthEventMap, UserRemovedReason, } from './types';
|
|
4
|
-
export { isUserZkEvm, RollupType, MarketingConsentStatus, AuthEvents, } from './types';
|
|
3
|
+
export type { User, UserProfile, UserZkEvm, DirectLoginMethod, DirectLoginOptions, LoginOptions, DeviceTokenResponse, OidcConfiguration, AuthModuleConfiguration, PopupOverlayOptions, PassportMetadata, PassportChainMetadata, ChainAddress, ZkEvmInfo, IdTokenPayload, PKCEData, AuthEventMap, UserRemovedReason, } from './types';
|
|
4
|
+
export { isUserZkEvm, RollupType, EvmChain, MarketingConsentStatus, AuthEvents, } from './types';
|
|
5
5
|
export { default as TypedEventEmitter } from './utils/typedEventEmitter';
|
|
6
6
|
export { PassportError, PassportErrorType, withPassportError, isAPIError, } from './errors';
|
|
7
7
|
export { decodeJwtPayload } from './utils/jwt';
|
|
8
|
+
export { loginWithPopup, loginWithEmbedded, loginWithRedirect, handleLoginCallback, type LoginConfig, type TokenResponse, type StandaloneLoginOptions, } from './login/standalone';
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone login functions for stateless authentication flows.
|
|
3
|
+
* These functions handle OAuth login without managing session state,
|
|
4
|
+
* making them ideal for use with external session managers like NextAuth.
|
|
5
|
+
*/
|
|
6
|
+
import type { DirectLoginOptions, ZkEvmInfo } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for standalone login functions
|
|
9
|
+
*/
|
|
10
|
+
export interface LoginConfig {
|
|
11
|
+
/** Your Immutable application client ID */
|
|
12
|
+
clientId: string;
|
|
13
|
+
/** The OAuth redirect URI for your application */
|
|
14
|
+
redirectUri: string;
|
|
15
|
+
/** Optional separate redirect URI for popup flows */
|
|
16
|
+
popupRedirectUri?: string;
|
|
17
|
+
/** OAuth audience (default: "platform_api") */
|
|
18
|
+
audience?: string;
|
|
19
|
+
/** OAuth scopes (default: "openid profile email offline_access transact") */
|
|
20
|
+
scope?: string;
|
|
21
|
+
/** Authentication domain (default: "https://auth.immutable.com") */
|
|
22
|
+
authenticationDomain?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Token response from successful authentication
|
|
26
|
+
*/
|
|
27
|
+
export interface TokenResponse {
|
|
28
|
+
/** OAuth access token for API calls */
|
|
29
|
+
accessToken: string;
|
|
30
|
+
/** OAuth refresh token for token renewal */
|
|
31
|
+
refreshToken?: string;
|
|
32
|
+
/** OpenID Connect ID token */
|
|
33
|
+
idToken?: string;
|
|
34
|
+
/** Unix timestamp (ms) when the access token expires */
|
|
35
|
+
accessTokenExpires: number;
|
|
36
|
+
/** User profile information */
|
|
37
|
+
profile: {
|
|
38
|
+
sub: string;
|
|
39
|
+
email?: string;
|
|
40
|
+
nickname?: string;
|
|
41
|
+
};
|
|
42
|
+
/** zkEVM wallet information if available */
|
|
43
|
+
zkEvm?: ZkEvmInfo;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Extended login options for popup/redirect flows
|
|
47
|
+
*/
|
|
48
|
+
export interface StandaloneLoginOptions {
|
|
49
|
+
/** Direct login options (social provider, email, etc.) */
|
|
50
|
+
directLoginOptions?: DirectLoginOptions;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Login with a popup window.
|
|
54
|
+
* Opens a popup for OAuth authentication and returns tokens when complete.
|
|
55
|
+
*
|
|
56
|
+
* @param config - Login configuration
|
|
57
|
+
* @param options - Optional login options (direct login, etc.)
|
|
58
|
+
* @returns Promise resolving to token response
|
|
59
|
+
* @throws Error if popup is blocked or login fails
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* import { loginWithPopup } from '@imtbl/auth';
|
|
64
|
+
*
|
|
65
|
+
* const tokens = await loginWithPopup({
|
|
66
|
+
* clientId: 'your-client-id',
|
|
67
|
+
* redirectUri: 'https://your-app.com/callback',
|
|
68
|
+
* });
|
|
69
|
+
* console.log(tokens.accessToken);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function loginWithPopup(config: LoginConfig, options?: StandaloneLoginOptions): Promise<TokenResponse>;
|
|
73
|
+
/**
|
|
74
|
+
* Login with an embedded iframe modal.
|
|
75
|
+
* First displays a modal for the user to select their login method (email, Google, etc.),
|
|
76
|
+
* then opens a popup for OAuth authentication and returns tokens when complete.
|
|
77
|
+
*
|
|
78
|
+
* This provides a smoother user experience compared to loginWithPopup as the user
|
|
79
|
+
* can choose their login method before the OAuth popup opens.
|
|
80
|
+
*
|
|
81
|
+
* @param config - Login configuration
|
|
82
|
+
* @returns Promise resolving to token response
|
|
83
|
+
* @throws Error if modal is closed or login fails
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* import { loginWithEmbedded } from '@imtbl/auth';
|
|
88
|
+
*
|
|
89
|
+
* const tokens = await loginWithEmbedded({
|
|
90
|
+
* clientId: 'your-client-id',
|
|
91
|
+
* redirectUri: 'https://your-app.com/callback',
|
|
92
|
+
* });
|
|
93
|
+
* console.log(tokens.accessToken);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function loginWithEmbedded(config: LoginConfig): Promise<TokenResponse>;
|
|
97
|
+
/**
|
|
98
|
+
* Login with redirect.
|
|
99
|
+
* Redirects the current page to OAuth authentication.
|
|
100
|
+
* After authentication, the user will be redirected back to your redirectUri.
|
|
101
|
+
* Use `handleLoginCallback` to complete the flow.
|
|
102
|
+
*
|
|
103
|
+
* @param config - Login configuration
|
|
104
|
+
* @param options - Optional login options (direct login, etc.)
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* import { loginWithRedirect } from '@imtbl/auth';
|
|
109
|
+
*
|
|
110
|
+
* // In your login button handler
|
|
111
|
+
* loginWithRedirect({
|
|
112
|
+
* clientId: 'your-client-id',
|
|
113
|
+
* redirectUri: 'https://your-app.com/callback',
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function loginWithRedirect(config: LoginConfig, options?: StandaloneLoginOptions): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Handle the OAuth callback after redirect-based login.
|
|
120
|
+
* Extracts the authorization code from the URL and exchanges it for tokens.
|
|
121
|
+
*
|
|
122
|
+
* @param config - Login configuration (must match what was used in loginWithRedirect)
|
|
123
|
+
* @returns Promise resolving to token response, or undefined if not a valid callback
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* // In your callback page
|
|
128
|
+
* import { handleLoginCallback } from '@imtbl/auth';
|
|
129
|
+
*
|
|
130
|
+
* const tokens = await handleLoginCallback({
|
|
131
|
+
* clientId: 'your-client-id',
|
|
132
|
+
* redirectUri: 'https://your-app.com/callback',
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* if (tokens) {
|
|
136
|
+
* // Login successful, tokens contains accessToken, refreshToken, etc.
|
|
137
|
+
* await signIn('immutable', { tokens: JSON.stringify(tokens) });
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function handleLoginCallback(config: LoginConfig): Promise<TokenResponse | undefined>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -13,21 +13,42 @@ export type UserProfile = {
|
|
|
13
13
|
export declare enum RollupType {
|
|
14
14
|
ZKEVM = "zkEvm"
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Supported EVM chains for user registration
|
|
18
|
+
* Matches EvmChain from @imtbl/wallet but defined here to avoid circular dependency
|
|
19
|
+
*/
|
|
20
|
+
export declare enum EvmChain {
|
|
21
|
+
ZKEVM = "zkevm",
|
|
22
|
+
ARBITRUM_ONE = "arbitrum_one"
|
|
23
|
+
}
|
|
24
|
+
export type ChainAddress = {
|
|
25
|
+
ethAddress: `0x${string}`;
|
|
26
|
+
userAdminAddress: `0x${string}`;
|
|
27
|
+
};
|
|
28
|
+
export type ZkEvmInfo = ChainAddress;
|
|
16
29
|
export type User = {
|
|
17
30
|
idToken?: string;
|
|
18
31
|
accessToken: string;
|
|
19
32
|
refreshToken?: string;
|
|
20
33
|
profile: UserProfile;
|
|
21
34
|
expired?: boolean;
|
|
22
|
-
[RollupType.ZKEVM]?:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
35
|
+
[RollupType.ZKEVM]?: ChainAddress;
|
|
36
|
+
} & {
|
|
37
|
+
[K in Exclude<EvmChain, EvmChain.ZKEVM>]?: ChainAddress;
|
|
26
38
|
};
|
|
39
|
+
export type PassportChainMetadata = {
|
|
40
|
+
eth_address: string;
|
|
41
|
+
user_admin_address: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Passport metadata
|
|
45
|
+
* - zkEVM: flat fields (zkevm_eth_address, zkevm_user_admin_address)
|
|
46
|
+
* - Other chains: nested objects (arbitrum_one: { eth_address, user_admin_address })
|
|
47
|
+
*/
|
|
27
48
|
export type PassportMetadata = {
|
|
28
49
|
zkevm_eth_address?: string;
|
|
29
50
|
zkevm_user_admin_address?: string;
|
|
30
|
-
}
|
|
51
|
+
} & Partial<Record<Exclude<EvmChain, EvmChain.ZKEVM>, PassportChainMetadata>>;
|
|
31
52
|
export interface OidcConfiguration {
|
|
32
53
|
clientId: string;
|
|
33
54
|
logoutRedirectUri?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imtbl/auth",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.6-alpha.0",
|
|
4
4
|
"description": "Authentication SDK for Immutable",
|
|
5
5
|
"author": "Immutable",
|
|
6
6
|
"bugs": "https://github.com/immutable/ts-immutable-sdk/issues",
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@imtbl/generated-clients": "2.12.
|
|
29
|
-
"@imtbl/metrics": "2.12.
|
|
28
|
+
"@imtbl/generated-clients": "2.12.6-alpha.0",
|
|
29
|
+
"@imtbl/metrics": "2.12.6-alpha.0",
|
|
30
30
|
"localforage": "^1.10.0",
|
|
31
31
|
"oidc-client-ts": "3.4.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@swc/core": "^1.
|
|
34
|
+
"@swc/core": "^1.4.2",
|
|
35
35
|
"@swc/jest": "^0.2.37",
|
|
36
36
|
"@types/jest": "^29.5.12",
|
|
37
|
-
"@types/node": "^
|
|
37
|
+
"@types/node": "^22.10.7",
|
|
38
38
|
"@jest/test-sequencer": "^29.7.0",
|
|
39
|
-
"jest": "^29.
|
|
39
|
+
"jest": "^29.7.0",
|
|
40
40
|
"jest-environment-jsdom": "^29.4.3",
|
|
41
41
|
"ts-node": "^10.9.1",
|
|
42
42
|
"tsup": "^8.3.0",
|