@frontegg/redux-store 6.155.0-alpha.4 → 6.155.0-alpha.6
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/sagas/afterAuthNavigation.saga.d.ts +3 -1
- package/auth/LoginState/sagas/afterAuthNavigation.saga.js +40 -12
- package/auth/LoginState/utils.d.ts +1 -0
- package/auth/LoginState/utils.js +1 -1
- package/index.js +1 -1
- package/node/auth/LoginState/sagas/afterAuthNavigation.saga.js +39 -11
- package/node/auth/LoginState/utils.js +2 -1
- package/node/index.js +1 -1
- package/package.json +1 -1
|
@@ -3,13 +3,15 @@ import { User } from '../../interfaces';
|
|
|
3
3
|
interface AfterAuthNavigationUtilOptions {
|
|
4
4
|
customLoginAuthenticatedUrl?: string;
|
|
5
5
|
forceStepUpUrl?: string;
|
|
6
|
+
shouldStepUpDuringLogin?: boolean;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Utility to share after auth navigation flow between login and step up
|
|
9
10
|
* @param resetStateAction reset state action
|
|
10
11
|
* @param customLoginAuthenticatedUrl custom login authenticated url if exists
|
|
12
|
+
* @param shouldStepUpDuringLogin true when it's login after step up flow
|
|
11
13
|
*/
|
|
12
|
-
export declare function afterAuthNavigationUtil(resetStateAction: () => Action, { customLoginAuthenticatedUrl, forceStepUpUrl }?: AfterAuthNavigationUtilOptions): Generator<import("redux-saga/effects").CallEffect<true> | import("redux-saga/effects").CallEffect<string>, void, string>;
|
|
14
|
+
export declare function afterAuthNavigationUtil(resetStateAction: () => Action, { customLoginAuthenticatedUrl, forceStepUpUrl, shouldStepUpDuringLogin }?: AfterAuthNavigationUtilOptions): Generator<import("redux-saga/effects").CallEffect<true> | import("redux-saga/effects").CallEffect<string>, void, string | undefined>;
|
|
13
15
|
/**
|
|
14
16
|
* After auth navigation for login flow
|
|
15
17
|
* Handling also step up scenario when user silently logout to continue to step up
|
|
@@ -2,11 +2,23 @@ import { ContextHolder } from '@frontegg/rest-api';
|
|
|
2
2
|
import { delay, put, select, call } from 'redux-saga/effects';
|
|
3
3
|
import { loadCustomLoginRoutes } from '../../CustomLoginState/saga';
|
|
4
4
|
import { actions } from '../../reducer';
|
|
5
|
-
import { getPathAndSearchParamsFromUrl, getRedirectUrl } from '../utils';
|
|
5
|
+
import { getPathAndSearchParamsFromUrl, getRedirectUrl, isAbsoluteUrl } from '../utils';
|
|
6
6
|
import { FRONTEGG_AFTER_AUTH_REDIRECT_URL } from '../../../constants';
|
|
7
7
|
import { isSteppedUp } from '../../StepUpState';
|
|
8
8
|
import { SHOULD_STEP_UP_KEY } from '../../StepUpState/consts';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @param url
|
|
12
|
+
* @returns url without the origin if it's the same origin as the current window origin
|
|
13
|
+
*/
|
|
14
|
+
function cleanUrlIfSameOrigin(url) {
|
|
15
|
+
var _window, _window2;
|
|
16
|
+
if (!url.startsWith((_window = window) == null ? void 0 : _window.location.origin)) {
|
|
17
|
+
return url;
|
|
18
|
+
}
|
|
19
|
+
return url.replace((_window2 = window) == null ? void 0 : _window2.location.origin, '');
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
/**
|
|
11
23
|
* @param customLoginAuthenticatedUrl custom login authenticated url if exists
|
|
12
24
|
* @returns the authenticated url to redirect to after auth navigation
|
|
@@ -32,32 +44,47 @@ function* getUrlForAfterAuthNavigation(customLoginAuthenticatedUrl) {
|
|
|
32
44
|
if (!finalUrl || [loginUrl, logoutUrl, socialLoginCallbackUrl, activateUrl].includes(finalUrl)) {
|
|
33
45
|
finalUrl = authenticatedUrl;
|
|
34
46
|
}
|
|
35
|
-
|
|
47
|
+
const redirectUrl = getRedirectUrl({
|
|
36
48
|
authenticatedUrl: finalUrl,
|
|
37
49
|
includeQueryParam,
|
|
38
50
|
enforceRedirectToSameSite,
|
|
39
51
|
allowedRedirectOrigins
|
|
40
52
|
});
|
|
53
|
+
|
|
54
|
+
// clean origin if it's the same origin as the current window origin to avoid refresh in afterAuthNavigationUtil
|
|
55
|
+
return cleanUrlIfSameOrigin(redirectUrl);
|
|
41
56
|
}
|
|
42
57
|
/**
|
|
43
58
|
* Utility to share after auth navigation flow between login and step up
|
|
44
59
|
* @param resetStateAction reset state action
|
|
45
60
|
* @param customLoginAuthenticatedUrl custom login authenticated url if exists
|
|
61
|
+
* @param shouldStepUpDuringLogin true when it's login after step up flow
|
|
46
62
|
*/
|
|
47
63
|
export function* afterAuthNavigationUtil(resetStateAction, {
|
|
48
64
|
customLoginAuthenticatedUrl,
|
|
49
|
-
forceStepUpUrl
|
|
65
|
+
forceStepUpUrl,
|
|
66
|
+
shouldStepUpDuringLogin
|
|
50
67
|
} = {}) {
|
|
51
68
|
const onRedirectTo = ContextHolder.onRedirectTo;
|
|
52
|
-
let redirectUrl;
|
|
69
|
+
let redirectUrl = undefined;
|
|
53
70
|
if (forceStepUpUrl) {
|
|
54
71
|
// scenario to get to here: invalid max age, try to step up -> logout, login with magic code/link -> redirect to step up page for email code as the second factor
|
|
55
72
|
// we don't want to remove the FRONTEGG_AFTER_AUTH_REDIRECT_URL when we are in the step up flow
|
|
56
73
|
redirectUrl = forceStepUpUrl;
|
|
57
74
|
} else {
|
|
58
|
-
var
|
|
59
|
-
|
|
60
|
-
|
|
75
|
+
var _window3;
|
|
76
|
+
if (shouldStepUpDuringLogin) {
|
|
77
|
+
// getUrlForAfterAuthNavigation give priority to the redirectUrl
|
|
78
|
+
// avoiding use of getUrlForAfterAuthNavigation because we don't want to use the redirectUrl for magic link for example
|
|
79
|
+
const localStorageRedirectUrl = window.localStorage.getItem(FRONTEGG_AFTER_AUTH_REDIRECT_URL);
|
|
80
|
+
if (localStorageRedirectUrl && !isAbsoluteUrl(localStorageRedirectUrl)) {
|
|
81
|
+
redirectUrl = localStorageRedirectUrl;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!redirectUrl) {
|
|
85
|
+
redirectUrl = yield call(getUrlForAfterAuthNavigation, customLoginAuthenticatedUrl);
|
|
86
|
+
}
|
|
87
|
+
(_window3 = window) == null ? void 0 : _window3.localStorage.removeItem(FRONTEGG_AFTER_AUTH_REDIRECT_URL);
|
|
61
88
|
}
|
|
62
89
|
yield delay(200);
|
|
63
90
|
put(resetStateAction());
|
|
@@ -71,7 +98,7 @@ export function* afterAuthNavigationUtil(resetStateAction, {
|
|
|
71
98
|
* Handling also step up scenario when user silently logout to continue to step up
|
|
72
99
|
*/
|
|
73
100
|
export function* afterAuthNavigation() {
|
|
74
|
-
var
|
|
101
|
+
var _window4;
|
|
75
102
|
const {
|
|
76
103
|
routes: {
|
|
77
104
|
customLoginAuthenticatedUrl,
|
|
@@ -80,13 +107,13 @@ export function* afterAuthNavigation() {
|
|
|
80
107
|
} = yield select(state => state.auth);
|
|
81
108
|
|
|
82
109
|
// 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
|
|
83
|
-
const shouldStepUp = (
|
|
110
|
+
const shouldStepUp = (_window4 = window) == null ? void 0 : _window4.localStorage.getItem(SHOULD_STEP_UP_KEY);
|
|
84
111
|
const user = yield select(({
|
|
85
112
|
auth
|
|
86
113
|
}) => auth.user);
|
|
87
114
|
if (shouldStepUp) {
|
|
88
|
-
var
|
|
89
|
-
(
|
|
115
|
+
var _window5;
|
|
116
|
+
(_window5 = window) == null ? void 0 : _window5.localStorage.removeItem(SHOULD_STEP_UP_KEY);
|
|
90
117
|
}
|
|
91
118
|
if (stepUpUrl && shouldStepUp && !isSteppedUp(user)) {
|
|
92
119
|
yield call(afterAuthNavigationUtil, actions.resetLoginState, {
|
|
@@ -103,7 +130,8 @@ export function* afterAuthNavigation() {
|
|
|
103
130
|
});
|
|
104
131
|
}
|
|
105
132
|
yield call(afterAuthNavigationUtil, actions.resetLoginState, {
|
|
106
|
-
customLoginAuthenticatedUrl: customLoginURL
|
|
133
|
+
customLoginAuthenticatedUrl: customLoginURL,
|
|
134
|
+
shouldStepUpDuringLogin: !!shouldStepUp
|
|
107
135
|
});
|
|
108
136
|
}
|
|
109
137
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IEmailPasswordlessPreLogin, ILoginResponse, IPasswordlessPreLogin, MFAStrategyEnum, UserMFADevicesResponse } from '@frontegg/rest-api';
|
|
2
2
|
import { MFAStep } from '../MfaState/interfaces';
|
|
3
|
+
export declare const isAbsoluteUrl: (path: string) => boolean;
|
|
3
4
|
export declare const getRedirectUrl: ({ authenticatedUrl, enforceRedirectToSameSite, allowedRedirectOrigins, includeQueryParam, }: {
|
|
4
5
|
authenticatedUrl: string;
|
|
5
6
|
enforceRedirectToSameSite: boolean;
|
package/auth/LoginState/utils.js
CHANGED
package/index.js
CHANGED
|
@@ -14,6 +14,18 @@ var _utils = require("../utils");
|
|
|
14
14
|
var _constants = require("../../../constants");
|
|
15
15
|
var _StepUpState = require("../../StepUpState");
|
|
16
16
|
var _consts = require("../../StepUpState/consts");
|
|
17
|
+
/**
|
|
18
|
+
* @param url
|
|
19
|
+
* @returns url without the origin if it's the same origin as the current window origin
|
|
20
|
+
*/
|
|
21
|
+
function cleanUrlIfSameOrigin(url) {
|
|
22
|
+
var _window, _window2;
|
|
23
|
+
if (!url.startsWith((_window = window) == null ? void 0 : _window.location.origin)) {
|
|
24
|
+
return url;
|
|
25
|
+
}
|
|
26
|
+
return url.replace((_window2 = window) == null ? void 0 : _window2.location.origin, '');
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
/**
|
|
18
30
|
* @param customLoginAuthenticatedUrl custom login authenticated url if exists
|
|
19
31
|
* @returns the authenticated url to redirect to after auth navigation
|
|
@@ -39,32 +51,47 @@ function* getUrlForAfterAuthNavigation(customLoginAuthenticatedUrl) {
|
|
|
39
51
|
if (!finalUrl || [loginUrl, logoutUrl, socialLoginCallbackUrl, activateUrl].includes(finalUrl)) {
|
|
40
52
|
finalUrl = authenticatedUrl;
|
|
41
53
|
}
|
|
42
|
-
|
|
54
|
+
const redirectUrl = (0, _utils.getRedirectUrl)({
|
|
43
55
|
authenticatedUrl: finalUrl,
|
|
44
56
|
includeQueryParam,
|
|
45
57
|
enforceRedirectToSameSite,
|
|
46
58
|
allowedRedirectOrigins
|
|
47
59
|
});
|
|
60
|
+
|
|
61
|
+
// clean origin if it's the same origin as the current window origin to avoid refresh in afterAuthNavigationUtil
|
|
62
|
+
return cleanUrlIfSameOrigin(redirectUrl);
|
|
48
63
|
}
|
|
49
64
|
/**
|
|
50
65
|
* Utility to share after auth navigation flow between login and step up
|
|
51
66
|
* @param resetStateAction reset state action
|
|
52
67
|
* @param customLoginAuthenticatedUrl custom login authenticated url if exists
|
|
68
|
+
* @param shouldStepUpDuringLogin true when it's login after step up flow
|
|
53
69
|
*/
|
|
54
70
|
function* afterAuthNavigationUtil(resetStateAction, {
|
|
55
71
|
customLoginAuthenticatedUrl,
|
|
56
|
-
forceStepUpUrl
|
|
72
|
+
forceStepUpUrl,
|
|
73
|
+
shouldStepUpDuringLogin
|
|
57
74
|
} = {}) {
|
|
58
75
|
const onRedirectTo = _restApi.ContextHolder.onRedirectTo;
|
|
59
|
-
let redirectUrl;
|
|
76
|
+
let redirectUrl = undefined;
|
|
60
77
|
if (forceStepUpUrl) {
|
|
61
78
|
// scenario to get to here: invalid max age, try to step up -> logout, login with magic code/link -> redirect to step up page for email code as the second factor
|
|
62
79
|
// we don't want to remove the FRONTEGG_AFTER_AUTH_REDIRECT_URL when we are in the step up flow
|
|
63
80
|
redirectUrl = forceStepUpUrl;
|
|
64
81
|
} else {
|
|
65
|
-
var
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
var _window3;
|
|
83
|
+
if (shouldStepUpDuringLogin) {
|
|
84
|
+
// getUrlForAfterAuthNavigation give priority to the redirectUrl
|
|
85
|
+
// avoiding use of getUrlForAfterAuthNavigation because we don't want to use the redirectUrl for magic link for example
|
|
86
|
+
const localStorageRedirectUrl = window.localStorage.getItem(_constants.FRONTEGG_AFTER_AUTH_REDIRECT_URL);
|
|
87
|
+
if (localStorageRedirectUrl && !(0, _utils.isAbsoluteUrl)(localStorageRedirectUrl)) {
|
|
88
|
+
redirectUrl = localStorageRedirectUrl;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (!redirectUrl) {
|
|
92
|
+
redirectUrl = yield (0, _effects.call)(getUrlForAfterAuthNavigation, customLoginAuthenticatedUrl);
|
|
93
|
+
}
|
|
94
|
+
(_window3 = window) == null ? void 0 : _window3.localStorage.removeItem(_constants.FRONTEGG_AFTER_AUTH_REDIRECT_URL);
|
|
68
95
|
}
|
|
69
96
|
yield (0, _effects.delay)(200);
|
|
70
97
|
(0, _effects.put)(resetStateAction());
|
|
@@ -78,7 +105,7 @@ function* afterAuthNavigationUtil(resetStateAction, {
|
|
|
78
105
|
* Handling also step up scenario when user silently logout to continue to step up
|
|
79
106
|
*/
|
|
80
107
|
function* afterAuthNavigation() {
|
|
81
|
-
var
|
|
108
|
+
var _window4;
|
|
82
109
|
const {
|
|
83
110
|
routes: {
|
|
84
111
|
customLoginAuthenticatedUrl,
|
|
@@ -87,13 +114,13 @@ function* afterAuthNavigation() {
|
|
|
87
114
|
} = yield (0, _effects.select)(state => state.auth);
|
|
88
115
|
|
|
89
116
|
// 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
|
|
90
|
-
const shouldStepUp = (
|
|
117
|
+
const shouldStepUp = (_window4 = window) == null ? void 0 : _window4.localStorage.getItem(_consts.SHOULD_STEP_UP_KEY);
|
|
91
118
|
const user = yield (0, _effects.select)(({
|
|
92
119
|
auth
|
|
93
120
|
}) => auth.user);
|
|
94
121
|
if (shouldStepUp) {
|
|
95
|
-
var
|
|
96
|
-
(
|
|
122
|
+
var _window5;
|
|
123
|
+
(_window5 = window) == null ? void 0 : _window5.localStorage.removeItem(_consts.SHOULD_STEP_UP_KEY);
|
|
97
124
|
}
|
|
98
125
|
if (stepUpUrl && shouldStepUp && !(0, _StepUpState.isSteppedUp)(user)) {
|
|
99
126
|
yield (0, _effects.call)(afterAuthNavigationUtil, _reducer.actions.resetLoginState, {
|
|
@@ -110,7 +137,8 @@ function* afterAuthNavigation() {
|
|
|
110
137
|
});
|
|
111
138
|
}
|
|
112
139
|
yield (0, _effects.call)(afterAuthNavigationUtil, _reducer.actions.resetLoginState, {
|
|
113
|
-
customLoginAuthenticatedUrl: customLoginURL
|
|
140
|
+
customLoginAuthenticatedUrl: customLoginURL,
|
|
141
|
+
shouldStepUpDuringLogin: !!shouldStepUp
|
|
114
142
|
});
|
|
115
143
|
}
|
|
116
144
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getSearchParamsFromUrl = exports.getSearchParam = exports.getRedirectUrl = exports.getPathAndSearchParamsFromUrl = exports.getNumberOfMfaDevices = exports.getMfaStepForNotEnrolledUsers = exports.getMfaStepForEnrolledUsers = exports.TENANT_ID_PARAM_KEY = void 0;
|
|
6
|
+
exports.isAbsoluteUrl = exports.getSearchParamsFromUrl = exports.getSearchParam = exports.getRedirectUrl = exports.getPathAndSearchParamsFromUrl = exports.getNumberOfMfaDevices = exports.getMfaStepForNotEnrolledUsers = exports.getMfaStepForEnrolledUsers = exports.TENANT_ID_PARAM_KEY = void 0;
|
|
7
7
|
exports.isEmailPayload = isEmailPayload;
|
|
8
8
|
exports.isOauthCallbackRoute = exports.isMfaRequired = void 0;
|
|
9
9
|
var _restApi = require("@frontegg/rest-api");
|
|
@@ -16,6 +16,7 @@ const isAbsoluteUrl = path => {
|
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
+
exports.isAbsoluteUrl = isAbsoluteUrl;
|
|
19
20
|
const isValidRedirectUrl = (redirectUrl, allowedRedirectOrigins) => {
|
|
20
21
|
const currentUrl = new URL(window.location.href);
|
|
21
22
|
const redirectURL = new URL(redirectUrl);
|
package/node/index.js
CHANGED