@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.mjs
CHANGED
|
@@ -4230,7 +4230,11 @@ async function buildAuthorize(opts, guestHint) {
|
|
|
4230
4230
|
const cfg = await getConfig();
|
|
4231
4231
|
if (!cfg.appId)
|
|
4232
4232
|
throw new Error('appId is not configured (init the SDK with your appId)');
|
|
4233
|
-
|
|
4233
|
+
// Web: default to the current page so callers don't have to pass redirectUri. Native has no
|
|
4234
|
+
// window — it MUST pass an https universal link (the system auth session needs a real URL).
|
|
4235
|
+
const redirectUri = opts.redirectUri || (hasDOM() ? window.location.origin + window.location.pathname : undefined);
|
|
4236
|
+
if (!redirectUri)
|
|
4237
|
+
throw new Error('redirectUri is required on React Native — pass the https universal link the app owner registered.');
|
|
4234
4238
|
const { verifier, challenge } = await makePkce();
|
|
4235
4239
|
const state = randomState();
|
|
4236
4240
|
const base = await issuerBase();
|
|
@@ -4389,6 +4393,21 @@ async function completeLoginFromRedirect() {
|
|
|
4389
4393
|
const returnedState = url.searchParams.get('state');
|
|
4390
4394
|
if (!code)
|
|
4391
4395
|
return null;
|
|
4396
|
+
// POPUP path: if we're the redirect_uri page running INSIDE the loginWithPopup() window,
|
|
4397
|
+
// hand the code to the opener and close — no separate completeLoginInPopup() call needed.
|
|
4398
|
+
// The opener is the same app/origin, so post to our own origin (the opener's message
|
|
4399
|
+
// handler checks ev.origin === redirect_uri origin). One call now finishes BOTH flows.
|
|
4400
|
+
if (window.opener && window.opener !== window) {
|
|
4401
|
+
try {
|
|
4402
|
+
window.opener.postMessage({ type: 'bounded-oidc-code', code, state: returnedState }, window.location.origin);
|
|
4403
|
+
}
|
|
4404
|
+
catch ( /* ignore */_a) { /* ignore */ }
|
|
4405
|
+
try {
|
|
4406
|
+
window.close();
|
|
4407
|
+
}
|
|
4408
|
+
catch ( /* ignore */_b) { /* ignore */ }
|
|
4409
|
+
return null;
|
|
4410
|
+
}
|
|
4392
4411
|
setAuthLoading(true);
|
|
4393
4412
|
try {
|
|
4394
4413
|
const raw = sessionStorage.getItem(PKCE_STORE_KEY);
|
|
@@ -4410,7 +4429,8 @@ async function completeLoginFromRedirect() {
|
|
|
4410
4429
|
}
|
|
4411
4430
|
}
|
|
4412
4431
|
/** Popup variant: open the hosted login in a popup; resolves with the User once the popup's
|
|
4413
|
-
* redirect_uri page posts the code back. The redirect_uri page
|
|
4432
|
+
* redirect_uri page posts the code back. The redirect_uri page just calls the usual
|
|
4433
|
+
* completeLoginFromRedirect() (which auto-detects the popup) — no separate call needed. */
|
|
4414
4434
|
async function loginWithPopup(opts) {
|
|
4415
4435
|
if (!hasDOM())
|
|
4416
4436
|
throw new Error('loginWithPopup is web-only — on React Native use loginWithRedirect()');
|
|
@@ -4422,15 +4442,20 @@ async function loginWithPopup(opts) {
|
|
|
4422
4442
|
const popup = window.open(url, 'bounded-oidc', `width=${w},height=${h},left=${left},top=${top}`);
|
|
4423
4443
|
if (!popup)
|
|
4424
4444
|
throw new Error('Popup blocked — use loginWithRedirect() instead');
|
|
4425
|
-
|
|
4445
|
+
// Use the RESOLVED redirect_uri (buildAuthorize defaulted it to the current page on web),
|
|
4446
|
+
// not opts.redirectUri which may be undefined.
|
|
4447
|
+
const expectedOrigin = new URL(pkce.redirectUri).origin;
|
|
4426
4448
|
return await new Promise((resolve, reject) => {
|
|
4449
|
+
let settled = false;
|
|
4450
|
+
let timer;
|
|
4451
|
+
const cleanup = () => { settled = true; clearInterval(timer); window.removeEventListener('message', onMsg); };
|
|
4427
4452
|
const onMsg = async (ev) => {
|
|
4428
4453
|
if (ev.origin !== expectedOrigin)
|
|
4429
4454
|
return; // only trust the redirect_uri origin
|
|
4430
4455
|
const d = ev.data;
|
|
4431
4456
|
if (!d || d.type !== 'bounded-oidc-code' || typeof d.code !== 'string')
|
|
4432
4457
|
return;
|
|
4433
|
-
|
|
4458
|
+
cleanup();
|
|
4434
4459
|
try {
|
|
4435
4460
|
const raw = sessionStorage.getItem(PKCE_STORE_KEY);
|
|
4436
4461
|
if (!raw)
|
|
@@ -4451,11 +4476,17 @@ async function loginWithPopup(opts) {
|
|
|
4451
4476
|
}
|
|
4452
4477
|
};
|
|
4453
4478
|
window.addEventListener('message', onMsg);
|
|
4454
|
-
|
|
4479
|
+
// The popup posts its code and then closes ITSELF, so a naive "popup.closed -> reject"
|
|
4480
|
+
// races the just-posted message and would report a spurious "Login window closed" on a
|
|
4481
|
+
// SUCCESSFUL login. When we see it closed, wait a beat for that pending message to settle
|
|
4482
|
+
// before declaring the window closed.
|
|
4483
|
+
timer = setInterval(() => {
|
|
4455
4484
|
if (popup.closed) {
|
|
4456
4485
|
clearInterval(timer);
|
|
4457
|
-
|
|
4458
|
-
|
|
4486
|
+
setTimeout(() => { if (!settled) {
|
|
4487
|
+
cleanup();
|
|
4488
|
+
reject(new Error('Login window closed'));
|
|
4489
|
+
} }, 500);
|
|
4459
4490
|
}
|
|
4460
4491
|
}, 500);
|
|
4461
4492
|
});
|