@metamask-previews/permission-controller 12.1.1-preview-565dfca2 → 12.1.1-preview-3fa1672

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