@bounded-sh/client 0.0.111 → 0.0.112-ux-audit.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/index.d.ts +3 -1
- package/dist/auth/oidc-auth.d.ts +2 -0
- package/dist/auth/providers/email-auth-provider.d.ts +1 -1
- package/dist/auth/providers/guest-auth-provider.d.ts +1 -1
- package/dist/auth/providers/injected-evm-wallet-provider.d.ts +1 -1
- package/dist/auth/providers/injected-wallet-provider.d.ts +1 -1
- package/dist/auth/providers/offchain-auth-provider.d.ts +1 -1
- package/dist/auth/providers/privy-expo-provider.d.ts +1 -1
- package/dist/{email-auth-provider-CVp6hSCo.mjs → email-auth-provider-BfCH7K6N.mjs} +4 -3
- package/dist/email-auth-provider-BfCH7K6N.mjs.map +1 -0
- package/dist/{email-auth-provider-DxS2WYxM.js → email-auth-provider-CG5cxOj0.js} +4 -3
- package/dist/email-auth-provider-CG5cxOj0.js.map +1 -0
- package/dist/{email-auth-provider-CiqhQ1c2.js → email-auth-provider-DTrCfOJd.js} +4 -3
- package/dist/email-auth-provider-DTrCfOJd.js.map +1 -0
- package/dist/{email-auth-provider-BfBvF_4M.mjs → email-auth-provider-eyi3Wpnx.mjs} +4 -3
- package/dist/email-auth-provider-eyi3Wpnx.mjs.map +1 -0
- package/dist/{guest-auth-provider-Bm_yqQF6.mjs → guest-auth-provider-BsW56oJg.mjs} +10 -5
- package/dist/guest-auth-provider-BsW56oJg.mjs.map +1 -0
- package/dist/{guest-auth-provider-Cc8y4Qd1.mjs → guest-auth-provider-DjOFjtnk.mjs} +10 -5
- package/dist/guest-auth-provider-DjOFjtnk.mjs.map +1 -0
- package/dist/{guest-auth-provider-DDBXeHoo.js → guest-auth-provider-Dtl1J-2F.js} +10 -5
- package/dist/guest-auth-provider-Dtl1J-2F.js.map +1 -0
- package/dist/{guest-auth-provider-D9FGNuP9.js → guest-auth-provider-Tndt6tzJ.js} +10 -5
- package/dist/guest-auth-provider-Tndt6tzJ.js.map +1 -0
- package/dist/{index-BghQ8jX0.js → index-Brdwqgqs.js} +213 -60
- package/dist/index-Brdwqgqs.js.map +1 -0
- package/dist/{index-B9__gwTi.mjs → index-CRxls8Qc.mjs} +214 -61
- package/dist/index-CRxls8Qc.mjs.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{index.native-BHjpXkKQ.mjs → index.native-CAH_ks0s.mjs} +200 -56
- package/dist/index.native-CAH_ks0s.mjs.map +1 -0
- package/dist/{index.native-B_AFa0GD.js → index.native-ingNhWPw.js} +199 -55
- package/dist/index.native-ingNhWPw.js.map +1 -0
- package/dist/index.native.js +1 -1
- package/dist/index.native.mjs +1 -1
- package/dist/{injected-evm-wallet-provider-CIeCSOPL.mjs → injected-evm-wallet-provider-BjkCeRBL.mjs} +4 -3
- package/dist/injected-evm-wallet-provider-BjkCeRBL.mjs.map +1 -0
- package/dist/{injected-evm-wallet-provider-DeLUwvGs.js → injected-evm-wallet-provider-Cao1U0NZ.js} +4 -3
- package/dist/{injected-evm-wallet-provider-DeLUwvGs.js.map → injected-evm-wallet-provider-Cao1U0NZ.js.map} +1 -1
- package/dist/{injected-evm-wallet-provider-Ckb85p6a.js → injected-evm-wallet-provider-CwOGXCDt.js} +4 -3
- package/dist/injected-evm-wallet-provider-CwOGXCDt.js.map +1 -0
- package/dist/{injected-evm-wallet-provider-BUjqxQxp.mjs → injected-evm-wallet-provider-DXjwPjLW.mjs} +4 -3
- package/dist/{injected-evm-wallet-provider-BUjqxQxp.mjs.map → injected-evm-wallet-provider-DXjwPjLW.mjs.map} +1 -1
- package/dist/{injected-wallet-provider-BlzA0J_V.mjs → injected-wallet-provider-BG6gGNch.mjs} +4 -3
- package/dist/{injected-wallet-provider-BlzA0J_V.mjs.map → injected-wallet-provider-BG6gGNch.mjs.map} +1 -1
- package/dist/{injected-wallet-provider-BEuj4sM3.mjs → injected-wallet-provider-CfYNIIHd.mjs} +4 -3
- package/dist/{injected-wallet-provider-BEuj4sM3.mjs.map → injected-wallet-provider-CfYNIIHd.mjs.map} +1 -1
- package/dist/{injected-wallet-provider-CUKdAuFu.js → injected-wallet-provider-DSlHfgMU.js} +4 -3
- package/dist/{injected-wallet-provider-CUKdAuFu.js.map → injected-wallet-provider-DSlHfgMU.js.map} +1 -1
- package/dist/{injected-wallet-provider-Cfb4ayCP.js → injected-wallet-provider-LTnqoaYD.js} +4 -3
- package/dist/{injected-wallet-provider-Cfb4ayCP.js.map → injected-wallet-provider-LTnqoaYD.js.map} +1 -1
- package/package.json +2 -2
- package/dist/email-auth-provider-BfBvF_4M.mjs.map +0 -1
- package/dist/email-auth-provider-CVp6hSCo.mjs.map +0 -1
- package/dist/email-auth-provider-CiqhQ1c2.js.map +0 -1
- package/dist/email-auth-provider-DxS2WYxM.js.map +0 -1
- package/dist/guest-auth-provider-Bm_yqQF6.mjs.map +0 -1
- package/dist/guest-auth-provider-Cc8y4Qd1.mjs.map +0 -1
- package/dist/guest-auth-provider-D9FGNuP9.js.map +0 -1
- package/dist/guest-auth-provider-DDBXeHoo.js.map +0 -1
- package/dist/index-B9__gwTi.mjs.map +0 -1
- package/dist/index-BghQ8jX0.js.map +0 -1
- package/dist/index.native-BHjpXkKQ.mjs.map +0 -1
- package/dist/index.native-B_AFa0GD.js.map +0 -1
- package/dist/injected-evm-wallet-provider-CIeCSOPL.mjs.map +0 -1
- package/dist/injected-evm-wallet-provider-Ckb85p6a.js.map +0 -1
|
@@ -277,8 +277,9 @@ class OffchainAuthProvider {
|
|
|
277
277
|
async logout() {
|
|
278
278
|
await this.wrappedProvider.logout();
|
|
279
279
|
}
|
|
280
|
-
async restoreSession() {
|
|
281
|
-
const
|
|
280
|
+
async restoreSession(beforeCommit) {
|
|
281
|
+
const provider = this.wrappedProvider;
|
|
282
|
+
const user = await provider.restoreSession(beforeCommit);
|
|
282
283
|
if (user) {
|
|
283
284
|
return Object.assign(Object.assign({}, user), { provider: this });
|
|
284
285
|
}
|
|
@@ -5532,7 +5533,8 @@ async function loginWithRedirect(opts) {
|
|
|
5532
5533
|
return runNativeLogin(opts);
|
|
5533
5534
|
if (!hasDOM$2())
|
|
5534
5535
|
throw new Error('loginWithRedirect requires a browser or a configured React Native platform');
|
|
5535
|
-
const { url, pkce } = await buildAuthorize(opts);
|
|
5536
|
+
const { url, pkce } = await untilAborted(buildAuthorize(opts), opts.signal);
|
|
5537
|
+
throwIfCancelled(opts.signal);
|
|
5536
5538
|
// Stash the verifier + state so the redirect_uri page can finish the exchange. sessionStorage
|
|
5537
5539
|
// is per-tab and cleared on close — appropriate for a short-lived auth handshake. Keyed by
|
|
5538
5540
|
// this attempt's own state so a second concurrent login cannot overwrite it.
|
|
@@ -5561,9 +5563,29 @@ async function completeLoginFromRedirect() {
|
|
|
5561
5563
|
throw error;
|
|
5562
5564
|
return result.user;
|
|
5563
5565
|
}
|
|
5566
|
+
function throwIfCancelled(signal) {
|
|
5567
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
5568
|
+
throw new Error('cancelled');
|
|
5569
|
+
}
|
|
5570
|
+
async function untilAborted(work, signal) {
|
|
5571
|
+
if (!signal)
|
|
5572
|
+
return work;
|
|
5573
|
+
throwIfCancelled(signal);
|
|
5574
|
+
let onAbort;
|
|
5575
|
+
try {
|
|
5576
|
+
return await Promise.race([work, new Promise((_, reject) => {
|
|
5577
|
+
onAbort = () => reject(new Error('cancelled'));
|
|
5578
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
5579
|
+
})]);
|
|
5580
|
+
}
|
|
5581
|
+
finally {
|
|
5582
|
+
signal.removeEventListener('abort', onAbort);
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5564
5585
|
/** Popup variant: open the hosted login in a popup; resolves with the User once the popup's
|
|
5565
5586
|
* redirect_uri page initializes the SDK, which hands the code back automatically. */
|
|
5566
5587
|
async function loginWithPopup(opts) {
|
|
5588
|
+
throwIfCancelled(opts.signal);
|
|
5567
5589
|
if (!hasDOM$2())
|
|
5568
5590
|
throw new Error('loginWithPopup is web-only — on React Native use loginWithRedirect()');
|
|
5569
5591
|
// Open synchronously, before PKCE/config awaits consume the click's user-
|
|
@@ -5581,7 +5603,7 @@ async function loginWithPopup(opts) {
|
|
|
5581
5603
|
throw new Error('Popup blocked — use loginWithRedirect() instead');
|
|
5582
5604
|
let authorization;
|
|
5583
5605
|
try {
|
|
5584
|
-
authorization = await buildAuthorize(opts, 'popup');
|
|
5606
|
+
authorization = await untilAborted(buildAuthorize(opts, 'popup'), opts.signal);
|
|
5585
5607
|
}
|
|
5586
5608
|
catch (error) {
|
|
5587
5609
|
try {
|
|
@@ -5598,6 +5620,7 @@ async function loginWithPopup(opts) {
|
|
|
5598
5620
|
// window with no listener or watchdog attached.
|
|
5599
5621
|
let expectedOrigin;
|
|
5600
5622
|
try {
|
|
5623
|
+
throwIfCancelled(opts.signal);
|
|
5601
5624
|
expectedOrigin = new URL(pkce.redirectUri).origin;
|
|
5602
5625
|
sessionStorage.setItem(pkceKey(pkce.state), JSON.stringify(pkce));
|
|
5603
5626
|
}
|
|
@@ -5629,20 +5652,42 @@ async function loginWithPopup(opts) {
|
|
|
5629
5652
|
setAuthLoading(true); // reflect "signing in…" while the popup is open
|
|
5630
5653
|
try {
|
|
5631
5654
|
return await new Promise((resolve, reject) => {
|
|
5655
|
+
var _a, _b;
|
|
5632
5656
|
let settled = false;
|
|
5657
|
+
let handedOff = false;
|
|
5658
|
+
let committing = false;
|
|
5633
5659
|
let timer;
|
|
5634
5660
|
let navigationTimer;
|
|
5635
5661
|
let completionTimer;
|
|
5636
5662
|
const cleanup = () => {
|
|
5637
|
-
settled = true;
|
|
5638
5663
|
clearInterval(timer);
|
|
5639
5664
|
clearTimeout(navigationTimer);
|
|
5640
5665
|
clearTimeout(completionTimer);
|
|
5641
5666
|
window.removeEventListener('message', onMsg);
|
|
5642
5667
|
removeAttempt(pkce.state);
|
|
5643
5668
|
};
|
|
5669
|
+
const finish = (error, user) => {
|
|
5670
|
+
var _a;
|
|
5671
|
+
if (settled)
|
|
5672
|
+
return;
|
|
5673
|
+
settled = true;
|
|
5674
|
+
cleanup();
|
|
5675
|
+
(_a = opts.signal) === null || _a === void 0 ? void 0 : _a.removeEventListener('abort', onAbort);
|
|
5676
|
+
try {
|
|
5677
|
+
popup.close();
|
|
5678
|
+
}
|
|
5679
|
+
catch ( /* ignore */_b) { /* ignore */ }
|
|
5680
|
+
if (error)
|
|
5681
|
+
reject(error);
|
|
5682
|
+
else
|
|
5683
|
+
resolve(user);
|
|
5684
|
+
};
|
|
5685
|
+
// Provider adoption commits synchronously after its final guard. An auth
|
|
5686
|
+
// listener dismissing the card there cannot cancel an already signed-in user.
|
|
5687
|
+
const onAbort = () => { if (!committing)
|
|
5688
|
+
finish(new Error('cancelled')); };
|
|
5644
5689
|
const onMsg = async (ev) => {
|
|
5645
|
-
if (settled || ev.origin !== expectedOrigin || ev.source !== popup)
|
|
5690
|
+
if (settled || handedOff || ev.origin !== expectedOrigin || ev.source !== popup)
|
|
5646
5691
|
return;
|
|
5647
5692
|
const d = ev.data;
|
|
5648
5693
|
if (!d || d.type !== 'bounded-oidc-code' ||
|
|
@@ -5656,35 +5701,30 @@ async function loginWithPopup(opts) {
|
|
|
5656
5701
|
return;
|
|
5657
5702
|
if (d.appId !== pkce.appId || d.issuer !== pkce.issuer)
|
|
5658
5703
|
return;
|
|
5704
|
+
handedOff = true;
|
|
5659
5705
|
cleanup();
|
|
5660
5706
|
try {
|
|
5707
|
+
throwIfCancelled(opts.signal);
|
|
5661
5708
|
await validateAttempt(pkce, new URL(d.callbackUrl));
|
|
5709
|
+
throwIfCancelled(opts.signal);
|
|
5662
5710
|
popup.postMessage({ type: 'bounded-oidc-accepted', state: pkce.state }, expectedOrigin);
|
|
5663
5711
|
if (d.error)
|
|
5664
5712
|
throw new Error(typeof d.errorDescription === 'string' ? d.errorDescription : `Login failed: ${d.error}`);
|
|
5665
|
-
const user = await exchangeCode(d.code, pkce);
|
|
5666
|
-
|
|
5667
|
-
popup.close();
|
|
5668
|
-
}
|
|
5669
|
-
catch ( /* ignore */_a) { /* ignore */ }
|
|
5670
|
-
resolve(user);
|
|
5713
|
+
const user = await exchangeCode(d.code, pkce, opts.signal, () => { committing = true; });
|
|
5714
|
+
finish(undefined, user);
|
|
5671
5715
|
}
|
|
5672
5716
|
catch (e) {
|
|
5673
|
-
|
|
5674
|
-
popup.close();
|
|
5675
|
-
}
|
|
5676
|
-
catch ( /* ignore */_b) { /* ignore */ }
|
|
5677
|
-
reject(e);
|
|
5717
|
+
finish(e);
|
|
5678
5718
|
}
|
|
5679
5719
|
};
|
|
5720
|
+
(_a = opts.signal) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', onAbort, { once: true });
|
|
5721
|
+
if ((_b = opts.signal) === null || _b === void 0 ? void 0 : _b.aborted) {
|
|
5722
|
+
onAbort();
|
|
5723
|
+
return;
|
|
5724
|
+
}
|
|
5680
5725
|
window.addEventListener('message', onMsg);
|
|
5681
5726
|
completionTimer = setTimeout(() => {
|
|
5682
|
-
|
|
5683
|
-
try {
|
|
5684
|
-
popup.close();
|
|
5685
|
-
}
|
|
5686
|
-
catch ( /* ignore */_a) { /* ignore */ }
|
|
5687
|
-
reject(new Error('Login expired or its popup disconnected. Start sign-in again.'));
|
|
5727
|
+
finish(new Error('Login expired or its popup disconnected. Start sign-in again.'));
|
|
5688
5728
|
}, LOGIN_TIMEOUT_MS);
|
|
5689
5729
|
// Some browser/extension combinations can return a real popup handle but
|
|
5690
5730
|
// strand the window at about:blank instead of navigating to the hosted
|
|
@@ -5705,23 +5745,18 @@ async function loginWithPopup(opts) {
|
|
|
5705
5745
|
const NAVIGATION_RECHECK_MS = 2000;
|
|
5706
5746
|
const navigationStartedAt = Date.now();
|
|
5707
5747
|
const checkNavigation = () => {
|
|
5708
|
-
if (settled || popup.closed)
|
|
5748
|
+
if (settled || handedOff || popup.closed)
|
|
5709
5749
|
return;
|
|
5710
5750
|
try {
|
|
5711
5751
|
if (popup.location.href === 'about:blank') {
|
|
5712
5752
|
if (Date.now() - navigationStartedAt >= NAVIGATION_GRACE_MS) {
|
|
5713
|
-
|
|
5714
|
-
try {
|
|
5715
|
-
popup.close();
|
|
5716
|
-
}
|
|
5717
|
-
catch ( /* ignore */_a) { /* ignore */ }
|
|
5718
|
-
reject(new Error('Popup stalled at about:blank - use loginWithRedirect() instead'));
|
|
5753
|
+
finish(new Error('Popup stalled at about:blank - use loginWithRedirect() instead'));
|
|
5719
5754
|
return;
|
|
5720
5755
|
}
|
|
5721
5756
|
navigationTimer = setTimeout(checkNavigation, NAVIGATION_RECHECK_MS);
|
|
5722
5757
|
}
|
|
5723
5758
|
}
|
|
5724
|
-
catch ( /* cross-origin hosted auth loaded normally */
|
|
5759
|
+
catch ( /* cross-origin hosted auth loaded normally */_a) { /* cross-origin hosted auth loaded normally */ }
|
|
5725
5760
|
};
|
|
5726
5761
|
navigationTimer = setTimeout(checkNavigation, NAVIGATION_RECHECK_MS);
|
|
5727
5762
|
// The popup posts its code and then closes ITSELF, so a naive "popup.closed -> reject"
|
|
@@ -5731,10 +5766,8 @@ async function loginWithPopup(opts) {
|
|
|
5731
5766
|
timer = setInterval(() => {
|
|
5732
5767
|
if (popup.closed) {
|
|
5733
5768
|
clearInterval(timer);
|
|
5734
|
-
setTimeout(() => { if (!settled)
|
|
5735
|
-
|
|
5736
|
-
reject(new Error('Login window closed'));
|
|
5737
|
-
} }, 500);
|
|
5769
|
+
setTimeout(() => { if (!settled && !handedOff)
|
|
5770
|
+
finish(new Error('Login window closed')); }, 500);
|
|
5738
5771
|
}
|
|
5739
5772
|
}, 500);
|
|
5740
5773
|
});
|
|
@@ -5785,9 +5818,10 @@ async function inlineAuthEndpoint() {
|
|
|
5785
5818
|
const cfg = await core.getConfig();
|
|
5786
5819
|
return { base: await issuerBase(), appId: cfg.appId };
|
|
5787
5820
|
}
|
|
5788
|
-
async function exchangeCode(code, pkce) {
|
|
5821
|
+
async function exchangeCode(code, pkce, signal, onCommitting) {
|
|
5789
5822
|
const generation = getInitializationGeneration();
|
|
5790
5823
|
const beforeCommit = () => {
|
|
5824
|
+
throwIfCancelled(signal);
|
|
5791
5825
|
if (generation !== getInitializationGeneration())
|
|
5792
5826
|
throw new Error('Login was superseded by SDK reinitialization. Start sign-in again.');
|
|
5793
5827
|
};
|
|
@@ -5803,7 +5837,7 @@ async function exchangeCode(code, pkce) {
|
|
|
5803
5837
|
let res;
|
|
5804
5838
|
try {
|
|
5805
5839
|
res = await fetch(`${base}/api/auth/oauth2/token`, {
|
|
5806
|
-
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: body.toString(),
|
|
5840
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: body.toString(), signal,
|
|
5807
5841
|
});
|
|
5808
5842
|
}
|
|
5809
5843
|
catch (err) {
|
|
@@ -5829,7 +5863,7 @@ async function exchangeCode(code, pkce) {
|
|
|
5829
5863
|
// Adopt on EVERY session surface (see establishInlineSession) - hosted
|
|
5830
5864
|
// popup/redirect completions all land here, so this closes their gap too.
|
|
5831
5865
|
try {
|
|
5832
|
-
await adoptSessionProvider({ provider: oidcProviderSingleton, method: 'email', configKey: 'direct:oidc', user, beforeCommit });
|
|
5866
|
+
await adoptSessionProvider({ provider: oidcProviderSingleton, method: 'email', configKey: 'direct:oidc', user, beforeCommit: () => { beforeCommit(); onCommitting === null || onCommitting === void 0 ? void 0 : onCommitting(); } });
|
|
5833
5867
|
}
|
|
5834
5868
|
catch (error) {
|
|
5835
5869
|
if (typeof rollback === 'function')
|
|
@@ -5898,6 +5932,31 @@ function idTokenIsGuest(idToken, expectedAddress) {
|
|
|
5898
5932
|
function storedSessionIsGuest() {
|
|
5899
5933
|
return idTokenIsGuest(getStoredIdToken());
|
|
5900
5934
|
}
|
|
5935
|
+
/** Internal: select a cross-tab restore from bearer claims, never global hints. */
|
|
5936
|
+
function storedSessionAuthMethod(config) {
|
|
5937
|
+
try {
|
|
5938
|
+
const token = getStoredIdToken();
|
|
5939
|
+
if (!token)
|
|
5940
|
+
return null;
|
|
5941
|
+
let payload = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
|
|
5942
|
+
payload += '='.repeat((4 - payload.length % 4) % 4);
|
|
5943
|
+
const claims = JSON.parse(getPlatform().atob(payload));
|
|
5944
|
+
const method = claims.is_anonymous === true ? 'guest'
|
|
5945
|
+
: claims['custom:walletProvider'] === 'turnkey' || claims.email ? 'email'
|
|
5946
|
+
: claims['custom:evmWalletAddress'] ? 'evm-wallet'
|
|
5947
|
+
: claims['custom:walletAddress'] ? 'phantom' : 'email';
|
|
5948
|
+
if (config.authMethod != null && canonicalWalletAuthMethod(config.authMethod) !== method)
|
|
5949
|
+
return null;
|
|
5950
|
+
if (method === 'evm-wallet' && config.authMethod !== 'evm-wallet')
|
|
5951
|
+
return null;
|
|
5952
|
+
if (method === 'phantom' && (isWalletLoginDisabled(config) || isEmailRequired(config)))
|
|
5953
|
+
return null;
|
|
5954
|
+
return method;
|
|
5955
|
+
}
|
|
5956
|
+
catch (_a) {
|
|
5957
|
+
return null;
|
|
5958
|
+
}
|
|
5959
|
+
}
|
|
5901
5960
|
/**
|
|
5902
5961
|
* Pick the provider used for an ordinary `init({ appId })` restore.
|
|
5903
5962
|
*
|
|
@@ -6159,9 +6218,10 @@ function optionalProviderError(method) {
|
|
|
6159
6218
|
`loginWithRedirect(...) for Bounded Auth, signInAnonymously() for guests, ` +
|
|
6160
6219
|
`or install/import an explicit wallet-provider entry once your app opts into "${method}".`);
|
|
6161
6220
|
}
|
|
6162
|
-
async function getAuthProvider(config) {
|
|
6221
|
+
async function getAuthProvider(config, fromStorage = false) {
|
|
6163
6222
|
var _a;
|
|
6164
|
-
const
|
|
6223
|
+
const requestedAuthMethod = config ? (fromStorage ? storedSessionAuthMethod(config) : authMethodForInit(config)) : null;
|
|
6224
|
+
const nextProviderConfigKey = config ? authProviderConfigKey(Object.assign(Object.assign({}, config), { authMethod: requestedAuthMethod })) : null;
|
|
6165
6225
|
if (currentAuthProvider && (!config || currentAuthProviderConfigKey === nextProviderConfigKey)) {
|
|
6166
6226
|
return currentAuthProvider;
|
|
6167
6227
|
}
|
|
@@ -6176,7 +6236,8 @@ async function getAuthProvider(config) {
|
|
|
6176
6236
|
initConfig = config;
|
|
6177
6237
|
// Keep what the app actually wrote for error text; everything else runs on
|
|
6178
6238
|
// the canonical method so exactly one string reaches storage and the issuer.
|
|
6179
|
-
|
|
6239
|
+
if (!requestedAuthMethod)
|
|
6240
|
+
throw new Error('The stored session is incompatible with this app authentication configuration.');
|
|
6180
6241
|
const authMethod = canonicalWalletAuthMethod(requestedAuthMethod);
|
|
6181
6242
|
const rpcUrl = normalizeSolanaRpcUrl(config.rpcUrl);
|
|
6182
6243
|
const configuredNetwork = getConfiguredSolanaNetwork(config);
|
|
@@ -6201,7 +6262,7 @@ async function getAuthProvider(config) {
|
|
|
6201
6262
|
// manager as legacy email sessions. Human login should be started
|
|
6202
6263
|
// with loginWithRedirect(); this provider is kept as the restore and
|
|
6203
6264
|
// logout surface for those sessions.
|
|
6204
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-
|
|
6265
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-CG5cxOj0.js'); })).EmailAuthProvider();
|
|
6205
6266
|
break;
|
|
6206
6267
|
case "phantom": {
|
|
6207
6268
|
// First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
|
|
@@ -6243,7 +6304,7 @@ async function getAuthProvider(config) {
|
|
|
6243
6304
|
// (bounded-login-widget.ts), so registration never counts as
|
|
6244
6305
|
// evidence the user has a wallet.
|
|
6245
6306
|
await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
|
|
6246
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
6307
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-LTnqoaYD.js'); });
|
|
6247
6308
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
6248
6309
|
break;
|
|
6249
6310
|
}
|
|
@@ -6256,7 +6317,7 @@ async function getAuthProvider(config) {
|
|
|
6256
6317
|
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
6257
6318
|
// to point at a specific wallet or set chainId/domain.
|
|
6258
6319
|
const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
|
|
6259
|
-
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-
|
|
6320
|
+
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-CwOGXCDt.js'); });
|
|
6260
6321
|
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
6261
6322
|
break;
|
|
6262
6323
|
}
|
|
@@ -6281,7 +6342,7 @@ async function getAuthProvider(config) {
|
|
|
6281
6342
|
break;
|
|
6282
6343
|
case "guest":
|
|
6283
6344
|
// Anonymous auth: a device-local ed25519 keypair signs the challenge.
|
|
6284
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
6345
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-Dtl1J-2F.js'); })).GuestAuthProvider();
|
|
6285
6346
|
break;
|
|
6286
6347
|
}
|
|
6287
6348
|
if (!currentAuthProvider) {
|
|
@@ -6343,7 +6404,7 @@ async function signInAnonymously() {
|
|
|
6343
6404
|
// Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
|
|
6344
6405
|
// the main bundle for data-only apps. Specifier is a static string literal
|
|
6345
6406
|
// so bundle-splitting can see it.
|
|
6346
|
-
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
6407
|
+
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-Dtl1J-2F.js'); })).GuestAuthProvider();
|
|
6347
6408
|
setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
|
|
6348
6409
|
// adoptSessionProvider awaits only getConfig() (already resolved here) and then
|
|
6349
6410
|
// runs every write - provider/method/config/marker/user - in one synchronous
|
|
@@ -6514,7 +6575,7 @@ function ensureSharedWalletLoginReady() {
|
|
|
6514
6575
|
if (!sharedWalletReady) {
|
|
6515
6576
|
sharedWalletReady = (async () => {
|
|
6516
6577
|
await core.getConfig();
|
|
6517
|
-
await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
6578
|
+
await Promise.resolve().then(function () { return require('./injected-wallet-provider-LTnqoaYD.js'); });
|
|
6518
6579
|
})().catch((error) => {
|
|
6519
6580
|
sharedWalletReady = null;
|
|
6520
6581
|
throw error;
|
|
@@ -6617,7 +6678,7 @@ async function loginWithWallet(options) {
|
|
|
6617
6678
|
await ensureSharedWalletLoginReady();
|
|
6618
6679
|
else
|
|
6619
6680
|
await ensureWalletLoginReady();
|
|
6620
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
6681
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-LTnqoaYD.js'); });
|
|
6621
6682
|
// Keep the RAW wallet provider: the offchain wrapper forwards only a fixed
|
|
6622
6683
|
// set of methods, so cleanup below must speak to the provider that actually
|
|
6623
6684
|
// holds the config rather than to whatever is wrapping it.
|
|
@@ -6889,7 +6950,8 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
6889
6950
|
logout: logout$1,
|
|
6890
6951
|
preloadWalletLogin: preloadWalletLogin,
|
|
6891
6952
|
resolveAuthMode: resolveAuthMode,
|
|
6892
|
-
signInAnonymously: signInAnonymously
|
|
6953
|
+
signInAnonymously: signInAnonymously,
|
|
6954
|
+
storedSessionAuthMethod: storedSessionAuthMethod
|
|
6893
6955
|
});
|
|
6894
6956
|
|
|
6895
6957
|
/**
|
|
@@ -6967,12 +7029,80 @@ let isAuthLoading = false;
|
|
|
6967
7029
|
let authReadyPromise = null;
|
|
6968
7030
|
let initializingConfig = null;
|
|
6969
7031
|
let initializationGeneration = 0;
|
|
7032
|
+
let initializedConfig = null;
|
|
7033
|
+
let storageBridgeRegistered = false;
|
|
7034
|
+
let observedIdToken = null;
|
|
7035
|
+
let observedIssuer = null;
|
|
7036
|
+
// Storage events carry no authority. Re-read the active manager's app/issuer
|
|
7037
|
+
// namespace, then use the ordinary initializer/provider restore and listeners.
|
|
7038
|
+
function registerStorageBridge() {
|
|
7039
|
+
if (storageBridgeRegistered || !getPlatform().hasDOM || typeof window === 'undefined')
|
|
7040
|
+
return;
|
|
7041
|
+
storageBridgeRegistered = true;
|
|
7042
|
+
window.addEventListener('storage', (event) => {
|
|
7043
|
+
if (event.storageArea !== window.localStorage || !initializedConfig)
|
|
7044
|
+
return;
|
|
7045
|
+
void syncStoredSession().catch((error) => console.warn('Bounded session synchronization failed:', error));
|
|
7046
|
+
});
|
|
7047
|
+
}
|
|
7048
|
+
async function syncStoredSession() {
|
|
7049
|
+
const config = initializedConfig;
|
|
7050
|
+
if (!config)
|
|
7051
|
+
return;
|
|
7052
|
+
const token = core.WebSessionManager.getIdToken();
|
|
7053
|
+
const issuer = core.WebSessionManager.getIssuer();
|
|
7054
|
+
if (token === observedIdToken && issuer === observedIssuer)
|
|
7055
|
+
return;
|
|
7056
|
+
observedIdToken = token;
|
|
7057
|
+
observedIssuer = issuer;
|
|
7058
|
+
const generation = ++initializationGeneration;
|
|
7059
|
+
// Hide the former principal while the replacement is validated. This also
|
|
7060
|
+
// reconnects live reads through the existing auth-state change path.
|
|
7061
|
+
setCurrentUser(null);
|
|
7062
|
+
if (authReadyPromise)
|
|
7063
|
+
await authReadyPromise.catch(() => { });
|
|
7064
|
+
if (generation !== initializationGeneration || config !== initializedConfig)
|
|
7065
|
+
return;
|
|
7066
|
+
const record = await core.WebSessionManager.readSessionWithGeneration();
|
|
7067
|
+
if (generation !== initializationGeneration || config !== initializedConfig)
|
|
7068
|
+
return;
|
|
7069
|
+
if (!record)
|
|
7070
|
+
return;
|
|
7071
|
+
const normalize = (url) => (url || '').replace(/\/+$/, '');
|
|
7072
|
+
const resolvedConfig = await core.getConfig();
|
|
7073
|
+
if (generation !== initializationGeneration || config !== initializedConfig)
|
|
7074
|
+
return;
|
|
7075
|
+
const allowedIssuers = [normalize(resolvedConfig.humanAuthApiUrl || 'https://auth.bounded.sh'), normalize(resolvedConfig.authApiUrl)].filter(Boolean);
|
|
7076
|
+
// A legacy shared blob can belong to another app. Never restore or clear
|
|
7077
|
+
// that app's credential; the current app remains signed out.
|
|
7078
|
+
if ((record.appId && record.appId !== config.appId)
|
|
7079
|
+
|| (record.issuer && !allowedIssuers.includes(normalize(record.issuer))))
|
|
7080
|
+
return;
|
|
7081
|
+
if (!storedSessionAuthMethod(config))
|
|
7082
|
+
return;
|
|
7083
|
+
const restored = startInitialization(config, true);
|
|
7084
|
+
const restoreGeneration = initializationGeneration;
|
|
7085
|
+
try {
|
|
7086
|
+
await restored;
|
|
7087
|
+
}
|
|
7088
|
+
catch (error) {
|
|
7089
|
+
if (restoreGeneration === initializationGeneration && core.WebSessionManager.getIdToken())
|
|
7090
|
+
throw error;
|
|
7091
|
+
}
|
|
7092
|
+
}
|
|
6970
7093
|
/** Internal guard for a login result arriving after the app reconfigured the SDK. */
|
|
6971
7094
|
function getInitializationGeneration() { return initializationGeneration; }
|
|
6972
7095
|
// This file acts as a middleware for the global state of the SDK
|
|
6973
7096
|
// This mostly involves setting up the AuthProvider and managing the current user
|
|
6974
|
-
async function initialize(requestedConfig) {
|
|
7097
|
+
async function initialize(requestedConfig, fromStorage) {
|
|
6975
7098
|
const newConfig = withDefaultSolanaRpcUrl(requestedConfig);
|
|
7099
|
+
const generation = initializationGeneration;
|
|
7100
|
+
const validateStorage = fromStorage ? core.WebSessionManager.captureSessionEstablishment() : undefined;
|
|
7101
|
+
const beforeCommit = () => {
|
|
7102
|
+
if (generation !== initializationGeneration)
|
|
7103
|
+
throw new Error('Session restore was superseded.');
|
|
7104
|
+
validateStorage === null || validateStorage === void 0 ? void 0 : validateStorage();
|
|
7105
|
+
};
|
|
6976
7106
|
// Mark auth as loading for the ENTIRE init/restore window so consumers render
|
|
6977
7107
|
// a neutral/loading state instead of the signed-out UI while we rehydrate the
|
|
6978
7108
|
// session — otherwise getCurrentUser() is null + loading is false during the
|
|
@@ -6991,8 +7121,9 @@ async function initialize(requestedConfig) {
|
|
|
6991
7121
|
// onAuthStateChanged never fired, and every consumer UI went on showing a
|
|
6992
7122
|
// connected wallet for a session the server no longer knew about.
|
|
6993
7123
|
registerSessionClearedBridge();
|
|
7124
|
+
registerStorageBridge();
|
|
6994
7125
|
// Get auth provider first
|
|
6995
|
-
authProviderInstance = await getAuthProvider(newConfig);
|
|
7126
|
+
authProviderInstance = await getAuthProvider(newConfig, fromStorage);
|
|
6996
7127
|
// Initialize config with auth provider
|
|
6997
7128
|
await core.init(Object.assign(Object.assign({}, newConfig), { authProvider: authProviderInstance }));
|
|
6998
7129
|
// A return establishes its own provider/session, or hands off a popup.
|
|
@@ -7017,7 +7148,8 @@ async function initialize(requestedConfig) {
|
|
|
7017
7148
|
// Wait for restoreSession to complete
|
|
7018
7149
|
// The appId check is done in SessionManager.getSession which is called by restoreSession
|
|
7019
7150
|
// If there's an appId mismatch, the session will be cleared and restoreSession will return null
|
|
7020
|
-
let user = await authProviderInstance.restoreSession();
|
|
7151
|
+
let user = await authProviderInstance.restoreSession(beforeCommit);
|
|
7152
|
+
beforeCommit();
|
|
7021
7153
|
// If a session exists but was created before auth method tracking (legacy session),
|
|
7022
7154
|
// clear it to avoid mismatches when the app switches auth methods (e.g. email → phantom)
|
|
7023
7155
|
//
|
|
@@ -7025,9 +7157,10 @@ async function initialize(requestedConfig) {
|
|
|
7025
7157
|
// unawaited call would return a Promise (always truthy) — nulling the user
|
|
7026
7158
|
// unconditionally AND letting setCurrentUser run while the old credential
|
|
7027
7159
|
// was still in storage.
|
|
7028
|
-
if (user && await clearIncompatibleSession()) {
|
|
7160
|
+
if (user && !fromStorage && await clearIncompatibleSession()) {
|
|
7029
7161
|
user = null;
|
|
7030
7162
|
}
|
|
7163
|
+
beforeCommit();
|
|
7031
7164
|
setCurrentUser(user);
|
|
7032
7165
|
// Mark init as completed
|
|
7033
7166
|
initCompleted = true;
|
|
@@ -7067,13 +7200,17 @@ function sameConfigValue(a, b, seen = new WeakMap()) {
|
|
|
7067
7200
|
&& sameConfigValue(a[key], b[key], seen));
|
|
7068
7201
|
}
|
|
7069
7202
|
function init$1(newConfig) {
|
|
7203
|
+
return startInitialization(newConfig, false);
|
|
7204
|
+
}
|
|
7205
|
+
function startInitialization(newConfig, fromStorage) {
|
|
7070
7206
|
if (initializingConfig) {
|
|
7071
7207
|
if (sameConfigValue(initializingConfig, newConfig)) {
|
|
7072
7208
|
return authReadyPromise;
|
|
7073
7209
|
}
|
|
7074
7210
|
return Promise.reject(new Error('SDK initialization is in progress. Await init() before changing its configuration.'));
|
|
7075
7211
|
}
|
|
7076
|
-
|
|
7212
|
+
initializedConfig = Object.assign({}, newConfig);
|
|
7213
|
+
initializingConfig = initializedConfig;
|
|
7077
7214
|
initializationGeneration++;
|
|
7078
7215
|
let resolveReady;
|
|
7079
7216
|
let rejectReady;
|
|
@@ -7085,7 +7222,7 @@ function init$1(newConfig) {
|
|
|
7085
7222
|
// auth-loading listener to call waitForAuthReady() synchronously when init()
|
|
7086
7223
|
// announces that session restoration has begun.
|
|
7087
7224
|
authReadyPromise = ready;
|
|
7088
|
-
void initialize(initializingConfig).then(() => { initializingConfig = null; resolveReady(); }, (error) => { initializingConfig = null; rejectReady(error); });
|
|
7225
|
+
void initialize(initializingConfig, fromStorage).then(() => { initializingConfig = null; resolveReady(); }, (error) => { initializingConfig = null; rejectReady(error); });
|
|
7089
7226
|
return ready;
|
|
7090
7227
|
}
|
|
7091
7228
|
/**
|
|
@@ -7158,6 +7295,13 @@ function userPrincipalKey(user) {
|
|
|
7158
7295
|
}
|
|
7159
7296
|
// Update the currentUser and notify listeners
|
|
7160
7297
|
function setCurrentUser(user) {
|
|
7298
|
+
observedIdToken = getCurrentIdToken();
|
|
7299
|
+
try {
|
|
7300
|
+
observedIssuer = core.getActiveSessionManager().getIssuer();
|
|
7301
|
+
}
|
|
7302
|
+
catch (_a) {
|
|
7303
|
+
observedIssuer = null;
|
|
7304
|
+
}
|
|
7161
7305
|
// Enrich with the universal identity fields (id/email) derived from the
|
|
7162
7306
|
// active session's idToken — central chokepoint so every provider's user
|
|
7163
7307
|
// object gains { id, address, email } without each construction site
|
|
@@ -8105,7 +8249,8 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8105
8249
|
return authApi.loginWithRedirect(options);
|
|
8106
8250
|
// Invoke immediately inside the click handler to retain popup activation.
|
|
8107
8251
|
return authApi.loginWithPopup(options).catch((error) => {
|
|
8108
|
-
|
|
8252
|
+
var _a;
|
|
8253
|
+
if (!((_a = options.signal) === null || _a === void 0 ? void 0 : _a.aborted) && shouldFallbackToRedirect(error))
|
|
8109
8254
|
return authApi.loginWithRedirect(options);
|
|
8110
8255
|
throw error;
|
|
8111
8256
|
});
|
|
@@ -8243,6 +8388,12 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8243
8388
|
let activeAttempt = 0;
|
|
8244
8389
|
let abortScopedLogin = null;
|
|
8245
8390
|
let abortGesture = null;
|
|
8391
|
+
const startHostedLogin = (options) => {
|
|
8392
|
+
const controller = new AbortController();
|
|
8393
|
+
const abort = () => controller.abort();
|
|
8394
|
+
abortScopedLogin = abort;
|
|
8395
|
+
return hostedLogin(Object.assign(Object.assign({}, options), { signal: controller.signal }));
|
|
8396
|
+
};
|
|
8246
8397
|
/** Reject a gesture promise already waiting on a view that is going away. */
|
|
8247
8398
|
const abortPendingGesture = () => {
|
|
8248
8399
|
const abort = abortGesture;
|
|
@@ -8268,6 +8419,7 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8268
8419
|
if (!attemptIsCurrent(id))
|
|
8269
8420
|
return false;
|
|
8270
8421
|
activeAttempt = 0;
|
|
8422
|
+
abortScopedLogin = null;
|
|
8271
8423
|
return true;
|
|
8272
8424
|
};
|
|
8273
8425
|
/** Take the card back (Back, a lane switch, settling the modal). Deliberately
|
|
@@ -8422,7 +8574,7 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8422
8574
|
loginHint: input.value,
|
|
8423
8575
|
redirectUri: opts.redirectUri,
|
|
8424
8576
|
};
|
|
8425
|
-
|
|
8577
|
+
startHostedLogin(emailOpts)
|
|
8426
8578
|
// A hosted login that RESOLVES minted a real session, so it settles
|
|
8427
8579
|
// the card even if another lane has since taken it - dropping it
|
|
8428
8580
|
// would leave the app signed in behind a widget that says it is not.
|
|
@@ -8472,7 +8624,7 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8472
8624
|
}
|
|
8473
8625
|
setBusy(b, "Opening secure sign-in\u2026");
|
|
8474
8626
|
const socialOpts = { provider: method, redirectUri: opts.redirectUri };
|
|
8475
|
-
|
|
8627
|
+
startHostedLogin(socialOpts)
|
|
8476
8628
|
.then((u) => {
|
|
8477
8629
|
if (u) {
|
|
8478
8630
|
settleAttempt(attempt);
|
|
@@ -10544,8 +10696,9 @@ class PrivyExpoProvider {
|
|
|
10544
10696
|
const { signature } = await this.signAndSubmitInternal(transaction, wallet, connection);
|
|
10545
10697
|
return signature;
|
|
10546
10698
|
}
|
|
10547
|
-
async restoreSession() {
|
|
10699
|
+
async restoreSession(beforeCommit) {
|
|
10548
10700
|
const session = await core.getActiveSessionManager().getSession();
|
|
10701
|
+
beforeCommit === null || beforeCommit === void 0 ? void 0 : beforeCommit();
|
|
10549
10702
|
if (session) {
|
|
10550
10703
|
this.authenticatedAddress = session.address;
|
|
10551
10704
|
return { provider: this, address: session.address };
|
|
@@ -11130,4 +11283,4 @@ exports.useAuth = useAuth;
|
|
|
11130
11283
|
exports.useBuildRun = useBuildRun;
|
|
11131
11284
|
exports.useQuery = useQuery;
|
|
11132
11285
|
exports.waitForAuthReady = waitForAuthReady;
|
|
11133
|
-
//# sourceMappingURL=index-
|
|
11286
|
+
//# sourceMappingURL=index-Brdwqgqs.js.map
|