@truedat/auth 7.5.9 → 7.5.10
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/package.json +40 -64
- package/src/groups/components/EditGroup.js +0 -1
- package/src/groups/components/Group.js +0 -1
- package/src/groups/components/GroupBreadcrumbs.js +1 -2
- package/src/groups/components/GroupCard.js +3 -3
- package/src/groups/components/GroupCards.js +2 -3
- package/src/groups/components/GroupForm.js +0 -1
- package/src/groups/components/GroupLoader.js +19 -51
- package/src/groups/components/GroupUsers.js +4 -3
- package/src/groups/components/GroupUsersTable.js +4 -4
- package/src/groups/components/GroupsLoader.js +2 -2
- package/src/groups/components/GroupsSearchLoader.js +1 -1
- package/src/groups/components/NewGroup.js +0 -1
- package/src/groups/components/__tests__/Group.spec.js +0 -1
- package/src/groups/components/__tests__/GroupCard.spec.js +23 -7
- package/src/groups/components/__tests__/GroupCards.spec.js +9 -6
- package/src/groups/components/__tests__/GroupLoader.spec.js +71 -0
- package/src/groups/components/__tests__/GroupUsers.spec.js +8 -12
- package/src/groups/components/__tests__/GroupUsersTable.spec.js +34 -42
- package/src/groups/components/__tests__/GroupsSearchLoader.spec.js +0 -1
- package/src/groups/components/__tests__/__snapshots__/Group.spec.js.snap +1 -2
- package/src/groups/components/__tests__/__snapshots__/GroupCard.spec.js.snap +43 -94
- package/src/groups/components/__tests__/__snapshots__/GroupCards.spec.js.snap +118 -53
- package/src/groups/components/__tests__/__snapshots__/GroupLoader.spec.js.snap +11 -0
- package/src/groups/components/__tests__/__snapshots__/GroupUsers.spec.js.snap +38 -45
- package/src/groups/components/__tests__/__snapshots__/GroupUsersTable.spec.js.snap +121 -213
- package/src/groups/components/index.js +1 -1
- package/src/groups/sagas/__tests__/deleteGroupUser.spec.js +6 -6
- package/src/groups/sagas/deleteGroup.js +1 -1
- package/src/groups/sagas/deleteGroupUser.js +2 -2
- package/src/groups/sagas/fetchGroup.js +1 -1
- package/src/groups/sagas/updateGroup.js +1 -1
- package/src/roles/components/NewRole.js +0 -1
- package/src/roles/components/PermissionGroup.js +0 -1
- package/src/roles/components/Role.js +8 -3
- package/src/roles/components/RoleCards.js +2 -3
- package/src/roles/components/RoleForm.js +1 -1
- package/src/roles/components/RoleLoader.js +26 -39
- package/src/roles/components/RoleRoutes.js +29 -32
- package/src/roles/components/RoleSelector.js +0 -1
- package/src/roles/components/Roles.js +1 -3
- package/src/roles/components/RolesLoader.js +2 -2
- package/src/roles/components/__tests__/PermissionGroup.spec.js +7 -17
- package/src/roles/components/__tests__/Role.spec.js +0 -1
- package/src/roles/components/__tests__/RoleCards.spec.js +11 -10
- package/src/roles/components/__tests__/RoleRoutes.spec.js +53 -7
- package/src/roles/components/__tests__/RoleSelector.spec.js +0 -1
- package/src/roles/components/__tests__/Roles.spec.js +2 -3
- package/src/roles/components/__tests__/__snapshots__/PermissionGroup.spec.js.snap +3 -5
- package/src/roles/components/__tests__/__snapshots__/Role.spec.js.snap +4 -4
- package/src/roles/components/__tests__/__snapshots__/RoleCards.spec.js.snap +57 -127
- package/src/roles/components/__tests__/__snapshots__/RoleRoutes.spec.js.snap +38 -5
- package/src/roles/components/__tests__/__snapshots__/RoleSelector.spec.js.snap +1 -1
- package/src/roles/components/__tests__/__snapshots__/Roles.spec.js.snap +6 -3
- package/src/roles/components/index.js +1 -1
- package/src/roles/reducers/rolePermissions.js +1 -1
- package/src/roles/reducers/roleRedirect.js +1 -1
- package/src/roles/sagas/deleteRole.js +1 -1
- package/src/roles/sagas/fetchRole.js +1 -1
- package/src/roles/sagas/fetchRolePermissions.js +1 -1
- package/src/roles/sagas/updateRole.js +1 -1
- package/src/roles/sagas/updateRolePermissions.js +1 -1
- package/src/sessions/components/Auth0Callback.js +5 -4
- package/src/sessions/components/Auth0LoginButton.js +2 -2
- package/src/sessions/components/AuthMethodsLoader.js +10 -19
- package/src/sessions/components/LoginButtons.js +4 -4
- package/src/sessions/components/NonceCallback.js +21 -38
- package/src/sessions/components/OidcLoginButton.js +0 -1
- package/src/sessions/components/OpenIDConnect.js +5 -4
- package/src/sessions/components/PrivateRoute.js +25 -57
- package/src/sessions/components/ProxyLoginCallback.js +0 -2
- package/src/sessions/components/SamlCallback.js +0 -2
- package/src/sessions/components/UnauthorizedRoute.js +28 -31
- package/src/sessions/components/__tests__/Auth0LoginButton.spec.js +12 -12
- package/src/sessions/components/__tests__/AuthMethodsLoader.spec.js +15 -12
- package/src/sessions/components/__tests__/NonceCallback.spec.js +84 -0
- package/src/sessions/components/__tests__/OidcLoginButton.spec.js +10 -10
- package/src/sessions/components/__tests__/OpenIDConnect.spec.js +7 -8
- package/src/sessions/components/__tests__/PrivateRoute.spec.js +90 -0
- package/src/sessions/components/__tests__/UnauthorizedRoute.spec.js +88 -0
- package/src/sessions/components/__tests__/__snapshots__/Auth0LoginButton.spec.js.snap +22 -24
- package/src/sessions/components/__tests__/__snapshots__/NonceCallback.spec.js.snap +18 -0
- package/src/sessions/components/__tests__/__snapshots__/OidcLoginButton.spec.js.snap +18 -18
- package/src/sessions/components/__tests__/__snapshots__/PrivateRoute.spec.js.snap +9 -0
- package/src/sessions/components/__tests__/__snapshots__/UnauthorizedRoute.spec.js.snap +9 -0
- package/src/sessions/components/index.js +1 -1
- package/src/sessions/sagas/__tests__/login.spec.js +4 -4
- package/src/sessions/sagas/__tests__/refresh.spec.js +2 -2
- package/src/sessions/sagas/__tests__/token.spec.js +4 -4
- package/src/sessions/sagas/login.js +5 -5
- package/src/sessions/sagas/refresh.js +2 -2
- package/src/sessions/sagas/token.js +2 -2
- package/src/users/components/AdminUserRoutes.js +35 -51
- package/src/users/components/EditUser.js +0 -1
- package/src/users/components/GroupUserCrumbs.js +8 -8
- package/src/users/components/InitialUser.js +0 -1
- package/src/users/components/NewUser.js +0 -1
- package/src/users/components/Password.js +0 -1
- package/src/users/components/User.js +2 -2
- package/src/users/components/UserAclRow.js +1 -2
- package/src/users/components/UserAcls.js +0 -1
- package/src/users/components/UserActions.js +1 -2
- package/src/users/components/UserBreadcrumbs.js +2 -3
- package/src/users/components/UserCard.js +3 -3
- package/src/users/components/UserCards.js +5 -4
- package/src/users/components/UserDomainsFilter.js +2 -5
- package/src/users/components/UserForm.js +8 -33
- package/src/users/components/UserGroupAclRow.js +1 -2
- package/src/users/components/UserGroupAcls.js +0 -1
- package/src/users/components/UserLoader.js +21 -48
- package/src/users/components/UserPassword.js +0 -1
- package/src/users/components/UserRoutes.js +73 -7
- package/src/users/components/UserSelector.js +0 -1
- package/src/users/components/UserTabs.js +1 -2
- package/src/users/components/UsersAndGroups.js +6 -6
- package/src/users/components/UsersLoader.js +2 -2
- package/src/users/components/UsersSearchLoader.js +2 -1
- package/src/users/components/__tests__/CanInitLoader.spec.js +6 -13
- package/src/users/components/__tests__/EditUser.spec.js +4 -33
- package/src/users/components/__tests__/InitialUser.spec.js +4 -34
- package/src/users/components/__tests__/NewUser.spec.js +4 -35
- package/src/users/components/__tests__/Password.spec.js +59 -69
- package/src/users/components/__tests__/User.spec.js +1 -2
- package/src/users/components/__tests__/UserAclRow.spec.js +5 -7
- package/src/users/components/__tests__/UserAcls.spec.js +8 -9
- package/src/users/components/__tests__/UserActions.spec.js +4 -5
- package/src/users/components/__tests__/UserCard.spec.js +11 -11
- package/src/users/components/__tests__/UserCards.spec.js +39 -31
- package/src/users/components/__tests__/UserDomainsFilter.spec.js +12 -22
- package/src/users/components/__tests__/UserForm.spec.js +24 -44
- package/src/users/components/__tests__/UserGroupAclRow.spec.js +1 -2
- package/src/users/components/__tests__/UserGroupAcls.spec.js +8 -9
- package/src/users/components/__tests__/UserLoader.spec.js +85 -0
- package/src/users/components/__tests__/UserPassword.spec.js +8 -21
- package/src/users/components/__tests__/UserRoutes.spec.js +129 -4
- package/src/users/components/__tests__/UserSelector.spec.js +0 -1
- package/src/users/components/__tests__/UsersAndGroups.spec.js +45 -5
- package/src/users/components/__tests__/UsersSearchLoader.spec.js +0 -1
- package/src/users/components/__tests__/__snapshots__/EditUser.spec.js.snap +23 -21
- package/src/users/components/__tests__/__snapshots__/InitialUser.spec.js.snap +22 -21
- package/src/users/components/__tests__/__snapshots__/NewUser.spec.js.snap +25 -23
- package/src/users/components/__tests__/__snapshots__/Password.spec.js.snap +8 -7
- package/src/users/components/__tests__/__snapshots__/User.spec.js.snap +7 -6
- package/src/users/components/__tests__/__snapshots__/UserAclRow.spec.js.snap +12 -11
- package/src/users/components/__tests__/__snapshots__/UserActions.spec.js.snap +56 -67
- package/src/users/components/__tests__/__snapshots__/UserCard.spec.js.snap +56 -70
- package/src/users/components/__tests__/__snapshots__/UserCards.spec.js.snap +117 -83
- package/src/users/components/__tests__/__snapshots__/UserDomainsFilter.spec.js.snap +2 -2
- package/src/users/components/__tests__/__snapshots__/UserForm.spec.js.snap +21 -20
- package/src/users/components/__tests__/__snapshots__/UserLoader.spec.js.snap +3 -0
- package/src/users/components/__tests__/__snapshots__/UserPassword.spec.js.snap +9 -7
- package/src/users/components/__tests__/__snapshots__/UserRoutes.spec.js.snap +170 -16
- package/src/users/components/__tests__/__snapshots__/UserSelector.spec.js.snap +1 -1
- package/src/users/components/__tests__/__snapshots__/UsersAndGroups.spec.js.snap +75 -14
- package/src/users/sagas/__tests__/fetchUser.spec.js +3 -5
- package/src/users/sagas/__tests__/updateUser.spec.js +1 -1
- package/src/users/sagas/deleteUser.js +1 -1
- package/src/users/sagas/fetchUser.js +1 -1
- package/src/users/sagas/updateUser.js +1 -1
- package/src/users/components/__tests__/__snapshots__/CanInitLoader.spec.js.snap +0 -3
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import
|
|
2
|
+
import { useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
|
-
import { useLocation
|
|
5
|
+
import { useLocation } from "react-router";
|
|
6
|
+
import { Navigate } from "react-router";
|
|
6
7
|
import auth0 from "auth0-js";
|
|
7
8
|
import { Loading } from "@truedat/core/components";
|
|
8
9
|
import queryString from "query-string";
|
|
@@ -41,9 +42,9 @@ export const CallbackOrRedirect = ({
|
|
|
41
42
|
}, [token, auth0Config, auth0Login, location.hash]);
|
|
42
43
|
|
|
43
44
|
if (token) {
|
|
44
|
-
return <
|
|
45
|
+
return <Navigate to={to} />;
|
|
45
46
|
} else if (authRedirect) {
|
|
46
|
-
return <
|
|
47
|
+
return <Navigate to={authRedirect} />;
|
|
47
48
|
} else {
|
|
48
49
|
return <Loading size="massive" />;
|
|
49
50
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import
|
|
2
|
+
import { Component } from "react";
|
|
3
3
|
import auth0 from "auth0-js";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
import { connect } from "react-redux";
|
|
6
6
|
import { FormattedMessage } from "react-intl";
|
|
7
7
|
|
|
8
|
-
export class Auth0LoginButton extends
|
|
8
|
+
export class Auth0LoginButton extends Component {
|
|
9
9
|
static propTypes = {
|
|
10
10
|
icon: PropTypes.string,
|
|
11
11
|
};
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { withRouter } from "react-router-dom";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { useDispatch } from "react-redux";
|
|
4
|
+
import { useLocation } from "react-router";
|
|
6
5
|
import { fetchAuthMethods } from "../routines";
|
|
7
6
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
7
|
+
export default function AuthMethodsLoader() {
|
|
8
|
+
const location = useLocation();
|
|
9
|
+
const dispatch = useDispatch();
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
fetchAuthMethods(location);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
dispatch(fetchAuthMethods(location));
|
|
13
|
+
}, [dispatch, location]);
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
return null;
|
|
21
16
|
}
|
|
22
|
-
|
|
23
|
-
export default connect(() => ({}), { fetchAuthMethods })(
|
|
24
|
-
withRouter(AuthMethodsLoader)
|
|
25
|
-
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import
|
|
2
|
+
import { Component } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
5
|
import { FormattedMessage } from "react-intl";
|
|
@@ -16,7 +16,7 @@ const toButton = ([method, url], i) => (
|
|
|
16
16
|
</a>
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
export class LoginButtons extends
|
|
19
|
+
export class LoginButtons extends Component {
|
|
20
20
|
render() {
|
|
21
21
|
const { authMethods } = this.props;
|
|
22
22
|
return _.isEmpty(authMethods)
|
|
@@ -26,11 +26,11 @@ export class LoginButtons extends React.Component {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
LoginButtons.propTypes = {
|
|
29
|
-
authMethods: PropTypes.object
|
|
29
|
+
authMethods: PropTypes.object,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
const mapStateToProps = ({ authMethods }) => ({
|
|
33
|
-
authMethods
|
|
33
|
+
authMethods,
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
export default connect(mapStateToProps)(LoginButtons);
|
|
@@ -1,49 +1,32 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { withRouter, Redirect } from "react-router-dom";
|
|
3
|
+
import { useLocation, Navigate } from "react-router";
|
|
4
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
6
5
|
import queryString from "query-string";
|
|
7
6
|
import { Loading } from "@truedat/core/components";
|
|
8
7
|
import { nonceLogin } from "../routines";
|
|
9
8
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
location: PropTypes.object,
|
|
16
|
-
nonceLogin: PropTypes.func,
|
|
17
|
-
};
|
|
9
|
+
export default function NonceCallback({ authMethod }) {
|
|
10
|
+
const dispatch = useDispatch();
|
|
11
|
+
const location = useLocation();
|
|
12
|
+
const authentication = useSelector((state) => state.authentication);
|
|
13
|
+
const authRedirect = useSelector((state) => state.authRedirect);
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
const {
|
|
21
|
-
location: { hash },
|
|
22
|
-
nonceLogin,
|
|
23
|
-
authMethod,
|
|
24
|
-
} = this.props;
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const { hash } = location;
|
|
25
17
|
const opts = queryString.parse(hash);
|
|
26
|
-
nonceLogin({ ...opts, auth_realm: authMethod });
|
|
27
|
-
}
|
|
18
|
+
dispatch(nonceLogin({ ...opts, auth_realm: authMethod }));
|
|
19
|
+
}, [location, dispatch, authMethod]);
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} else {
|
|
36
|
-
return <Loading size="massive" />;
|
|
37
|
-
}
|
|
21
|
+
if (authentication?.token) {
|
|
22
|
+
return <Navigate to="/" />;
|
|
23
|
+
} else if (authRedirect) {
|
|
24
|
+
return <Navigate to={authRedirect} />;
|
|
25
|
+
} else {
|
|
26
|
+
return <Loading size="massive" />;
|
|
38
27
|
}
|
|
39
28
|
}
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export default compose(
|
|
47
|
-
withRouter,
|
|
48
|
-
connect(mapStateToProps, { nonceLogin })
|
|
49
|
-
)(NonceCallback);
|
|
30
|
+
NonceCallback.propTypes = {
|
|
31
|
+
authMethod: PropTypes.string,
|
|
32
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import
|
|
2
|
+
import { useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import queryString from "query-string";
|
|
5
5
|
import { connect } from "react-redux";
|
|
6
|
-
import {
|
|
6
|
+
import { useLocation } from "react-router";
|
|
7
|
+
import { Navigate } from "react-router";
|
|
7
8
|
import { Loading } from "@truedat/core/components";
|
|
8
9
|
import { SEARCH } from "@truedat/core/routes";
|
|
9
10
|
import { openIdLogin } from "../routines";
|
|
@@ -27,9 +28,9 @@ export const OpenIDConnect = ({
|
|
|
27
28
|
}, [authentication, openIdLogin, opts]);
|
|
28
29
|
|
|
29
30
|
if (authentication?.token) {
|
|
30
|
-
return <
|
|
31
|
+
return <Navigate to={to} />;
|
|
31
32
|
} else if (authRedirect) {
|
|
32
|
-
return <
|
|
33
|
+
return <Navigate to={authRedirect} />;
|
|
33
34
|
} else {
|
|
34
35
|
return <Loading size="massive" />;
|
|
35
36
|
}
|
|
@@ -1,69 +1,37 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { useLocation } from "react-router";
|
|
5
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
6
|
+
import { Navigate } from "react-router";
|
|
7
7
|
import { LOGIN, UNAUTHORIZED } from "@truedat/core/routes";
|
|
8
8
|
import { retrieveToken } from "../routines";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
10
|
+
function PrivateRoute({ component: Component }) {
|
|
11
|
+
const dispatch = useDispatch();
|
|
12
|
+
const location = useLocation();
|
|
13
|
+
const { token, hasPermissions } = useSelector(({ authentication }) => ({
|
|
14
|
+
token: authentication.token,
|
|
15
|
+
hasPermissions: !_.isEmpty(authentication.entitlements),
|
|
16
|
+
}));
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
const { token, retrieveToken } = this.props;
|
|
18
|
+
useEffect(() => {
|
|
21
19
|
if (token === undefined) {
|
|
22
|
-
retrieveToken();
|
|
20
|
+
dispatch(retrieveToken());
|
|
23
21
|
}
|
|
24
|
-
}
|
|
22
|
+
}, [token, dispatch]);
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} = this.props;
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<Route
|
|
37
|
-
{...rest}
|
|
38
|
-
render={(props) => {
|
|
39
|
-
if (token && !hasPermissions) {
|
|
40
|
-
return (
|
|
41
|
-
<Redirect
|
|
42
|
-
to={{
|
|
43
|
-
pathname: UNAUTHORIZED,
|
|
44
|
-
state: { from: location },
|
|
45
|
-
}}
|
|
46
|
-
/>
|
|
47
|
-
);
|
|
48
|
-
} else if (token) {
|
|
49
|
-
return <Component {...props} />;
|
|
50
|
-
} else {
|
|
51
|
-
return (
|
|
52
|
-
<Redirect to={{ pathname: LOGIN, state: { from: location } }} />
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}}
|
|
56
|
-
/>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
24
|
+
return token && !hasPermissions ? (
|
|
25
|
+
<Navigate to={{ pathname: UNAUTHORIZED }} state={{ from: location }} />
|
|
26
|
+
) : token ? (
|
|
27
|
+
<Component />
|
|
28
|
+
) : (
|
|
29
|
+
<Navigate to={{ pathname: LOGIN }} state={{ from: location }} />
|
|
30
|
+
);
|
|
59
31
|
}
|
|
60
32
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
33
|
+
PrivateRoute.propTypes = {
|
|
34
|
+
component: PropTypes.func,
|
|
35
|
+
};
|
|
65
36
|
|
|
66
|
-
export default
|
|
67
|
-
withRouter,
|
|
68
|
-
connect(mapStateToProps, { retrieveToken })
|
|
69
|
-
)(PrivateRoute);
|
|
37
|
+
export default PrivateRoute;
|
|
@@ -1,45 +1,42 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
5
|
-
import { Route,
|
|
4
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
5
|
+
import { Routes, Route, Navigate } from "react-router";
|
|
6
6
|
import { LOGIN } from "@truedat/core/routes";
|
|
7
7
|
import { retrieveToken } from "../routines";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
9
|
+
function UnauthorizedRoute({ component: Component, path = "/" }) {
|
|
10
|
+
const dispatch = useDispatch();
|
|
11
|
+
const { token, hasPermissions } = useSelector(({ authentication }) => ({
|
|
12
|
+
token: authentication.token,
|
|
13
|
+
hasPermissions: !_.isEmpty(authentication.entitlements),
|
|
14
|
+
}));
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
const { token, retrieveToken } = this.props;
|
|
16
|
+
useEffect(() => {
|
|
19
17
|
if (token === undefined) {
|
|
20
|
-
retrieveToken();
|
|
18
|
+
dispatch(retrieveToken());
|
|
21
19
|
}
|
|
22
|
-
}
|
|
20
|
+
}, [token, dispatch]);
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return (
|
|
22
|
+
return (
|
|
23
|
+
<Routes>
|
|
27
24
|
<Route
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
path={path}
|
|
26
|
+
element={
|
|
27
|
+
token && !hasPermissions ? (
|
|
28
|
+
<Component />
|
|
29
|
+
) : (
|
|
30
|
+
<Navigate to={{ pathname: LOGIN }} />
|
|
31
|
+
)
|
|
32
|
+
}
|
|
35
33
|
/>
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
</Routes>
|
|
35
|
+
);
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
38
|
+
UnauthorizedRoute.propTypes = {
|
|
39
|
+
component: PropTypes.func,
|
|
40
|
+
};
|
|
44
41
|
|
|
45
|
-
export default
|
|
42
|
+
export default UnauthorizedRoute;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { shallow } from "enzyme";
|
|
1
|
+
import { render } from "@truedat/test/render";
|
|
3
2
|
import { Auth0LoginButton } from "../Auth0LoginButton";
|
|
4
3
|
|
|
5
4
|
describe("<Auth0LoginButton />", () => {
|
|
6
5
|
const auth0_config = {
|
|
7
|
-
domain: "0"
|
|
6
|
+
domain: "0",
|
|
8
7
|
};
|
|
9
|
-
const invalid_auth0_config = {};
|
|
10
8
|
const icon = "user icon";
|
|
11
9
|
|
|
12
|
-
it("matches the latest snapshot", () => {
|
|
10
|
+
it("matches the latest snapshot with custom icon", async () => {
|
|
13
11
|
const props = { auth0_config, icon };
|
|
14
|
-
const
|
|
15
|
-
expect(
|
|
16
|
-
expect(
|
|
12
|
+
const rendered = render(<Auth0LoginButton {...props} />);
|
|
13
|
+
expect(rendered.container).toMatchSnapshot();
|
|
14
|
+
expect(rendered.container.querySelector("i.user.icon")).toBeInTheDocument();
|
|
17
15
|
});
|
|
18
16
|
|
|
19
|
-
it("matches the latest snapshot with a default icon", () => {
|
|
17
|
+
it("matches the latest snapshot with a default icon", async () => {
|
|
20
18
|
const props = { auth0_config };
|
|
21
|
-
const
|
|
22
|
-
expect(
|
|
23
|
-
expect(
|
|
19
|
+
const rendered = render(<Auth0LoginButton {...props} />);
|
|
20
|
+
expect(rendered.container).toMatchSnapshot();
|
|
21
|
+
expect(
|
|
22
|
+
rendered.container.querySelector("i.sign-in.icon")
|
|
23
|
+
).toBeInTheDocument();
|
|
24
24
|
});
|
|
25
25
|
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { render } from "@truedat/test/render";
|
|
2
|
+
import AuthMethodsLoader from "../AuthMethodsLoader";
|
|
3
|
+
|
|
4
|
+
jest.mock("react-router", () => ({
|
|
5
|
+
...jest.requireActual("react-router"),
|
|
6
|
+
useLocation: jest.fn().mockReturnValue({}),
|
|
7
|
+
}));
|
|
4
8
|
|
|
5
9
|
describe("<AuthMethodsLoader />", () => {
|
|
6
|
-
it("triggers fetchAuthMethods on mount", () => {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
).
|
|
14
|
-
expect(fetchAuthMethods.mock.calls.length).toBe(1);
|
|
10
|
+
it("triggers fetchAuthMethods on mount", async () => {
|
|
11
|
+
const dispatch = jest.fn();
|
|
12
|
+
const rendered = render(<AuthMethodsLoader />, {
|
|
13
|
+
dispatch,
|
|
14
|
+
fallback: false,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
expect(dispatch).toHaveBeenCalledTimes(1);
|
|
15
18
|
});
|
|
16
19
|
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
+
import queryString from "query-string";
|
|
4
|
+
import NonceCallback from "../NonceCallback";
|
|
5
|
+
import { nonceLogin } from "../../routines";
|
|
6
|
+
|
|
7
|
+
jest.mock("react-router", () => ({
|
|
8
|
+
...jest.requireActual("react-router"),
|
|
9
|
+
useLocation: jest.fn().mockReturnValue({ hash: "#token=test-token" }),
|
|
10
|
+
Navigate: jest
|
|
11
|
+
.fn()
|
|
12
|
+
.mockImplementation(({ to }) => <div>Navigate to {to}</div>),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock("query-string", () => ({
|
|
16
|
+
parse: jest.fn().mockReturnValue({ token: "test-token" }),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe("<NonceCallback />", () => {
|
|
20
|
+
it("matches the latest snapshot", async () => {
|
|
21
|
+
const rendered = render(<NonceCallback authMethod="test-method" />, {
|
|
22
|
+
state: {
|
|
23
|
+
authentication: {
|
|
24
|
+
token: "valid-token",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
await waitForLoad(rendered);
|
|
29
|
+
expect(rendered.container).toMatchSnapshot();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("dispatches nonceLogin with parsed hash and auth method", async () => {
|
|
33
|
+
const mockDispatch = jest.fn();
|
|
34
|
+
const rendered = render(<NonceCallback authMethod="test-method" />, {
|
|
35
|
+
dispatch: mockDispatch,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
expect(queryString.parse).toHaveBeenCalledWith("#token=test-token");
|
|
39
|
+
expect(mockDispatch).toHaveBeenCalledWith(
|
|
40
|
+
nonceLogin({ token: "test-token", auth_realm: "test-method" })
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("navigates to root when token exists", async () => {
|
|
45
|
+
const rendered = render(<NonceCallback authMethod="test-method" />, {
|
|
46
|
+
state: {
|
|
47
|
+
authentication: {
|
|
48
|
+
token: "valid-token",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
await waitForLoad(rendered);
|
|
53
|
+
|
|
54
|
+
expect(rendered.getByText(/navigate to \//i)).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("navigates to authRedirect when it exists", async () => {
|
|
58
|
+
const rendered = render(<NonceCallback authMethod="test-method" />, {
|
|
59
|
+
state: {
|
|
60
|
+
authentication: {
|
|
61
|
+
token: null,
|
|
62
|
+
},
|
|
63
|
+
authRedirect: "/redirect-path",
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
await waitForLoad(rendered);
|
|
67
|
+
|
|
68
|
+
expect(
|
|
69
|
+
rendered.getByText(/navigate to \/redirect-path/i)
|
|
70
|
+
).toBeInTheDocument();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("shows loading when no token or redirect exists", async () => {
|
|
74
|
+
const rendered = render(<NonceCallback authMethod="test-method" />, {
|
|
75
|
+
state: {
|
|
76
|
+
authentication: {
|
|
77
|
+
token: null,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
expect(rendered.container).toMatchSnapshot();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { shallow } from "enzyme";
|
|
1
|
+
import { render } from "@truedat/test/render";
|
|
3
2
|
import { OidcLoginButton } from "../OidcLoginButton";
|
|
4
3
|
|
|
5
4
|
describe("<OidcLoginButton />", () => {
|
|
6
5
|
const url = "https://auth.oidc.org/authorize?foo=bar";
|
|
7
|
-
const icon = "google icon";
|
|
8
6
|
|
|
9
|
-
it("matches the latest snapshot", () => {
|
|
10
|
-
const props = { url
|
|
11
|
-
const
|
|
12
|
-
expect(
|
|
7
|
+
it("matches the latest snapshot with custom icon", async () => {
|
|
8
|
+
const props = { url };
|
|
9
|
+
const rendered = render(<OidcLoginButton {...props} />);
|
|
10
|
+
expect(rendered.container).toMatchSnapshot();
|
|
13
11
|
});
|
|
14
12
|
|
|
15
|
-
it("matches the latest snapshot with a default icon", () => {
|
|
13
|
+
it("matches the latest snapshot with a default icon", async () => {
|
|
16
14
|
const props = { url };
|
|
17
|
-
const
|
|
18
|
-
expect(
|
|
15
|
+
const rendered = render(<OidcLoginButton {...props} />);
|
|
16
|
+
expect(rendered.container).toMatchSnapshot();
|
|
17
|
+
|
|
18
|
+
expect(rendered.container.querySelector("a")).toBeInTheDocument();
|
|
19
19
|
});
|
|
20
20
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { render } from "@truedat/test/render";
|
|
3
2
|
import { waitFor } from "@testing-library/react";
|
|
4
3
|
import OpenIDConnect from "../OpenIDConnect";
|
|
@@ -6,27 +5,27 @@ import OpenIDConnect from "../OpenIDConnect";
|
|
|
6
5
|
const landingUrl = "/landingUrl";
|
|
7
6
|
const authentication = { token: "token" };
|
|
8
7
|
|
|
9
|
-
jest.mock("react-router
|
|
10
|
-
...jest.requireActual("react-router
|
|
11
|
-
|
|
8
|
+
jest.mock("react-router", () => ({
|
|
9
|
+
...jest.requireActual("react-router"),
|
|
10
|
+
Navigate: jest.fn(({ to }) => `Navigate to ${to}`),
|
|
12
11
|
}));
|
|
13
12
|
|
|
14
13
|
describe("<OpenIDConnect />", () => {
|
|
15
|
-
it("
|
|
14
|
+
it("Navigates to the defined landing URL", async () => {
|
|
16
15
|
const state = { landingUrl, authentication };
|
|
17
16
|
const renderOpts = { state };
|
|
18
17
|
const { getByText } = render(<OpenIDConnect />, renderOpts);
|
|
19
18
|
await waitFor(() =>
|
|
20
|
-
expect(getByText("
|
|
19
|
+
expect(getByText("Navigate to /landingUrl")).not.toBeNull()
|
|
21
20
|
);
|
|
22
21
|
});
|
|
23
22
|
|
|
24
|
-
it("
|
|
23
|
+
it("Navigates to /search if landingUrl is not defined", async () => {
|
|
25
24
|
const state = { authentication };
|
|
26
25
|
const renderOpts = { state };
|
|
27
26
|
const { getByText } = render(<OpenIDConnect />, renderOpts);
|
|
28
27
|
await waitFor(() =>
|
|
29
|
-
expect(getByText("
|
|
28
|
+
expect(getByText("Navigate to /search")).not.toBeNull()
|
|
30
29
|
);
|
|
31
30
|
});
|
|
32
31
|
});
|