UNPKG

3.35 kBJavaScriptView Raw
1import React, {PureComponent} from 'react';
2import PropTypes from 'prop-types';
3
4import Auth, {
5 USER_CHANGED_EVENT,
6 LOGOUT_POSTPONED_EVENT,
7 USER_CHANGE_POSTPONED_EVENT
8} from '../auth/auth';
9import alertService from '../alert-service/alert-service';
10
11import Profile from './profile';
12
13const CERTIFICATE_MISMATCH_HEADER = 'x-client-certificate-token-mismatch';
14
15export 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 // do nothing
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 // noop
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}