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

mendersoftware / gui / 1081664682

22 Nov 2023 02:11PM UTC coverage: 82.798% (-17.2%) from 99.964%
1081664682

Pull #4214

gitlab-ci

tranchitella
fix: Fixed the infinite page redirects when the back button is pressed

Remove the location and navigate from the useLocationParams.setValue callback
dependencies as they change the set function that is presented in other
useEffect dependencies. This happens when the back button is clicked, which
leads to the location changing infinitely.

Changelog: Title
Ticket: MEN-6847
Ticket: MEN-6796

Signed-off-by: Ihor Aleksandrychiev <ihor.aleksandrychiev@northern.tech>
Signed-off-by: Fabio Tranchitella <fabio.tranchitella@northern.tech>
Pull Request #4214: fix: Fixed the infinite page redirects when the back button is pressed

4319 of 6292 branches covered (0.0%)

8332 of 10063 relevant lines covered (82.8%)

191.0 hits per line

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

93.18
/src/js/constants/userConstants.js
1
'use strict';
2

3
// Copyright 2015 Northern.tech AS
4
//
5
//    Licensed under the Apache License, Version 2.0 (the "License");
6
//    you may not use this file except in compliance with the License.
7
//    You may obtain a copy of the License at
8
//
9
//        http://www.apache.org/licenses/LICENSE-2.0
10
//
11
//    Unless required by applicable law or agreed to in writing, software
12
//    distributed under the License is distributed on an "AS IS" BASIS,
13
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
//    See the License for the specific language governing permissions and
15
//    limitations under the License.
16
import { apiUrl } from '../api/general-api';
17
import { ALL_DEVICES } from './deviceConstants';
18
import { ALL_RELEASES } from './releaseConstants';
19

20
export const useradmApiUrlv1 = `${apiUrl.v1}/useradm`;
183✔
21
export const useradmApiUrlv2 = `${apiUrl.v2}/useradm`;
183✔
22
export { useradmApiUrlv1 as useradmApiUrl };
23

24
const staticRolesByName = {
183✔
25
  admin: 'RBAC_ROLE_PERMIT_ALL',
26
  readOnly: 'RBAC_ROLE_OBSERVER',
27
  ci: 'RBAC_ROLE_CI',
28
  deploymentsManager: 'RBAC_ROLE_DEPLOYMENTS_MANAGER',
29
  terminalAccess: 'RBAC_ROLE_REMOTE_TERMINAL'
30
};
31

32
export const PermissionTypes = {
183✔
33
  Any: 'any',
34
  Get: 'GET',
35
  Post: 'POST',
36
  Put: 'PUT',
37
  Delete: 'DELETE',
38
  Patch: 'PATCH',
39
  DeviceGroup: 'DEVICE_GROUP',
40
  DeviceId: 'DEVICE_ID'
41
};
42

43
const permissionSetIds = {
183✔
44
  Basic: 'Basic',
45
  ConfigureDevices: 'ConfigureDevices',
46
  ConnectToDevices: 'ConnectToDevices',
47
  DeployToDevices: 'DeployToDevices',
48
  ManageDevices: 'ManageDevices',
49
  ManageReleases: 'ManageReleases',
50
  ManageUsers: 'ManageUsers',
51
  ReadAuditLogs: 'ReadAuditLogs',
52
  ReadDevices: 'ReadDevices',
53
  ReadReleases: 'ReadReleases',
54
  ReadUsers: 'ReadUsers',
55
  SuperUser: 'SuperUser',
56
  UploadArtifacts: 'UploadArtifacts'
57
};
58

59
export const uiPermissionsById = {
183✔
60
  configure: {
61
    explanations: { groups: `'Configure' allows the user to use mender-configure features and apply configurations.` },
62
    permissionLevel: 2,
63
    permissionSets: { groups: permissionSetIds.ConfigureDevices },
64
    title: 'Configure',
65
    value: 'configure',
66
    verbs: [PermissionTypes.Get, PermissionTypes.Put, PermissionTypes.Post]
67
  },
68
  connect: {
69
    explanations: { groups: `'Connect' allows the user to use mender-connect features and Troubleshoot add-ons.` },
70
    permissionLevel: 2,
71
    permissionSets: { groups: permissionSetIds.ConnectToDevices },
72
    title: 'Connect',
73
    value: 'connect',
74
    verbs: [PermissionTypes.Get, PermissionTypes.Put]
75
  },
76
  deploy: {
77
    explanations: { groups: `'Deploy' allows the user to deploy software or configuration updates to devices.` },
78
    permissionLevel: 2,
79
    permissionSets: { deployments: permissionSetIds.DeployToDevices, groups: permissionSetIds.DeployToDevices },
80
    title: 'Deploy',
81
    value: 'deploy',
82
    verbs: [PermissionTypes.Post]
83
  },
84
  manage: {
85
    explanations: {
86
      groups: `'Manage' allows the user to edit device name, notes, and manage authentication status. For 'All devices' it also allows the user to edit and create device groups.`,
87
      releases: `'Manage' allows the user to upload new artifacts, edit release descriptions and remove artifacts.`
88
    },
89
    permissionLevel: 2,
90
    permissionSets: {
91
      groups: permissionSetIds.ManageDevices,
92
      releases: permissionSetIds.ManageReleases,
93
      userManagement: permissionSetIds.ManageUsers
94
    },
95
    title: 'Manage',
96
    value: 'manage',
97
    verbs: [PermissionTypes.Post, PermissionTypes.Put, PermissionTypes.Patch]
98
  },
99
  read: {
100
    explanations: { groups: `'Read' allows the user to view devices.` },
101
    permissionLevel: 1,
102
    permissionSets: {
103
      auditlog: permissionSetIds.ReadAuditLogs,
104
      groups: permissionSetIds.ReadDevices,
105
      releases: permissionSetIds.ReadReleases,
106
      userManagement: permissionSetIds.ReadUsers
107
    },
108
    title: 'Read',
109
    value: 'read',
110
    verbs: [PermissionTypes.Get, PermissionTypes.Post]
111
  },
112
  upload: {
113
    explanations: { groups: `'Upload' allows the user to upload new Artifacts.` },
114
    unscopedOnly: { releases: true },
115
    permissionLevel: 1,
116
    permissionSets: { releases: permissionSetIds.UploadArtifacts },
117
    title: 'Upload',
118
    value: 'upload',
119
    verbs: [PermissionTypes.Post, PermissionTypes.Put, PermissionTypes.Patch]
120
  }
121
};
122

123
/**
124
 * _uiPermissions_ represent the possible permissions/ rights that can be given for the area
125
 * _endpoints_ represent the possible endpoints this definition might be affecting in the UI and what
126
 *              functionality might be affected
127
 *
128
 */
129
export const scopedPermissionAreas = {
183✔
130
  groups: { key: 'groups', excessiveAccessSelector: ALL_DEVICES, scopeType: 'DeviceGroups' },
131
  releases: { key: 'releases', excessiveAccessSelector: ALL_RELEASES, scopeType: 'Releases' }
132
};
133

134
export const uiPermissionsByArea = {
183✔
135
  auditlog: {
136
    endpoints: [{ path: /\/(auditlog)/i, types: [PermissionTypes.Get], uiPermissions: [uiPermissionsById.read] }],
137
    explanation:
138
      'Granting access to the audit log will allow tracing changes to devices, releases and user accounts, as well as providing information about deployments.',
139
    uiPermissions: [uiPermissionsById.read],
140
    title: 'System audit log'
141
  },
142
  deployments: {
143
    endpoints: [
144
      { path: /\/(deployments\/deployments)/i, types: [PermissionTypes.Post, PermissionTypes.Put], uiPermissions: [uiPermissionsById.deploy] },
145
      { path: /\/(deployments\/deployments)/i, types: [PermissionTypes.Get], uiPermissions: [uiPermissionsById.read] },
146
      { path: /\/(deployments\/config)/i, types: [PermissionTypes.Get, PermissionTypes.Put], uiPermissions: [uiPermissionsById.manage] }
147
    ],
148
    explanation: 'Providing deploy permissions will allow deployments to be created using the releases and devices a user has access to.',
149
    uiPermissions: [uiPermissionsById.read, uiPermissionsById.deploy],
150
    title: 'Deployments'
151
  },
152
  groups: {
153
    endpoints: [
154
      {
155
        path: /\/(devauth|inventory|deviceconfig|devicemonitor|deviceconnect\/devices)/i,
156
        types: [PermissionTypes.Get],
157
        uiPermissions: [uiPermissionsById.read]
158
      },
159
      { path: /\/(devauth|inventory)/i, types: [PermissionTypes.Put, PermissionTypes.Post], uiPermissions: [uiPermissionsById.manage] },
160
      { path: /\/(deviceconfig)/i, types: [PermissionTypes.Get, PermissionTypes.Put, PermissionTypes.Post], uiPermissions: [uiPermissionsById.configure] },
161
      { path: /\/(deviceconnect\/devices)/i, types: [PermissionTypes.Get, PermissionTypes.Post], uiPermissions: [uiPermissionsById.connect] }
162
    ],
163
    explanation: 'Device group management permissions control the degree to which devices in a group can be accessed and moved to other groups.',
164
    scope: scopedPermissionAreas.groups.scopeType,
165
    uiPermissions: [uiPermissionsById.read, uiPermissionsById.manage, uiPermissionsById.deploy, uiPermissionsById.configure, uiPermissionsById.connect],
166
    title: 'Group Management'
167
  },
168
  releases: {
169
    endpoints: [
170
      { path: /\/(deployments\/artifacts|deployments\/deployments\/releases)/i, types: [PermissionTypes.Get], uiPermissions: [uiPermissionsById.read] },
171
      {
172
        path: /\/(deployments\/artifacts|deployments\/deployments\/releases)/i,
173
        types: [PermissionTypes.Post, PermissionTypes.Put],
174
        uiPermissions: [uiPermissionsById.read, uiPermissionsById.upload]
175
      },
176
      {
177
        path: /\/(deployments\/artifacts|deployments\/deployments\/releases)/i,
178
        types: [PermissionTypes.Delete],
179
        uiPermissions: [uiPermissionsById.read, uiPermissionsById.manage]
180
      }
181
    ],
182
    explanation: 'Release permissions can be granted to allow artifact & release modifications, as well as the creation of new releases.',
183
    scope: 'ReleaseTags',
184
    uiPermissions: [uiPermissionsById.read, uiPermissionsById.manage, uiPermissionsById.upload],
185
    title: 'Releases'
186
  },
187
  userManagement: {
188
    endpoints: [
189
      { path: /\/(useradm)/i, types: [PermissionTypes.Get], uiPermissions: [uiPermissionsById.read] },
190
      { path: /\/(useradm)/i, types: [PermissionTypes.Post], uiPermissions: [uiPermissionsById.manage] }
191
    ],
192
    explanation:
193
      'User management permissions should be granted carefully, as these allow privilege increases for any users managed by a user with user management permissions',
194
    uiPermissions: [uiPermissionsById.read, uiPermissionsById.manage],
195
    title: 'User Management'
196
  }
197
};
198

199
export const emptyUiPermissions = Object.freeze({
183✔
200
  auditlog: [],
201
  deployments: [],
202
  groups: Object.freeze({}),
203
  releases: Object.freeze({}),
204
  userManagement: []
205
});
206

207
export const emptyRole = Object.freeze({
183✔
208
  name: undefined,
209
  description: '',
210
  permissions: [],
211
  uiPermissions: Object.freeze({ ...emptyUiPermissions })
212
});
213

214
const permissionMapper = permission => permission.value;
3,294✔
215
export const itemUiPermissionsReducer = (accu, { item, uiPermissions }) => (item ? { ...accu, [item]: uiPermissions } : accu);
183✔
216

217
const checkSinglePermission = (permission, requiredPermission) =>
183✔
218
  requiredPermission === permission || uiPermissionsById[permission].permissionLevel > uiPermissionsById[requiredPermission].permissionLevel;
×
219

220
export const checkPermissionsObject = (permissions, requiredPermission, scopedAccess, superAccess) =>
183✔
221
  permissions[superAccess]?.some(permission => checkSinglePermission(permission, requiredPermission)) ||
×
222
  permissions[scopedAccess]?.some(permission => checkSinglePermission(permission, requiredPermission));
×
223

224
export const rolesById = Object.freeze({
183✔
225
  [staticRolesByName.admin]: {
226
    name: 'Admin',
227
    value: staticRolesByName.admin,
228
    description: 'Full access',
229
    permissions: [], // permissions refers to the values returned from the backend
230
    uiPermissions: {
231
      ...emptyUiPermissions,
232
      auditlog: uiPermissionsByArea.auditlog.uiPermissions.map(permissionMapper),
233
      deployments: uiPermissionsByArea.deployments.uiPermissions.map(permissionMapper),
234
      groups: { [ALL_DEVICES]: uiPermissionsByArea.groups.uiPermissions.map(permissionMapper) },
235
      releases: { [ALL_RELEASES]: uiPermissionsByArea.releases.uiPermissions.map(permissionMapper) },
236
      userManagement: uiPermissionsByArea.userManagement.uiPermissions.map(permissionMapper)
237
    }
238
  },
239
  [staticRolesByName.readOnly]: {
240
    name: 'Read Access',
241
    value: staticRolesByName.readOnly,
242
    description: '',
243
    permissions: [],
244
    uiPermissions: {
245
      ...emptyUiPermissions,
246
      deployments: [uiPermissionsById.read.value],
247
      groups: { [ALL_DEVICES]: [uiPermissionsById.read.value] },
248
      releases: { [ALL_RELEASES]: [uiPermissionsById.read.value] },
249
      userManagement: [uiPermissionsById.read.value]
250
    }
251
  },
252
  [staticRolesByName.ci]: {
253
    name: 'Releases Manager',
254
    value: staticRolesByName.ci,
255
    description: '',
256
    permissions: [],
257
    uiPermissions: {
258
      ...emptyUiPermissions,
259
      releases: { [ALL_RELEASES]: uiPermissionsByArea.releases.uiPermissions.map(permissionMapper) }
260
    }
261
  },
262
  [staticRolesByName.deploymentsManager]: {
263
    name: 'Deployments Manager',
264
    value: staticRolesByName.deploymentsManager,
265
    description: '',
266
    permissions: [],
267
    uiPermissions: {
268
      ...emptyUiPermissions,
269
      deployments: uiPermissionsByArea.deployments.uiPermissions.map(permissionMapper),
270
      groups: { [ALL_DEVICES]: [uiPermissionsById.deploy.value] },
271
      releases: { [ALL_RELEASES]: [uiPermissionsById.read.value] }
272
    }
273
  },
274
  [staticRolesByName.terminalAccess]: {
275
    name: 'Troubleshooting',
276
    value: staticRolesByName.terminalAccess,
277
    description: 'Access to the troubleshooting features: Remote Terminal, File Transfer, Port Forwarding',
278
    permissions: [],
279
    uiPermissions: {
280
      ...emptyUiPermissions,
281
      groups: { [ALL_DEVICES]: [uiPermissionsById.connect.value] }
282
    }
283
  }
284
});
285

286
export const defaultPermissionSets = {
183✔
287
  [permissionSetIds.Basic]: {
288
    name: permissionSetIds.Basic,
289
    result: {
290
      // this is needed to prevent the detailed permissions of the basic permission set from being interpreted as allowing read & management access to user endpoints
291
      userManagement: [uiPermissionsById.read.value]
292
    }
293
  },
294
  [permissionSetIds.SuperUser]: {
295
    name: permissionSetIds.SuperUser,
296
    result: {
297
      ...rolesById[staticRolesByName.admin].uiPermissions
298
    }
299
  },
300
  [permissionSetIds.ManageUsers]: {
301
    name: permissionSetIds.ManageUsers,
302
    result: {
303
      userManagement: [uiPermissionsById.manage.value]
304
    }
305
  },
306
  [permissionSetIds.ReadAuditLogs]: {
307
    name: permissionSetIds.ReadAuditLogs,
308
    result: {
309
      auditlog: [uiPermissionsById.read.value]
310
    }
311
  },
312
  [permissionSetIds.ReadReleases]: {
313
    name: permissionSetIds.ReadReleases,
314
    result: {
315
      releases: { [ALL_RELEASES]: [uiPermissionsById.read.value] }
316
    }
317
  },
318
  [permissionSetIds.ReadUsers]: {
319
    name: permissionSetIds.ReadUsers,
320
    result: {
321
      userManagement: [uiPermissionsById.read.value]
322
    }
323
  },
324
  [permissionSetIds.UploadArtifacts]: {
325
    name: permissionSetIds.UploadArtifacts,
326
    result: {
327
      releases: { [ALL_RELEASES]: [uiPermissionsById.upload.value] }
328
    }
329
  },
330
  [permissionSetIds.ManageReleases]: {
331
    name: permissionSetIds.ManageReleases,
332
    result: {
333
      releases: { [ALL_RELEASES]: [uiPermissionsById.manage.value] }
334
    }
335
  },
336
  [permissionSetIds.ConfigureDevices]: {
337
    name: permissionSetIds.ConfigureDevices,
338
    result: {
339
      deployments: [uiPermissionsById.read.value, uiPermissionsById.deploy.value],
340
      groups: { [ALL_DEVICES]: [uiPermissionsById.read.value, uiPermissionsById.configure.value] }
341
    }
342
  },
343
  [permissionSetIds.ConnectToDevices]: {
344
    name: permissionSetIds.ConnectToDevices,
345
    result: {
346
      groups: { [ALL_DEVICES]: [uiPermissionsById.read.value, uiPermissionsById.connect.value] }
347
    }
348
  },
349
  [permissionSetIds.DeployToDevices]: {
350
    name: permissionSetIds.DeployToDevices,
351
    result: {
352
      deployments: [uiPermissionsById.deploy.value, uiPermissionsById.manage.value, uiPermissionsById.read.value],
353
      groups: { [ALL_DEVICES]: [uiPermissionsById.read.value, uiPermissionsById.deploy.value] }
354
    }
355
  },
356
  [permissionSetIds.ManageDevices]: {
357
    name: permissionSetIds.ManageDevices,
358
    result: {
359
      groups: { [ALL_DEVICES]: [uiPermissionsById.read.value, uiPermissionsById.manage.value] }
360
    }
361
  },
362
  [permissionSetIds.ReadDevices]: {
363
    name: permissionSetIds.ReadDevices,
364
    result: {
365
      groups: { [ALL_DEVICES]: [uiPermissionsById.read.value] }
366
    }
367
  }
368
};
369

370
export const RECEIVED_QR_CODE = 'RECEIVED_QR_CODE';
183✔
371

372
export const SUCCESSFULLY_LOGGED_IN = 'SUCCESSFULLY_LOGGED_IN';
183✔
373
export const USER_LOGOUT = 'USER_LOGOUT';
183✔
374
export const RECEIVED_ACTIVATION_CODE = 'RECEIVED_ACTIVATION_CODE';
183✔
375
export const RECEIVED_USER_LIST = 'RECEIVED_USER_LIST';
183✔
376
export const RECEIVED_USER = 'RECEIVED_USER';
183✔
377
export const CREATED_USER = 'CREATED_USER';
183✔
378
export const REMOVED_USER = 'REMOVED_USER';
183✔
379
export const UPDATED_USER = 'UPDATED_USER';
183✔
380

381
export const RECEIVED_PERMISSION_SETS = 'RECEIVED_PERMISSION_SETS';
183✔
382
export const RECEIVED_ROLES = 'RECEIVED_ROLES';
183✔
383
export const CREATED_ROLE = 'CREATED_ROLE';
183✔
384
export const UPDATED_ROLE = 'UPDATED_ROLE';
183✔
385
export const REMOVED_ROLE = 'REMOVED_ROLE';
183✔
386

387
export const SET_CUSTOM_COLUMNS = 'SET_CUSTOM_COLUMNS';
183✔
388
export const SET_GLOBAL_SETTINGS = 'SET_GLOBAL_SETTINGS';
183✔
389
export const SET_USER_SETTINGS = 'SET_USER_SETTINGS';
183✔
390
export const SET_SHOW_CONNECT_DEVICE = 'SET_SHOW_CONNECT_DEVICE';
183✔
391
export const SET_TOOLTIP_STATE = 'SET_TOOLTIP_STATE';
183✔
392
export const SET_TOOLTIPS_STATE = 'SET_TOOLTIPS_STATE';
183✔
393

394
export const OWN_USER_ID = 'me';
183✔
395

396
export const rolesByName = {
183✔
397
  ...staticRolesByName,
398
  deploymentCreation: { action: 'CREATE_DEPLOYMENT', object: { type: 'DEVICE_GROUP', value: undefined } },
399
  groupAccess: { action: 'VIEW_DEVICE', object: { type: 'DEVICE_GROUP', value: undefined } },
400
  userManagement: { action: 'http', object: { type: 'any', value: `${useradmApiUrlv1}/.*` } }
401
};
402
export const twoFAStates = {
183✔
403
  enabled: 'enabled',
404
  disabled: 'disabled',
405
  unverified: 'unverified'
406
};
407
export const settingsKeys = { initialized: 'settings-initialized' };
183✔
408

409
export const READ_STATES = {
183✔
410
  read: 'read',
411
  seen: 'seen',
412
  unread: 'unread'
413
};
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