@commercetools-frontend/permissions 27.12.0 → 27.14.0

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.
@@ -52,7 +52,7 @@ var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
52
52
  var upperFirst__default = /*#__PURE__*/_interopDefault(upperFirst);
53
53
 
54
54
  // NOTE: This string will be replaced on build time with the package version.
55
- var version = "27.12.0";
55
+ var version = "27.14.0";
56
56
 
57
57
  // Permissions
58
58
 
@@ -149,6 +149,32 @@ const hasEveryActionRight = (demandedActionRights, actualActionRights) => _every
149
149
  // - actualPermissions:
150
150
  // { canViewProducts: true, canManageOrders: false }
151
151
  const hasSomePermissions = (demandedPermissions, actualPermissions) => _someInstanceProperty__default["default"](demandedPermissions).call(demandedPermissions, permission => hasPermission(permission, actualPermissions));
152
+ /**
153
+ * Pure permission check shared by `useIsAuthorized` and callers that cannot use
154
+ * the hook (e.g. OR-ing visibility across many navbar menus).
155
+ *
156
+ * Handles virtual permissions first:
157
+ * - `Administrator` → `isAdminOfAnyOrganization`
158
+ * - `AdministratorOfCurrentProject` → `isUserAdminOfCurrentProject`
159
+ * Then falls back to `hasSomePermissions` / `hasEveryPermissions`.
160
+ */
161
+ const isAuthorizedForDemandedPermissions = _ref => {
162
+ let demandedPermissions = _ref.demandedPermissions,
163
+ actualPermissions = _ref.actualPermissions,
164
+ _ref$isAdminOfAnyOrga = _ref.isAdminOfAnyOrganization,
165
+ isAdminOfAnyOrganization = _ref$isAdminOfAnyOrga === void 0 ? false : _ref$isAdminOfAnyOrga,
166
+ _ref$isUserAdminOfCur = _ref.isUserAdminOfCurrentProject,
167
+ isUserAdminOfCurrentProject = _ref$isUserAdminOfCur === void 0 ? false : _ref$isUserAdminOfCur,
168
+ _ref$shouldMatchSomeP = _ref.shouldMatchSomePermissions,
169
+ shouldMatchSomePermissions = _ref$shouldMatchSomeP === void 0 ? false : _ref$shouldMatchSomeP;
170
+ if (_includesInstanceProperty__default["default"](demandedPermissions).call(demandedPermissions, 'Administrator')) {
171
+ return isAdminOfAnyOrganization;
172
+ }
173
+ if (_includesInstanceProperty__default["default"](demandedPermissions).call(demandedPermissions, 'AdministratorOfCurrentProject')) {
174
+ return Boolean(isUserAdminOfCurrentProject);
175
+ }
176
+ return shouldMatchSomePermissions ? hasSomePermissions(demandedPermissions, actualPermissions) : hasEveryPermissions(demandedPermissions, actualPermissions);
177
+ };
152
178
  const getHasDemandedDataFence = options => {
153
179
  if (!options.selectDataFenceData) return false;
154
180
  const hasDemandedPermission = hasPermission(options.demandedDataFence.name, {
@@ -223,10 +249,10 @@ const hasSomeDataFence = options => {
223
249
  if (!actualDataFenceByTypeAndGroup) return false;
224
250
 
225
251
  // we try to find if the demanded dataFence is available inside the actual datafences
226
- const specificActualDataFence = _findInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](actualDataFenceByTypeAndGroup)).call(_context3, _ref => {
227
- let _ref2 = _slicedToArray(_ref, 2),
228
- dataFenceName = _ref2[0],
229
- dataFenceValue = _ref2[1];
252
+ const specificActualDataFence = _findInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](actualDataFenceByTypeAndGroup)).call(_context3, _ref2 => {
253
+ let _ref3 = _slicedToArray(_ref2, 2),
254
+ dataFenceName = _ref3[0],
255
+ dataFenceValue = _ref3[1];
230
256
  // Either the manage permission matches or the
231
257
  // a demanded view permission is implied by a manage permission.
232
258
  const doesDataFenceMatchByName = dataFenceName === toCanCase(demandedDataFence.name) || dataFenceName === toCanCase(toManageCase(demandedDataFence.name));
@@ -290,11 +316,15 @@ const useIsAuthorized = _ref => {
290
316
  const actualPermissions = applicationShellConnectors.useApplicationContext(applicationContext => projectPermissions?.permissions ?? applicationContext.permissions);
291
317
  const actualActionRights = applicationShellConnectors.useApplicationContext(applicationContext => projectPermissions?.actionRights ?? applicationContext.actionRights);
292
318
  const actualDataFences = applicationShellConnectors.useApplicationContext(applicationContext => projectPermissions?.dataFences ?? applicationContext.dataFences);
293
- if (hasDemandedAdministratorPermission) {
294
- return isAdminOfAnyOrganization;
295
- }
296
- if (hasDemandedAdministratorOfCurrentProjectPermission) {
297
- return isUserAdminOfCurrentProject ?? false;
319
+ const hasDemandedPermissions = isAuthorizedForDemandedPermissions({
320
+ demandedPermissions,
321
+ actualPermissions,
322
+ isAdminOfAnyOrganization,
323
+ isUserAdminOfCurrentProject,
324
+ shouldMatchSomePermissions
325
+ });
326
+ if (hasDemandedAdministratorPermission || hasDemandedAdministratorOfCurrentProjectPermission) {
327
+ return hasDemandedPermissions;
298
328
  }
299
329
 
300
330
  // if the user has no permissions and no dataFences assigned to them, they are not authorized
@@ -311,7 +341,6 @@ const useIsAuthorized = _ref => {
311
341
  selectDataFenceData
312
342
  });
313
343
  }
314
- const hasDemandedPermissions = shouldMatchSomePermissions ? hasSomePermissions(demandedPermissions, actualPermissions) : hasEveryPermissions(demandedPermissions, actualPermissions);
315
344
  const hasDemandedActionRights = hasEveryActionRight(demandedActionRights || [], actualActionRights);
316
345
  return hasDemandedDataFences || hasDemandedPermissions && hasDemandedActionRights;
317
346
  };
@@ -442,5 +471,6 @@ exports.branchOnPermissions = branchOnPermissions;
442
471
  exports.hasEveryPermissions = hasEveryPermissions;
443
472
  exports.hasSomePermissions = hasSomePermissions;
444
473
  exports.injectAuthorized = injectAuthorized;
474
+ exports.isAuthorizedForDemandedPermissions = isAuthorizedForDemandedPermissions;
445
475
  exports.useIsAuthorized = useIsAuthorized;
446
476
  exports.version = version;
@@ -51,7 +51,7 @@ var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
51
51
  var upperFirst__default = /*#__PURE__*/_interopDefault(upperFirst);
52
52
 
53
53
  // NOTE: This string will be replaced on build time with the package version.
54
- var version = "27.12.0";
54
+ var version = "27.14.0";
55
55
 
56
56
  // Permissions
57
57
 
@@ -148,6 +148,32 @@ const hasEveryActionRight = (demandedActionRights, actualActionRights) => _every
148
148
  // - actualPermissions:
149
149
  // { canViewProducts: true, canManageOrders: false }
150
150
  const hasSomePermissions = (demandedPermissions, actualPermissions) => _someInstanceProperty__default["default"](demandedPermissions).call(demandedPermissions, permission => hasPermission(permission, actualPermissions));
151
+ /**
152
+ * Pure permission check shared by `useIsAuthorized` and callers that cannot use
153
+ * the hook (e.g. OR-ing visibility across many navbar menus).
154
+ *
155
+ * Handles virtual permissions first:
156
+ * - `Administrator` → `isAdminOfAnyOrganization`
157
+ * - `AdministratorOfCurrentProject` → `isUserAdminOfCurrentProject`
158
+ * Then falls back to `hasSomePermissions` / `hasEveryPermissions`.
159
+ */
160
+ const isAuthorizedForDemandedPermissions = _ref => {
161
+ let demandedPermissions = _ref.demandedPermissions,
162
+ actualPermissions = _ref.actualPermissions,
163
+ _ref$isAdminOfAnyOrga = _ref.isAdminOfAnyOrganization,
164
+ isAdminOfAnyOrganization = _ref$isAdminOfAnyOrga === void 0 ? false : _ref$isAdminOfAnyOrga,
165
+ _ref$isUserAdminOfCur = _ref.isUserAdminOfCurrentProject,
166
+ isUserAdminOfCurrentProject = _ref$isUserAdminOfCur === void 0 ? false : _ref$isUserAdminOfCur,
167
+ _ref$shouldMatchSomeP = _ref.shouldMatchSomePermissions,
168
+ shouldMatchSomePermissions = _ref$shouldMatchSomeP === void 0 ? false : _ref$shouldMatchSomeP;
169
+ if (_includesInstanceProperty__default["default"](demandedPermissions).call(demandedPermissions, 'Administrator')) {
170
+ return isAdminOfAnyOrganization;
171
+ }
172
+ if (_includesInstanceProperty__default["default"](demandedPermissions).call(demandedPermissions, 'AdministratorOfCurrentProject')) {
173
+ return Boolean(isUserAdminOfCurrentProject);
174
+ }
175
+ return shouldMatchSomePermissions ? hasSomePermissions(demandedPermissions, actualPermissions) : hasEveryPermissions(demandedPermissions, actualPermissions);
176
+ };
151
177
  const getHasDemandedDataFence = options => {
152
178
  if (!options.selectDataFenceData) return false;
153
179
  const hasDemandedPermission = hasPermission(options.demandedDataFence.name, {
@@ -222,10 +248,10 @@ const hasSomeDataFence = options => {
222
248
  if (!actualDataFenceByTypeAndGroup) return false;
223
249
 
224
250
  // we try to find if the demanded dataFence is available inside the actual datafences
225
- const specificActualDataFence = _findInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](actualDataFenceByTypeAndGroup)).call(_context3, _ref => {
226
- let _ref2 = _slicedToArray(_ref, 2),
227
- dataFenceName = _ref2[0],
228
- dataFenceValue = _ref2[1];
251
+ const specificActualDataFence = _findInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](actualDataFenceByTypeAndGroup)).call(_context3, _ref2 => {
252
+ let _ref3 = _slicedToArray(_ref2, 2),
253
+ dataFenceName = _ref3[0],
254
+ dataFenceValue = _ref3[1];
229
255
  // Either the manage permission matches or the
230
256
  // a demanded view permission is implied by a manage permission.
231
257
  const doesDataFenceMatchByName = dataFenceName === toCanCase(demandedDataFence.name) || dataFenceName === toCanCase(toManageCase(demandedDataFence.name));
@@ -288,11 +314,15 @@ const useIsAuthorized = _ref => {
288
314
  const actualPermissions = applicationShellConnectors.useApplicationContext(applicationContext => projectPermissions?.permissions ?? applicationContext.permissions);
289
315
  const actualActionRights = applicationShellConnectors.useApplicationContext(applicationContext => projectPermissions?.actionRights ?? applicationContext.actionRights);
290
316
  const actualDataFences = applicationShellConnectors.useApplicationContext(applicationContext => projectPermissions?.dataFences ?? applicationContext.dataFences);
291
- if (hasDemandedAdministratorPermission) {
292
- return isAdminOfAnyOrganization;
293
- }
294
- if (hasDemandedAdministratorOfCurrentProjectPermission) {
295
- return isUserAdminOfCurrentProject ?? false;
317
+ const hasDemandedPermissions = isAuthorizedForDemandedPermissions({
318
+ demandedPermissions,
319
+ actualPermissions,
320
+ isAdminOfAnyOrganization,
321
+ isUserAdminOfCurrentProject,
322
+ shouldMatchSomePermissions
323
+ });
324
+ if (hasDemandedAdministratorPermission || hasDemandedAdministratorOfCurrentProjectPermission) {
325
+ return hasDemandedPermissions;
296
326
  }
297
327
 
298
328
  // if the user has no permissions and no dataFences assigned to them, they are not authorized
@@ -309,7 +339,6 @@ const useIsAuthorized = _ref => {
309
339
  selectDataFenceData
310
340
  });
311
341
  }
312
- const hasDemandedPermissions = shouldMatchSomePermissions ? hasSomePermissions(demandedPermissions, actualPermissions) : hasEveryPermissions(demandedPermissions, actualPermissions);
313
342
  const hasDemandedActionRights = hasEveryActionRight(demandedActionRights || [], actualActionRights);
314
343
  return hasDemandedDataFences || hasDemandedPermissions && hasDemandedActionRights;
315
344
  };
@@ -440,5 +469,6 @@ exports.branchOnPermissions = branchOnPermissions;
440
469
  exports.hasEveryPermissions = hasEveryPermissions;
441
470
  exports.hasSomePermissions = hasSomePermissions;
442
471
  exports.injectAuthorized = injectAuthorized;
472
+ exports.isAuthorizedForDemandedPermissions = isAuthorizedForDemandedPermissions;
443
473
  exports.useIsAuthorized = useIsAuthorized;
444
474
  exports.version = version;
@@ -26,7 +26,7 @@ import upperFirst from 'lodash/upperFirst';
26
26
  import { jsx, Fragment } from '@emotion/react/jsx-runtime';
27
27
 
28
28
  // NOTE: This string will be replaced on build time with the package version.
29
- var version = "27.12.0";
29
+ var version = "27.14.0";
30
30
 
31
31
  // Permissions
32
32
 
@@ -123,6 +123,32 @@ const hasEveryActionRight = (demandedActionRights, actualActionRights) => _every
123
123
  // - actualPermissions:
124
124
  // { canViewProducts: true, canManageOrders: false }
125
125
  const hasSomePermissions = (demandedPermissions, actualPermissions) => _someInstanceProperty(demandedPermissions).call(demandedPermissions, permission => hasPermission(permission, actualPermissions));
126
+ /**
127
+ * Pure permission check shared by `useIsAuthorized` and callers that cannot use
128
+ * the hook (e.g. OR-ing visibility across many navbar menus).
129
+ *
130
+ * Handles virtual permissions first:
131
+ * - `Administrator` → `isAdminOfAnyOrganization`
132
+ * - `AdministratorOfCurrentProject` → `isUserAdminOfCurrentProject`
133
+ * Then falls back to `hasSomePermissions` / `hasEveryPermissions`.
134
+ */
135
+ const isAuthorizedForDemandedPermissions = _ref => {
136
+ let demandedPermissions = _ref.demandedPermissions,
137
+ actualPermissions = _ref.actualPermissions,
138
+ _ref$isAdminOfAnyOrga = _ref.isAdminOfAnyOrganization,
139
+ isAdminOfAnyOrganization = _ref$isAdminOfAnyOrga === void 0 ? false : _ref$isAdminOfAnyOrga,
140
+ _ref$isUserAdminOfCur = _ref.isUserAdminOfCurrentProject,
141
+ isUserAdminOfCurrentProject = _ref$isUserAdminOfCur === void 0 ? false : _ref$isUserAdminOfCur,
142
+ _ref$shouldMatchSomeP = _ref.shouldMatchSomePermissions,
143
+ shouldMatchSomePermissions = _ref$shouldMatchSomeP === void 0 ? false : _ref$shouldMatchSomeP;
144
+ if (_includesInstanceProperty(demandedPermissions).call(demandedPermissions, 'Administrator')) {
145
+ return isAdminOfAnyOrganization;
146
+ }
147
+ if (_includesInstanceProperty(demandedPermissions).call(demandedPermissions, 'AdministratorOfCurrentProject')) {
148
+ return Boolean(isUserAdminOfCurrentProject);
149
+ }
150
+ return shouldMatchSomePermissions ? hasSomePermissions(demandedPermissions, actualPermissions) : hasEveryPermissions(demandedPermissions, actualPermissions);
151
+ };
126
152
  const getHasDemandedDataFence = options => {
127
153
  if (!options.selectDataFenceData) return false;
128
154
  const hasDemandedPermission = hasPermission(options.demandedDataFence.name, {
@@ -197,10 +223,10 @@ const hasSomeDataFence = options => {
197
223
  if (!actualDataFenceByTypeAndGroup) return false;
198
224
 
199
225
  // we try to find if the demanded dataFence is available inside the actual datafences
200
- const specificActualDataFence = _findInstanceProperty(_context3 = _Object$entries(actualDataFenceByTypeAndGroup)).call(_context3, _ref => {
201
- let _ref2 = _slicedToArray(_ref, 2),
202
- dataFenceName = _ref2[0],
203
- dataFenceValue = _ref2[1];
226
+ const specificActualDataFence = _findInstanceProperty(_context3 = _Object$entries(actualDataFenceByTypeAndGroup)).call(_context3, _ref2 => {
227
+ let _ref3 = _slicedToArray(_ref2, 2),
228
+ dataFenceName = _ref3[0],
229
+ dataFenceValue = _ref3[1];
204
230
  // Either the manage permission matches or the
205
231
  // a demanded view permission is implied by a manage permission.
206
232
  const doesDataFenceMatchByName = dataFenceName === toCanCase(demandedDataFence.name) || dataFenceName === toCanCase(toManageCase(demandedDataFence.name));
@@ -264,11 +290,15 @@ const useIsAuthorized = _ref => {
264
290
  const actualPermissions = useApplicationContext(applicationContext => projectPermissions?.permissions ?? applicationContext.permissions);
265
291
  const actualActionRights = useApplicationContext(applicationContext => projectPermissions?.actionRights ?? applicationContext.actionRights);
266
292
  const actualDataFences = useApplicationContext(applicationContext => projectPermissions?.dataFences ?? applicationContext.dataFences);
267
- if (hasDemandedAdministratorPermission) {
268
- return isAdminOfAnyOrganization;
269
- }
270
- if (hasDemandedAdministratorOfCurrentProjectPermission) {
271
- return isUserAdminOfCurrentProject ?? false;
293
+ const hasDemandedPermissions = isAuthorizedForDemandedPermissions({
294
+ demandedPermissions,
295
+ actualPermissions,
296
+ isAdminOfAnyOrganization,
297
+ isUserAdminOfCurrentProject,
298
+ shouldMatchSomePermissions
299
+ });
300
+ if (hasDemandedAdministratorPermission || hasDemandedAdministratorOfCurrentProjectPermission) {
301
+ return hasDemandedPermissions;
272
302
  }
273
303
 
274
304
  // if the user has no permissions and no dataFences assigned to them, they are not authorized
@@ -285,7 +315,6 @@ const useIsAuthorized = _ref => {
285
315
  selectDataFenceData
286
316
  });
287
317
  }
288
- const hasDemandedPermissions = shouldMatchSomePermissions ? hasSomePermissions(demandedPermissions, actualPermissions) : hasEveryPermissions(demandedPermissions, actualPermissions);
289
318
  const hasDemandedActionRights = hasEveryActionRight(demandedActionRights || [], actualActionRights);
290
319
  return hasDemandedDataFences || hasDemandedPermissions && hasDemandedActionRights;
291
320
  };
@@ -410,4 +439,4 @@ const branchOnPermissions = function (demandedPermissions, FallbackComponent) {
410
439
  };
411
440
  };
412
441
 
413
- export { Authorized, RestrictedByPermissions, branchOnPermissions, hasEveryPermissions, hasSomePermissions, injectAuthorized, useIsAuthorized, version };
442
+ export { Authorized, RestrictedByPermissions, branchOnPermissions, hasEveryPermissions, hasSomePermissions, injectAuthorized, isAuthorizedForDemandedPermissions, useIsAuthorized, version };
@@ -3,4 +3,4 @@ export { default as RestrictedByPermissions } from "./components/restricted-by-p
3
3
  export { default as branchOnPermissions } from "./components/branch-on-permissions/index.js";
4
4
  export { default as Authorized, injectAuthorized, } from "./components/authorized/index.js";
5
5
  export { default as useIsAuthorized } from "./hooks/use-is-authorized/index.js";
6
- export { hasEveryPermissions, hasSomePermissions, } from "./utils/has-permissions.js";
6
+ export { hasEveryPermissions, hasSomePermissions, isAuthorizedForDemandedPermissions, } from "./utils/has-permissions.js";
@@ -45,5 +45,22 @@ export declare const hasActionRight: (demandedActionRight: TDemandedActionRight,
45
45
  export declare const hasEveryPermissions: (demandedPermissions: TPermissionName[], actualPermissions: TPermissions | null) => boolean;
46
46
  export declare const hasEveryActionRight: (demandedActionRights: TDemandedActionRight[], actualActionRights: TActionRights | null) => boolean;
47
47
  export declare const hasSomePermissions: (demandedPermissions: TPermissionName[], actualPermissions: TPermissions | null) => boolean;
48
+ type TIsAuthorizedForDemandedPermissionsOptions = {
49
+ demandedPermissions: TPermissionName[];
50
+ actualPermissions: TPermissions | null;
51
+ isAdminOfAnyOrganization?: boolean;
52
+ isUserAdminOfCurrentProject?: boolean | null;
53
+ shouldMatchSomePermissions?: boolean;
54
+ };
55
+ /**
56
+ * Pure permission check shared by `useIsAuthorized` and callers that cannot use
57
+ * the hook (e.g. OR-ing visibility across many navbar menus).
58
+ *
59
+ * Handles virtual permissions first:
60
+ * - `Administrator` → `isAdminOfAnyOrganization`
61
+ * - `AdministratorOfCurrentProject` → `isUserAdminOfCurrentProject`
62
+ * Then falls back to `hasSomePermissions` / `hasEveryPermissions`.
63
+ */
64
+ export declare const isAuthorizedForDemandedPermissions: ({ demandedPermissions, actualPermissions, isAdminOfAnyOrganization, isUserAdminOfCurrentProject, shouldMatchSomePermissions, }: TIsAuthorizedForDemandedPermissionsOptions) => boolean;
48
65
  export declare const hasSomeDataFence: (options: TOptionsForAppliedDataFence) => boolean;
49
66
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-frontend/permissions",
3
- "version": "27.12.0",
3
+ "version": "27.14.0",
4
4
  "description": "React components to declaratively handle MC permissions",
5
5
  "bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
6
6
  "repository": {
@@ -38,8 +38,8 @@
38
38
  "prop-types": "15.8.1",
39
39
  "tiny-invariant": "1.3.3",
40
40
  "tiny-warning": "1.0.3",
41
- "@commercetools-frontend/application-shell-connectors": "^27.12.0",
42
- "@commercetools-frontend/sentry": "^27.12.0"
41
+ "@commercetools-frontend/application-shell-connectors": "^27.14.0",
42
+ "@commercetools-frontend/sentry": "^27.14.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/jest": "^29.5.14",