diff --git a/packages/permission-controller/src/PermissionController.test.ts b/packages/permission-controller/src/PermissionController.test.ts index 8181ea5e55..e4e8ca6bea 100644 --- a/packages/permission-controller/src/PermissionController.test.ts +++ b/packages/permission-controller/src/PermissionController.test.ts @@ -4654,6 +4654,67 @@ describe('PermissionController', () => { expect(requestPermissionsSpy).toHaveBeenCalledTimes(1); }); + + it('action: PermissionController:updateCaveat', async () => { + const messenger = getUnrestrictedMessenger(); + const state = { + subjects: { + 'metamask.io': { + origin: 'metamask.io', + permissions: { + wallet_getSecretArray: { + id: 'escwEx9JrOxGZKZk3RkL4', + parentCapability: 'wallet_getSecretArray', + invoker: 'metamask.io', + caveats: [ + { type: CaveatTypes.filterArrayResponse, value: ['bar'] }, + ], + date: 1632618373085, + }, + }, + }, + }, + }; + const options = getPermissionControllerOptions({ + messenger: getPermissionControllerMessenger(messenger), + state, + }); + + const controller = new PermissionController< + DefaultPermissionSpecifications, + DefaultCaveatSpecifications + >(options); + + const updateCaveatSpy = jest.spyOn(controller, 'updateCaveat'); + + await messenger.call( + 'PermissionController:updateCaveat', + 'metamask.io', + 'wallet_getSecretArray', + CaveatTypes.filterArrayResponse, + ['baz'], + ); + + expect(updateCaveatSpy).toHaveBeenCalledTimes(1); + expect(controller.state).toStrictEqual({ + subjects: { + 'metamask.io': { + origin: 'metamask.io', + permissions: { + wallet_getSecretArray: { + id: 'escwEx9JrOxGZKZk3RkL4', + parentCapability: 'wallet_getSecretArray', + invoker: 'metamask.io', + caveats: [ + { type: CaveatTypes.filterArrayResponse, value: ['baz'] }, + ], + date: 1632618373085, + }, + }, + }, + }, + }); + }); }); describe('permission middleware', () => { diff --git a/packages/permission-controller/src/PermissionController.ts b/packages/permission-controller/src/PermissionController.ts index 8327f7bfc3..43073adb48 100644 --- a/packages/permission-controller/src/PermissionController.ts +++ b/packages/permission-controller/src/PermissionController.ts @@ -258,6 +258,14 @@ export type RevokePermissionForAllSubjects = { handler: GenericPermissionController['revokePermissionForAllSubjects']; }; +/** + * Updates a caveat value for a specified caveat type belonging to a specific target and origin. + */ +export type UpdateCaveat = { + type: `${typeof controllerName}:updateCaveat`; + handler: GenericPermissionController['updateCaveat']; +}; + /** * Clears all permissions from the {@link PermissionController}. */ @@ -289,7 +297,8 @@ export type PermissionControllerActions = | RequestPermissions | RevokeAllPermissions | RevokePermissionForAllSubjects - | RevokePermissions; + | RevokePermissions + | UpdateCaveat; /** * The generic state change event of the {@link PermissionController}. @@ -755,6 +764,18 @@ export class PermissionController< `${controllerName}:revokePermissions` as const, this.revokePermissions.bind(this), ); + + this.messagingSystem.registerActionHandler( + `${controllerName}:updateCaveat` as const, + (origin, target, caveatType, caveatValue) => { + this.updateCaveat( + origin, + target, + caveatType as ExtractAllowedCaveatTypes, + caveatValue, + ); + }, + ); } /**