@metamask/permission-controller 12.1.1 → 12.2.1

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/dist/Caveat.cjs.map +1 -1
  3. package/dist/Caveat.mjs.map +1 -1
  4. package/dist/PermissionController.cjs +406 -642
  5. package/dist/PermissionController.cjs.map +1 -1
  6. package/dist/PermissionController.d.cts +10 -270
  7. package/dist/PermissionController.d.cts.map +1 -1
  8. package/dist/PermissionController.d.mts +10 -270
  9. package/dist/PermissionController.d.mts.map +1 -1
  10. package/dist/PermissionController.mjs +406 -642
  11. package/dist/PermissionController.mjs.map +1 -1
  12. package/dist/SubjectMetadataController.cjs +42 -40
  13. package/dist/SubjectMetadataController.cjs.map +1 -1
  14. package/dist/SubjectMetadataController.d.cts +1 -17
  15. package/dist/SubjectMetadataController.d.cts.map +1 -1
  16. package/dist/SubjectMetadataController.d.mts +1 -17
  17. package/dist/SubjectMetadataController.d.mts.map +1 -1
  18. package/dist/SubjectMetadataController.mjs +42 -40
  19. package/dist/SubjectMetadataController.mjs.map +1 -1
  20. package/dist/errors.cjs +8 -7
  21. package/dist/errors.cjs.map +1 -1
  22. package/dist/errors.d.cts +4 -9
  23. package/dist/errors.d.cts.map +1 -1
  24. package/dist/errors.d.mts +4 -9
  25. package/dist/errors.d.mts.map +1 -1
  26. package/dist/errors.mjs +1 -0
  27. package/dist/errors.mjs.map +1 -1
  28. package/dist/permission-middleware.cjs +1 -1
  29. package/dist/permission-middleware.cjs.map +1 -1
  30. package/dist/permission-middleware.d.cts +4 -3
  31. package/dist/permission-middleware.d.cts.map +1 -1
  32. package/dist/permission-middleware.d.mts +4 -3
  33. package/dist/permission-middleware.d.mts.map +1 -1
  34. package/dist/permission-middleware.mjs +1 -1
  35. package/dist/permission-middleware.mjs.map +1 -1
  36. package/dist/rpc-methods/revokePermissions.cjs.map +1 -1
  37. package/dist/rpc-methods/revokePermissions.d.cts +1 -1
  38. package/dist/rpc-methods/revokePermissions.d.cts.map +1 -1
  39. package/dist/rpc-methods/revokePermissions.d.mts +1 -1
  40. package/dist/rpc-methods/revokePermissions.d.mts.map +1 -1
  41. package/dist/rpc-methods/revokePermissions.mjs.map +1 -1
  42. package/dist/utils.cjs.map +1 -1
  43. package/dist/utils.d.cts.map +1 -1
  44. package/dist/utils.d.mts.map +1 -1
  45. package/dist/utils.mjs.map +1 -1
  46. package/package.json +9 -13
@@ -4,10 +4,16 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
7
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
8
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
9
15
  };
10
- var _PermissionController_instances, _PermissionController_expectGetCaveatMerger, _PermissionController_applyGrantedPermissions, _PermissionController_mergeIncrementalPermissions, _PermissionController_mergePermission, _PermissionController_mergeCaveat, _PermissionController_handleApprovedPermissions;
16
+ var _PermissionController_instances, _PermissionController_caveatSpecifications, _PermissionController_permissionSpecifications, _PermissionController_unrestrictedMethods, _PermissionController_getPermissionSpecification, _PermissionController_getCaveatSpecification, _PermissionController_expectGetCaveatMerger, _PermissionController_validatePermissionSpecifications, _PermissionController_registerMessageHandlers, _PermissionController_getTypedPermissionSpecification, _PermissionController_deletePermission, _PermissionController_setCaveat, _PermissionController_deleteCaveat, _PermissionController_validateModifiedPermission, _PermissionController_targetExists, _PermissionController_applyGrantedPermissions, _PermissionController_validatePermission, _PermissionController_setValidatedPermissions, _PermissionController_constructCaveats, _PermissionController_validateCaveat, _PermissionController_validateRequestedPermissions, _PermissionController_mergeIncrementalPermissions, _PermissionController_mergePermission, _PermissionController_mergeCaveat, _PermissionController_requestUserApproval, _PermissionController_handleApprovedPermissions, _PermissionController_getSideEffects, _PermissionController_executeSideEffects, _PermissionController_validateApprovedPermissions, _PermissionController_hasApprovalRequest, _PermissionController_rejectPermissionsRequest, _PermissionController_executeRestrictedMethod;
11
17
  Object.defineProperty(exports, "__esModule", { value: true });
12
18
  exports.PermissionController = exports.CaveatMutatorOperation = void 0;
13
19
  const base_controller_1 = require("@metamask/base-controller");
@@ -81,7 +87,7 @@ class PermissionController extends base_controller_1.BaseController {
81
87
  * @returns The names of all unrestricted JSON-RPC methods
82
88
  */
83
89
  get unrestrictedMethods() {
84
- return this._unrestrictedMethods;
90
+ return __classPrivateFieldGet(this, _PermissionController_unrestrictedMethods, "f");
85
91
  }
86
92
  /**
87
93
  * Constructs the PermissionController.
@@ -112,96 +118,22 @@ class PermissionController extends base_controller_1.BaseController {
112
118
  },
113
119
  });
114
120
  _PermissionController_instances.add(this);
115
- this._unrestrictedMethods = new Set(unrestrictedMethods);
116
- this._caveatSpecifications = (0, deep_freeze_strict_1.default)({ ...caveatSpecifications });
117
- this.validatePermissionSpecifications(permissionSpecifications, this._caveatSpecifications);
118
- this._permissionSpecifications = (0, deep_freeze_strict_1.default)({
121
+ _PermissionController_caveatSpecifications.set(this, void 0);
122
+ _PermissionController_permissionSpecifications.set(this, void 0);
123
+ _PermissionController_unrestrictedMethods.set(this, void 0);
124
+ __classPrivateFieldSet(this, _PermissionController_unrestrictedMethods, new Set(unrestrictedMethods), "f");
125
+ __classPrivateFieldSet(this, _PermissionController_caveatSpecifications, (0, deep_freeze_strict_1.default)({ ...caveatSpecifications }), "f");
126
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validatePermissionSpecifications).call(this, permissionSpecifications, __classPrivateFieldGet(this, _PermissionController_caveatSpecifications, "f"));
127
+ __classPrivateFieldSet(this, _PermissionController_permissionSpecifications, (0, deep_freeze_strict_1.default)({
119
128
  ...permissionSpecifications,
120
- });
121
- this.registerMessageHandlers();
129
+ }), "f");
130
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_registerMessageHandlers).call(this);
122
131
  this.createPermissionMiddleware = (0, permission_middleware_1.getPermissionMiddlewareFactory)({
123
- executeRestrictedMethod: this._executeRestrictedMethod.bind(this),
132
+ executeRestrictedMethod: __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_executeRestrictedMethod).bind(this),
124
133
  getRestrictedMethod: this.getRestrictedMethod.bind(this),
125
134
  isUnrestrictedMethod: this.unrestrictedMethods.has.bind(this.unrestrictedMethods),
126
135
  });
127
136
  }
128
- /**
129
- * Gets a permission specification.
130
- *
131
- * @param targetName - The name of the permission specification to get.
132
- * @returns The permission specification with the specified target name.
133
- */
134
- getPermissionSpecification(targetName) {
135
- return this._permissionSpecifications[targetName];
136
- }
137
- /**
138
- * Gets a caveat specification.
139
- *
140
- * @param caveatType - The type of the caveat specification to get.
141
- * @returns The caveat specification with the specified type.
142
- */
143
- getCaveatSpecification(caveatType) {
144
- return this._caveatSpecifications[caveatType];
145
- }
146
- /**
147
- * Constructor helper for validating permission specifications.
148
- *
149
- * Throws an error if validation fails.
150
- *
151
- * @param permissionSpecifications - The permission specifications passed to
152
- * this controller's constructor.
153
- * @param caveatSpecifications - The caveat specifications passed to this
154
- * controller.
155
- */
156
- validatePermissionSpecifications(permissionSpecifications, caveatSpecifications) {
157
- Object.entries(permissionSpecifications).forEach(([targetName, { permissionType, targetName: innerTargetName, allowedCaveats },]) => {
158
- if (!permissionType || !(0, utils_1.hasProperty)(Permission_1.PermissionType, permissionType)) {
159
- throw new Error(`Invalid permission type: "${permissionType}"`);
160
- }
161
- if (!targetName) {
162
- throw new Error(`Invalid permission target name: "${targetName}"`);
163
- }
164
- if (targetName !== innerTargetName) {
165
- throw new Error(`Invalid permission specification: target name "${targetName}" must match specification.targetName value "${innerTargetName}".`);
166
- }
167
- if (allowedCaveats) {
168
- allowedCaveats.forEach((caveatType) => {
169
- if (!(0, utils_1.hasProperty)(caveatSpecifications, caveatType)) {
170
- throw new errors_1.UnrecognizedCaveatTypeError(caveatType);
171
- }
172
- const specification = caveatSpecifications[caveatType];
173
- const isRestrictedMethodCaveat = (0, Caveat_1.isRestrictedMethodCaveatSpecification)(specification);
174
- if ((permissionType === Permission_1.PermissionType.RestrictedMethod &&
175
- !isRestrictedMethodCaveat) ||
176
- (permissionType === Permission_1.PermissionType.Endowment &&
177
- isRestrictedMethodCaveat)) {
178
- throw new errors_1.CaveatSpecificationMismatchError(specification, permissionType);
179
- }
180
- });
181
- }
182
- });
183
- }
184
- /**
185
- * Constructor helper for registering the controller's messenger actions.
186
- */
187
- registerMessageHandlers() {
188
- this.messenger.registerActionHandler(`${controllerName}:clearPermissions`, () => this.clearState());
189
- this.messenger.registerActionHandler(`${controllerName}:getEndowments`, (origin, targetName, requestData) => this.getEndowments(origin, targetName, requestData));
190
- this.messenger.registerActionHandler(`${controllerName}:getSubjectNames`, () => this.getSubjectNames());
191
- this.messenger.registerActionHandler(`${controllerName}:getPermissions`, (origin) => this.getPermissions(origin));
192
- this.messenger.registerActionHandler(`${controllerName}:hasPermission`, (origin, targetName) => this.hasPermission(origin, targetName));
193
- this.messenger.registerActionHandler(`${controllerName}:hasPermissions`, (origin) => this.hasPermissions(origin));
194
- this.messenger.registerActionHandler(`${controllerName}:grantPermissions`, this.grantPermissions.bind(this));
195
- this.messenger.registerActionHandler(`${controllerName}:grantPermissionsIncremental`, this.grantPermissionsIncremental.bind(this));
196
- this.messenger.registerActionHandler(`${controllerName}:requestPermissions`, (subject, permissions) => this.requestPermissions(subject, permissions));
197
- this.messenger.registerActionHandler(`${controllerName}:requestPermissionsIncremental`, (subject, permissions) => this.requestPermissionsIncremental(subject, permissions));
198
- this.messenger.registerActionHandler(`${controllerName}:revokeAllPermissions`, (origin) => this.revokeAllPermissions(origin));
199
- this.messenger.registerActionHandler(`${controllerName}:revokePermissionForAllSubjects`, (target) => this.revokePermissionForAllSubjects(target));
200
- this.messenger.registerActionHandler(`${controllerName}:revokePermissions`, this.revokePermissions.bind(this));
201
- this.messenger.registerActionHandler(`${controllerName}:updateCaveat`, (origin, target, caveatType, caveatValue) => {
202
- this.updateCaveat(origin, target, caveatType, caveatValue);
203
- });
204
- }
205
137
  /**
206
138
  * Clears the state of the controller.
207
139
  */
@@ -212,33 +144,6 @@ class PermissionController extends base_controller_1.BaseController {
212
144
  };
213
145
  });
214
146
  }
215
- /**
216
- * Gets the permission specification corresponding to the given permission
217
- * type and target name. Throws an error if the target name does not
218
- * correspond to a permission, or if the specification is not of the
219
- * given permission type.
220
- *
221
- * @template Type - The type of the permission specification to get.
222
- * @param permissionType - The type of the permission specification to get.
223
- * @param targetName - The name of the permission whose specification to get.
224
- * @param requestingOrigin - The origin of the requesting subject, if any.
225
- * Will be added to any thrown errors.
226
- * @returns The specification object corresponding to the given type and
227
- * target name.
228
- */
229
- getTypedPermissionSpecification(permissionType, targetName, requestingOrigin) {
230
- const failureError = permissionType === Permission_1.PermissionType.RestrictedMethod
231
- ? (0, errors_1.methodNotFound)(targetName, requestingOrigin ? { origin: requestingOrigin } : undefined)
232
- : new errors_1.EndowmentPermissionDoesNotExistError(targetName, requestingOrigin);
233
- if (!this.targetExists(targetName)) {
234
- throw failureError;
235
- }
236
- const specification = this.getPermissionSpecification(targetName);
237
- if (!(0, Permission_1.hasSpecificationType)(specification, permissionType)) {
238
- throw failureError;
239
- }
240
- return specification;
241
- }
242
147
  /**
243
148
  * Gets the implementation of the specified restricted method.
244
149
  *
@@ -252,7 +157,7 @@ class PermissionController extends base_controller_1.BaseController {
252
157
  * @returns The restricted method implementation.
253
158
  */
254
159
  getRestrictedMethod(method, origin) {
255
- return this.getTypedPermissionSpecification(Permission_1.PermissionType.RestrictedMethod, method, origin).methodImplementation;
160
+ return __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getTypedPermissionSpecification).call(this, Permission_1.PermissionType.RestrictedMethod, method, origin).methodImplementation;
256
161
  }
257
162
  /**
258
163
  * Gets a list of all origins of subjects.
@@ -350,7 +255,7 @@ class PermissionController extends base_controller_1.BaseController {
350
255
  if (!(0, utils_1.hasProperty)(permissions, target)) {
351
256
  throw new errors_1.PermissionDoesNotExistError(origin, target);
352
257
  }
353
- this.deletePermission(draftState.subjects, origin, target);
258
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_deletePermission).call(this, draftState.subjects, origin, target);
354
259
  });
355
260
  });
356
261
  });
@@ -369,30 +274,11 @@ class PermissionController extends base_controller_1.BaseController {
369
274
  Object.entries(draftState.subjects).forEach(([origin, subject]) => {
370
275
  const { permissions } = subject;
371
276
  if ((0, utils_1.hasProperty)(permissions, target)) {
372
- this.deletePermission(draftState.subjects, origin, target);
277
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_deletePermission).call(this, draftState.subjects, origin, target);
373
278
  }
374
279
  });
375
280
  });
376
281
  }
377
- /**
378
- * Deletes the permission identified by the given origin and target. If the
379
- * permission is the single remaining permission of its subject, the subject
380
- * is also deleted.
381
- *
382
- * @param subjects - The draft permission controller subjects.
383
- * @param origin - The origin of the subject associated with the permission
384
- * to delete.
385
- * @param target - The target name of the permission to delete.
386
- */
387
- deletePermission(subjects, origin, target) {
388
- const { permissions } = subjects[origin];
389
- if (Object.keys(permissions).length > 1) {
390
- delete permissions[target];
391
- }
392
- else {
393
- delete subjects[origin];
394
- }
395
- }
396
282
  /**
397
283
  * Checks whether the permission of the subject corresponding to the given
398
284
  * origin has a caveat of the specified type.
@@ -456,7 +342,7 @@ class PermissionController extends base_controller_1.BaseController {
456
342
  if (this.hasCaveat(origin, target, caveatType)) {
457
343
  throw new errors_1.CaveatAlreadyExistsError(origin, target, caveatType);
458
344
  }
459
- this.setCaveat(origin, target, caveatType, caveatValue);
345
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_setCaveat).call(this, origin, target, caveatType, caveatValue);
460
346
  }
461
347
  /**
462
348
  * Updates the value of the caveat of the specified type belonging to the
@@ -480,74 +366,7 @@ class PermissionController extends base_controller_1.BaseController {
480
366
  if (!this.hasCaveat(origin, target, caveatType)) {
481
367
  throw new errors_1.CaveatDoesNotExistError(origin, target, caveatType);
482
368
  }
483
- this.setCaveat(origin, target, caveatType, caveatValue);
484
- }
485
- /**
486
- * Sets the specified caveat on the specified permission. Overwrites existing
487
- * caveats of the same type in-place (preserving array order), and adds the
488
- * caveat to the end of the array otherwise.
489
- *
490
- * Throws an error if the permission does not exist or fails to validate after
491
- * its caveats have been modified.
492
- *
493
- * @see {@link PermissionController.addCaveat}
494
- * @see {@link PermissionController.updateCaveat}
495
- * @template TargetName - The permission target name. Should be inferred.
496
- * @template CaveatType - The valid caveat types for the permission. Should
497
- * be inferred.
498
- * @param origin - The origin of the subject.
499
- * @param target - The target name of the permission.
500
- * @param caveatType - The type of the caveat to set.
501
- * @param caveatValue - The value of the caveat to set.
502
- */
503
- setCaveat(origin, target, caveatType, caveatValue) {
504
- this.update((draftState) => {
505
- const subject = draftState.subjects[origin];
506
- // Unreachable because `hasCaveat` is always called before this, and it
507
- // throws if permissions are missing. TypeScript needs this, however.
508
- /* istanbul ignore if */
509
- if (!subject) {
510
- throw new errors_1.UnrecognizedSubjectError(origin);
511
- }
512
- const permission = subject.permissions[target];
513
- /* istanbul ignore if: practically impossible, but TypeScript wants it */
514
- if (!permission) {
515
- throw new errors_1.PermissionDoesNotExistError(origin, target);
516
- }
517
- const caveat = {
518
- type: caveatType,
519
- value: caveatValue,
520
- };
521
- this.validateCaveat(caveat, origin, target);
522
- let addedCaveat = false;
523
- if (permission.caveats) {
524
- const caveatIndex = permission.caveats.findIndex((existingCaveat) => existingCaveat.type === caveat.type);
525
- if (caveatIndex === -1) {
526
- permission.caveats.push(caveat);
527
- addedCaveat = true;
528
- }
529
- else {
530
- permission.caveats.splice(caveatIndex, 1, caveat);
531
- }
532
- }
533
- else {
534
- // At this point, we don't know if the specific permission is allowed
535
- // to have caveats, but it should be impossible to call this method
536
- // for a permission that may not have any caveats. If all else fails,
537
- // the permission validator is also called.
538
- // @ts-expect-error See above comment
539
- permission.caveats = [caveat];
540
- addedCaveat = true;
541
- }
542
- // Mutating a caveat does not warrant permission validation, but mutating
543
- // the caveat array does.
544
- if (addedCaveat) {
545
- this.validateModifiedPermission(permission, origin, {
546
- invokePermissionValidator: true,
547
- performCaveatValidation: false, // We just validated the caveat
548
- });
549
- }
550
- });
369
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_setCaveat).call(this, origin, target, caveatType, caveatValue);
551
370
  }
552
371
  /**
553
372
  * Updates all caveats with the specified type for all subjects and
@@ -599,13 +418,13 @@ class PermissionController extends base_controller_1.BaseController {
599
418
  // results in an error.
600
419
  targetCaveat.value =
601
420
  mutatorResult.value;
602
- this.validateCaveat(targetCaveat, subject.origin, permission.parentCapability);
421
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateCaveat).call(this, targetCaveat, subject.origin, permission.parentCapability);
603
422
  break;
604
423
  case CaveatMutatorOperation.DeleteCaveat:
605
- this.deleteCaveat(permission, targetCaveatType, subject.origin);
424
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_deleteCaveat).call(this, permission, targetCaveatType, subject.origin);
606
425
  break;
607
426
  case CaveatMutatorOperation.RevokePermission:
608
- this.deletePermission(draftState.subjects, subject.origin, permission.parentCapability);
427
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_deletePermission).call(this, draftState.subjects, subject.origin, permission.parentCapability);
609
428
  break;
610
429
  default: {
611
430
  // Overriding as `never` is the expected result of exhaustiveness checking,
@@ -640,70 +459,9 @@ class PermissionController extends base_controller_1.BaseController {
640
459
  if (!permission.caveats) {
641
460
  throw new errors_1.CaveatDoesNotExistError(origin, target, caveatType);
642
461
  }
643
- this.deleteCaveat(permission, caveatType, origin);
462
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_deleteCaveat).call(this, permission, caveatType, origin);
644
463
  });
645
464
  }
646
- /**
647
- * Deletes the specified caveat from the specified permission. If no caveats
648
- * remain after deletion, the permission's caveat property is set to `null`.
649
- * The permission is validated after being modified.
650
- *
651
- * Throws an error if the permission does not have a caveat with the specified
652
- * type.
653
- *
654
- * @param permission - The permission whose caveat to delete.
655
- * @param caveatType - The type of the caveat to delete.
656
- * @param origin - The origin the permission subject.
657
- */
658
- deleteCaveat(permission, caveatType, origin) {
659
- /* istanbul ignore if: not possible in our usage */
660
- if (!permission.caveats) {
661
- throw new errors_1.CaveatDoesNotExistError(origin, permission.parentCapability, caveatType);
662
- }
663
- const caveatIndex = permission.caveats.findIndex((existingCaveat) => existingCaveat.type === caveatType);
664
- if (caveatIndex === -1) {
665
- throw new errors_1.CaveatDoesNotExistError(origin, permission.parentCapability, caveatType);
666
- }
667
- if (permission.caveats.length === 1) {
668
- permission.caveats = null;
669
- }
670
- else {
671
- permission.caveats.splice(caveatIndex, 1);
672
- }
673
- this.validateModifiedPermission(permission, origin, {
674
- invokePermissionValidator: true,
675
- performCaveatValidation: false, // No caveat object was mutated
676
- });
677
- }
678
- /**
679
- * Validates the specified modified permission. Should **always** be invoked
680
- * on a permission when its caveat array has been mutated.
681
- *
682
- * Just like {@link PermissionController.validatePermission}, except that the
683
- * corresponding target name and specification are retrieved first, and an
684
- * error is thrown if the target name does not exist.
685
- *
686
- * @param permission - The modified permission to validate.
687
- * @param origin - The origin associated with the permission.
688
- * @param validationFlags - Validation flags. See {@link PermissionController.validatePermission}.
689
- */
690
- validateModifiedPermission(permission, origin, validationFlags) {
691
- /* istanbul ignore if: this should be impossible */
692
- if (!this.targetExists(permission.parentCapability)) {
693
- throw new Error(`Fatal: Existing permission target "${permission.parentCapability}" has no specification.`);
694
- }
695
- this.validatePermission(this.getPermissionSpecification(permission.parentCapability), permission, origin, validationFlags);
696
- }
697
- /**
698
- * Verifies the existence the specified permission target, i.e. whether it has
699
- * a specification.
700
- *
701
- * @param target - The requested permission target.
702
- * @returns Whether the permission target exists.
703
- */
704
- targetExists(target) {
705
- return (0, utils_1.hasProperty)(this._permissionSpecifications, target);
706
- }
707
465
  /**
708
466
  * Grants _approved_ permissions to the specified subject. Every permission and
709
467
  * caveat is stringently validated—including by calling their specification
@@ -760,139 +518,6 @@ class PermissionController extends base_controller_1.BaseController {
760
518
  requestData,
761
519
  });
762
520
  }
763
- /**
764
- * Validates the specified permission by:
765
- * - Ensuring that if `subjectTypes` is specified, the subject requesting the permission is of a type in the list.
766
- * - Ensuring that its `caveats` property is either `null` or a non-empty array.
767
- * - Ensuring that it only includes caveats allowed by its specification.
768
- * - Ensuring that it includes no duplicate caveats (by caveat type).
769
- * - Validating each caveat object, if `performCaveatValidation` is `true`.
770
- * - Calling the validator of its specification, if one exists and `invokePermissionValidator` is `true`.
771
- *
772
- * An error is thrown if validation fails.
773
- *
774
- * @param specification - The specification of the permission.
775
- * @param permission - The permission to validate.
776
- * @param origin - The origin associated with the permission.
777
- * @param validationOptions - Validation options.
778
- * @param validationOptions.invokePermissionValidator - Whether to invoke the
779
- * permission's consumer-specified validator function, if any.
780
- * @param validationOptions.performCaveatValidation - Whether to invoke
781
- * {@link PermissionController.validateCaveat} on each of the permission's
782
- * caveats.
783
- */
784
- validatePermission(specification, permission, origin, { invokePermissionValidator, performCaveatValidation, }) {
785
- const { allowedCaveats, validator, targetName } = specification;
786
- if (specification.subjectTypes?.length &&
787
- specification.subjectTypes.length > 0) {
788
- const metadata = this.messenger.call('SubjectMetadataController:getSubjectMetadata', origin);
789
- if (!metadata ||
790
- metadata.subjectType === null ||
791
- !specification.subjectTypes.includes(metadata.subjectType)) {
792
- throw specification.permissionType === Permission_1.PermissionType.RestrictedMethod
793
- ? (0, errors_1.methodNotFound)(targetName, { origin })
794
- : new errors_1.EndowmentPermissionDoesNotExistError(targetName, origin);
795
- }
796
- }
797
- if ((0, utils_1.hasProperty)(permission, 'caveats')) {
798
- const { caveats } = permission;
799
- if (caveats !== null && !(Array.isArray(caveats) && caveats.length > 0)) {
800
- throw new errors_1.InvalidCaveatsPropertyError(origin, targetName, caveats);
801
- }
802
- const seenCaveatTypes = new Set();
803
- caveats?.forEach((caveat) => {
804
- if (performCaveatValidation) {
805
- this.validateCaveat(caveat, origin, targetName);
806
- }
807
- if (!allowedCaveats?.includes(caveat.type)) {
808
- throw new errors_1.ForbiddenCaveatError(caveat.type, origin, targetName);
809
- }
810
- if (seenCaveatTypes.has(caveat.type)) {
811
- throw new errors_1.DuplicateCaveatError(caveat.type, origin, targetName);
812
- }
813
- seenCaveatTypes.add(caveat.type);
814
- });
815
- }
816
- if (invokePermissionValidator && validator) {
817
- validator(permission, origin, targetName);
818
- }
819
- }
820
- /**
821
- * Assigns the specified permissions to the subject with the given origin.
822
- * Overwrites all existing permissions, and creates a subject entry if it
823
- * doesn't already exist.
824
- *
825
- * ATTN: Assumes that the new permissions have been validated.
826
- *
827
- * @param origin - The origin of the grantee subject.
828
- * @param permissions - The new permissions for the grantee subject.
829
- */
830
- setValidatedPermissions(origin, permissions) {
831
- this.update((draftState) => {
832
- if (!draftState.subjects[origin]) {
833
- draftState.subjects[origin] = { origin, permissions: {} };
834
- }
835
- draftState.subjects[origin].permissions = (0, immer_1.castDraft)(permissions);
836
- });
837
- }
838
- /**
839
- * Validates the requested caveats for the permission of the specified
840
- * subject origin and target name and returns the validated caveat array.
841
- *
842
- * Throws an error if validation fails.
843
- *
844
- * @param origin - The origin of the permission subject.
845
- * @param target - The permission target name.
846
- * @param requestedCaveats - The requested caveats to construct.
847
- * @returns The constructed caveats.
848
- */
849
- constructCaveats(origin, target, requestedCaveats) {
850
- const caveatArray = requestedCaveats?.map((requestedCaveat) => {
851
- this.validateCaveat(requestedCaveat, origin, target);
852
- // Reassign so that we have a fresh object.
853
- const { type, value } = requestedCaveat;
854
- return { type, value };
855
- });
856
- return caveatArray && (0, controller_utils_1.isNonEmptyArray)(caveatArray)
857
- ? caveatArray
858
- : undefined;
859
- }
860
- /**
861
- * This methods validates that the specified caveat is an object with the
862
- * expected properties and types. It also ensures that a caveat specification
863
- * exists for the requested caveat type, and calls the specification
864
- * validator, if it exists, on the caveat object.
865
- *
866
- * Throws an error if validation fails.
867
- *
868
- * @param caveat - The caveat object to validate.
869
- * @param origin - The origin associated with the subject of the parent
870
- * permission.
871
- * @param target - The target name associated with the parent permission.
872
- */
873
- validateCaveat(caveat, origin, target) {
874
- if (!(0, controller_utils_1.isPlainObject)(caveat)) {
875
- throw new errors_1.InvalidCaveatError(caveat, origin, target);
876
- }
877
- if (Object.keys(caveat).length !== 2) {
878
- throw new errors_1.InvalidCaveatFieldsError(caveat, origin, target);
879
- }
880
- if (typeof caveat.type !== 'string') {
881
- throw new errors_1.InvalidCaveatTypeError(caveat, origin, target);
882
- }
883
- const specification = this.getCaveatSpecification(caveat.type);
884
- if (!specification) {
885
- throw new errors_1.UnrecognizedCaveatTypeError(caveat.type, origin, target);
886
- }
887
- if (!(0, utils_1.hasProperty)(caveat, 'value') || caveat.value === undefined) {
888
- throw new errors_1.CaveatMissingValueError(caveat, origin, target);
889
- }
890
- if (!(0, controller_utils_1.isValidJson)(caveat.value)) {
891
- throw new errors_1.CaveatInvalidJsonError(caveat, origin, target);
892
- }
893
- // Typecast: TypeScript still believes that the caveat is a PlainObject.
894
- specification.validator?.(caveat, origin, target);
895
- }
896
521
  /**
897
522
  * Initiates a permission request that requires user approval.
898
523
  *
@@ -921,7 +546,7 @@ class PermissionController extends base_controller_1.BaseController {
921
546
  async requestPermissions(subject, requestedPermissions, options = {}) {
922
547
  const { origin } = subject;
923
548
  const { id = (0, nanoid_1.nanoid)(), preserveExistingPermissions = true } = options;
924
- this.validateRequestedPermissions(origin, requestedPermissions);
549
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateRequestedPermissions).call(this, origin, requestedPermissions);
925
550
  const metadata = {
926
551
  ...options.metadata,
927
552
  id,
@@ -931,7 +556,7 @@ class PermissionController extends base_controller_1.BaseController {
931
556
  metadata,
932
557
  permissions: requestedPermissions,
933
558
  };
934
- const approvedRequest = await this.requestUserApproval(permissionsRequest);
559
+ const approvedRequest = await __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_requestUserApproval).call(this, permissionsRequest);
935
560
  return await __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_handleApprovedPermissions).call(this, {
936
561
  subject,
937
562
  metadata,
@@ -973,7 +598,7 @@ class PermissionController extends base_controller_1.BaseController {
973
598
  async requestPermissionsIncremental(subject, requestedPermissions, options = {}) {
974
599
  const { origin } = subject;
975
600
  const { id = (0, nanoid_1.nanoid)() } = options;
976
- this.validateRequestedPermissions(origin, requestedPermissions);
601
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateRequestedPermissions).call(this, origin, requestedPermissions);
977
602
  const currentPermissions = this.getPermissions(origin) ?? {};
978
603
  const [newPermissions, permissionDiffMap] = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_mergeIncrementalPermissions).call(this, currentPermissions, requestedPermissions);
979
604
  // The second undefined check is just for type narrowing purposes. These values
@@ -985,7 +610,7 @@ class PermissionController extends base_controller_1.BaseController {
985
610
  // It does not spark joy to run this validation again after the merger operation.
986
611
  // But, optimizing this procedure is probably not worth it, especially considering
987
612
  // that the worst-case scenario for validation degrades to the below function call.
988
- this.validateRequestedPermissions(origin, newPermissions);
613
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateRequestedPermissions).call(this, origin, newPermissions);
989
614
  }
990
615
  catch (error) {
991
616
  if (error instanceof Error) {
@@ -1007,7 +632,7 @@ class PermissionController extends base_controller_1.BaseController {
1007
632
  permissionDiffMap,
1008
633
  },
1009
634
  };
1010
- const approvedRequest = await this.requestUserApproval(permissionsRequest);
635
+ const approvedRequest = await __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_requestUserApproval).call(this, permissionsRequest);
1011
636
  return await __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_handleApprovedPermissions).call(this, {
1012
637
  subject,
1013
638
  metadata,
@@ -1015,172 +640,6 @@ class PermissionController extends base_controller_1.BaseController {
1015
640
  approvedRequest,
1016
641
  });
1017
642
  }
1018
- /**
1019
- * Validates requested permissions. Throws if validation fails.
1020
- *
1021
- * This method ensures that the requested permissions are a properly
1022
- * formatted {@link RequestedPermissions} object, and performs the same
1023
- * validation as {@link PermissionController.grantPermissions}, except that
1024
- * consumer-specified permission validator functions are not called, since
1025
- * they are only called on fully constructed, approved permissions that are
1026
- * otherwise completely valid.
1027
- *
1028
- * Unrecognzied properties on requested permissions are ignored.
1029
- *
1030
- * @param origin - The origin of the grantee subject.
1031
- * @param requestedPermissions - The requested permissions.
1032
- */
1033
- validateRequestedPermissions(origin, requestedPermissions) {
1034
- if (!(0, controller_utils_1.isPlainObject)(requestedPermissions)) {
1035
- throw (0, errors_1.invalidParams)({
1036
- message: `Requested permissions for origin "${origin}" is not a plain object.`,
1037
- data: { origin, requestedPermissions },
1038
- });
1039
- }
1040
- if (Object.keys(requestedPermissions).length === 0) {
1041
- throw (0, errors_1.invalidParams)({
1042
- message: `Permissions request for origin "${origin}" contains no permissions.`,
1043
- data: { requestedPermissions },
1044
- });
1045
- }
1046
- for (const targetName of Object.keys(requestedPermissions)) {
1047
- const permission = requestedPermissions[targetName];
1048
- if (!this.targetExists(targetName)) {
1049
- throw (0, errors_1.methodNotFound)(targetName, { origin, requestedPermissions });
1050
- }
1051
- if (!(0, controller_utils_1.isPlainObject)(permission) ||
1052
- (permission.parentCapability !== undefined &&
1053
- targetName !== permission.parentCapability)) {
1054
- throw (0, errors_1.invalidParams)({
1055
- message: `Permissions request for origin "${origin}" contains invalid requested permission(s).`,
1056
- data: { origin, requestedPermissions },
1057
- });
1058
- }
1059
- // Here we validate the permission without invoking its validator, if any.
1060
- // The validator will be invoked after the permission has been approved.
1061
- this.validatePermission(this.getPermissionSpecification(targetName),
1062
- // Typecast: The permission is still a "PlainObject" here.
1063
- permission, origin, { invokePermissionValidator: false, performCaveatValidation: true });
1064
- }
1065
- }
1066
- /**
1067
- * Adds a request to the {@link ApprovalController} using the
1068
- * {@link AddApprovalRequest} action. Also validates the resulting approved
1069
- * permissions request, and throws an error if validation fails.
1070
- *
1071
- * @param permissionsRequest - The permissions request object.
1072
- * @returns The approved permissions request object.
1073
- */
1074
- async requestUserApproval(permissionsRequest) {
1075
- const { origin, id } = permissionsRequest.metadata;
1076
- const approvedRequest = await this.messenger.call('ApprovalController:addRequest', {
1077
- id,
1078
- origin,
1079
- requestData: permissionsRequest,
1080
- type: utils_2.MethodNames.RequestPermissions,
1081
- }, true);
1082
- this.validateApprovedPermissions(approvedRequest, { id, origin });
1083
- return approvedRequest;
1084
- }
1085
- /**
1086
- * Reunites all the side-effects (onPermitted and onFailure) of the requested permissions inside a record of arrays.
1087
- *
1088
- * @param permissions - The approved permissions.
1089
- * @returns The {@link SideEffects} object containing the handlers arrays.
1090
- */
1091
- getSideEffects(permissions) {
1092
- return Object.keys(permissions).reduce((sideEffectList, targetName) => {
1093
- if (this.targetExists(targetName)) {
1094
- const specification = this.getPermissionSpecification(targetName);
1095
- if (specification.sideEffect) {
1096
- sideEffectList.permittedHandlers[targetName] =
1097
- specification.sideEffect.onPermitted;
1098
- if (specification.sideEffect.onFailure) {
1099
- sideEffectList.failureHandlers[targetName] =
1100
- specification.sideEffect.onFailure;
1101
- }
1102
- }
1103
- }
1104
- return sideEffectList;
1105
- }, { permittedHandlers: {}, failureHandlers: {} });
1106
- }
1107
- /**
1108
- * Executes the side-effects of the approved permissions while handling the errors if any.
1109
- * It will pass an instance of the {@link messenger} and the request data associated with the permission request to the handlers through its params.
1110
- *
1111
- * @param sideEffects - the side-effect record created by {@link getSideEffects}
1112
- * @param requestData - the permissions requestData.
1113
- * @returns the value returned by all the `onPermitted` handlers in an array.
1114
- */
1115
- async executeSideEffects(sideEffects, requestData) {
1116
- const { permittedHandlers, failureHandlers } = sideEffects;
1117
- const params = {
1118
- requestData,
1119
- messenger: this.messenger,
1120
- };
1121
- const promiseResults = await Promise.allSettled(Object.values(permittedHandlers).map((permittedHandler) => permittedHandler(params)));
1122
- // lib.es2020.promise.d.ts does not export its types so we're using a simple type.
1123
- const rejectedHandlers = promiseResults.filter((promise) => promise.status === 'rejected');
1124
- if (rejectedHandlers.length > 0) {
1125
- const failureHandlersList = Object.values(failureHandlers);
1126
- if (failureHandlersList.length > 0) {
1127
- try {
1128
- await Promise.all(failureHandlersList.map((failureHandler) => failureHandler(params)));
1129
- }
1130
- catch (error) {
1131
- throw (0, errors_1.internalError)('Unexpected error in side-effects', { error });
1132
- }
1133
- }
1134
- const reasons = rejectedHandlers.map((handler) => handler.reason);
1135
- reasons.forEach((reason) => {
1136
- console.error(reason);
1137
- });
1138
- throw reasons.length > 1
1139
- ? (0, errors_1.internalError)('Multiple errors occurred during side-effects execution', { errors: reasons })
1140
- : reasons[0];
1141
- }
1142
- // lib.es2020.promise.d.ts does not export its types so we're using a simple type.
1143
- return promiseResults.map(({ value }) => value);
1144
- }
1145
- /**
1146
- * Validates an approved {@link PermissionsRequest} object. The approved
1147
- * request must have the required `metadata` and `permissions` properties,
1148
- * the `id` and `origin` of the `metadata` must match the original request
1149
- * metadata, and the requested permissions must be valid per
1150
- * {@link PermissionController.validateRequestedPermissions}. Any extra
1151
- * metadata properties are ignored.
1152
- *
1153
- * An error is thrown if validation fails.
1154
- *
1155
- * @param approvedRequest - The approved permissions request object.
1156
- * @param originalMetadata - The original request metadata.
1157
- */
1158
- validateApprovedPermissions(approvedRequest, originalMetadata) {
1159
- const { id, origin } = originalMetadata;
1160
- if (!(0, controller_utils_1.isPlainObject)(approvedRequest) ||
1161
- !(0, controller_utils_1.isPlainObject)(approvedRequest.metadata)) {
1162
- throw (0, errors_1.internalError)(`Approved permissions request for subject "${origin}" is invalid.`, { data: { approvedRequest } });
1163
- }
1164
- const { metadata: { id: newId, origin: newOrigin }, permissions, } = approvedRequest;
1165
- if (newId !== id) {
1166
- throw (0, errors_1.internalError)(`Approved permissions request for subject "${origin}" mutated its id.`, { originalId: id, mutatedId: newId });
1167
- }
1168
- if (newOrigin !== origin) {
1169
- throw (0, errors_1.internalError)(`Approved permissions request for subject "${origin}" mutated its origin.`, { originalOrigin: origin, mutatedOrigin: newOrigin });
1170
- }
1171
- try {
1172
- this.validateRequestedPermissions(origin, permissions);
1173
- }
1174
- catch (error) {
1175
- if (error instanceof Error) {
1176
- // Re-throw as an internal error; we should never receive invalid approved
1177
- // permissions.
1178
- throw (0, errors_1.internalError)(`Invalid approved permissions request: ${error.message}`, error instanceof rpc_errors_1.JsonRpcError ? error.data : undefined);
1179
- }
1180
- /* istanbul ignore next: This should be impossible */
1181
- throw (0, errors_1.internalError)('Unrecognized error type', { error });
1182
- }
1183
- }
1184
643
  /**
1185
644
  * Accepts a permissions request created by
1186
645
  * {@link PermissionController.requestPermissions}.
@@ -1189,11 +648,11 @@ class PermissionController extends base_controller_1.BaseController {
1189
648
  */
1190
649
  async acceptPermissionsRequest(request) {
1191
650
  const { id } = request.metadata;
1192
- if (!this.hasApprovalRequest({ id })) {
651
+ if (!__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_hasApprovalRequest).call(this, { id })) {
1193
652
  throw new errors_1.PermissionsRequestNotFoundError(id);
1194
653
  }
1195
654
  if (Object.keys(request.permissions).length === 0) {
1196
- this._rejectPermissionsRequest(id, (0, errors_1.invalidParams)({
655
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_rejectPermissionsRequest).call(this, id, (0, errors_1.invalidParams)({
1197
656
  message: 'Must request at least one permission.',
1198
657
  }));
1199
658
  return;
@@ -1204,7 +663,7 @@ class PermissionController extends base_controller_1.BaseController {
1204
663
  catch (error) {
1205
664
  // If accepting unexpectedly fails, reject the request and re-throw the
1206
665
  // error
1207
- this._rejectPermissionsRequest(id, error);
666
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_rejectPermissionsRequest).call(this, id, error);
1208
667
  throw error;
1209
668
  }
1210
669
  }
@@ -1215,37 +674,10 @@ class PermissionController extends base_controller_1.BaseController {
1215
674
  * @param id - The id of the request to be rejected.
1216
675
  */
1217
676
  async rejectPermissionsRequest(id) {
1218
- if (!this.hasApprovalRequest({ id })) {
677
+ if (!__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_hasApprovalRequest).call(this, { id })) {
1219
678
  throw new errors_1.PermissionsRequestNotFoundError(id);
1220
679
  }
1221
- this._rejectPermissionsRequest(id, (0, errors_1.userRejectedRequest)());
1222
- }
1223
- /**
1224
- * Checks whether the {@link ApprovalController} has a particular permissions
1225
- * request.
1226
- *
1227
- * @see {@link PermissionController.acceptPermissionsRequest} and
1228
- * {@link PermissionController.rejectPermissionsRequest} for usage.
1229
- * @param options - The {@link HasApprovalRequest} options.
1230
- * @param options.id - The id of the approval request to check for.
1231
- * @returns Whether the specified request exists.
1232
- */
1233
- hasApprovalRequest(options) {
1234
- return this.messenger.call('ApprovalController:hasRequest', options);
1235
- }
1236
- /**
1237
- * Rejects the permissions request with the specified id, with the specified
1238
- * error as the reason. This method is effectively a wrapper around a
1239
- * messenger call for the `ApprovalController:rejectRequest` action.
1240
- *
1241
- * @see {@link PermissionController.acceptPermissionsRequest} and
1242
- * {@link PermissionController.rejectPermissionsRequest} for usage.
1243
- * @param id - The id of the request to reject.
1244
- * @param error - The error associated with the rejection.
1245
- * @returns Nothing
1246
- */
1247
- _rejectPermissionsRequest(id, error) {
1248
- return this.messenger.call('ApprovalController:rejectRequest', id, error);
680
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_rejectPermissionsRequest).call(this, id, (0, errors_1.userRejectedRequest)());
1249
681
  }
1250
682
  /**
1251
683
  * Gets the subject's endowments per the specified endowment permission.
@@ -1263,7 +695,7 @@ class PermissionController extends base_controller_1.BaseController {
1263
695
  if (!this.hasPermission(origin, targetName)) {
1264
696
  throw (0, errors_1.unauthorized)({ data: { origin, targetName } });
1265
697
  }
1266
- return this.getTypedPermissionSpecification(Permission_1.PermissionType.Endowment, targetName, origin).endowmentGetter({ origin, requestData });
698
+ return __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getTypedPermissionSpecification).call(this, Permission_1.PermissionType.Endowment, targetName, origin).endowmentGetter({ origin, requestData });
1267
699
  }
1268
700
  /**
1269
701
  * Executes a restricted method as the subject with the given origin.
@@ -1293,46 +725,164 @@ class PermissionController extends base_controller_1.BaseController {
1293
725
  async executeRestrictedMethod(origin, targetName, params) {
1294
726
  // Throws if the method does not exist
1295
727
  const methodImplementation = this.getRestrictedMethod(targetName, origin);
1296
- const result = await this._executeRestrictedMethod(methodImplementation, { origin }, targetName, params);
728
+ const result = await __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_executeRestrictedMethod).call(this, methodImplementation, { origin }, targetName, params);
1297
729
  if (result === undefined) {
1298
730
  throw new Error(`Internal request for method "${targetName}" as origin "${origin}" returned no result.`);
1299
731
  }
1300
732
  return result;
1301
733
  }
1302
- /**
1303
- * An internal method used in the controller's `json-rpc-engine` middleware
1304
- * and {@link PermissionController.executeRestrictedMethod}. Calls the
1305
- * specified restricted method implementation after decorating it with the
1306
- * caveats of its permission. Throws if the subject does not have the
1307
- * requisite permission.
1308
- *
1309
- * ATTN: Parameter validation is the responsibility of the caller, or
1310
- * the restricted method implementation in the case of `params`.
1311
- *
1312
- * @see {@link PermissionController.executeRestrictedMethod} and
1313
- * {@link PermissionController.createPermissionMiddleware} for usage.
1314
- * @param methodImplementation - The implementation of the method to call.
1315
- * @param subject - Metadata about the subject that made the request.
1316
- * @param method - The method name
1317
- * @param params - Params needed for executing the restricted method
1318
- * @returns The result of the restricted method implementation
1319
- */
1320
- _executeRestrictedMethod(methodImplementation, subject, method, params = []) {
1321
- const { origin } = subject;
1322
- const permission = this.getPermission(origin, method);
1323
- if (!permission) {
1324
- throw (0, errors_1.unauthorized)({ data: { origin, method } });
1325
- }
1326
- return (0, Caveat_1.decorateWithCaveats)(methodImplementation, permission, this._caveatSpecifications)({ method, params, context: { origin } });
1327
- }
1328
734
  }
1329
735
  exports.PermissionController = PermissionController;
1330
- _PermissionController_instances = new WeakSet(), _PermissionController_expectGetCaveatMerger = function _PermissionController_expectGetCaveatMerger(caveatType) {
1331
- const { merger } = this.getCaveatSpecification(caveatType);
736
+ _PermissionController_caveatSpecifications = new WeakMap(), _PermissionController_permissionSpecifications = new WeakMap(), _PermissionController_unrestrictedMethods = new WeakMap(), _PermissionController_instances = new WeakSet(), _PermissionController_getPermissionSpecification = function _PermissionController_getPermissionSpecification(targetName) {
737
+ return __classPrivateFieldGet(this, _PermissionController_permissionSpecifications, "f")[targetName];
738
+ }, _PermissionController_getCaveatSpecification = function _PermissionController_getCaveatSpecification(caveatType) {
739
+ return __classPrivateFieldGet(this, _PermissionController_caveatSpecifications, "f")[caveatType];
740
+ }, _PermissionController_expectGetCaveatMerger = function _PermissionController_expectGetCaveatMerger(caveatType) {
741
+ const { merger } = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getCaveatSpecification).call(this, caveatType);
1332
742
  if (merger === undefined) {
1333
743
  throw new errors_1.CaveatMergerDoesNotExistError(caveatType);
1334
744
  }
1335
745
  return merger;
746
+ }, _PermissionController_validatePermissionSpecifications = function _PermissionController_validatePermissionSpecifications(permissionSpecifications, caveatSpecifications) {
747
+ Object.entries(permissionSpecifications).forEach(([targetName, { permissionType, targetName: innerTargetName, allowedCaveats },]) => {
748
+ if (!permissionType || !(0, utils_1.hasProperty)(Permission_1.PermissionType, permissionType)) {
749
+ throw new Error(`Invalid permission type: "${permissionType}"`);
750
+ }
751
+ if (!targetName) {
752
+ throw new Error(`Invalid permission target name: "${targetName}"`);
753
+ }
754
+ if (targetName !== innerTargetName) {
755
+ throw new Error(`Invalid permission specification: target name "${targetName}" must match specification.targetName value "${innerTargetName}".`);
756
+ }
757
+ if (allowedCaveats) {
758
+ allowedCaveats.forEach((caveatType) => {
759
+ if (!(0, utils_1.hasProperty)(caveatSpecifications, caveatType)) {
760
+ throw new errors_1.UnrecognizedCaveatTypeError(caveatType);
761
+ }
762
+ const specification = caveatSpecifications[caveatType];
763
+ const isRestrictedMethodCaveat = (0, Caveat_1.isRestrictedMethodCaveatSpecification)(specification);
764
+ if ((permissionType === Permission_1.PermissionType.RestrictedMethod &&
765
+ !isRestrictedMethodCaveat) ||
766
+ (permissionType === Permission_1.PermissionType.Endowment &&
767
+ isRestrictedMethodCaveat)) {
768
+ throw new errors_1.CaveatSpecificationMismatchError(specification, permissionType);
769
+ }
770
+ });
771
+ }
772
+ });
773
+ }, _PermissionController_registerMessageHandlers = function _PermissionController_registerMessageHandlers() {
774
+ this.messenger.registerActionHandler(`${controllerName}:clearPermissions`, () => this.clearState());
775
+ this.messenger.registerActionHandler(`${controllerName}:getEndowments`, (origin, targetName, requestData) => this.getEndowments(origin, targetName, requestData));
776
+ this.messenger.registerActionHandler(`${controllerName}:getSubjectNames`, () => this.getSubjectNames());
777
+ this.messenger.registerActionHandler(`${controllerName}:getPermissions`, (origin) => this.getPermissions(origin));
778
+ this.messenger.registerActionHandler(`${controllerName}:hasPermission`, (origin, targetName) => this.hasPermission(origin, targetName));
779
+ this.messenger.registerActionHandler(`${controllerName}:hasPermissions`, (origin) => this.hasPermissions(origin));
780
+ this.messenger.registerActionHandler(`${controllerName}:grantPermissions`, this.grantPermissions.bind(this));
781
+ this.messenger.registerActionHandler(`${controllerName}:grantPermissionsIncremental`, this.grantPermissionsIncremental.bind(this));
782
+ this.messenger.registerActionHandler(`${controllerName}:requestPermissions`, (subject, permissions) => this.requestPermissions(subject, permissions));
783
+ this.messenger.registerActionHandler(`${controllerName}:requestPermissionsIncremental`, (subject, permissions) => this.requestPermissionsIncremental(subject, permissions));
784
+ this.messenger.registerActionHandler(`${controllerName}:revokeAllPermissions`, (origin) => this.revokeAllPermissions(origin));
785
+ this.messenger.registerActionHandler(`${controllerName}:revokePermissionForAllSubjects`, (target) => this.revokePermissionForAllSubjects(target));
786
+ this.messenger.registerActionHandler(`${controllerName}:revokePermissions`, this.revokePermissions.bind(this));
787
+ this.messenger.registerActionHandler(`${controllerName}:updateCaveat`, (origin, target, caveatType, caveatValue) => {
788
+ this.updateCaveat(origin, target, caveatType, caveatValue);
789
+ });
790
+ this.messenger.registerActionHandler(`${controllerName}:getCaveat`, (origin, target, caveatType) => this.getCaveat(origin, target, caveatType));
791
+ }, _PermissionController_getTypedPermissionSpecification = function _PermissionController_getTypedPermissionSpecification(permissionType, targetName, requestingOrigin) {
792
+ const failureError = permissionType === Permission_1.PermissionType.RestrictedMethod
793
+ ? (0, errors_1.methodNotFound)(targetName, requestingOrigin ? { origin: requestingOrigin } : undefined)
794
+ : new errors_1.EndowmentPermissionDoesNotExistError(targetName, requestingOrigin);
795
+ if (!__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_targetExists).call(this, targetName)) {
796
+ throw failureError;
797
+ }
798
+ const specification = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getPermissionSpecification).call(this, targetName);
799
+ if (!(0, Permission_1.hasSpecificationType)(specification, permissionType)) {
800
+ throw failureError;
801
+ }
802
+ return specification;
803
+ }, _PermissionController_deletePermission = function _PermissionController_deletePermission(subjects, origin, target) {
804
+ const { permissions } = subjects[origin];
805
+ if (Object.keys(permissions).length > 1) {
806
+ delete permissions[target];
807
+ }
808
+ else {
809
+ delete subjects[origin];
810
+ }
811
+ }, _PermissionController_setCaveat = function _PermissionController_setCaveat(origin, target, caveatType, caveatValue) {
812
+ this.update((draftState) => {
813
+ const subject = draftState.subjects[origin];
814
+ // Unreachable because `hasCaveat` is always called before this, and it
815
+ // throws if permissions are missing. TypeScript needs this, however.
816
+ /* istanbul ignore if */
817
+ if (!subject) {
818
+ throw new errors_1.UnrecognizedSubjectError(origin);
819
+ }
820
+ const permission = subject.permissions[target];
821
+ /* istanbul ignore if: practically impossible, but TypeScript wants it */
822
+ if (!permission) {
823
+ throw new errors_1.PermissionDoesNotExistError(origin, target);
824
+ }
825
+ const caveat = {
826
+ type: caveatType,
827
+ value: caveatValue,
828
+ };
829
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateCaveat).call(this, caveat, origin, target);
830
+ let addedCaveat = false;
831
+ if (permission.caveats) {
832
+ const caveatIndex = permission.caveats.findIndex((existingCaveat) => existingCaveat.type === caveat.type);
833
+ if (caveatIndex === -1) {
834
+ permission.caveats.push(caveat);
835
+ addedCaveat = true;
836
+ }
837
+ else {
838
+ permission.caveats.splice(caveatIndex, 1, caveat);
839
+ }
840
+ }
841
+ else {
842
+ // At this point, we don't know if the specific permission is allowed
843
+ // to have caveats, but it should be impossible to call this method
844
+ // for a permission that may not have any caveats. If all else fails,
845
+ // the permission validator is also called.
846
+ // @ts-expect-error See above comment
847
+ permission.caveats = [caveat];
848
+ addedCaveat = true;
849
+ }
850
+ // Mutating a caveat does not warrant permission validation, but mutating
851
+ // the caveat array does.
852
+ if (addedCaveat) {
853
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateModifiedPermission).call(this, permission, origin, {
854
+ invokePermissionValidator: true,
855
+ performCaveatValidation: false, // We just validated the caveat
856
+ });
857
+ }
858
+ });
859
+ }, _PermissionController_deleteCaveat = function _PermissionController_deleteCaveat(permission, caveatType, origin) {
860
+ /* istanbul ignore if: not possible in our usage */
861
+ if (!permission.caveats) {
862
+ throw new errors_1.CaveatDoesNotExistError(origin, permission.parentCapability, caveatType);
863
+ }
864
+ const caveatIndex = permission.caveats.findIndex((existingCaveat) => existingCaveat.type === caveatType);
865
+ if (caveatIndex === -1) {
866
+ throw new errors_1.CaveatDoesNotExistError(origin, permission.parentCapability, caveatType);
867
+ }
868
+ if (permission.caveats.length === 1) {
869
+ permission.caveats = null;
870
+ }
871
+ else {
872
+ permission.caveats.splice(caveatIndex, 1);
873
+ }
874
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateModifiedPermission).call(this, permission, origin, {
875
+ invokePermissionValidator: true,
876
+ performCaveatValidation: false, // No caveat object was mutated
877
+ });
878
+ }, _PermissionController_validateModifiedPermission = function _PermissionController_validateModifiedPermission(permission, origin, validationFlags) {
879
+ /* istanbul ignore if: this should be impossible */
880
+ if (!__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_targetExists).call(this, permission.parentCapability)) {
881
+ throw new Error(`Fatal: Existing permission target "${permission.parentCapability}" has no specification.`);
882
+ }
883
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validatePermission).call(this, __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getPermissionSpecification).call(this, permission.parentCapability), permission, origin, validationFlags);
884
+ }, _PermissionController_targetExists = function _PermissionController_targetExists(target) {
885
+ return (0, utils_1.hasProperty)(__classPrivateFieldGet(this, _PermissionController_permissionSpecifications, "f"), target);
1336
886
  }, _PermissionController_applyGrantedPermissions = function _PermissionController_applyGrantedPermissions({ approvedPermissions, subject, mergePermissions, preserveExistingPermissions, requestData, }) {
1337
887
  const { origin } = subject;
1338
888
  if (!origin || typeof origin !== 'string') {
@@ -1344,7 +894,7 @@ _PermissionController_instances = new WeakSet(), _PermissionController_expectGet
1344
894
  }
1345
895
  : {});
1346
896
  for (const [requestedTarget, approvedPermission] of Object.entries(approvedPermissions)) {
1347
- if (!this.targetExists(requestedTarget)) {
897
+ if (!__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_targetExists).call(this, requestedTarget)) {
1348
898
  throw (0, errors_1.methodNotFound)(requestedTarget);
1349
899
  }
1350
900
  if (approvedPermission.parentCapability !== undefined &&
@@ -1354,9 +904,9 @@ _PermissionController_instances = new WeakSet(), _PermissionController_expectGet
1354
904
  // We have verified that the target exists, and reassign it to change its
1355
905
  // type.
1356
906
  const targetName = requestedTarget;
1357
- const specification = this.getPermissionSpecification(targetName);
907
+ const specification = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getPermissionSpecification).call(this, targetName);
1358
908
  // The requested caveats are validated here.
1359
- const caveats = this.constructCaveats(origin, targetName, approvedPermission.caveats);
909
+ const caveats = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_constructCaveats).call(this, origin, targetName, approvedPermission.caveats);
1360
910
  const permissionOptions = {
1361
911
  caveats,
1362
912
  invoker: origin,
@@ -1372,14 +922,120 @@ _PermissionController_instances = new WeakSet(), _PermissionController_expectGet
1372
922
  if (mergePermissions) {
1373
923
  permission = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_mergePermission).call(this, permissions[targetName], permission)[0];
1374
924
  }
1375
- this.validatePermission(specification, permission, origin, {
925
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validatePermission).call(this, specification, permission, origin, {
1376
926
  invokePermissionValidator: true,
1377
927
  performCaveatValidation: true,
1378
928
  });
1379
929
  permissions[targetName] = permission;
1380
930
  }
1381
- this.setValidatedPermissions(origin, permissions);
931
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_setValidatedPermissions).call(this, origin, permissions);
1382
932
  return permissions;
933
+ }, _PermissionController_validatePermission = function _PermissionController_validatePermission(specification, permission, origin, { invokePermissionValidator, performCaveatValidation, }) {
934
+ const { allowedCaveats, validator, targetName } = specification;
935
+ if (specification.subjectTypes?.length &&
936
+ specification.subjectTypes.length > 0) {
937
+ const metadata = this.messenger.call('SubjectMetadataController:getSubjectMetadata', origin);
938
+ if (!metadata ||
939
+ metadata.subjectType === null ||
940
+ !specification.subjectTypes.includes(metadata.subjectType)) {
941
+ throw specification.permissionType === Permission_1.PermissionType.RestrictedMethod
942
+ ? (0, errors_1.methodNotFound)(targetName, { origin })
943
+ : new errors_1.EndowmentPermissionDoesNotExistError(targetName, origin);
944
+ }
945
+ }
946
+ if ((0, utils_1.hasProperty)(permission, 'caveats')) {
947
+ const { caveats } = permission;
948
+ if (caveats !== null && !(Array.isArray(caveats) && caveats.length > 0)) {
949
+ throw new errors_1.InvalidCaveatsPropertyError(origin, targetName, caveats);
950
+ }
951
+ const seenCaveatTypes = new Set();
952
+ caveats?.forEach((caveat) => {
953
+ if (performCaveatValidation) {
954
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateCaveat).call(this, caveat, origin, targetName);
955
+ }
956
+ if (!allowedCaveats?.includes(caveat.type)) {
957
+ throw new errors_1.ForbiddenCaveatError(caveat.type, origin, targetName);
958
+ }
959
+ if (seenCaveatTypes.has(caveat.type)) {
960
+ throw new errors_1.DuplicateCaveatError(caveat.type, origin, targetName);
961
+ }
962
+ seenCaveatTypes.add(caveat.type);
963
+ });
964
+ }
965
+ if (invokePermissionValidator && validator) {
966
+ validator(permission, origin, targetName);
967
+ }
968
+ }, _PermissionController_setValidatedPermissions = function _PermissionController_setValidatedPermissions(origin, permissions) {
969
+ this.update((draftState) => {
970
+ if (!draftState.subjects[origin]) {
971
+ draftState.subjects[origin] = { origin, permissions: {} };
972
+ }
973
+ draftState.subjects[origin].permissions = (0, immer_1.castDraft)(permissions);
974
+ });
975
+ }, _PermissionController_constructCaveats = function _PermissionController_constructCaveats(origin, target, requestedCaveats) {
976
+ const caveatArray = requestedCaveats?.map((requestedCaveat) => {
977
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateCaveat).call(this, requestedCaveat, origin, target);
978
+ // Reassign so that we have a fresh object.
979
+ const { type, value } = requestedCaveat;
980
+ return { type, value };
981
+ });
982
+ return caveatArray && (0, controller_utils_1.isNonEmptyArray)(caveatArray)
983
+ ? caveatArray
984
+ : undefined;
985
+ }, _PermissionController_validateCaveat = function _PermissionController_validateCaveat(caveat, origin, target) {
986
+ if (!(0, controller_utils_1.isPlainObject)(caveat)) {
987
+ throw new errors_1.InvalidCaveatError(caveat, origin, target);
988
+ }
989
+ if (Object.keys(caveat).length !== 2) {
990
+ throw new errors_1.InvalidCaveatFieldsError(caveat, origin, target);
991
+ }
992
+ if (typeof caveat.type !== 'string') {
993
+ throw new errors_1.InvalidCaveatTypeError(caveat, origin, target);
994
+ }
995
+ const specification = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getCaveatSpecification).call(this, caveat.type);
996
+ if (!specification) {
997
+ throw new errors_1.UnrecognizedCaveatTypeError(caveat.type, origin, target);
998
+ }
999
+ if (!(0, utils_1.hasProperty)(caveat, 'value') || caveat.value === undefined) {
1000
+ throw new errors_1.CaveatMissingValueError(caveat, origin, target);
1001
+ }
1002
+ if (!(0, controller_utils_1.isValidJson)(caveat.value)) {
1003
+ throw new errors_1.CaveatInvalidJsonError(caveat, origin, target);
1004
+ }
1005
+ // Typecast: TypeScript still believes that the caveat is a PlainObject.
1006
+ specification.validator?.(caveat, origin, target);
1007
+ }, _PermissionController_validateRequestedPermissions = function _PermissionController_validateRequestedPermissions(origin, requestedPermissions) {
1008
+ if (!(0, controller_utils_1.isPlainObject)(requestedPermissions)) {
1009
+ throw (0, errors_1.invalidParams)({
1010
+ message: `Requested permissions for origin "${origin}" is not a plain object.`,
1011
+ data: { origin, requestedPermissions },
1012
+ });
1013
+ }
1014
+ if (Object.keys(requestedPermissions).length === 0) {
1015
+ throw (0, errors_1.invalidParams)({
1016
+ message: `Permissions request for origin "${origin}" contains no permissions.`,
1017
+ data: { requestedPermissions },
1018
+ });
1019
+ }
1020
+ for (const targetName of Object.keys(requestedPermissions)) {
1021
+ const permission = requestedPermissions[targetName];
1022
+ if (!__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_targetExists).call(this, targetName)) {
1023
+ throw (0, errors_1.methodNotFound)(targetName, { origin, requestedPermissions });
1024
+ }
1025
+ if (!(0, controller_utils_1.isPlainObject)(permission) ||
1026
+ (permission.parentCapability !== undefined &&
1027
+ targetName !== permission.parentCapability)) {
1028
+ throw (0, errors_1.invalidParams)({
1029
+ message: `Permissions request for origin "${origin}" contains invalid requested permission(s).`,
1030
+ data: { origin, requestedPermissions },
1031
+ });
1032
+ }
1033
+ // Here we validate the permission without invoking its validator, if any.
1034
+ // The validator will be invoked after the permission has been approved.
1035
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validatePermission).call(this, __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getPermissionSpecification).call(this, targetName),
1036
+ // Typecast: The permission is still a "PlainObject" here.
1037
+ permission, origin, { invokePermissionValidator: false, performCaveatValidation: true });
1038
+ }
1383
1039
  }, _PermissionController_mergeIncrementalPermissions = function _PermissionController_mergeIncrementalPermissions(existingPermissions, incrementalRequestedPermissions) {
1384
1040
  const permissionDiffMap = {};
1385
1041
  // Use immer's produce as a convenience for calculating the new permissions
@@ -1457,6 +1113,25 @@ _PermissionController_instances = new WeakSet(), _PermissionController_expectGet
1457
1113
  diff,
1458
1114
  ]
1459
1115
  : [];
1116
+ }, _PermissionController_requestUserApproval =
1117
+ /**
1118
+ * Adds a request to the {@link ApprovalController} using the
1119
+ * {@link ApprovalControllerAddRequestAction} action. Also validates the resulting approved
1120
+ * permissions request, and throws an error if validation fails.
1121
+ *
1122
+ * @param permissionsRequest - The permissions request object.
1123
+ * @returns The approved permissions request object.
1124
+ */
1125
+ async function _PermissionController_requestUserApproval(permissionsRequest) {
1126
+ const { origin, id } = permissionsRequest.metadata;
1127
+ const approvedRequest = await this.messenger.call('ApprovalController:addRequest', {
1128
+ id,
1129
+ origin,
1130
+ requestData: permissionsRequest,
1131
+ type: utils_2.MethodNames.RequestPermissions,
1132
+ }, true);
1133
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateApprovedPermissions).call(this, approvedRequest, { id, origin });
1134
+ return approvedRequest;
1460
1135
  }, _PermissionController_handleApprovedPermissions =
1461
1136
  /**
1462
1137
  * Accepts a permissions request that has been approved by the user. This
@@ -1474,9 +1149,9 @@ _PermissionController_instances = new WeakSet(), _PermissionController_expectGet
1474
1149
  async function _PermissionController_handleApprovedPermissions({ subject, metadata, preserveExistingPermissions, approvedRequest, }) {
1475
1150
  const { permissions: approvedPermissions, ...requestData } = approvedRequest;
1476
1151
  const approvedMetadata = { ...metadata };
1477
- const sideEffects = this.getSideEffects(approvedPermissions);
1152
+ const sideEffects = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getSideEffects).call(this, approvedPermissions);
1478
1153
  if (Object.values(sideEffects.permittedHandlers).length > 0) {
1479
- const sideEffectsData = await this.executeSideEffects(sideEffects, approvedRequest);
1154
+ const sideEffectsData = await __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_executeSideEffects).call(this, sideEffects, approvedRequest);
1480
1155
  approvedMetadata.data = Object.keys(sideEffects.permittedHandlers).reduce((acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }), {});
1481
1156
  }
1482
1157
  return [
@@ -1488,5 +1163,94 @@ async function _PermissionController_handleApprovedPermissions({ subject, metada
1488
1163
  }),
1489
1164
  approvedMetadata,
1490
1165
  ];
1166
+ }, _PermissionController_getSideEffects = function _PermissionController_getSideEffects(permissions) {
1167
+ return Object.keys(permissions).reduce((sideEffectList, targetName) => {
1168
+ if (__classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_targetExists).call(this, targetName)) {
1169
+ const specification = __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_getPermissionSpecification).call(this, targetName);
1170
+ if (specification.sideEffect) {
1171
+ sideEffectList.permittedHandlers[targetName] =
1172
+ specification.sideEffect.onPermitted;
1173
+ if (specification.sideEffect.onFailure) {
1174
+ sideEffectList.failureHandlers[targetName] =
1175
+ specification.sideEffect.onFailure;
1176
+ }
1177
+ }
1178
+ }
1179
+ return sideEffectList;
1180
+ }, { permittedHandlers: {}, failureHandlers: {} });
1181
+ }, _PermissionController_executeSideEffects =
1182
+ /**
1183
+ * Executes the side-effects of the approved permissions while handling the errors if any.
1184
+ * It will pass an instance of the {@link messenger} and the request data associated with the permission request to the handlers through its params.
1185
+ *
1186
+ * @param sideEffects - the side-effect record created by {@link #getSideEffects}
1187
+ * @param requestData - the permissions requestData.
1188
+ * @returns the value returned by all the `onPermitted` handlers in an array.
1189
+ */
1190
+ async function _PermissionController_executeSideEffects(sideEffects, requestData) {
1191
+ const { permittedHandlers, failureHandlers } = sideEffects;
1192
+ const params = {
1193
+ requestData,
1194
+ messenger: this.messenger,
1195
+ };
1196
+ const promiseResults = await Promise.allSettled(Object.values(permittedHandlers).map((permittedHandler) => permittedHandler(params)));
1197
+ // lib.es2020.promise.d.ts does not export its types so we're using a simple type.
1198
+ const rejectedHandlers = promiseResults.filter((promise) => promise.status === 'rejected');
1199
+ if (rejectedHandlers.length > 0) {
1200
+ const failureHandlersList = Object.values(failureHandlers);
1201
+ if (failureHandlersList.length > 0) {
1202
+ try {
1203
+ await Promise.all(failureHandlersList.map((failureHandler) => failureHandler(params)));
1204
+ }
1205
+ catch (error) {
1206
+ throw (0, errors_1.internalError)('Unexpected error in side-effects', { error });
1207
+ }
1208
+ }
1209
+ const reasons = rejectedHandlers.map((handler) => handler.reason);
1210
+ reasons.forEach((reason) => {
1211
+ console.error(reason);
1212
+ });
1213
+ throw reasons.length > 1
1214
+ ? (0, errors_1.internalError)('Multiple errors occurred during side-effects execution', { errors: reasons })
1215
+ : reasons[0];
1216
+ }
1217
+ // lib.es2020.promise.d.ts does not export its types so we're using a simple type.
1218
+ return promiseResults.map(({ value }) => value);
1219
+ }, _PermissionController_validateApprovedPermissions = function _PermissionController_validateApprovedPermissions(approvedRequest, originalMetadata) {
1220
+ const { id, origin } = originalMetadata;
1221
+ if (!(0, controller_utils_1.isPlainObject)(approvedRequest) ||
1222
+ !(0, controller_utils_1.isPlainObject)(approvedRequest.metadata)) {
1223
+ throw (0, errors_1.internalError)(`Approved permissions request for subject "${origin}" is invalid.`, { data: { approvedRequest } });
1224
+ }
1225
+ const { metadata: { id: newId, origin: newOrigin }, permissions, } = approvedRequest;
1226
+ if (newId !== id) {
1227
+ throw (0, errors_1.internalError)(`Approved permissions request for subject "${origin}" mutated its id.`, { originalId: id, mutatedId: newId });
1228
+ }
1229
+ if (newOrigin !== origin) {
1230
+ throw (0, errors_1.internalError)(`Approved permissions request for subject "${origin}" mutated its origin.`, { originalOrigin: origin, mutatedOrigin: newOrigin });
1231
+ }
1232
+ try {
1233
+ __classPrivateFieldGet(this, _PermissionController_instances, "m", _PermissionController_validateRequestedPermissions).call(this, origin, permissions);
1234
+ }
1235
+ catch (error) {
1236
+ if (error instanceof Error) {
1237
+ // Re-throw as an internal error; we should never receive invalid approved
1238
+ // permissions.
1239
+ throw (0, errors_1.internalError)(`Invalid approved permissions request: ${error.message}`, error instanceof rpc_errors_1.JsonRpcError ? error.data : undefined);
1240
+ }
1241
+ /* istanbul ignore next: This should be impossible */
1242
+ throw (0, errors_1.internalError)('Unrecognized error type', { error });
1243
+ }
1244
+ }, _PermissionController_hasApprovalRequest = function _PermissionController_hasApprovalRequest(options) {
1245
+ return this.messenger.call('ApprovalController:hasRequest', options);
1246
+ }, _PermissionController_rejectPermissionsRequest = function _PermissionController_rejectPermissionsRequest(id, error) {
1247
+ return this.messenger.call('ApprovalController:rejectRequest', id, error);
1248
+ }, _PermissionController_executeRestrictedMethod = function _PermissionController_executeRestrictedMethod(methodImplementation, subject, method, params = []) {
1249
+ const { origin } = subject;
1250
+ const permission = this.getPermission(origin, method);
1251
+ if (!permission) {
1252
+ throw (0, errors_1.unauthorized)({ data: { origin, method } });
1253
+ }
1254
+ return (0, Caveat_1.decorateWithCaveats)(methodImplementation, permission, __classPrivateFieldGet(this, _PermissionController_caveatSpecifications, "f"))({ method, params, context: { origin } });
1491
1255
  };
1492
1256
  //# sourceMappingURL=PermissionController.cjs.map