1 | import React, {PureComponent} from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 |
|
4 | import Auth, {
|
5 | USER_CHANGED_EVENT,
|
6 | LOGOUT_POSTPONED_EVENT,
|
7 | USER_CHANGE_POSTPONED_EVENT
|
8 | } from '../auth/auth';
|
9 | import alertService from '../alert-service/alert-service';
|
10 |
|
11 | import Profile from './profile';
|
12 |
|
13 | const CERTIFICATE_MISMATCH_HEADER = 'x-client-certificate-token-mismatch';
|
14 |
|
15 | export default class SmartProfile extends PureComponent {
|
16 | static Size = Profile.Size;
|
17 |
|
18 | static propTypes = {
|
19 | auth: PropTypes.instanceOf(Auth).isRequired,
|
20 | className: PropTypes.string,
|
21 | translations: PropTypes.object,
|
22 | profileUrl: PropTypes.string,
|
23 | size: Profile.propTypes.size,
|
24 | round: Profile.propTypes.round
|
25 | };
|
26 |
|
27 | state = {
|
28 | user: null,
|
29 | size: Profile.defaultProps.size,
|
30 | isLogoutPostponed: false,
|
31 | isUserChangePostponed: false
|
32 | };
|
33 |
|
34 | componentDidMount() {
|
35 | this.requestUser();
|
36 | }
|
37 |
|
38 | login = async () => {
|
39 | this.setState({loading: true});
|
40 |
|
41 | try {
|
42 | await this.props.auth.login();
|
43 | } catch (err) {
|
44 |
|
45 | } finally {
|
46 | this.setState({loading: false});
|
47 | }
|
48 | };
|
49 |
|
50 | logout = () => this.props.auth.logout();
|
51 |
|
52 | switchUser = () => this.props.auth.switchUser();
|
53 |
|
54 | onRevertPostponement = () => {
|
55 | if (this.state.isLogoutPostponed) {
|
56 | this.props.auth.login();
|
57 | }
|
58 | if (this.state.isUserChangePostponed) {
|
59 | this.props.auth.updateUser();
|
60 | }
|
61 | };
|
62 |
|
63 | async requestUser() {
|
64 | try {
|
65 | const {auth} = this.props;
|
66 | const user = await auth.requestUser();
|
67 | this.checkUserCertificateMismatch(user);
|
68 | this.setState({user});
|
69 |
|
70 | auth.addListener(USER_CHANGED_EVENT, newUser => {
|
71 | this.setState({
|
72 | user: newUser,
|
73 | isLogoutPostponed: false,
|
74 | isUserChangePostponed: false
|
75 | });
|
76 | });
|
77 |
|
78 | auth.addListener(LOGOUT_POSTPONED_EVENT, () => {
|
79 | this.setState({isLogoutPostponed: true});
|
80 | });
|
81 |
|
82 | auth.addListener(USER_CHANGE_POSTPONED_EVENT, () => {
|
83 | this.setState({isUserChangePostponed: true});
|
84 | });
|
85 | } catch (e) {
|
86 |
|
87 | }
|
88 | }
|
89 |
|
90 | checkUserCertificateMismatch(user) {
|
91 | const {auth, translations} = this.props;
|
92 | const userMeta = auth.http.getMetaForResponse(user);
|
93 | if (userMeta?.headers?.has(CERTIFICATE_MISMATCH_HEADER)) {
|
94 | const message = translations?.certificateMismatch || `You are authenticated as ${user.login || user.name}. To authenticate with the client certificate for your account, log out, then click the "Log in with certificate" option on the login page.`;
|
95 | alertService.warning(message, 0);
|
96 | }
|
97 | }
|
98 |
|
99 | render() {
|
100 | const {user, loading, isLogoutPostponed, isUserChangePostponed} = this.state;
|
101 | const {auth, profileUrl, ...props} = this.props;
|
102 | const url = profileUrl || (user ? `${auth.config.serverUri}users/${user.id}` : '');
|
103 |
|
104 | return (
|
105 | <Profile
|
106 | onLogin={this.login}
|
107 | onLogout={this.logout}
|
108 | onSwitchUser={this.switchUser}
|
109 | loading={loading}
|
110 | user={user}
|
111 | profileUrl={url}
|
112 | showApplyChangedUser={isUserChangePostponed}
|
113 | showLogIn={isLogoutPostponed}
|
114 | showLogOut={!isLogoutPostponed}
|
115 | showSwitchUser={auth._canShowDialogs() && !isLogoutPostponed && !isUserChangePostponed}
|
116 | onRevertPostponement={this.onRevertPostponement}
|
117 | {...props}
|
118 | />
|
119 | );
|
120 | }
|
121 | }
|