@frontegg/redux-store 7.123.0-alpha.2 → 7.123.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/auth/LoginState/actions/afterAuthNavigation.actions.js +63 -42
- package/auth/LoginState/interfaces.d.ts +7 -0
- package/auth/LoginState/state.js +1 -0
- package/index.js +1 -1
- package/node/auth/LoginState/actions/afterAuthNavigation.actions.js +63 -42
- package/node/auth/LoginState/state.js +1 -0
- package/node/index.js +1 -1
- package/package.json +2 -2
|
@@ -212,7 +212,7 @@ export default ((store, api, sharedActions) => {
|
|
|
212
212
|
*/
|
|
213
213
|
|
|
214
214
|
const afterAuthNavigation = async payload => {
|
|
215
|
-
var
|
|
215
|
+
var _store$auth$tenantSel2;
|
|
216
216
|
// Once the choose-tenant step starts a switch the chooser owns navigation. Every re-entry here
|
|
217
217
|
// (the switch's token refresh, and — critically — a late or timed-out switch completing AFTER the
|
|
218
218
|
// user hit the escape hatch) must be a no-op, so navigation can't run twice or jump into the wrong
|
|
@@ -239,52 +239,73 @@ export default ((store, api, sharedActions) => {
|
|
|
239
239
|
}); // consume: later re-entries stay suppressed
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
// never re-prompted.
|
|
251
|
-
// login with magic code, try to step up, no other mfa, invalid max age, force_enroll -> logout, login with first factor, not-stepped up jwt -> navigate to step up
|
|
252
|
-
const shouldStepUp = (_window4 = window) == null ? void 0 : _window4.localStorage.getItem(SHOULD_STEP_UP_KEY);
|
|
253
|
-
const user = store.auth.user;
|
|
254
|
-
if (shouldStepUp) {
|
|
255
|
-
var _window5;
|
|
256
|
-
(_window5 = window) == null ? void 0 : _window5.localStorage.removeItem(SHOULD_STEP_UP_KEY);
|
|
257
|
-
}
|
|
258
|
-
if (stepUpUrl && shouldStepUp && !isSteppedUp(user)) {
|
|
259
|
-
return afterAuthNavigationUtil(actions.resetLoginState, {
|
|
260
|
-
forceStepUpUrl: stepUpUrl
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
if (await shouldRouteToChooseTenant()) {
|
|
242
|
+
// Callers expose the authenticated user in the store BEFORE this function's async gates resolve,
|
|
243
|
+
// so a host app that redirects on `user != null` (e.g. the hosted-login postlogin) would complete
|
|
244
|
+
// the flow before the choose-organization step can render. Raise `tenantChoicePending` in the same
|
|
245
|
+
// synchronous block (same store batch as the user set) so such hosts can hold, and always lower it
|
|
246
|
+
// once the gate has decided: by then either `step` is chooseTenant (the chooser now covers the
|
|
247
|
+
// hold) or the flow finalized. Written only when the integrator opted into tenant selection.
|
|
248
|
+
const tenantSelectionEnabled = ((_store$auth$tenantSel2 = store.auth.tenantSelection) == null ? void 0 : _store$auth$tenantSel2.enabled) === true;
|
|
249
|
+
if (tenantSelectionEnabled) {
|
|
264
250
|
actions.setLoginState({
|
|
265
|
-
|
|
266
|
-
loading: false
|
|
267
|
-
});
|
|
268
|
-
// Mirror the other post-auth interstitials (e.g. promptPasskeys): navigate to the login URL
|
|
269
|
-
// so the ChooseTenant step actually renders even when afterAuthNavigation is invoked from an
|
|
270
|
-
// OAuth/social callback route.
|
|
271
|
-
store.auth.onRedirectTo(store.auth.routes.loginUrl, {
|
|
272
|
-
preserveQueryParams: true
|
|
251
|
+
tenantChoicePending: true
|
|
273
252
|
});
|
|
274
|
-
return; // do NOT finalize; ChooseTenant confirm re-enters afterAuthNavigation
|
|
275
253
|
}
|
|
254
|
+
try {
|
|
255
|
+
var _window4, _payload$preventRedir;
|
|
256
|
+
const {
|
|
257
|
+
customLoginAuthenticatedUrl,
|
|
258
|
+
stepUpUrl
|
|
259
|
+
} = store.auth.routes;
|
|
260
|
+
|
|
261
|
+
// Step-up on the CURRENT tenant resolves before the org chooser: a user who needs both
|
|
262
|
+
// authenticates + steps up first, then picks an org. switchTenant handles any MFA the chosen
|
|
263
|
+
// org requires on its own, and the isSteppedUp guard below means an already-stepped-up user is
|
|
264
|
+
// never re-prompted.
|
|
265
|
+
// login with magic code, try to step up, no other mfa, invalid max age, force_enroll -> logout, login with first factor, not-stepped up jwt -> navigate to step up
|
|
266
|
+
const shouldStepUp = (_window4 = window) == null ? void 0 : _window4.localStorage.getItem(SHOULD_STEP_UP_KEY);
|
|
267
|
+
const user = store.auth.user;
|
|
268
|
+
if (shouldStepUp) {
|
|
269
|
+
var _window5;
|
|
270
|
+
(_window5 = window) == null ? void 0 : _window5.localStorage.removeItem(SHOULD_STEP_UP_KEY);
|
|
271
|
+
}
|
|
272
|
+
if (stepUpUrl && shouldStepUp && !isSteppedUp(user)) {
|
|
273
|
+
return await afterAuthNavigationUtil(actions.resetLoginState, {
|
|
274
|
+
forceStepUpUrl: stepUpUrl
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (await shouldRouteToChooseTenant()) {
|
|
278
|
+
actions.setLoginState({
|
|
279
|
+
step: LoginStep.chooseTenant,
|
|
280
|
+
loading: false
|
|
281
|
+
});
|
|
282
|
+
// Mirror the other post-auth interstitials (e.g. promptPasskeys): navigate to the login URL
|
|
283
|
+
// so the ChooseTenant step actually renders even when afterAuthNavigation is invoked from an
|
|
284
|
+
// OAuth/social callback route.
|
|
285
|
+
store.auth.onRedirectTo(store.auth.routes.loginUrl, {
|
|
286
|
+
preserveQueryParams: true
|
|
287
|
+
});
|
|
288
|
+
return; // do NOT finalize; ChooseTenant confirm re-enters afterAuthNavigation
|
|
289
|
+
}
|
|
276
290
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
291
|
+
let customLoginURL = customLoginAuthenticatedUrl;
|
|
292
|
+
if (!customLoginAuthenticatedUrl) {
|
|
293
|
+
var _store$auth$routes;
|
|
294
|
+
await actions.loadCustomLoginRoutes();
|
|
295
|
+
customLoginURL = (_store$auth$routes = store.auth.routes) == null ? void 0 : _store$auth$routes.customLoginAuthenticatedUrl;
|
|
296
|
+
}
|
|
297
|
+
return await afterAuthNavigationUtil(actions.resetLoginState, {
|
|
298
|
+
customLoginAuthenticatedUrl: customLoginURL,
|
|
299
|
+
shouldStepUpDuringLogin: !!shouldStepUp,
|
|
300
|
+
preventRedirectUrlOriginCleaning: (_payload$preventRedir = payload == null ? void 0 : payload.preventRedirectUrlOriginCleaning) != null ? _payload$preventRedir : false
|
|
301
|
+
});
|
|
302
|
+
} finally {
|
|
303
|
+
if (tenantSelectionEnabled) {
|
|
304
|
+
actions.setLoginState({
|
|
305
|
+
tenantChoicePending: false
|
|
306
|
+
});
|
|
307
|
+
}
|
|
282
308
|
}
|
|
283
|
-
return afterAuthNavigationUtil(actions.resetLoginState, {
|
|
284
|
-
customLoginAuthenticatedUrl: customLoginURL,
|
|
285
|
-
shouldStepUpDuringLogin: !!shouldStepUp,
|
|
286
|
-
preventRedirectUrlOriginCleaning: (_payload$preventRedir = payload == null ? void 0 : payload.preventRedirectUrlOriginCleaning) != null ? _payload$preventRedir : false
|
|
287
|
-
});
|
|
288
309
|
};
|
|
289
310
|
|
|
290
311
|
/**
|
|
@@ -63,6 +63,13 @@ export interface LoginState {
|
|
|
63
63
|
* so re-entry into afterAuthNavigation finalizes without re-prompting.
|
|
64
64
|
*/
|
|
65
65
|
tenantChoiceResolved: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* True from afterAuthNavigation entry until the choose-organization gate decides (choose-organization
|
|
68
|
+
* feature, only when `tenantSelection.enabled`). The authenticated user is exposed in the store BEFORE
|
|
69
|
+
* the gate's async work resolves, so host apps that redirect on `user != null` (e.g. the hosted-login
|
|
70
|
+
* postlogin) must hold while this is set or they complete the flow before the chooser can render.
|
|
71
|
+
*/
|
|
72
|
+
tenantChoicePending?: boolean;
|
|
66
73
|
/**
|
|
67
74
|
* True while the choose-organization step is performing switchTenant + showing its success
|
|
68
75
|
* interstitial. switchTenant refreshes the token, which re-enters afterAuthNavigation; this flag
|
package/auth/LoginState/state.js
CHANGED
package/index.js
CHANGED
|
@@ -219,7 +219,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
219
219
|
*/
|
|
220
220
|
|
|
221
221
|
const afterAuthNavigation = async payload => {
|
|
222
|
-
var
|
|
222
|
+
var _store$auth$tenantSel2;
|
|
223
223
|
// Once the choose-tenant step starts a switch the chooser owns navigation. Every re-entry here
|
|
224
224
|
// (the switch's token refresh, and — critically — a late or timed-out switch completing AFTER the
|
|
225
225
|
// user hit the escape hatch) must be a no-op, so navigation can't run twice or jump into the wrong
|
|
@@ -246,52 +246,73 @@ var _default = (store, api, sharedActions) => {
|
|
|
246
246
|
}); // consume: later re-entries stay suppressed
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// never re-prompted.
|
|
258
|
-
// login with magic code, try to step up, no other mfa, invalid max age, force_enroll -> logout, login with first factor, not-stepped up jwt -> navigate to step up
|
|
259
|
-
const shouldStepUp = (_window4 = window) == null ? void 0 : _window4.localStorage.getItem(_consts.SHOULD_STEP_UP_KEY);
|
|
260
|
-
const user = store.auth.user;
|
|
261
|
-
if (shouldStepUp) {
|
|
262
|
-
var _window5;
|
|
263
|
-
(_window5 = window) == null ? void 0 : _window5.localStorage.removeItem(_consts.SHOULD_STEP_UP_KEY);
|
|
264
|
-
}
|
|
265
|
-
if (stepUpUrl && shouldStepUp && !(0, _helpers3.isSteppedUp)(user)) {
|
|
266
|
-
return afterAuthNavigationUtil(actions.resetLoginState, {
|
|
267
|
-
forceStepUpUrl: stepUpUrl
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
if (await shouldRouteToChooseTenant()) {
|
|
249
|
+
// Callers expose the authenticated user in the store BEFORE this function's async gates resolve,
|
|
250
|
+
// so a host app that redirects on `user != null` (e.g. the hosted-login postlogin) would complete
|
|
251
|
+
// the flow before the choose-organization step can render. Raise `tenantChoicePending` in the same
|
|
252
|
+
// synchronous block (same store batch as the user set) so such hosts can hold, and always lower it
|
|
253
|
+
// once the gate has decided: by then either `step` is chooseTenant (the chooser now covers the
|
|
254
|
+
// hold) or the flow finalized. Written only when the integrator opted into tenant selection.
|
|
255
|
+
const tenantSelectionEnabled = ((_store$auth$tenantSel2 = store.auth.tenantSelection) == null ? void 0 : _store$auth$tenantSel2.enabled) === true;
|
|
256
|
+
if (tenantSelectionEnabled) {
|
|
271
257
|
actions.setLoginState({
|
|
272
|
-
|
|
273
|
-
loading: false
|
|
274
|
-
});
|
|
275
|
-
// Mirror the other post-auth interstitials (e.g. promptPasskeys): navigate to the login URL
|
|
276
|
-
// so the ChooseTenant step actually renders even when afterAuthNavigation is invoked from an
|
|
277
|
-
// OAuth/social callback route.
|
|
278
|
-
store.auth.onRedirectTo(store.auth.routes.loginUrl, {
|
|
279
|
-
preserveQueryParams: true
|
|
258
|
+
tenantChoicePending: true
|
|
280
259
|
});
|
|
281
|
-
return; // do NOT finalize; ChooseTenant confirm re-enters afterAuthNavigation
|
|
282
260
|
}
|
|
261
|
+
try {
|
|
262
|
+
var _window4, _payload$preventRedir;
|
|
263
|
+
const {
|
|
264
|
+
customLoginAuthenticatedUrl,
|
|
265
|
+
stepUpUrl
|
|
266
|
+
} = store.auth.routes;
|
|
267
|
+
|
|
268
|
+
// Step-up on the CURRENT tenant resolves before the org chooser: a user who needs both
|
|
269
|
+
// authenticates + steps up first, then picks an org. switchTenant handles any MFA the chosen
|
|
270
|
+
// org requires on its own, and the isSteppedUp guard below means an already-stepped-up user is
|
|
271
|
+
// never re-prompted.
|
|
272
|
+
// login with magic code, try to step up, no other mfa, invalid max age, force_enroll -> logout, login with first factor, not-stepped up jwt -> navigate to step up
|
|
273
|
+
const shouldStepUp = (_window4 = window) == null ? void 0 : _window4.localStorage.getItem(_consts.SHOULD_STEP_UP_KEY);
|
|
274
|
+
const user = store.auth.user;
|
|
275
|
+
if (shouldStepUp) {
|
|
276
|
+
var _window5;
|
|
277
|
+
(_window5 = window) == null ? void 0 : _window5.localStorage.removeItem(_consts.SHOULD_STEP_UP_KEY);
|
|
278
|
+
}
|
|
279
|
+
if (stepUpUrl && shouldStepUp && !(0, _helpers3.isSteppedUp)(user)) {
|
|
280
|
+
return await afterAuthNavigationUtil(actions.resetLoginState, {
|
|
281
|
+
forceStepUpUrl: stepUpUrl
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
if (await shouldRouteToChooseTenant()) {
|
|
285
|
+
actions.setLoginState({
|
|
286
|
+
step: _interfaces.LoginStep.chooseTenant,
|
|
287
|
+
loading: false
|
|
288
|
+
});
|
|
289
|
+
// Mirror the other post-auth interstitials (e.g. promptPasskeys): navigate to the login URL
|
|
290
|
+
// so the ChooseTenant step actually renders even when afterAuthNavigation is invoked from an
|
|
291
|
+
// OAuth/social callback route.
|
|
292
|
+
store.auth.onRedirectTo(store.auth.routes.loginUrl, {
|
|
293
|
+
preserveQueryParams: true
|
|
294
|
+
});
|
|
295
|
+
return; // do NOT finalize; ChooseTenant confirm re-enters afterAuthNavigation
|
|
296
|
+
}
|
|
283
297
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
298
|
+
let customLoginURL = customLoginAuthenticatedUrl;
|
|
299
|
+
if (!customLoginAuthenticatedUrl) {
|
|
300
|
+
var _store$auth$routes;
|
|
301
|
+
await actions.loadCustomLoginRoutes();
|
|
302
|
+
customLoginURL = (_store$auth$routes = store.auth.routes) == null ? void 0 : _store$auth$routes.customLoginAuthenticatedUrl;
|
|
303
|
+
}
|
|
304
|
+
return await afterAuthNavigationUtil(actions.resetLoginState, {
|
|
305
|
+
customLoginAuthenticatedUrl: customLoginURL,
|
|
306
|
+
shouldStepUpDuringLogin: !!shouldStepUp,
|
|
307
|
+
preventRedirectUrlOriginCleaning: (_payload$preventRedir = payload == null ? void 0 : payload.preventRedirectUrlOriginCleaning) != null ? _payload$preventRedir : false
|
|
308
|
+
});
|
|
309
|
+
} finally {
|
|
310
|
+
if (tenantSelectionEnabled) {
|
|
311
|
+
actions.setLoginState({
|
|
312
|
+
tenantChoicePending: false
|
|
313
|
+
});
|
|
314
|
+
}
|
|
289
315
|
}
|
|
290
|
-
return afterAuthNavigationUtil(actions.resetLoginState, {
|
|
291
|
-
customLoginAuthenticatedUrl: customLoginURL,
|
|
292
|
-
shouldStepUpDuringLogin: !!shouldStepUp,
|
|
293
|
-
preventRedirectUrlOriginCleaning: (_payload$preventRedir = payload == null ? void 0 : payload.preventRedirectUrlOriginCleaning) != null ? _payload$preventRedir : false
|
|
294
|
-
});
|
|
295
316
|
};
|
|
296
317
|
|
|
297
318
|
/**
|
package/node/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontegg/redux-store",
|
|
3
|
-
"version": "7.123.0
|
|
3
|
+
"version": "7.123.0",
|
|
4
4
|
"main": "./node/index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Frontegg LTD",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@babel/runtime": "^7.18.6",
|
|
9
9
|
"@frontegg/entitlements-javascript-commons": "1.1.2",
|
|
10
|
-
"@frontegg/rest-api": "7.123.0
|
|
10
|
+
"@frontegg/rest-api": "7.123.0",
|
|
11
11
|
"fast-deep-equal": "3.1.3",
|
|
12
12
|
"get-value": "^3.0.1",
|
|
13
13
|
"proxy-compare": "^3.0.0",
|