Skip to content
21 changes: 16 additions & 5 deletions packages/permission-controller/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,18 +326,29 @@ const permissionController = new PermissionController({

### Adding the permission middleware

The permission middleware is created via `createPermissionMiddlewareV2` for
`JsonRpcEngineV2`, or via the deprecated `createPermissionMiddleware` for the
legacy `JsonRpcEngine`. Both factories take a messenger with the
`PermissionController:executeRestrictedMethod` and
`PermissionController:hasUnrestrictedMethod` actions, typically obtained by
delegating them from a root messenger to a subject-scoped messenger.

```typescript
// This should take place where a middleware stack is created for a particular
// subject.

// The subject could be a port, stream, socket, etc.
const origin = getOrigin(subject);

const engine = new JsonRpcEngine();
engine.push(/* your various middleware*/);
engine.push(permissionController.createPermissionMiddleware({ origin }));
// Your middleware stack is now permissioned
engine.push(/* your other various middleware*/);
// `messenger` is a messenger delegated the two actions listed above, e.g.
// via `rootMessenger.delegate({ actions: [...], messenger: subjectMessenger })`.
const engine = JsonRpcEngineV2.create({
middleware: [
/* your various middleware */
createPermissionMiddlewareV2({ messenger, subject: { origin } }),
/* your other various middleware */
],
});
```

### Calling a restricted method internally
Expand Down
11 changes: 9 additions & 2 deletions packages/permission-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Expose `createPermissionMiddleware` through the messenger ([#8502](https://github.com/MetaMask/core/pull/8502))
- Add `createPermissionMiddlewareV2`, a `JsonRpcEngineV2` variant of the standalone permission middleware factory ([#8532](https://github.com/MetaMask/core/pull/8532))

### Changed

- **BREAKING:** Decouple the permission middleware from `PermissionController` and expose it as a standalone function ([#8532](https://github.com/MetaMask/core/pull/8532))
- The standalone `createPermissionMiddleware` replaces the former `PermissionController.prototype.createPermissionMiddleware`; it is imported from `@metamask/permission-controller` and called with a messenger and subject metadata, and targets the legacy `JsonRpcEngine`.
- New integrations should prefer `createPermissionMiddlewareV2`, which targets `JsonRpcEngineV2`.
- Bump `@metamask/controller-utils` from `^11.19.0` to `^11.20.0` ([#8344](https://github.com/MetaMask/core/pull/8344))
- Bump `@metamask/messenger` from `^1.0.0` to `^1.1.1` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373))
- Bump `@metamask/base-controller` from `^9.0.1` to `^9.1.0` ([#8457](https://github.com/MetaMask/core/pull/8457))

### Deprecated

- Deprecate `createPermissionMiddleware` in favor of `createPermissionMiddlewareV2`, which targets `JsonRpcEngineV2` ([#8532](https://github.com/MetaMask/core/pull/8532))

## [12.3.0]

### Added
Expand Down Expand Up @@ -186,7 +193,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as
["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md).
All of the ATTW checks now pass.
- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)).
- Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648))
- Previously, the build tool we used to generate JavaScript files extracted
common code to "chunk" files. While this was intended to make this package
more tree-shakeable, it also made debugging more difficult for our
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,25 @@
import type { PermissionController } from './PermissionController';

/**
* Clears the state of the controller.
* Checks whether the given method was declared as unrestricted at
* construction time. Methods unknown to the controller return `false` and
* would be treated as restricted by callers such as the permission
* middleware.
*
* @param method - The name of the method to check.
* @returns Whether the method is unrestricted.
*/
export type PermissionControllerClearStateAction = {
type: `PermissionController:clearState`;
handler: PermissionController['clearState'];
export type PermissionControllerHasUnrestrictedMethodAction = {
type: `PermissionController:hasUnrestrictedMethod`;
handler: PermissionController['hasUnrestrictedMethod'];
};

/**
* Creates a permission middleware function. Like any {@link JsonRpcEngine}
* middleware, each middleware will only receive requests from a particular
* subject / origin.
*
* The middlewares returned will pass through requests for
* unrestricted methods, and attempt to execute restricted methods. If a method
* is neither restricted nor unrestricted, a "method not found" error will be
* returned.
* If a method is restricted, the middleware will first attempt to retrieve the
* subject's permission for that method. If the permission is found, the method
* will be executed. Otherwise, an "unauthorized" error will be returned.
*
* The middleware **must** be added in the correct place in the middleware
* stack in order for it to work. See the README for an example.
*
* @param subject The permission subject.
* @returns A `json-rpc-engine` middleware.
* Clears the state of the controller.
*/
export type PermissionControllerCreatePermissionMiddlewareAction = {
type: `PermissionController:createPermissionMiddleware`;
handler: PermissionController['createPermissionMiddleware'];
export type PermissionControllerClearStateAction = {
type: `PermissionController:clearState`;
handler: PermissionController['clearState'];
};

/**
Expand Down Expand Up @@ -86,7 +76,7 @@ export type PermissionControllerHasPermissionsAction = {
/**
* Revokes all permissions from the specified origin.
*
* Throws an error of the origin has no permissions.
* Throws an error if the origin has no permissions.
*
* @param origin - The origin whose permissions to revoke.
*/
Expand Down Expand Up @@ -293,12 +283,42 @@ export type PermissionControllerGetEndowmentsAction = {
handler: PermissionController['getEndowments'];
};

/**
* Executes a restricted method as the subject with the given origin.
* The specified params, if any, will be passed to the method implementation.
*
* ATTN: Great caution should be exercised in the use of this method.
* Methods that cause side effects or affect application state should
* be avoided.
*
* This method will first attempt to retrieve the requested restricted method
* implementation, throwing if it does not exist. The method will then be
* invoked as though the subject with the specified origin had invoked it with
* the specified parameters. This means that any existing caveats will be
* applied to the restricted method, and this method will throw if the
* restricted method or its caveat decorators throw.
*
* In addition, this method will throw if the subject does not have a
* permission for the specified restricted method.
*
* @param origin - The origin of the subject to execute the method on behalf
* of.
* @param targetName - The name of the method to execute. This must be a valid
* permission target name.
* @param params - The parameters to pass to the method implementation.
* @returns The result of the executed method.
*/
export type PermissionControllerExecuteRestrictedMethodAction = {
type: `PermissionController:executeRestrictedMethod`;
handler: PermissionController['executeRestrictedMethod'];
};

/**
* Union of all PermissionController action types.
*/
export type PermissionControllerMethodActions =
| PermissionControllerHasUnrestrictedMethodAction
| PermissionControllerClearStateAction
| PermissionControllerCreatePermissionMiddlewareAction
| PermissionControllerGetSubjectNamesAction
| PermissionControllerGetPermissionsAction
| PermissionControllerHasPermissionAction
Expand All @@ -312,4 +332,5 @@ export type PermissionControllerMethodActions =
| PermissionControllerGrantPermissionsIncrementalAction
| PermissionControllerRequestPermissionsAction
| PermissionControllerRequestPermissionsIncrementalAction
| PermissionControllerGetEndowmentsAction;
| PermissionControllerGetEndowmentsAction
| PermissionControllerExecuteRestrictedMethodAction;
Loading
Loading