@imtbl/auth 2.10.7-alpha.5 → 2.11.1-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.
@@ -1,11 +1,11 @@
1
1
  import { UserManager, User, ErrorTimeout, ErrorResponse, InMemoryWebStorage, WebStorageStateStore } from 'oidc-client-ts';
2
- import Ee, { isAxiosError } from 'axios';
3
- import q from 'jwt-decode';
4
- import { getDetail, Detail, track, trackFlow, trackError, identify } from '@imtbl/metrics';
5
- import ce from 'localforage';
2
+ import ve, { isAxiosError } from 'axios';
3
+ import X from 'jwt-decode';
4
+ import Ee from 'localforage';
5
+ import { track, identify, getDetail, Detail, trackFlow, trackError } from '@imtbl/metrics';
6
6
  import { EventEmitter } from 'events';
7
7
 
8
- var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q(e).exp??0,o=Date.now()/1e3+re;return r>o}catch{return !1}}savePKCEData(e){localStorage.setItem(F,e.state),localStorage.setItem(H,e.verifier);}getPKCEData(){let e=localStorage.getItem(F),t=localStorage.getItem(H);return e&&t?{state:e,verifier:t}:null}};var oe=(...i)=>{if(typeof process>"u")return;process?.env?.JEST_WORKER_ID===void 0&&console.warn(...i);},h={warn:oe};function V(i){try{let e=q(i),t=Math.floor(Date.now()/1e3);return e.exp?e.exp<=t+30:!0}catch{return !0}}function G(i){let{id_token:e,access_token:t}=i;return !t||!e?!0:V(t)||V(e)}var P=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION="INVALID_CONFIGURATION",s.WALLET_CONNECTION_ERROR="WALLET_CONNECTION_ERROR",s.NOT_LOGGED_IN_ERROR="NOT_LOGGED_IN_ERROR",s.SILENT_LOGIN_ERROR="SILENT_LOGIN_ERROR",s.REFRESH_TOKEN_ERROR="REFRESH_TOKEN_ERROR",s.USER_REGISTRATION_ERROR="USER_REGISTRATION_ERROR",s.USER_NOT_REGISTERED_ERROR="USER_NOT_REGISTERED_ERROR",s.LOGOUT_ERROR="LOGOUT_ERROR",s.TRANSFER_ERROR="TRANSFER_ERROR",s.CREATE_ORDER_ERROR="CREATE_ORDER_ERROR",s.CANCEL_ORDER_ERROR="CANCEL_ORDER_ERROR",s.EXCHANGE_TRANSFER_ERROR="EXCHANGE_TRANSFER_ERROR",s.CREATE_TRADE_ERROR="CREATE_TRADE_ERROR",s.OPERATION_NOT_SUPPORTED_ERROR="OPERATION_NOT_SUPPORTED_ERROR",s.LINK_WALLET_ALREADY_LINKED_ERROR="LINK_WALLET_ALREADY_LINKED_ERROR",s.LINK_WALLET_MAX_WALLETS_LINKED_ERROR="LINK_WALLET_MAX_WALLETS_LINKED_ERROR",s.LINK_WALLET_VALIDATION_ERROR="LINK_WALLET_VALIDATION_ERROR",s.LINK_WALLET_DUPLICATE_NONCE_ERROR="LINK_WALLET_DUPLICATE_NONCE_ERROR",s.LINK_WALLET_GENERIC_ERROR="LINK_WALLET_GENERIC_ERROR",s.SERVICE_UNAVAILABLE_ERROR="SERVICE_UNAVAILABLE_ERROR",s))(P||{});function se(i){return "code"in i&&"message"in i}var u=class extends Error{type;constructor(e,t){super(e),this.type=t;}},f=async(i,e)=>{try{return await i()}catch(t){let r;throw t instanceof u&&t.type==="SERVICE_UNAVAILABLE_ERROR"?new u(t.message,t.type):(isAxiosError(t)&&t.response?.data&&se(t.response.data)?r=t.response.data.message:r=t.message,new u(r,e))}};var B=(e=>(e.ZKEVM="zkEvm",e))(B||{}),M=i=>!!i.zkEvm,K=(t=>(t.OptedIn="opted_in",t.Unsubscribed="unsubscribed",t))(K||{}),U=(t=>(t.LOGGED_OUT="loggedOut",t.LOGGED_IN="loggedIn",t))(U||{});var C="passport-overlay",y="passport-overlay-contents",I=`${C}-close`,A=`${C}-try-again`,Z=`
8
+ var L=(s=>(s.AUTHENTICATION_ERROR="AUTHENTICATION_ERROR",s.INVALID_CONFIGURATION="INVALID_CONFIGURATION",s.WALLET_CONNECTION_ERROR="WALLET_CONNECTION_ERROR",s.NOT_LOGGED_IN_ERROR="NOT_LOGGED_IN_ERROR",s.SILENT_LOGIN_ERROR="SILENT_LOGIN_ERROR",s.REFRESH_TOKEN_ERROR="REFRESH_TOKEN_ERROR",s.USER_REGISTRATION_ERROR="USER_REGISTRATION_ERROR",s.USER_NOT_REGISTERED_ERROR="USER_NOT_REGISTERED_ERROR",s.LOGOUT_ERROR="LOGOUT_ERROR",s.TRANSFER_ERROR="TRANSFER_ERROR",s.CREATE_ORDER_ERROR="CREATE_ORDER_ERROR",s.CANCEL_ORDER_ERROR="CANCEL_ORDER_ERROR",s.EXCHANGE_TRANSFER_ERROR="EXCHANGE_TRANSFER_ERROR",s.CREATE_TRADE_ERROR="CREATE_TRADE_ERROR",s.OPERATION_NOT_SUPPORTED_ERROR="OPERATION_NOT_SUPPORTED_ERROR",s.LINK_WALLET_ALREADY_LINKED_ERROR="LINK_WALLET_ALREADY_LINKED_ERROR",s.LINK_WALLET_MAX_WALLETS_LINKED_ERROR="LINK_WALLET_MAX_WALLETS_LINKED_ERROR",s.LINK_WALLET_VALIDATION_ERROR="LINK_WALLET_VALIDATION_ERROR",s.LINK_WALLET_DUPLICATE_NONCE_ERROR="LINK_WALLET_DUPLICATE_NONCE_ERROR",s.LINK_WALLET_GENERIC_ERROR="LINK_WALLET_GENERIC_ERROR",s.SERVICE_UNAVAILABLE_ERROR="SERVICE_UNAVAILABLE_ERROR",s.TRANSACTION_REJECTED="TRANSACTION_REJECTED",s))(L||{});function D(o){return typeof o=="object"&&o!==null&&"code"in o&&"message"in o}var p=class extends Error{type;constructor(e,t){super(e),this.type=t;}},g=async(o,e)=>{try{return await o()}catch(t){let r;throw t instanceof p&&t.type==="SERVICE_UNAVAILABLE_ERROR"?new p(t.message,t.type):(isAxiosError(t)&&t.response?.data&&D(t.response.data)?r=t.response.data.message:r=t.message,new p(r,e))}};var ee=(o,e,t)=>{let r=e.map(n=>!o[n]&&n).filter(n=>n).join(", ");if(r!==""){let n=`${r} cannot be null`;throw new p(n,"INVALID_CONFIGURATION")}},_=class{authenticationDomain;passportDomain;oidcConfiguration;crossSdkBridgeEnabled;popupOverlayOptions;constructor({authenticationDomain:e,passportDomain:t,crossSdkBridgeEnabled:r,popupOverlayOptions:n,...i}){ee(i,["clientId","redirectUri"]),this.oidcConfiguration=i,this.crossSdkBridgeEnabled=r||!1,this.popupOverlayOptions=n,this.authenticationDomain=e||"https://auth.immutable.com",this.passportDomain=t||"https://passport.immutable.com";}};var N=(e=>(e.ZKEVM="zkEvm",e))(N||{}),w=o=>!!o.zkEvm,S=(t=>(t.OptedIn="opted_in",t.Unsubscribed="unsubscribed",t))(S||{}),U=(t=>(t.LOGGED_OUT="loggedOut",t.LOGGED_IN="loggedIn",t))(U||{});var F="im_passport_embedded_login_prompt";var E="passport-overlay",R="passport-overlay-contents",P=`${E}-close`,I=`${E}-try-again`,H=`
9
9
  <svg
10
10
  viewBox="0 0 20 20"
11
11
  fill="none"
@@ -17,7 +17,7 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
17
17
  fill="#F3F3F3"
18
18
  />
19
19
  </svg>
20
- `,$=`
20
+ `,V=`
21
21
  <svg
22
22
  viewBox="0 0 17 16"
23
23
  fill="none"
@@ -31,7 +31,7 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
31
31
  fill="#E01A3D"
32
32
  />
33
33
  </svg>
34
- `,x=`
34
+ `,b=`
35
35
  <svg
36
36
  style="
37
37
  max-width: 123px !important;
@@ -214,9 +214,9 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
214
214
  </clipPath>
215
215
  </defs>
216
216
  </svg>
217
- `;var ae=()=>`
217
+ `;var te=()=>`
218
218
  <button
219
- id="${I}"
219
+ id="${P}"
220
220
  style="
221
221
  background: #f3f3f326 !important;
222
222
  border: none !important;
@@ -232,11 +232,11 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
232
232
  justify-content: center !important;
233
233
  "
234
234
  >
235
- ${Z}
235
+ ${H}
236
236
  </button>
237
- `,W=()=>`
237
+ `,G=()=>`
238
238
  <button
239
- id="${A}"
239
+ id="${I}"
240
240
  style="
241
241
  margin-top: 27px !important;
242
242
  color: #f3f3f3 !important;
@@ -251,8 +251,8 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
251
251
  >
252
252
  Try again
253
253
  </button>
254
- `,le=()=>`
255
- ${x}
254
+ `,re=()=>`
255
+ ${b}
256
256
  <div
257
257
  style="
258
258
  color: #e01a3d !important;
@@ -262,7 +262,7 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
262
262
  margin-bottom: 10px !important;
263
263
  "
264
264
  >
265
- ${$}
265
+ ${V}
266
266
  Pop-up blocked
267
267
  </div>
268
268
  <p style="
@@ -275,9 +275,9 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
275
275
  If the problem continues, adjust your<br />
276
276
  browser settings.
277
277
  </p>
278
- ${W()}
279
- `,de=()=>`
280
- ${x}
278
+ ${G()}
279
+ `,ne=()=>`
280
+ ${b}
281
281
  <p style="
282
282
  color: #b6b6b6 !important;
283
283
  text-align: center !important;
@@ -286,10 +286,10 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
286
286
  >
287
287
  Secure pop-up not showing?<br />We'll help you re-launch
288
288
  </p>
289
- ${W()}
290
- `,Y=i=>`
289
+ ${G()}
290
+ `,B=o=>`
291
291
  <div
292
- id="${C}"
292
+ id="${E}"
293
293
  style="
294
294
  position: fixed !important;
295
295
  top: 0 !important;
@@ -312,9 +312,9 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
312
312
  z-index: 2147483647 !important;
313
313
  "
314
314
  >
315
- ${ae()}
315
+ ${te()}
316
316
  <div
317
- id="${y}"
317
+ id="${R}"
318
318
  style="
319
319
  display: flex !important;
320
320
  flex-direction: column !important;
@@ -322,12 +322,12 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
322
322
  max-width: 400px !important;
323
323
  "
324
324
  >
325
- ${i??""}
325
+ ${o??""}
326
326
  </div>
327
327
  </div>
328
- `,z=()=>`
328
+ `,Z=()=>`
329
329
  <div
330
- id="${C}"
330
+ id="${E}"
331
331
  style="
332
332
  position: fixed;
333
333
  top: 0;
@@ -345,7 +345,7 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
345
345
  "
346
346
  >
347
347
  <div
348
- id="${y}"
348
+ id="${R}"
349
349
  style="
350
350
  display: flex;
351
351
  flex-direction: column;
@@ -354,7 +354,7 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
354
354
  "
355
355
  />
356
356
  </div>
357
- `;function w({id:i,href:e,rel:t,crossOrigin:r}){let o=`${C}-${i}`;if(!document.getElementById(o)){let n=document.createElement("link");n.id=o,n.href=e,t&&(n.rel=t),r&&(n.crossOrigin=r),document.head.appendChild(n);}}var j=()=>Y(le()),Q=()=>Y(de());var v=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){w({id:"link-googleapis",href:"https://fonts.googleapis.com"}),w({id:"link-gstatic",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"}),w({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?j():Q(),document.body.insertAdjacentElement("beforeend",t),this.overlay=t;}}updateTryAgainButton(e){let t=document.getElementById(A);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=ce.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 Oe=500,ye={headers:{"Content-Type":"application/x-www-form-urlencoded"}},ve="/v2/logout",Te="/im-logged-out",Le="/authorize",Pe=i=>i?Te:ve,Ie=i=>{let{authenticationDomain:e,oidcConfiguration:t}=i,r;i.crossSdkBridgeEnabled?r=new k("ImmutableSDKPassport",ce.INDEXEDDB):typeof window<"u"?r=window.localStorage:r=new InMemoryWebStorage;let o=new WebStorageStateStore({store:r}),n=new URL(Pe(i.crossSdkBridgeEnabled),e.replace(/^(?:https?:\/\/)?(.*)/,"https://$1"));return n.searchParams.set("client_id",t.clientId),t.logoutRedirectUri&&n.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:n.toString(),revocation_endpoint:`${e}/oauth/revoke`},automaticSilentRenew:!1,scope:t.scope,userStore:o,revokeTokenTypes:["refresh_token"],extraQueryParams:{...t.audience?{audience:t.audience}:{}}}};function D(i){return btoa(String.fromCharCode(...new Uint8Array(i))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function Ae(i){let t=new TextEncoder().encode(i);return await window.crypto.subtle.digest("SHA-256",t)}var _=class i{userManager;deviceCredentialsManager;config;embeddedLoginPrompt;logoutMode;refreshingPromise=null;constructor(e,t){this.config=e,this.userManager=new UserManager(Ie(e)),this.deviceCredentialsManager=new O,this.embeddedLoginPrompt=t,this.logoutMode=e.oidcConfiguration.logoutMode||"redirect";}static mapOidcUserToDomainModel=e=>{let t;e.id_token&&(t=q(e.id_token)?.passport);let r={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}};return t?.zkevm_eth_address&&t?.zkevm_user_admin_address&&(r.zkEvm={ethAddress:t.zkevm_eth_address,userAdminAddress:t.zkevm_user_admin_address}),r};static mapDeviceTokenResponseToOidcUser=e=>{let t=q(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}})};buildExtraQueryParams(e,t){let r={...this.userManager.settings?.extraQueryParams??{},rid:getDetail(Detail.RUNTIME_ID)||"",third_party_a_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 getClientId(){return this.config.oidcConfiguration.clientId}async loginWithRedirect(e){return await this.userManager.clearStaleState(),f(async()=>{let t=this.buildExtraQueryParams(e);await this.userManager.signinRedirect({extraQueryParams:t});},"AUTHENTICATION_ERROR")}async login(e){return f(async()=>{let t,r;if(e)t=e;else if(!this.config.popupOverlayOptions?.disableHeadlessLoginPromptOverlay){let{imPassportTraceId:d,...l}=await this.embeddedLoginPrompt.displayEmbeddedLoginPrompt();t=l,r=d;}let o=window.crypto.randomUUID(),n=async()=>{let d=this.buildExtraQueryParams(t,r),l=this.userManager.signinPopup({extraQueryParams:d,popupWindowFeatures:{width:410,height:450},popupWindowTarget:o}),c=window.open("",o);if(c){let E=new Promise((a,g)=>{let S=setInterval(()=>{c.closed&&(clearInterval(S),g(new Error("Popup closed by user")));},Oe);l.finally(()=>{clearInterval(S),c.close();});});return Promise.race([l,E])}return l};return new Promise((d,l)=>{n().then(c=>{d(i.mapOidcUserToDomainModel(c));}).catch(c=>{if(!(c instanceof Error)||c.message!=="Attempted to navigate on a disposed window"){l(c);return}let E=!1,a=new v(this.config.popupOverlayOptions||{},!0);a.append(async()=>{try{if(E)window.open("",o);else {E=!0;let g=await n();a.remove(),d(i.mapOidcUserToDomainModel(g));}}catch(g){a.remove(),l(g);}},()=>{a.remove(),l(new Error("Popup closed by user"));});});})},"AUTHENTICATION_ERROR")}async getUserOrLogin(){let e=null;try{e=await this.getUser();}catch(t){h.warn("Failed to retrieve a cached user session",t);}return e||this.login()}static shouldUseSigninPopupCallback(){try{let r=`oidc.${new URLSearchParams(window.location.search).get("state")}`,o=localStorage.getItem(r);return JSON.parse(o||"{}")?.request_type==="si:p"}catch{return !1}}async loginCallback(){return f(async()=>{if(i.shouldUseSigninPopupCallback()){await this.userManager.signinPopupCallback(void 0,!0);return}let e=await this.userManager.signinCallback();if(e)return i.mapOidcUserToDomainModel(e)},"AUTHENTICATION_ERROR")}async getPKCEAuthorizationUrl(e,t){let r=D(window.crypto.getRandomValues(new Uint8Array(32))),o=D(await Ae(r)),n=D(window.crypto.getRandomValues(new Uint8Array(32))),{redirectUri:d,scope:l,audience:c,clientId:E}=this.config.oidcConfiguration;this.deviceCredentialsManager.savePKCEData({state:n,verifier:r});let a=new URL(Le,this.config.authenticationDomain);if(a.searchParams.set("response_type","code"),a.searchParams.set("code_challenge",o),a.searchParams.set("code_challenge_method","S256"),a.searchParams.set("client_id",E),a.searchParams.set("redirect_uri",d),a.searchParams.set("state",n),l&&a.searchParams.set("scope",l),c&&a.searchParams.set("audience",c),e){if(e.directLoginMethod==="email"){let g=e.email;g&&(a.searchParams.set("direct",e.directLoginMethod),a.searchParams.set("email",g));}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 loginWithPKCEFlowCallback(e,t){return f(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),n=i.mapDeviceTokenResponseToOidcUser(o),d=i.mapOidcUserToDomainModel(n);return await this.userManager.storeUser(n),d},"AUTHENTICATION_ERROR")}async getPKCEToken(e,t){return (await Ee.post(`${this.config.authenticationDomain}/oauth/token`,{client_id:this.config.oidcConfiguration.clientId,grant_type:"authorization_code",code_verifier:t,code:e,redirect_uri:this.config.oidcConfiguration.redirectUri},ye)).data}async storeTokens(e){return f(async()=>{let t=i.mapDeviceTokenResponseToOidcUser(e),r=i.mapOidcUserToDomainModel(t);return await this.userManager.storeUser(t),r},"AUTHENTICATION_ERROR")}async logout(){return f(async()=>{await this.userManager.revokeTokens(["refresh_token"]),this.logoutMode==="silent"?await this.userManager.signoutSilent():await this.userManager.signoutRedirect();},"LOGOUT_ERROR")}async logoutSilentCallback(e){return this.userManager.signoutSilentCallback(e)}async removeUser(){return this.userManager.removeUser()}async getLogoutUrl(){let e=this.userManager.settings?.metadata?.end_session_endpoint;return e||(h.warn("Failed to get logout URL"),null)}forceUserRefreshInBackground(){this.refreshTokenAndUpdatePromise().catch(e=>{h.warn("Failed to refresh user token",e);});}async forceUserRefresh(){return this.refreshTokenAndUpdatePromise().catch(e=>(h.warn("Failed to refresh user token",e),null))}async refreshTokenAndUpdatePromise(){return this.refreshingPromise?this.refreshingPromise:(this.refreshingPromise=new Promise(async(e,t)=>{try{let r=await this.userManager.signinSilent();if(r){e(i.mapOidcUserToDomainModel(r));return}e(null);}catch(r){let o="AUTHENTICATION_ERROR",n="Failed to refresh token",d=!0;if(r instanceof ErrorTimeout?(o="SILENT_LOGIN_ERROR",n=`${n}: ${r.message}`,d=!1):r instanceof ErrorResponse?(o="NOT_LOGGED_IN_ERROR",n=`${n}: ${r.message||r.error_description}`):r instanceof Error?n=`${n}: ${r.message}`:typeof r=="string"&&(n=`${n}: ${r}`),d)try{await this.userManager.removeUser();}catch(l){l instanceof Error&&(n=`${n}: Failed to remove user: ${l.message}`);}t(new u(n,o));}finally{this.refreshingPromise=null;}}),this.refreshingPromise)}async getUser(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(!G(t)){let r=i.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 getUserZkEvm(){let e=await this.getUser(M);if(!e)throw new Error("Failed to obtain a User with the required ZkEvm attributes");return e}};var we=(i,e,t)=>{let r=e.map(o=>!i[o]&&o).filter(o=>o).join(", ");if(r!==""){let o=`${r} cannot be null`;throw new u(o,"INVALID_CONFIGURATION")}},T=class{authenticationDomain;passportDomain;oidcConfiguration;crossSdkBridgeEnabled;popupOverlayOptions;constructor({authenticationDomain:e,passportDomain:t,crossSdkBridgeEnabled:r,popupOverlayOptions:o,...n}){we(n,["clientId","redirectUri"]),this.oidcConfiguration=n,this.crossSdkBridgeEnabled=r||!1,this.popupOverlayOptions=o,this.authenticationDomain=e||"https://auth.immutable.com",this.passportDomain=t||"https://passport.immutable.com";}};var X="im_passport_embedded_login_prompt";var m=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=z(),document.body.insertAdjacentElement("beforeend",r);let o=document.querySelector(`#${y}`);o&&o.appendChild(e),r.addEventListener("click",t),this.overlay=r;}}};var Me=660,Ue=440,xe="16px",J="passport-embedded-login-keyframes",ee="passport-embedded-login-iframe",L=class i{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(J))return;let e=document.createElement("style");e.id=J,e.textContent=`
357
+ `;function A({id:o,href:e,rel:t,crossOrigin:r}){let n=`${E}-${o}`;if(!document.getElementById(n)){let i=document.createElement("link");i.id=n,i.href=e,t&&(i.rel=t),r&&(i.crossOrigin=r),document.head.appendChild(i);}}var K=()=>B(re()),W=()=>B(ne());var m=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=Z(),document.body.insertAdjacentElement("beforeend",r);let n=document.querySelector(`#${R}`);n&&n.appendChild(e),r.addEventListener("click",t),this.overlay=r;}}};var se=660,ae=440,le="16px",$="passport-embedded-login-keyframes",Y="passport-embedded-login-iframe",O=class o{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($))return;let e=document.createElement("style");e.id=$,e.textContent=`
358
358
  @keyframes passportEmbeddedLoginPromptPopBounceIn {
359
359
  0% {
360
360
  opacity: 0.5;
@@ -373,7 +373,7 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
373
373
  }
374
374
 
375
375
  @media (max-height: 400px) {
376
- #${ee} {
376
+ #${Y} {
377
377
  width: 100% !important;
378
378
  max-width: none !important;
379
379
  }
@@ -387,6 +387,6 @@ var F="pkce_state",H="pkce_verifier",re=3600,O=class{isTokenValid(e){try{let r=q
387
387
  opacity: 1;
388
388
  }
389
389
  }
390
- `,document.head.appendChild(e);};getEmbeddedLoginIFrame=()=>{let e=document.createElement("iframe");return e.id=ee,e.src=this.getHref(),e.style.height="100vh",e.style.width="100vw",e.style.maxHeight=`${Me}px`,e.style.maxWidth=`${Ue}px`,e.style.borderRadius=xe,e.style.opacity="0",e.style.transform="scale(0.6)",e.style.animation="passportEmbeddedLoginPromptPopBounceIn 1s ease forwards",i.appendIFrameStylesIfNeeded(),e};displayEmbeddedLoginPrompt(){return new Promise((e,t)=>{let r=this.getEmbeddedLoginIFrame(),o=({data:n,origin:d})=>{if(!(d!==this.config.authenticationDomain||n.eventType!==X))switch(n.messageType){case"login_method_selected":{let l=n.payload;window.removeEventListener("message",o),m.remove(),e(l);break}case"login_prompt_error":{window.removeEventListener("message",o),m.remove(),t(new Error("Error during embedded login prompt",{cause:n.payload}));break}case"login_prompt_closed":{window.removeEventListener("message",o),m.remove(),t(new Error("Popup closed by user"));break}default:window.removeEventListener("message",o),m.remove(),t(new Error(`Unsupported message type: ${n.messageType}`));break}};window.addEventListener("message",o),m.appendOverlay(r,()=>{window.removeEventListener("message",o),m.remove(),t(new Error("Popup closed by user"));});})}};var R=class{emitter=new EventEmitter;emit(e,...t){this.emitter.emit(e,...t);}on(e,t){this.emitter.on(e,t);}removeListener(e,t){this.emitter.removeListener(e,t);}};var p=async(i,e,t=!0,r=!0)=>{let o=trackFlow("passport",e,t);try{return await i(o)}catch(n){throw n instanceof Error?trackError("passport",e,n,{flowId:o.details.flowId}):o.addEvent("errored"),n}finally{r&&o.addEvent("End");}};var N=class{authManager;config;eventEmitter;constructor(e){this.config=new T(e);let t=new L(this.config);this.authManager=new _(this.config,t),this.eventEmitter=new R,track("passport","initialise");}async login(e){return p(async()=>{let{useCachedSession:t=!1,useSilentLogin:r}=e||{},o=null;try{o=await this.authManager.getUser();}catch(n){if(n instanceof Error&&!n.message.includes("Unknown or invalid refresh token")&&trackError("passport","login",n),t)throw n;h.warn("Failed to retrieve a cached user session",n);}if(!o&&r)o=await this.authManager.forceUserRefresh();else if(!o&&!t){if(e?.useRedirectFlow)return await this.authManager.loginWithRedirect(e?.directLoginOptions),null;o=await this.authManager.login(e?.directLoginOptions);}return o&&(this.eventEmitter.emit("loggedIn",o),identify({passportId:o.profile.sub})),o},"login")}async loginWithRedirect(e){await this.authManager.loginWithRedirect(e);}async loginCallback(){return p(async()=>{let e=await this.authManager.loginCallback();if(!e)throw new Error("Login callback failed - no user returned");return this.eventEmitter.emit("loggedIn",e),identify({passportId:e.profile.sub}),e},"loginCallback")}async logout(){await p(async()=>{await this.authManager.logout(),this.eventEmitter.emit("loggedOut");},"logout");}async getUser(){return p(async()=>this.authManager.getUser(),"getUserInfo",!1)}async getIdToken(){return p(async()=>(await this.authManager.getUser())?.idToken,"getIdToken",!1)}async getAccessToken(){return p(async()=>(await this.authManager.getUser())?.accessToken,"getAccessToken",!1,!1)}async isLoggedIn(){return await this.getUser()!==null}async forceUserRefresh(){return this.authManager.forceUserRefresh()}async loginWithPKCEFlow(e,t){return p(async()=>this.authManager.getPKCEAuthorizationUrl(e,t),"loginWithPKCEFlow")}async loginWithPKCEFlowCallback(e,t){return p(async()=>{let r=await this.authManager.loginWithPKCEFlowCallback(e,t);return this.eventEmitter.emit("loggedIn",r),identify({passportId:r.profile.sub}),r},"loginWithPKCEFlowCallback")}async storeTokens(e){return p(async()=>{let t=await this.authManager.storeTokens(e);return this.eventEmitter.emit("loggedIn",t),identify({passportId:t.profile.sub}),t},"storeTokens")}async getLogoutUrl(){return p(async()=>(await this.authManager.removeUser(),this.eventEmitter.emit("loggedOut"),await this.authManager.getLogoutUrl()||void 0),"getLogoutUrl")}async logoutSilentCallback(e){return p(()=>this.authManager.logoutSilentCallback(e),"logoutSilentCallback")}getAuthManager(){return this.authManager}getConfig(){return this.config}};
390
+ `,document.head.appendChild(e);};getEmbeddedLoginIFrame=()=>{let e=document.createElement("iframe");return e.id=Y,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!==F))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 h=class{emitter=new EventEmitter;emit(e,...t){this.emitter.emit(e,...t);}on(e,t){this.emitter.on(e,t);}removeListener(e,t){this.emitter.removeListener(e,t);}};var c=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 z="pkce_state",j="pkce_verifier",ue=3600,y=class{isTokenValid(e){try{let r=X(e).exp??0,n=Date.now()/1e3+ue;return r>n}catch{return !1}}savePKCEData(e){localStorage.setItem(z,e.state),localStorage.setItem(j,e.verifier);}getPKCEData(){let e=localStorage.getItem(z),t=localStorage.getItem(j);return e&&t?{state:e,verifier:t}:null}};var ge=(...o)=>{if(typeof process>"u")return;process?.env?.JEST_WORKER_ID===void 0&&console.warn(...o);},C={warn:ge};function Q(o){try{let e=X(o),t=Math.floor(Date.now()/1e3);return e.exp?e.exp<=t+30:!0}catch{return !0}}function J(o){let{id_token:e,access_token:t}=o;return !t||!e?!0:Q(t)||Q(e)}var v=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?K():W(),document.body.insertAdjacentElement("beforeend",t),this.overlay=t;}}updateTryAgainButton(e){let t=document.getElementById(I);t&&(this.tryAgainListener&&t.removeEventListener("click",this.tryAgainListener),this.tryAgainListener=e,t.addEventListener("click",e));}updateCloseButton(e){let t=document.getElementById(P);t&&(this.onCloseListener&&t.removeEventListener("click",this.onCloseListener),this.onCloseListener=e,t.addEventListener("click",e));}};var k=class{storage;constructor(e,t){this.storage=Ee.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 we={headers:{"Content-Type":"application/x-www-form-urlencoded"}},Ue="/v2/logout",be="/im-logged-out",xe="/authorize",Me=o=>o?be:Ue,De=o=>{let{authenticationDomain:e,oidcConfiguration:t}=o,r;o.crossSdkBridgeEnabled?r=new k("ImmutableSDKPassport",Ee.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 x(o){return btoa(String.fromCharCode(...new Uint8Array(o))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function Ne(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 _(e),this.embeddedLoginPrompt=new O(this.config),this.userManager=new UserManager(De(this.config)),this.deviceCredentialsManager=new y,this.logoutMode=this.config.oidcConfiguration.logoutMode||"redirect",this.eventEmitter=new h,track("passport","initialise");}async login(e){return c(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;C.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 c(async()=>{let e=await this.loginCallbackInternal();return e&&this.handleSuccessfulLogin(e),e},"loginCallback")}async logout(){await c(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){C.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 c(async()=>(await this.getUserInternal())?.idToken,"getIdToken",!1)}async getAccessToken(){return c(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 c(async()=>this.getPKCEAuthorizationUrl(e,t),"loginWithPKCEFlow")}async loginWithPKCEFlowCallback(e,t){return c(async()=>{let r=await this.loginWithPKCEFlowCallbackInternal(e,t);return this.handleSuccessfulLogin(r),r},"loginWithPKCEFlowCallback")}async storeTokens(e){return c(async()=>{let t=await this.storeTokensInternal(e);return this.handleSuccessfulLogin(t),t},"storeTokens")}async getLogoutUrl(){return c(async()=>(await this.userManager.removeUser(),this.eventEmitter.emit("loggedOut"),await this.getLogoutUrlInternal()||void 0),"getLogoutUrl")}async logoutSilentCallback(e){return c(()=>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})};return new Promise((l,d)=>{i().then(u=>l(o.mapOidcUserToDomainModel(u))).catch(u=>{if(!(u instanceof Error)||u.message!=="Attempted to navigate on a disposed window"){d(u);return}let T=!1,a=new v(this.config.popupOverlayOptions||{},!0);a.append(async()=>{try{if(T)window.open("",n);else {T=!0;let f=await i();a.remove(),l(o.mapOidcUserToDomainModel(f));}}catch(f){a.remove(),d(f);}},()=>{a.remove(),d(new Error("Popup closed by user"));});});})},"AUTHENTICATION_ERROR")}static mapOidcUserToDomainModel=e=>{let t,r;if(e.id_token){let i=X(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=X(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=x(window.crypto.getRandomValues(new Uint8Array(32))),n=x(await Ne(r)),i=x(window.crypto.getRandomValues(new Uint8Array(32))),{redirectUri:l,scope:d,audience:u,clientId:T}=this.config.oidcConfiguration;this.deviceCredentialsManager.savePKCEData({state:i,verifier:r});let a=new URL(xe,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",T),a.searchParams.set("redirect_uri",l),a.searchParams.set("state",i),d&&a.searchParams.set("scope",d),u&&a.searchParams.set("audience",u),e){if(e.directLoginMethod==="email"){let f=e.email;f&&(a.searchParams.set("direct",e.directLoginMethod),a.searchParams.set("email",f));}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){return (await ve.post(`${this.config.authenticationDomain}/oauth/token`,{client_id:this.config.oidcConfiguration.clientId,grant_type:"authorization_code",code_verifier:t,code:e,redirect_uri:this.config.oidcConfiguration.redirectUri},we)).data}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||(C.warn("Failed to get logout URL"),null)}forceUserRefreshInBackgroundInternal(){this.refreshTokenAndUpdatePromise().catch(e=>{C.warn("Failed to refresh user token",e);});}async forceUserRefreshInternal(){return this.refreshTokenAndUpdatePromise().catch(e=>(C.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){e(o.mapOidcUserToDomainModel(r));return}e(null);}catch(r){let n="AUTHENTICATION_ERROR",i="Failed to refresh token",l=!0;if(r instanceof ErrorTimeout?(n="SILENT_LOGIN_ERROR",i=`${i}: ${r.message}`,l=!1):r instanceof ErrorResponse?(n="NOT_LOGGED_IN_ERROR",i=`${i}: ${r.message||r.error_description}`):r instanceof Error?i=`${i}: ${r.message}`:typeof r=="string"&&(i=`${i}: ${r}`),l)try{await this.userManager.removeUser();}catch(d){d instanceof Error&&(i=`${i}: Failed to remove user: ${d.message}`);}t(new p(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(!J(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(w);if(!e)throw new Error("Failed to obtain a User with the required ZkEvm attributes");return e}};
391
391
 
392
- export { N as Auth, T as AuthConfiguration, U as AuthEvents, _ as AuthManager, K as MarketingConsentStatus, u as PassportError, P as PassportErrorType, B as RollupType, R as TypedEventEmitter, M as isUserZkEvm, f as withPassportError };
392
+ export { M as Auth, _ as AuthConfiguration, U as AuthEvents, S as MarketingConsentStatus, p as PassportError, L as PassportErrorType, N as RollupType, h as TypedEventEmitter, D as isAPIError, w as isUserZkEvm, g as withPassportError };
@@ -1,14 +1,20 @@
1
- import AuthManager from './authManager';
2
1
  import { IAuthConfiguration } from './config';
3
- import { AuthModuleConfiguration, User, DirectLoginOptions, DeviceTokenResponse, LoginOptions, AuthEventMap } from './types';
2
+ import { AuthModuleConfiguration, User, DirectLoginOptions, DeviceTokenResponse, LoginOptions, AuthEventMap, UserZkEvm } from './types';
4
3
  import TypedEventEmitter from './utils/typedEventEmitter';
5
4
  /**
6
5
  * Public-facing Auth class for authentication
7
- * Wraps AuthManager with a simpler API
6
+ * Provides login/logout helpers and exposes auth state events
8
7
  */
9
8
  export declare class Auth {
10
- private authManager;
11
- private config;
9
+ private readonly config;
10
+ private readonly userManager;
11
+ private readonly deviceCredentialsManager;
12
+ private readonly embeddedLoginPrompt;
13
+ private readonly logoutMode;
14
+ /**
15
+ * Promise that is used to prevent multiple concurrent calls to the refresh token endpoint.
16
+ */
17
+ private refreshingPromise;
12
18
  /**
13
19
  * Event emitter for authentication events (LOGGED_IN, LOGGED_OUT)
14
20
  * Exposed for wallet and passport packages to subscribe to auth state changes
@@ -49,10 +55,10 @@ export declare class Auth {
49
55
  loginWithRedirect(directLoginOptions?: DirectLoginOptions): Promise<void>;
50
56
  /**
51
57
  * Login callback handler
52
- * Call this in your redirect URI page
53
- * @returns Promise that resolves with the authenticated user
58
+ * Call this in your redirect or popup callback page
59
+ * @returns Promise that resolves with the authenticated user or undefined (for popup flows)
54
60
  */
55
- loginCallback(): Promise<User>;
61
+ loginCallback(): Promise<User | undefined>;
56
62
  /**
57
63
  * Logout the current user
58
64
  * @returns Promise that resolves when logout is complete
@@ -63,6 +69,16 @@ export declare class Auth {
63
69
  * @returns Promise that resolves with the user or null if not authenticated
64
70
  */
65
71
  getUser(): Promise<User | null>;
72
+ /**
73
+ * Get the current authenticated user or initiate login if needed
74
+ * @returns Promise that resolves with an authenticated user
75
+ */
76
+ getUserOrLogin(): Promise<User>;
77
+ /**
78
+ * Get the current authenticated zkEVM user
79
+ * @returns Promise that resolves with a zkEVM-capable user
80
+ */
81
+ getUserZkEvm(): Promise<UserZkEvm>;
66
82
  /**
67
83
  * Get the ID token for the current user
68
84
  * @returns Promise that resolves with the ID token or undefined
@@ -83,6 +99,10 @@ export declare class Auth {
83
99
  * @returns Promise that resolves with the user or null if refresh fails
84
100
  */
85
101
  forceUserRefresh(): Promise<User | null>;
102
+ /**
103
+ * Trigger a background user refresh without awaiting the result
104
+ */
105
+ forceUserRefreshInBackground(): void;
86
106
  /**
87
107
  * Get the PKCE authorization URL for login flow
88
108
  * @param directLoginOptions - Optional direct login options
@@ -114,16 +134,33 @@ export declare class Auth {
114
134
  * @returns Promise that resolves when callback is handled
115
135
  */
116
136
  logoutSilentCallback(url: string): Promise<void>;
117
- /**
118
- * Get internal AuthManager instance
119
- * @internal
120
- * @returns AuthManager instance for advanced use cases
121
- */
122
- getAuthManager(): AuthManager;
123
137
  /**
124
138
  * Get auth configuration
125
139
  * @internal
126
140
  * @returns IAuthConfiguration instance
127
141
  */
128
142
  getConfig(): IAuthConfiguration;
143
+ /**
144
+ * Get the configured OIDC client ID
145
+ * @returns Promise that resolves with the client ID string
146
+ */
147
+ getClientId(): Promise<string>;
148
+ private handleSuccessfulLogin;
149
+ private buildExtraQueryParams;
150
+ private loginWithRedirectInternal;
151
+ private loginWithPopup;
152
+ private static mapOidcUserToDomainModel;
153
+ private static mapDeviceTokenResponseToOidcUser;
154
+ private loginCallbackInternal;
155
+ private getPKCEAuthorizationUrl;
156
+ private loginWithPKCEFlowCallbackInternal;
157
+ private getPKCEToken;
158
+ private storeTokensInternal;
159
+ private logoutInternal;
160
+ private getLogoutUrlInternal;
161
+ private forceUserRefreshInBackgroundInternal;
162
+ private forceUserRefreshInternal;
163
+ private refreshTokenAndUpdatePromise;
164
+ private getUserInternal;
165
+ private getUserZkEvmInternal;
129
166
  }
@@ -20,7 +20,8 @@ export declare enum PassportErrorType {
20
20
  LINK_WALLET_VALIDATION_ERROR = "LINK_WALLET_VALIDATION_ERROR",
21
21
  LINK_WALLET_DUPLICATE_NONCE_ERROR = "LINK_WALLET_DUPLICATE_NONCE_ERROR",
22
22
  LINK_WALLET_GENERIC_ERROR = "LINK_WALLET_GENERIC_ERROR",
23
- SERVICE_UNAVAILABLE_ERROR = "SERVICE_UNAVAILABLE_ERROR"
23
+ SERVICE_UNAVAILABLE_ERROR = "SERVICE_UNAVAILABLE_ERROR",
24
+ TRANSACTION_REJECTED = "TRANSACTION_REJECTED"
24
25
  }
25
26
  export declare function isAPIError(error: any): error is imx.APIError;
26
27
  export declare class PassportError extends Error {
@@ -1,7 +1,6 @@
1
1
  export { Auth } from './Auth';
2
- export { default as AuthManager } from './authManager';
3
2
  export { AuthConfiguration, type IAuthConfiguration } from './config';
4
3
  export type { User, UserProfile, UserZkEvm, DirectLoginMethod, DirectLoginOptions, LoginOptions, DeviceTokenResponse, OidcConfiguration, AuthModuleConfiguration, PopupOverlayOptions, PassportMetadata, IdTokenPayload, PKCEData, AuthEventMap, } from './types';
5
4
  export { isUserZkEvm, RollupType, MarketingConsentStatus, AuthEvents, } from './types';
6
5
  export { default as TypedEventEmitter } from './utils/typedEventEmitter';
7
- export { PassportError, PassportErrorType, withPassportError } from './errors';
6
+ export { PassportError, PassportErrorType, withPassportError, isAPIError, } from './errors';
@@ -8,6 +8,7 @@ export type UserProfile = {
8
8
  email?: string;
9
9
  nickname?: string;
10
10
  sub: string;
11
+ username?: string;
11
12
  };
12
13
  export declare enum RollupType {
13
14
  ZKEVM = "zkEvm"
@@ -77,6 +78,7 @@ export type TokenPayload = {
77
78
  };
78
79
  export type IdTokenPayload = {
79
80
  passport?: PassportMetadata;
81
+ username?: string;
80
82
  email: string;
81
83
  nickname: string;
82
84
  aud: string;
package/jest.config.ts ADDED
@@ -0,0 +1,27 @@
1
+ import type { Config } from 'jest';
2
+ import { execSync } from 'child_process';
3
+ import { name } from './package.json';
4
+
5
+ const rootDirs = execSync(`pnpm --filter ${name}... exec pwd`)
6
+ .toString()
7
+ .split('\n')
8
+ .filter(Boolean)
9
+ .map((dir) => `${dir}/dist`);
10
+
11
+ const config: Config = {
12
+ clearMocks: true,
13
+ roots: ['<rootDir>/src', ...rootDirs],
14
+ coverageProvider: 'v8',
15
+ moduleDirectories: ['node_modules', 'src'],
16
+ moduleNameMapper: { '^@imtbl/(.*)$': '<rootDir>/../../node_modules/@imtbl/$1/src' },
17
+ testEnvironment: 'jsdom',
18
+ transform: {
19
+ '^.+\\.(t|j)sx?$': '@swc/jest',
20
+ },
21
+ transformIgnorePatterns: [],
22
+ restoreMocks: true,
23
+ setupFiles: ['<rootDir>/jest.setup.js'],
24
+ };
25
+
26
+ export default config;
27
+
package/jest.setup.js ADDED
@@ -0,0 +1,4 @@
1
+ import { TextEncoder } from 'util';
2
+
3
+ global.TextEncoder = TextEncoder;
4
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imtbl/auth",
3
- "version": "2.10.7-alpha.5",
3
+ "version": "2.11.1-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,17 +25,24 @@
25
25
  }
26
26
  },
27
27
  "dependencies": {
28
- "@imtbl/config": "2.10.7-alpha.5",
29
- "@imtbl/metrics": "2.10.7-alpha.5",
28
+ "@imtbl/config": "2.11.1-alpha.0",
29
+ "@imtbl/metrics": "2.11.1-alpha.0",
30
30
  "axios": "^1.6.5",
31
31
  "jwt-decode": "^3.1.2",
32
32
  "localforage": "^1.10.0",
33
- "oidc-client-ts": "3.3.0",
33
+ "oidc-client-ts": "3.4.1",
34
34
  "uuid": "^9.0.1"
35
35
  },
36
36
  "devDependencies": {
37
- "@imtbl/toolkit": "2.10.7-alpha.5",
37
+ "@imtbl/toolkit": "2.11.1-alpha.0",
38
+ "@swc/core": "^1.3.36",
39
+ "@swc/jest": "^0.2.37",
40
+ "@types/jest": "^29.5.12",
38
41
  "@types/node": "^18.14.2",
42
+ "@jest/test-sequencer": "^29.7.0",
43
+ "jest": "^29.4.3",
44
+ "jest-environment-jsdom": "^29.4.3",
45
+ "ts-node": "^10.9.1",
39
46
  "tsup": "^8.3.0",
40
47
  "typescript": "^5.6.2"
41
48
  },
@@ -50,6 +57,7 @@
50
57
  "typegen": "tsc --customConditions default --emitDeclarationOnly --outDir dist/types",
51
58
  "pack:root": "pnpm pack --pack-destination $(dirname $(pnpm root -w))",
52
59
  "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0",
53
- "typecheck": "tsc --customConditions default --noEmit --jsx preserve"
60
+ "typecheck": "tsc --customConditions default --noEmit --jsx preserve",
61
+ "test": "jest"
54
62
  }
55
63
  }