@bounded-sh/client 0.0.29 → 0.0.31
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/oidc-auth.d.ts +9 -2
- package/dist/index.js +38 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -7
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +38 -7
- package/dist/index.native.js.map +1 -1
- package/dist/index.native.mjs +38 -7
- package/dist/index.native.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.native.js
CHANGED
|
@@ -4250,7 +4250,11 @@ async function buildAuthorize(opts, guestHint) {
|
|
|
4250
4250
|
const cfg = await core.getConfig();
|
|
4251
4251
|
if (!cfg.appId)
|
|
4252
4252
|
throw new Error('appId is not configured (init the SDK with your appId)');
|
|
4253
|
-
|
|
4253
|
+
// Web: default to the current page so callers don't have to pass redirectUri. Native has no
|
|
4254
|
+
// window — it MUST pass an https universal link (the system auth session needs a real URL).
|
|
4255
|
+
const redirectUri = opts.redirectUri || (hasDOM() ? window.location.origin + window.location.pathname : undefined);
|
|
4256
|
+
if (!redirectUri)
|
|
4257
|
+
throw new Error('redirectUri is required on React Native — pass the https universal link the app owner registered.');
|
|
4254
4258
|
const { verifier, challenge } = await makePkce();
|
|
4255
4259
|
const state = randomState();
|
|
4256
4260
|
const base = await issuerBase();
|
|
@@ -4409,6 +4413,21 @@ async function completeLoginFromRedirect() {
|
|
|
4409
4413
|
const returnedState = url.searchParams.get('state');
|
|
4410
4414
|
if (!code)
|
|
4411
4415
|
return null;
|
|
4416
|
+
// POPUP path: if we're the redirect_uri page running INSIDE the loginWithPopup() window,
|
|
4417
|
+
// hand the code to the opener and close — no separate completeLoginInPopup() call needed.
|
|
4418
|
+
// The opener is the same app/origin, so post to our own origin (the opener's message
|
|
4419
|
+
// handler checks ev.origin === redirect_uri origin). One call now finishes BOTH flows.
|
|
4420
|
+
if (window.opener && window.opener !== window) {
|
|
4421
|
+
try {
|
|
4422
|
+
window.opener.postMessage({ type: 'bounded-oidc-code', code, state: returnedState }, window.location.origin);
|
|
4423
|
+
}
|
|
4424
|
+
catch ( /* ignore */_a) { /* ignore */ }
|
|
4425
|
+
try {
|
|
4426
|
+
window.close();
|
|
4427
|
+
}
|
|
4428
|
+
catch ( /* ignore */_b) { /* ignore */ }
|
|
4429
|
+
return null;
|
|
4430
|
+
}
|
|
4412
4431
|
setAuthLoading(true);
|
|
4413
4432
|
try {
|
|
4414
4433
|
const raw = sessionStorage.getItem(PKCE_STORE_KEY);
|
|
@@ -4430,7 +4449,8 @@ async function completeLoginFromRedirect() {
|
|
|
4430
4449
|
}
|
|
4431
4450
|
}
|
|
4432
4451
|
/** Popup variant: open the hosted login in a popup; resolves with the User once the popup's
|
|
4433
|
-
* redirect_uri page posts the code back. The redirect_uri page
|
|
4452
|
+
* redirect_uri page posts the code back. The redirect_uri page just calls the usual
|
|
4453
|
+
* completeLoginFromRedirect() (which auto-detects the popup) — no separate call needed. */
|
|
4434
4454
|
async function loginWithPopup(opts) {
|
|
4435
4455
|
if (!hasDOM())
|
|
4436
4456
|
throw new Error('loginWithPopup is web-only — on React Native use loginWithRedirect()');
|
|
@@ -4442,15 +4462,20 @@ async function loginWithPopup(opts) {
|
|
|
4442
4462
|
const popup = window.open(url, 'bounded-oidc', `width=${w},height=${h},left=${left},top=${top}`);
|
|
4443
4463
|
if (!popup)
|
|
4444
4464
|
throw new Error('Popup blocked — use loginWithRedirect() instead');
|
|
4445
|
-
|
|
4465
|
+
// Use the RESOLVED redirect_uri (buildAuthorize defaulted it to the current page on web),
|
|
4466
|
+
// not opts.redirectUri which may be undefined.
|
|
4467
|
+
const expectedOrigin = new URL(pkce.redirectUri).origin;
|
|
4446
4468
|
return await new Promise((resolve, reject) => {
|
|
4469
|
+
let settled = false;
|
|
4470
|
+
let timer;
|
|
4471
|
+
const cleanup = () => { settled = true; clearInterval(timer); window.removeEventListener('message', onMsg); };
|
|
4447
4472
|
const onMsg = async (ev) => {
|
|
4448
4473
|
if (ev.origin !== expectedOrigin)
|
|
4449
4474
|
return; // only trust the redirect_uri origin
|
|
4450
4475
|
const d = ev.data;
|
|
4451
4476
|
if (!d || d.type !== 'bounded-oidc-code' || typeof d.code !== 'string')
|
|
4452
4477
|
return;
|
|
4453
|
-
|
|
4478
|
+
cleanup();
|
|
4454
4479
|
try {
|
|
4455
4480
|
const raw = sessionStorage.getItem(PKCE_STORE_KEY);
|
|
4456
4481
|
if (!raw)
|
|
@@ -4471,11 +4496,17 @@ async function loginWithPopup(opts) {
|
|
|
4471
4496
|
}
|
|
4472
4497
|
};
|
|
4473
4498
|
window.addEventListener('message', onMsg);
|
|
4474
|
-
|
|
4499
|
+
// The popup posts its code and then closes ITSELF, so a naive "popup.closed -> reject"
|
|
4500
|
+
// races the just-posted message and would report a spurious "Login window closed" on a
|
|
4501
|
+
// SUCCESSFUL login. When we see it closed, wait a beat for that pending message to settle
|
|
4502
|
+
// before declaring the window closed.
|
|
4503
|
+
timer = setInterval(() => {
|
|
4475
4504
|
if (popup.closed) {
|
|
4476
4505
|
clearInterval(timer);
|
|
4477
|
-
|
|
4478
|
-
|
|
4506
|
+
setTimeout(() => { if (!settled) {
|
|
4507
|
+
cleanup();
|
|
4508
|
+
reject(new Error('Login window closed'));
|
|
4509
|
+
} }, 500);
|
|
4479
4510
|
}
|
|
4480
4511
|
}, 500);
|
|
4481
4512
|
});
|