Skip to content

Commit

Permalink
feat(permission-controller): Allow passing additional metadata during…
Browse files Browse the repository at this point in the history
… requestPermissions (#4179)

## Explanation

For certain use-cases, such as the SDK, it may be beneficial to be able
to store additional metadata about permission requests. This PR adds a
`metadata` property to the `requestPermission` options which is merged
into the existing `metadata` object and ultimately stored in the
`ApprovalController`.

## Changelog

### `@metamask/permission-controller`

- **Added**: Allow passing additional metadata during requestPermissions

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
  • Loading branch information
FrederikBolding authored Apr 18, 2024
1 parent 8c7e1e0 commit 4e9711a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
52 changes: 52 additions & 0 deletions packages/permission-controller/src/PermissionController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2943,6 +2943,58 @@ describe('PermissionController', () => {
);
});

it('allows caller passing additional metadata', async () => {
const options = getPermissionControllerOptions();
const { messenger } = options;
const origin = 'metamask.io';

const callActionSpy = jest
.spyOn(messenger, 'call')
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.mockImplementationOnce(async (...args: any) => {
const [, { requestData }] = args;
return {
metadata: { ...requestData.metadata },
permissions: { ...requestData.permissions },
};
});

const controller = getDefaultPermissionController(options);
expect(
await controller.requestPermissions(
{ origin },
{
[PermissionNames.wallet_getSecretArray]: {},
},
{ metadata: { foo: 'bar' } },
),
).toMatchObject([
{
[PermissionNames.wallet_getSecretArray]: getPermissionMatcher({
parentCapability: PermissionNames.wallet_getSecretArray,
caveats: null,
invoker: origin,
}),
},
{ id: expect.any(String), origin },
]);

expect(callActionSpy).toHaveBeenCalledTimes(1);
expect(callActionSpy).toHaveBeenCalledWith(
'ApprovalController:addRequest',
{
id: expect.any(String),
origin,
requestData: {
metadata: { foo: 'bar', id: expect.any(String), origin },
permissions: { [PermissionNames.wallet_getSecretArray]: {} },
},
type: MethodNames.requestPermissions,
},
true,
);
});

it('requests a permission that requires permitted side-effects', async () => {
const options = getPermissionControllerOptions();
const { messenger } = options;
Expand Down
4 changes: 4 additions & 0 deletions packages/permission-controller/src/PermissionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export type PermissionSubjectMetadata = {
*/
export type PermissionsRequestMetadata = PermissionSubjectMetadata & {
id: string;
[key: string]: Json;
};

/**
Expand Down Expand Up @@ -1860,6 +1861,7 @@ export class PermissionController<
* id.
* @param options.preserveExistingPermissions - Whether to preserve the
* subject's existing permissions. Defaults to `true`.
* @param options.metadata - Additional metadata about the permission request.
* @returns The granted permissions and request metadata.
*/
async requestPermissions(
Expand All @@ -1868,6 +1870,7 @@ export class PermissionController<
options: {
id?: string;
preserveExistingPermissions?: boolean;
metadata?: Record<string, Json>;
} = {},
): Promise<
[
Expand All @@ -1885,6 +1888,7 @@ export class PermissionController<
this.validateRequestedPermissions(origin, requestedPermissions);

const metadata = {
...options.metadata,
id,
origin,
};
Expand Down

0 comments on commit 4e9711a

Please sign in to comment.