• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / gui / 1057188406

01 Nov 2023 04:24AM UTC coverage: 82.824% (-17.1%) from 99.964%
1057188406

Pull #4134

gitlab-ci

web-flow
chore: Bump uuid from 9.0.0 to 9.0.1

Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.0 to 9.0.1.
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #4134: chore: Bump uuid from 9.0.0 to 9.0.1

4349 of 6284 branches covered (0.0%)

8313 of 10037 relevant lines covered (82.82%)

200.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.37
/src/js/components/settings/user-management/selfusermanagement.js
1
// Copyright 2017 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React, { useState } from 'react';
15
import { useDispatch, useSelector } from 'react-redux';
16

17
import { Button, Switch, TextField } from '@mui/material';
18
import { makeStyles } from 'tss-react/mui';
19

20
import { setSnackbar } from '../../../actions/appActions';
21
import { editUser, saveUserSettings } from '../../../actions/userActions';
22
import { getToken } from '../../../auth';
23
import { DARK_MODE, LIGHT_MODE } from '../../../constants/appConstants';
24
import * as UserConstants from '../../../constants/userConstants';
25
import { isDarkMode, toggle } from '../../../helpers';
26
import { getCurrentUser, getFeatures, getIsEnterprise, getUserSettings } from '../../../selectors';
27
import ExpandableAttribute from '../../common/expandable-attribute';
28
import Form from '../../common/forms/form';
29
import PasswordInput from '../../common/forms/passwordinput';
30
import TextInput from '../../common/forms/textinput';
31
import InfoText from '../../common/infotext';
32
import AccessTokenManagement from '../accesstokenmanagement';
33
import { CopyTextToClipboard } from '../organization/organization';
34
import TwoFactorAuthSetup from './twofactorauthsetup';
35
import { getUserSSOState } from './userdefinition';
36

37
const useStyles = makeStyles()(() => ({
5✔
38
  formField: { width: 400, maxWidth: '100%' },
39
  changeButton: { margin: '30px 0 0 15px' },
40
  infoText: { margin: 0, width: '75%' },
41
  jwt: { maxWidth: '70%' },
42
  oauthIcon: { fontSize: '36px', marginRight: 10 },
43
  widthLimit: { maxWidth: 750 }
44
}));
45

46
export const SelfUserManagement = () => {
5✔
47
  const [editEmail, setEditEmail] = useState(false);
11✔
48
  const [editPass, setEditPass] = useState(false);
10✔
49
  const { classes } = useStyles();
10✔
50
  const dispatch = useDispatch();
10✔
51

52
  const { isHosted } = useSelector(getFeatures);
10✔
53
  const isEnterprise = useSelector(getIsEnterprise);
10✔
54
  const canHave2FA = isEnterprise || isHosted;
10✔
55
  const currentUser = useSelector(getCurrentUser);
10✔
56
  const hasTracking = useSelector(state => !!state.app.trackerCode);
19✔
57
  const { trackingConsentGiven: hasTrackingConsent, mode } = useSelector(getUserSettings);
10✔
58

59
  const editSubmit = userData => {
10✔
60
    if (userData.password != userData.password_confirmation) {
×
61
      dispatch(setSnackbar(`The passwords don't match`));
×
62
    } else {
63
      dispatch(editUser(UserConstants.OWN_USER_ID, userData)).then(() => {
×
64
        setEditEmail(false);
×
65
        setEditPass(false);
×
66
      });
67
    }
68
  };
69

70
  const handleEmail = () => setEditEmail(toggle);
10✔
71

72
  const toggleMode = () => {
10✔
73
    const newMode = isDarkMode(mode) ? LIGHT_MODE : DARK_MODE;
×
74
    dispatch(saveUserSettings({ mode: newMode }));
×
75
  };
76

77
  const handlePass = () => setEditPass(toggle);
10✔
78
  const email = currentUser.email;
10✔
79
  const { isOAuth2, provider } = getUserSSOState(currentUser);
10✔
80
  return (
10✔
81
    <div className={`margin-top-small ${classes.widthLimit}`}>
82
      <h2 className="margin-top-small">My profile</h2>
83
      {!editEmail && currentUser.email ? (
29✔
84
        <div className="flexbox space-between">
85
          <TextField className={classes.formField} label="Email" key={email} InputLabelProps={{ shrink: !!email }} disabled defaultValue={email} />
86
          {!isOAuth2 && (
17✔
87
            <Button className={`inline-block ${classes.changeButton}`} color="primary" id="change_email" onClick={handleEmail}>
88
              Change email
89
            </Button>
90
          )}
91
        </div>
92
      ) : (
93
        <Form
94
          defaultValues={{ email }}
95
          onSubmit={editSubmit}
96
          handleCancel={handleEmail}
97
          submitLabel="Save"
98
          showButtons={editEmail}
99
          buttonColor="secondary"
100
          submitButtonId="submit_email"
101
        >
102
          <TextInput disabled={false} hint="Email" id="email" InputLabelProps={{ shrink: !!email }} label="Email" validations="isLength:1,isEmail" />
103
          <PasswordInput id="current_password" label="Current password *" validations={`isLength:8,isNot:${email}`} required={true} />
104
        </Form>
105
      )}
106
      {!isOAuth2 &&
19✔
107
        (!editPass ? (
9✔
108
          <form className="flexbox space-between">
109
            <TextField className={classes.formField} label="Password" key="password-placeholder" disabled defaultValue="********" type="password" />
110
            <Button className={classes.changeButton} color="primary" id="change_password" onClick={handlePass}>
111
              Change password
112
            </Button>
113
          </form>
114
        ) : (
115
          <>
116
            <h3 className="margin-top margin-bottom-none">Change password</h3>
117
            <Form
118
              onSubmit={editSubmit}
119
              handleCancel={handlePass}
120
              submitLabel="Save"
121
              submitButtonId="submit_pass"
122
              buttonColor="secondary"
123
              showButtons={editPass}
124
            >
125
              <PasswordInput id="current_password" label="Current password *" validations={`isLength:8,isNot:${email}`} required />
126
              <PasswordInput className="edit-pass" id="password" label="Password *" validations={`isLength:8,isNot:${email}`} create generate required />
127
              <PasswordInput id="password_confirmation" label="Confirm password *" validations={`isLength:8,isNot:${email}`} required />
128
            </Form>
129
          </>
130
        ))}
131
      <div className="clickable flexbox space-between margin-top" onClick={toggleMode}>
132
        <p className="help-content">Enable dark theme</p>
133
        <Switch checked={isDarkMode(mode)} />
134
      </div>
135
      {!isOAuth2 ? (
10✔
136
        canHave2FA && <TwoFactorAuthSetup />
17✔
137
      ) : (
138
        <div className="flexbox margin-top">
139
          <div className={classes.oauthIcon}>{provider.icon}</div>
140
          <div className="info">
141
            You are logging in using your <strong>{provider.name}</strong> account.
142
            <br />
143
            Please connect to {provider.name} to update your login settings.
144
          </div>
145
        </div>
146
      )}
147
      <div className="flexbox space-between margin-top-large">
148
        <div className={classes.jwt}>
149
          <div className="help-content">Session token</div>
150
          <ExpandableAttribute
151
            component="div"
152
            disableGutters
153
            dividerDisabled
154
            secondary={getToken()}
155
            textClasses={{ secondary: 'inventory-text tenant-token-text' }}
156
          />
157
        </div>
158
        <div className="flexbox center-aligned">
159
          <CopyTextToClipboard token={getToken()} />
160
        </div>
161
      </div>
162
      {!isOAuth2 && <AccessTokenManagement />}
19✔
163
      {isEnterprise && hasTracking && (
18!
164
        <div className="margin-top">
165
          <div className="clickable flexbox space-between" onClick={() => dispatch(saveUserSettings({ trackingConsentGiven: !hasTrackingConsent }))}>
×
166
            <p className="help-content">Help us improve Mender</p>
167
            <Switch checked={!!hasTrackingConsent} />
168
          </div>
169
          <InfoText className={classes.infoText}>Enable usage data and errors to be sent to help us improve our service.</InfoText>
170
        </div>
171
      )}
172
    </div>
173
  );
174
};
175

176
export default SelfUserManagement;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc