@metamask-previews/permission-controller 9.0.2-preview-73f66baf → 9.0.2-preview-4e7f493

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 (84) hide show
  1. package/dist/Caveat.js +4 -4
  2. package/dist/Caveat.mjs +3 -3
  3. package/dist/Permission.js +1 -1
  4. package/dist/Permission.mjs +1 -1
  5. package/dist/PermissionController.js +7 -7
  6. package/dist/PermissionController.mjs +6 -6
  7. package/dist/SubjectMetadataController.js +1 -1
  8. package/dist/SubjectMetadataController.mjs +1 -1
  9. package/dist/chunk-2L4QPE5A.mjs +25 -0
  10. package/dist/chunk-3R56AY2L.mjs +35 -0
  11. package/dist/chunk-3R56AY2L.mjs.map +1 -0
  12. package/dist/{chunk-U5LTEXSU.js → chunk-3X6WO7UG.js} +28 -2
  13. package/dist/chunk-3X6WO7UG.js.map +1 -0
  14. package/dist/{chunk-MCDOYEJY.mjs → chunk-4B6NOD2D.mjs} +392 -96
  15. package/dist/chunk-4B6NOD2D.mjs.map +1 -0
  16. package/dist/{chunk-FEXS6SJF.mjs → chunk-AZUM6CBY.mjs} +27 -1
  17. package/dist/chunk-AZUM6CBY.mjs.map +1 -0
  18. package/dist/{chunk-YVXIWLBE.mjs → chunk-DUZPZORW.mjs} +2 -2
  19. package/dist/{chunk-6Z4WR2GC.js → chunk-DV74ZDGD.js} +7 -7
  20. package/dist/{chunk-5O77G5L6.js → chunk-GHOOCGN3.js} +4 -4
  21. package/dist/{chunk-R66I7AKM.js → chunk-I3DJ23QH.js} +437 -141
  22. package/dist/chunk-I3DJ23QH.js.map +1 -0
  23. package/dist/chunk-PTE4672I.js +35 -0
  24. package/dist/chunk-PTE4672I.js.map +1 -0
  25. package/dist/{chunk-DRXP4C4H.mjs → chunk-RJKSCKTD.mjs} +2 -2
  26. package/dist/chunk-RJKSCKTD.mjs.map +1 -0
  27. package/dist/{chunk-JG74NEYV.js → chunk-RKDXFKNN.js} +4 -4
  28. package/dist/chunk-RKDXFKNN.js.map +1 -0
  29. package/dist/{chunk-N4KQ2BHF.mjs → chunk-RXC2KFRK.mjs} +2 -2
  30. package/dist/{chunk-2ISIACR4.mjs → chunk-TBOKQ5NP.mjs} +4 -4
  31. package/dist/{chunk-AQ35E2HU.js → chunk-VM4LI55W.js} +3 -3
  32. package/dist/{chunk-YRNH4R3G.js → chunk-XM622CMP.js} +3 -3
  33. package/dist/{chunk-VFXNNVQY.mjs → chunk-Y6GRGXOL.mjs} +2 -2
  34. package/dist/chunk-Z2XKIXLS.js +25 -0
  35. package/dist/errors.js +9 -3
  36. package/dist/errors.mjs +8 -2
  37. package/dist/index.js +16 -10
  38. package/dist/index.mjs +15 -9
  39. package/dist/permission-middleware.js +4 -4
  40. package/dist/permission-middleware.mjs +3 -3
  41. package/dist/rpc-methods/getPermissions.js +2 -2
  42. package/dist/rpc-methods/getPermissions.mjs +2 -2
  43. package/dist/rpc-methods/index.js +7 -7
  44. package/dist/rpc-methods/index.mjs +6 -6
  45. package/dist/rpc-methods/requestPermissions.js +5 -5
  46. package/dist/rpc-methods/requestPermissions.mjs +4 -4
  47. package/dist/rpc-methods/revokePermissions.js +5 -5
  48. package/dist/rpc-methods/revokePermissions.mjs +4 -4
  49. package/dist/tsconfig.build.tsbuildinfo +1 -1
  50. package/dist/types/Caveat.d.ts +27 -0
  51. package/dist/types/Caveat.d.ts.map +1 -1
  52. package/dist/types/PermissionController.d.ts +113 -20
  53. package/dist/types/PermissionController.d.ts.map +1 -1
  54. package/dist/types/errors.d.ts +19 -0
  55. package/dist/types/errors.d.ts.map +1 -1
  56. package/dist/types/index.d.ts +2 -1
  57. package/dist/types/index.d.ts.map +1 -1
  58. package/dist/types/utils.d.ts +19 -2
  59. package/dist/types/utils.d.ts.map +1 -1
  60. package/dist/utils.js +5 -3
  61. package/dist/utils.mjs +6 -4
  62. package/package.json +1 -1
  63. package/dist/chunk-CSAU5B4Q.js +0 -10
  64. package/dist/chunk-DRXP4C4H.mjs.map +0 -1
  65. package/dist/chunk-FEXS6SJF.mjs.map +0 -1
  66. package/dist/chunk-JG74NEYV.js.map +0 -1
  67. package/dist/chunk-K5R57Y57.js +0 -12
  68. package/dist/chunk-K5R57Y57.js.map +0 -1
  69. package/dist/chunk-KVKKNDYV.mjs +0 -12
  70. package/dist/chunk-KVKKNDYV.mjs.map +0 -1
  71. package/dist/chunk-MCDOYEJY.mjs.map +0 -1
  72. package/dist/chunk-R66I7AKM.js.map +0 -1
  73. package/dist/chunk-U5LTEXSU.js.map +0 -1
  74. package/dist/chunk-ZSTKOCBT.mjs +0 -10
  75. /package/dist/{chunk-ZSTKOCBT.mjs.map → chunk-2L4QPE5A.mjs.map} +0 -0
  76. /package/dist/{chunk-YVXIWLBE.mjs.map → chunk-DUZPZORW.mjs.map} +0 -0
  77. /package/dist/{chunk-6Z4WR2GC.js.map → chunk-DV74ZDGD.js.map} +0 -0
  78. /package/dist/{chunk-5O77G5L6.js.map → chunk-GHOOCGN3.js.map} +0 -0
  79. /package/dist/{chunk-N4KQ2BHF.mjs.map → chunk-RXC2KFRK.mjs.map} +0 -0
  80. /package/dist/{chunk-2ISIACR4.mjs.map → chunk-TBOKQ5NP.mjs.map} +0 -0
  81. /package/dist/{chunk-AQ35E2HU.js.map → chunk-VM4LI55W.js.map} +0 -0
  82. /package/dist/{chunk-YRNH4R3G.js.map → chunk-XM622CMP.js.map} +0 -0
  83. /package/dist/{chunk-VFXNNVQY.mjs.map → chunk-Y6GRGXOL.mjs.map} +0 -0
  84. /package/dist/{chunk-CSAU5B4Q.js.map → chunk-Z2XKIXLS.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  decorateWithCaveats,
3
3
  isRestrictedMethodCaveatSpecification
4
- } from "./chunk-DRXP4C4H.mjs";
4
+ } from "./chunk-RJKSCKTD.mjs";
5
5
  import {
6
6
  PermissionType,
7
7
  constructPermission,
@@ -10,11 +10,13 @@ import {
10
10
  } from "./chunk-HYMS7IGB.mjs";
11
11
  import {
12
12
  getPermissionMiddlewareFactory
13
- } from "./chunk-N4KQ2BHF.mjs";
13
+ } from "./chunk-RXC2KFRK.mjs";
14
14
  import {
15
15
  CaveatAlreadyExistsError,
16
16
  CaveatDoesNotExistError,
17
17
  CaveatInvalidJsonError,
18
+ CaveatMergeTypeMismatchError,
19
+ CaveatMergerDoesNotExistError,
18
20
  CaveatMissingValueError,
19
21
  CaveatSpecificationMismatchError,
20
22
  DuplicateCaveatError,
@@ -25,6 +27,7 @@ import {
25
27
  InvalidCaveatFieldsError,
26
28
  InvalidCaveatTypeError,
27
29
  InvalidCaveatsPropertyError,
30
+ InvalidMergedPermissionsError,
28
31
  InvalidSubjectIdentifierError,
29
32
  PermissionDoesNotExistError,
30
33
  PermissionsRequestNotFoundError,
@@ -35,7 +38,14 @@ import {
35
38
  methodNotFound,
36
39
  unauthorized,
37
40
  userRejectedRequest
38
- } from "./chunk-FEXS6SJF.mjs";
41
+ } from "./chunk-AZUM6CBY.mjs";
42
+ import {
43
+ collectUniqueAndPairedCaveats
44
+ } from "./chunk-3R56AY2L.mjs";
45
+ import {
46
+ __privateAdd,
47
+ __privateMethod
48
+ } from "./chunk-2L4QPE5A.mjs";
39
49
 
40
50
  // src/PermissionController.ts
41
51
  import { BaseController } from "@metamask/base-controller";
@@ -47,7 +57,7 @@ import {
47
57
  import { JsonRpcError } from "@metamask/rpc-errors";
48
58
  import { hasProperty } from "@metamask/utils";
49
59
  import deepFreeze from "deep-freeze-strict";
50
- import { castDraft } from "immer";
60
+ import { castDraft, produce as immerProduce } from "immer";
51
61
  import { nanoid } from "nanoid";
52
62
  var controllerName = "PermissionController";
53
63
  function getStateMetadata() {
@@ -63,15 +73,8 @@ var CaveatMutatorOperation = /* @__PURE__ */ ((CaveatMutatorOperation2) => {
63
73
  CaveatMutatorOperation2[CaveatMutatorOperation2["revokePermission"] = 3] = "revokePermission";
64
74
  return CaveatMutatorOperation2;
65
75
  })(CaveatMutatorOperation || {});
76
+ var _expectGetCaveatMerger, expectGetCaveatMerger_fn, _applyGrantedPermissions, applyGrantedPermissions_fn, _mergeIncrementalPermissions, mergeIncrementalPermissions_fn, _mergePermission, mergePermission_fn, _mergeCaveat, mergeCaveat_fn, _handleApprovedPermissions, handleApprovedPermissions_fn;
66
77
  var PermissionController = class extends BaseController {
67
- /**
68
- * The names of all JSON-RPC methods that will be ignored by the controller.
69
- *
70
- * @returns The names of all unrestricted JSON-RPC methods
71
- */
72
- get unrestrictedMethods() {
73
- return this._unrestrictedMethods;
74
- }
75
78
  /**
76
79
  * Constructs the PermissionController.
77
80
  *
@@ -106,6 +109,62 @@ var PermissionController = class extends BaseController {
106
109
  ...state
107
110
  }
108
111
  });
112
+ /**
113
+ * Gets the merger function for the specified caveat. Throws if no
114
+ * merger exists.
115
+ *
116
+ * @param caveatType - The type of the caveat whose merger to get.
117
+ * @returns The caveat value merger function for the specified caveat type.
118
+ */
119
+ __privateAdd(this, _expectGetCaveatMerger);
120
+ __privateAdd(this, _applyGrantedPermissions);
121
+ /**
122
+ * Merges a set of incrementally requested permissions into the existing permissions of
123
+ * the requesting subject. The merge is a right-biased union, where the existing
124
+ * permissions are the left-hand side, and the incrementally requested permissions are
125
+ * the right-hand side.
126
+ *
127
+ * @param existingPermissions - The subject's existing permissions.
128
+ * @param incrementalRequestedPermissions - The requested permissions to merge.
129
+ * @returns The merged permissions and the resulting diff.
130
+ */
131
+ __privateAdd(this, _mergeIncrementalPermissions);
132
+ /**
133
+ * Performs a right-biased union between two permissions. The task of merging caveats
134
+ * of the same type between the two permissions is delegated to the corresponding
135
+ * caveat type's merger implementation.
136
+ *
137
+ * Throws if the left-hand and right-hand permissions both have a caveat whose
138
+ * specification does not provide a caveat value merger function.
139
+ *
140
+ * @param leftPermission - The left-hand permission to merge.
141
+ * @param rightPermission - The right-hand permission to merge.
142
+ * @returns The merged permission.
143
+ */
144
+ __privateAdd(this, _mergePermission);
145
+ /**
146
+ * Merges two caveats of the same type. The task of merging the values of the
147
+ * two caveats is delegated to the corresponding caveat type's merger implementation.
148
+ *
149
+ * @param leftCaveat - The left-hand caveat to merge.
150
+ * @param rightCaveat - The right-hand caveat to merge.
151
+ * @returns The merged caveat and the diff between the two caveats.
152
+ */
153
+ __privateAdd(this, _mergeCaveat);
154
+ /**
155
+ * Accepts a permissions request that has been approved by the user. This
156
+ * method should be called after the user has approved the request and the
157
+ * {@link ApprovalController} has resolved the user approval promise.
158
+ *
159
+ * @param options - Options bag.
160
+ * @param options.subject - The subject to grant permissions to.
161
+ * @param options.metadata - The metadata of the approved permissions request.
162
+ * @param options.preserveExistingPermissions - Whether to preserve the
163
+ * subject's existing permissions.
164
+ * @param options.approvedRequest - The approved permissions request to handle.
165
+ * @returns The granted permissions and request metadata.
166
+ */
167
+ __privateAdd(this, _handleApprovedPermissions);
109
168
  this._unrestrictedMethods = new Set(unrestrictedMethods);
110
169
  this._caveatSpecifications = deepFreeze({ ...caveatSpecifications });
111
170
  this.validatePermissionSpecifications(
@@ -124,6 +183,14 @@ var PermissionController = class extends BaseController {
124
183
  )
125
184
  });
126
185
  }
186
+ /**
187
+ * The names of all JSON-RPC methods that will be ignored by the controller.
188
+ *
189
+ * @returns The names of all unrestricted JSON-RPC methods
190
+ */
191
+ get unrestrictedMethods() {
192
+ return this._unrestrictedMethods;
193
+ }
127
194
  /**
128
195
  * Gets a permission specification.
129
196
  *
@@ -222,10 +289,18 @@ var PermissionController = class extends BaseController {
222
289
  `${controllerName}:grantPermissions`,
223
290
  this.grantPermissions.bind(this)
224
291
  );
292
+ this.messagingSystem.registerActionHandler(
293
+ `${controllerName}:grantPermissionsIncremental`,
294
+ this.grantPermissionsIncremental.bind(this)
295
+ );
225
296
  this.messagingSystem.registerActionHandler(
226
297
  `${controllerName}:requestPermissions`,
227
298
  (subject, permissions) => this.requestPermissions(subject, permissions)
228
299
  );
300
+ this.messagingSystem.registerActionHandler(
301
+ `${controllerName}:requestPermissionsIncremental`,
302
+ (subject, permissions) => this.requestPermissionsIncremental(subject, permissions)
303
+ );
229
304
  this.messagingSystem.registerActionHandler(
230
305
  `${controllerName}:revokeAllPermissions`,
231
306
  (origin) => this.revokeAllPermissions(origin)
@@ -750,10 +825,11 @@ var PermissionController = class extends BaseController {
750
825
  }
751
826
  /**
752
827
  * Grants _approved_ permissions to the specified subject. Every permission and
753
- * caveat is stringently validated – including by calling every specification
754
- * validator – and an error is thrown if any validation fails.
828
+ * caveat is stringently validated—including by calling their specification
829
+ * validators—and an error is thrown if validation fails.
755
830
  *
756
- * ATTN: This method does **not** prompt the user for approval.
831
+ * ATTN: This method does **not** prompt the user for approval. User consent must
832
+ * first be obtained through some other means.
757
833
  *
758
834
  * @see {@link PermissionController.requestPermissions} For initiating a
759
835
  * permissions request requiring user approval.
@@ -765,7 +841,7 @@ var PermissionController = class extends BaseController {
765
841
  * @param options.preserveExistingPermissions - Whether to preserve the
766
842
  * subject's existing permissions.
767
843
  * @param options.subject - The subject to grant permissions to.
768
- * @returns The granted permissions.
844
+ * @returns The subject's new permission state. It may or may not have changed.
769
845
  */
770
846
  grantPermissions({
771
847
  approvedPermissions,
@@ -773,53 +849,44 @@ var PermissionController = class extends BaseController {
773
849
  preserveExistingPermissions = true,
774
850
  subject
775
851
  }) {
776
- const { origin } = subject;
777
- if (!origin || typeof origin !== "string") {
778
- throw new InvalidSubjectIdentifierError(origin);
779
- }
780
- const permissions = preserveExistingPermissions ? {
781
- ...this.getPermissions(origin)
782
- } : {};
783
- for (const [requestedTarget, approvedPermission] of Object.entries(
784
- approvedPermissions
785
- )) {
786
- if (!this.targetExists(requestedTarget)) {
787
- throw methodNotFound(requestedTarget);
788
- }
789
- if (approvedPermission.parentCapability !== void 0 && requestedTarget !== approvedPermission.parentCapability) {
790
- throw new InvalidApprovedPermissionError(
791
- origin,
792
- requestedTarget,
793
- approvedPermission
794
- );
795
- }
796
- const targetName = requestedTarget;
797
- const specification = this.getPermissionSpecification(targetName);
798
- const caveats = this.constructCaveats(
799
- origin,
800
- targetName,
801
- approvedPermission.caveats
802
- );
803
- const permissionOptions = {
804
- caveats,
805
- invoker: origin,
806
- target: targetName
807
- };
808
- let permission;
809
- if (specification.factory) {
810
- permission = specification.factory(permissionOptions, requestData);
811
- this.validatePermission(specification, permission, origin);
812
- } else {
813
- permission = constructPermission(permissionOptions);
814
- this.validatePermission(specification, permission, origin, {
815
- invokePermissionValidator: true,
816
- performCaveatValidation: false
817
- });
818
- }
819
- permissions[targetName] = permission;
820
- }
821
- this.setValidatedPermissions(origin, permissions);
822
- return permissions;
852
+ return __privateMethod(this, _applyGrantedPermissions, applyGrantedPermissions_fn).call(this, {
853
+ approvedPermissions,
854
+ subject,
855
+ mergePermissions: false,
856
+ preserveExistingPermissions,
857
+ requestData
858
+ });
859
+ }
860
+ /**
861
+ * Incrementally grants _approved_ permissions to the specified subject. Every
862
+ * permission and caveat is stringently validated—including by calling their
863
+ * specification validators—and an error is thrown if validation fails.
864
+ *
865
+ * ATTN: This method does **not** prompt the user for approval. User consent must
866
+ * first be obtained through some other means.
867
+ *
868
+ * @see {@link PermissionController.requestPermissionsIncremental} For initiating
869
+ * an incremental permissions request requiring user approval.
870
+ * @param options - Options bag.
871
+ * @param options.approvedPermissions - The requested permissions approved by
872
+ * the user.
873
+ * @param options.requestData - Permission request data. Passed to permission
874
+ * factory functions.
875
+ * @param options.subject - The subject to grant permissions to.
876
+ * @returns The subject's new permission state. It may or may not have changed.
877
+ */
878
+ grantPermissionsIncremental({
879
+ approvedPermissions,
880
+ requestData,
881
+ subject
882
+ }) {
883
+ return __privateMethod(this, _applyGrantedPermissions, applyGrantedPermissions_fn).call(this, {
884
+ approvedPermissions,
885
+ subject,
886
+ mergePermissions: true,
887
+ preserveExistingPermissions: true,
888
+ requestData
889
+ });
823
890
  }
824
891
  /**
825
892
  * Validates the specified permission by:
@@ -952,9 +1019,11 @@ var PermissionController = class extends BaseController {
952
1019
  specification.validator?.(caveat, origin, target);
953
1020
  }
954
1021
  /**
955
- * Initiates a permission request that requires user approval. This should
956
- * always be used to grant additional permissions to a subject, unless user
957
- * approval has been obtained through some other means.
1022
+ * Initiates a permission request that requires user approval.
1023
+ *
1024
+ * Either this or {@link PermissionController.requestPermissionsIncremental}
1025
+ * should always be used to grant additional permissions to a subject,
1026
+ * unless user approval has been obtained through some other means.
958
1027
  *
959
1028
  * Permissions are validated at every step of the approval process, and this
960
1029
  * method will reject if validation fails.
@@ -988,36 +1057,85 @@ var PermissionController = class extends BaseController {
988
1057
  permissions: requestedPermissions
989
1058
  };
990
1059
  const approvedRequest = await this.requestUserApproval(permissionsRequest);
991
- const { permissions: approvedPermissions, ...requestData } = approvedRequest;
992
- const sideEffects = this.getSideEffects(approvedPermissions);
993
- if (Object.values(sideEffects.permittedHandlers).length > 0) {
994
- const sideEffectsData = await this.executeSideEffects(
995
- sideEffects,
996
- approvedRequest
997
- );
998
- const mappedData = Object.keys(sideEffects.permittedHandlers).reduce(
999
- (acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }),
1000
- {}
1001
- );
1002
- return [
1003
- this.grantPermissions({
1004
- subject,
1005
- approvedPermissions,
1006
- preserveExistingPermissions,
1007
- requestData
1008
- }),
1009
- { data: mappedData, ...metadata }
1010
- ];
1060
+ return await __privateMethod(this, _handleApprovedPermissions, handleApprovedPermissions_fn).call(this, {
1061
+ subject,
1062
+ metadata,
1063
+ preserveExistingPermissions,
1064
+ approvedRequest
1065
+ });
1066
+ }
1067
+ /**
1068
+ * Initiates an incremental permission request that prompts for user approval.
1069
+ * Incremental permission requests allow the caller to replace existing and/or
1070
+ * add brand new permissions and caveats for the specified subject.
1071
+ *
1072
+ * Incremental permission request are merged with the subject's existing permissions
1073
+ * through a right-biased union, where the incremental permission are the right-hand
1074
+ * side of the merger. If both sides of the merger specify the same caveats for a
1075
+ * given permission, the caveats are merged using their specification's caveat value
1076
+ * merger property.
1077
+ *
1078
+ * Either this or {@link PermissionController.requestPermissions} should
1079
+ * always be used to grant additional permissions to a subject, unless user
1080
+ * approval has been obtained through some other means.
1081
+ *
1082
+ * Permissions are validated at every step of the approval process, and this
1083
+ * method will reject if validation fails.
1084
+ *
1085
+ * @see {@link ApprovalController} For the user approval logic.
1086
+ * @see {@link PermissionController.acceptPermissionsRequest} For the method
1087
+ * that _accepts_ the request and resolves the user approval promise.
1088
+ * @see {@link PermissionController.rejectPermissionsRequest} For the method
1089
+ * that _rejects_ the request and the user approval promise.
1090
+ * @param subject - The grantee subject.
1091
+ * @param requestedPermissions - The requested permissions.
1092
+ * @param options - Additional options.
1093
+ * @param options.id - The id of the permissions request. Defaults to a unique
1094
+ * id.
1095
+ * @param options.metadata - Additional metadata about the permission request.
1096
+ * @returns The granted permissions and request metadata.
1097
+ */
1098
+ async requestPermissionsIncremental(subject, requestedPermissions, options = {}) {
1099
+ const { origin } = subject;
1100
+ const { id = nanoid() } = options;
1101
+ this.validateRequestedPermissions(origin, requestedPermissions);
1102
+ const currentPermissions = this.getPermissions(origin) ?? {};
1103
+ const [newPermissions, permissionDiffMap] = __privateMethod(this, _mergeIncrementalPermissions, mergeIncrementalPermissions_fn).call(this, currentPermissions, requestedPermissions);
1104
+ if (newPermissions === void 0 || permissionDiffMap === void 0) {
1105
+ return [];
1011
1106
  }
1012
- return [
1013
- this.grantPermissions({
1014
- subject,
1015
- approvedPermissions,
1016
- preserveExistingPermissions,
1017
- requestData
1018
- }),
1019
- metadata
1020
- ];
1107
+ try {
1108
+ this.validateRequestedPermissions(origin, newPermissions);
1109
+ } catch (error) {
1110
+ if (error instanceof Error) {
1111
+ throw new InvalidMergedPermissionsError(
1112
+ origin,
1113
+ error,
1114
+ permissionDiffMap
1115
+ );
1116
+ }
1117
+ throw internalError("Unrecognized error type", { error });
1118
+ }
1119
+ const metadata = {
1120
+ ...options.metadata,
1121
+ id,
1122
+ origin
1123
+ };
1124
+ const permissionsRequest = {
1125
+ metadata,
1126
+ permissions: newPermissions,
1127
+ diff: {
1128
+ currentPermissions,
1129
+ permissionDiffMap
1130
+ }
1131
+ };
1132
+ const approvedRequest = await this.requestUserApproval(permissionsRequest);
1133
+ return await __privateMethod(this, _handleApprovedPermissions, handleApprovedPermissions_fn).call(this, {
1134
+ subject,
1135
+ metadata,
1136
+ preserveExistingPermissions: false,
1137
+ approvedRequest
1138
+ });
1021
1139
  }
1022
1140
  /**
1023
1141
  * Validates requested permissions. Throws if validation fails.
@@ -1375,9 +1493,187 @@ var PermissionController = class extends BaseController {
1375
1493
  )({ method, params, context: { origin } });
1376
1494
  }
1377
1495
  };
1496
+ _expectGetCaveatMerger = new WeakSet();
1497
+ expectGetCaveatMerger_fn = function(caveatType) {
1498
+ const { merger } = this.getCaveatSpecification(caveatType);
1499
+ if (merger === void 0) {
1500
+ throw new CaveatMergerDoesNotExistError(caveatType);
1501
+ }
1502
+ return merger;
1503
+ };
1504
+ _applyGrantedPermissions = new WeakSet();
1505
+ applyGrantedPermissions_fn = function({
1506
+ approvedPermissions,
1507
+ subject,
1508
+ mergePermissions,
1509
+ preserveExistingPermissions,
1510
+ requestData
1511
+ }) {
1512
+ const { origin } = subject;
1513
+ if (!origin || typeof origin !== "string") {
1514
+ throw new InvalidSubjectIdentifierError(origin);
1515
+ }
1516
+ const permissions = preserveExistingPermissions ? {
1517
+ ...this.getPermissions(origin)
1518
+ } : {};
1519
+ for (const [requestedTarget, approvedPermission] of Object.entries(
1520
+ approvedPermissions
1521
+ )) {
1522
+ if (!this.targetExists(requestedTarget)) {
1523
+ throw methodNotFound(requestedTarget);
1524
+ }
1525
+ if (approvedPermission.parentCapability !== void 0 && requestedTarget !== approvedPermission.parentCapability) {
1526
+ throw new InvalidApprovedPermissionError(
1527
+ origin,
1528
+ requestedTarget,
1529
+ approvedPermission
1530
+ );
1531
+ }
1532
+ const targetName = requestedTarget;
1533
+ const specification = this.getPermissionSpecification(targetName);
1534
+ const caveats = this.constructCaveats(
1535
+ origin,
1536
+ targetName,
1537
+ approvedPermission.caveats
1538
+ );
1539
+ const permissionOptions = {
1540
+ caveats,
1541
+ invoker: origin,
1542
+ target: targetName
1543
+ };
1544
+ let permission;
1545
+ let performCaveatValidation = true;
1546
+ if (specification.factory) {
1547
+ permission = specification.factory(permissionOptions, requestData);
1548
+ } else {
1549
+ permission = constructPermission(permissionOptions);
1550
+ performCaveatValidation = false;
1551
+ }
1552
+ if (mergePermissions) {
1553
+ permission = __privateMethod(this, _mergePermission, mergePermission_fn).call(this, permissions[targetName], permission)[0];
1554
+ }
1555
+ this.validatePermission(specification, permission, origin, {
1556
+ invokePermissionValidator: true,
1557
+ performCaveatValidation
1558
+ });
1559
+ permissions[targetName] = permission;
1560
+ }
1561
+ this.setValidatedPermissions(origin, permissions);
1562
+ return permissions;
1563
+ };
1564
+ _mergeIncrementalPermissions = new WeakSet();
1565
+ mergeIncrementalPermissions_fn = function(existingPermissions, incrementalRequestedPermissions) {
1566
+ const permissionDiffMap = {};
1567
+ const newPermissions = immerProduce(
1568
+ existingPermissions,
1569
+ (draftExistingPermissions) => {
1570
+ const leftPermissions = draftExistingPermissions;
1571
+ Object.entries(incrementalRequestedPermissions).forEach(
1572
+ ([targetName, rightPermission]) => {
1573
+ const leftPermission = leftPermissions[targetName];
1574
+ const [newPermission, caveatsDiff] = __privateMethod(this, _mergePermission, mergePermission_fn).call(this, leftPermission ?? {}, rightPermission);
1575
+ if (leftPermission === void 0 || Object.keys(caveatsDiff).length > 0) {
1576
+ leftPermissions[targetName] = newPermission;
1577
+ permissionDiffMap[targetName] = caveatsDiff;
1578
+ }
1579
+ }
1580
+ );
1581
+ }
1582
+ );
1583
+ if (Object.keys(permissionDiffMap).length === 0) {
1584
+ return [];
1585
+ }
1586
+ return [newPermissions, permissionDiffMap];
1587
+ };
1588
+ _mergePermission = new WeakSet();
1589
+ mergePermission_fn = function(leftPermission, rightPermission) {
1590
+ const { caveatPairs, leftUniqueCaveats, rightUniqueCaveats } = collectUniqueAndPairedCaveats(leftPermission, rightPermission);
1591
+ const [mergedCaveats, caveatDiffMap] = caveatPairs.reduce(
1592
+ ([caveats, diffMap], [leftCaveat, rightCaveat]) => {
1593
+ const [newCaveat, diff] = __privateMethod(this, _mergeCaveat, mergeCaveat_fn).call(this, leftCaveat, rightCaveat);
1594
+ if (newCaveat !== void 0 && diff !== void 0) {
1595
+ caveats.push(newCaveat);
1596
+ diffMap[newCaveat.type] = diff;
1597
+ } else {
1598
+ caveats.push(leftCaveat);
1599
+ }
1600
+ return [caveats, diffMap];
1601
+ },
1602
+ [[], {}]
1603
+ );
1604
+ const mergedRightUniqueCaveats = rightUniqueCaveats.map((caveat) => {
1605
+ const [newCaveat, diff] = __privateMethod(this, _mergeCaveat, mergeCaveat_fn).call(this, void 0, caveat);
1606
+ caveatDiffMap[newCaveat.type] = diff;
1607
+ return newCaveat;
1608
+ });
1609
+ const allCaveats = [
1610
+ ...mergedCaveats,
1611
+ ...leftUniqueCaveats,
1612
+ ...mergedRightUniqueCaveats
1613
+ ];
1614
+ const newPermission = {
1615
+ ...leftPermission,
1616
+ ...rightPermission,
1617
+ ...allCaveats.length > 0 ? { caveats: allCaveats } : {}
1618
+ };
1619
+ return [newPermission, caveatDiffMap];
1620
+ };
1621
+ _mergeCaveat = new WeakSet();
1622
+ mergeCaveat_fn = function(leftCaveat, rightCaveat) {
1623
+ if (leftCaveat !== void 0 && leftCaveat.type !== rightCaveat.type) {
1624
+ throw new CaveatMergeTypeMismatchError(leftCaveat.type, rightCaveat.type);
1625
+ }
1626
+ const merger = __privateMethod(this, _expectGetCaveatMerger, expectGetCaveatMerger_fn).call(this, rightCaveat.type);
1627
+ if (leftCaveat === void 0) {
1628
+ return [
1629
+ {
1630
+ ...rightCaveat
1631
+ },
1632
+ rightCaveat.value
1633
+ ];
1634
+ }
1635
+ const [newValue, diff] = merger(leftCaveat.value, rightCaveat.value);
1636
+ return newValue !== void 0 && diff !== void 0 ? [
1637
+ {
1638
+ type: rightCaveat.type,
1639
+ value: newValue
1640
+ },
1641
+ diff
1642
+ ] : [];
1643
+ };
1644
+ _handleApprovedPermissions = new WeakSet();
1645
+ handleApprovedPermissions_fn = async function({
1646
+ subject,
1647
+ metadata,
1648
+ preserveExistingPermissions,
1649
+ approvedRequest
1650
+ }) {
1651
+ const { permissions: approvedPermissions, ...requestData } = approvedRequest;
1652
+ const approvedMetadata = { ...metadata };
1653
+ const sideEffects = this.getSideEffects(approvedPermissions);
1654
+ if (Object.values(sideEffects.permittedHandlers).length > 0) {
1655
+ const sideEffectsData = await this.executeSideEffects(
1656
+ sideEffects,
1657
+ approvedRequest
1658
+ );
1659
+ approvedMetadata.data = Object.keys(sideEffects.permittedHandlers).reduce(
1660
+ (acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }),
1661
+ {}
1662
+ );
1663
+ }
1664
+ return [
1665
+ this.grantPermissions({
1666
+ subject,
1667
+ approvedPermissions,
1668
+ preserveExistingPermissions,
1669
+ requestData
1670
+ }),
1671
+ approvedMetadata
1672
+ ];
1673
+ };
1378
1674
 
1379
1675
  export {
1380
1676
  CaveatMutatorOperation,
1381
1677
  PermissionController
1382
1678
  };
1383
- //# sourceMappingURL=chunk-MCDOYEJY.mjs.map
1679
+ //# sourceMappingURL=chunk-4B6NOD2D.mjs.map