@metamask/permission-controller 1.0.0
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.
- package/CHANGELOG.md +18 -0
- package/LICENSE +20 -0
- package/README.md +19 -0
- package/dist/Caveat.d.ts +182 -0
- package/dist/Caveat.js +57 -0
- package/dist/Caveat.js.map +1 -0
- package/dist/Permission.d.ts +422 -0
- package/dist/Permission.js +66 -0
- package/dist/Permission.js.map +1 -0
- package/dist/PermissionController.d.ts +870 -0
- package/dist/PermissionController.js +1229 -0
- package/dist/PermissionController.js.map +1 -0
- package/dist/errors.d.ts +158 -0
- package/dist/errors.js +196 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/permission-middleware.d.ts +32 -0
- package/dist/permission-middleware.js +64 -0
- package/dist/permission-middleware.js.map +1 -0
- package/dist/rpc-methods/getPermissions.d.ts +7 -0
- package/dist/rpc-methods/getPermissions.js +38 -0
- package/dist/rpc-methods/getPermissions.js.map +1 -0
- package/dist/rpc-methods/index.d.ts +4 -0
- package/dist/rpc-methods/index.js +7 -0
- package/dist/rpc-methods/index.js.map +1 -0
- package/dist/rpc-methods/requestPermissions.d.ts +16 -0
- package/dist/rpc-methods/requestPermissions.js +55 -0
- package/dist/rpc-methods/requestPermissions.js.map +1 -0
- package/dist/utils.d.ts +15 -0
- package/dist/utils.js +9 -0
- package/dist/utils.js.map +1 -0
- package/package.json +60 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.permissionRpcMethods = void 0;
|
|
30
|
+
__exportStar(require("./Caveat"), exports);
|
|
31
|
+
__exportStar(require("./errors"), exports);
|
|
32
|
+
__exportStar(require("./Permission"), exports);
|
|
33
|
+
__exportStar(require("./PermissionController"), exports);
|
|
34
|
+
__exportStar(require("./utils"), exports);
|
|
35
|
+
exports.permissionRpcMethods = __importStar(require("./rpc-methods"));
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,2CAAyB;AACzB,+CAA6B;AAC7B,yDAAuC;AACvC,0CAAwB;AACxB,sEAAsD","sourcesContent":["export * from './Caveat';\nexport * from './errors';\nexport * from './Permission';\nexport * from './PermissionController';\nexport * from './utils';\nexport * as permissionRpcMethods from './rpc-methods';\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Json } from '@metamask/types';
|
|
2
|
+
import { JsonRpcMiddleware } from 'json-rpc-engine';
|
|
3
|
+
import { GenericPermissionController, PermissionSubjectMetadata, RestrictedMethodParameters } from '.';
|
|
4
|
+
declare type PermissionMiddlewareFactoryOptions = {
|
|
5
|
+
executeRestrictedMethod: GenericPermissionController['_executeRestrictedMethod'];
|
|
6
|
+
getRestrictedMethod: GenericPermissionController['getRestrictedMethod'];
|
|
7
|
+
isUnrestrictedMethod: (method: string) => boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Creates a permission middleware function factory. Intended for internal use
|
|
11
|
+
* in the {@link PermissionController}. Like any {@link JsonRpcEngine}
|
|
12
|
+
* middleware, each middleware will only receive requests from a particular
|
|
13
|
+
* subject / origin. However, each middleware also requires access to some
|
|
14
|
+
* `PermissionController` internals, which is why this "factory factory" exists.
|
|
15
|
+
*
|
|
16
|
+
* The middlewares returned by the factory will pass through requests for
|
|
17
|
+
* unrestricted methods, and attempt to execute restricted methods. If a method
|
|
18
|
+
* is neither restricted nor unrestricted, a "method not found" error will be
|
|
19
|
+
* returned.
|
|
20
|
+
* If a method is restricted, the middleware will first attempt to retrieve the
|
|
21
|
+
* subject's permission for that method. If the permission is found, the method
|
|
22
|
+
* will be executed. Otherwise, an "unauthorized" error will be returned.
|
|
23
|
+
*
|
|
24
|
+
* @param options - Options bag.
|
|
25
|
+
* @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.
|
|
26
|
+
* @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.
|
|
27
|
+
* @param options.isUnrestrictedMethod - A function that checks whether a
|
|
28
|
+
* particular method is unrestricted.
|
|
29
|
+
* @returns A permission middleware factory function.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getPermissionMiddlewareFactory({ executeRestrictedMethod, getRestrictedMethod, isUnrestrictedMethod, }: PermissionMiddlewareFactoryOptions): (subject: PermissionSubjectMetadata) => JsonRpcMiddleware<RestrictedMethodParameters, Json>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getPermissionMiddlewareFactory = void 0;
|
|
13
|
+
const json_rpc_engine_1 = require("json-rpc-engine");
|
|
14
|
+
const errors_1 = require("./errors");
|
|
15
|
+
/**
|
|
16
|
+
* Creates a permission middleware function factory. Intended for internal use
|
|
17
|
+
* in the {@link PermissionController}. Like any {@link JsonRpcEngine}
|
|
18
|
+
* middleware, each middleware will only receive requests from a particular
|
|
19
|
+
* subject / origin. However, each middleware also requires access to some
|
|
20
|
+
* `PermissionController` internals, which is why this "factory factory" exists.
|
|
21
|
+
*
|
|
22
|
+
* The middlewares returned by the factory will pass through requests for
|
|
23
|
+
* unrestricted methods, and attempt to execute restricted methods. If a method
|
|
24
|
+
* is neither restricted nor unrestricted, a "method not found" error will be
|
|
25
|
+
* returned.
|
|
26
|
+
* If a method is restricted, the middleware will first attempt to retrieve the
|
|
27
|
+
* subject's permission for that method. If the permission is found, the method
|
|
28
|
+
* will be executed. Otherwise, an "unauthorized" error will be returned.
|
|
29
|
+
*
|
|
30
|
+
* @param options - Options bag.
|
|
31
|
+
* @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.
|
|
32
|
+
* @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.
|
|
33
|
+
* @param options.isUnrestrictedMethod - A function that checks whether a
|
|
34
|
+
* particular method is unrestricted.
|
|
35
|
+
* @returns A permission middleware factory function.
|
|
36
|
+
*/
|
|
37
|
+
function getPermissionMiddlewareFactory({ executeRestrictedMethod, getRestrictedMethod, isUnrestrictedMethod, }) {
|
|
38
|
+
return function createPermissionMiddleware(subject) {
|
|
39
|
+
const { origin } = subject;
|
|
40
|
+
if (typeof origin !== 'string' || !origin) {
|
|
41
|
+
throw new Error('The subject "origin" must be a non-empty string.');
|
|
42
|
+
}
|
|
43
|
+
const permissionsMiddleware = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const { method, params } = req;
|
|
45
|
+
// Skip registered unrestricted methods.
|
|
46
|
+
if (isUnrestrictedMethod(method)) {
|
|
47
|
+
return next();
|
|
48
|
+
}
|
|
49
|
+
// This will throw if no restricted method implementation is found.
|
|
50
|
+
const methodImplementation = getRestrictedMethod(method, origin);
|
|
51
|
+
// This will throw if the permission does not exist.
|
|
52
|
+
const result = yield executeRestrictedMethod(methodImplementation, subject, method, params);
|
|
53
|
+
if (result === undefined) {
|
|
54
|
+
res.error = (0, errors_1.internalError)(`Request for method "${req.method}" returned undefined result.`, { request: req });
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
res.result = result;
|
|
58
|
+
return undefined;
|
|
59
|
+
});
|
|
60
|
+
return (0, json_rpc_engine_1.createAsyncMiddleware)(permissionsMiddleware);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.getPermissionMiddlewareFactory = getPermissionMiddlewareFactory;
|
|
64
|
+
//# sourceMappingURL=permission-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-middleware.js","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,qDAMyB;AAGzB,qCAAyC;AAezC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACe;IACnC,OAAO,SAAS,0BAA0B,CACxC,OAAkC;QAElC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,MAAM,qBAAqB,GAAG,CAC5B,GAA+C,EAC/C,GAAiC,EACjC,IAAoC,EACrB,EAAE;YACjB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;YAE/B,wCAAwC;YACxC,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE;gBAChC,OAAO,IAAI,EAAE,CAAC;aACf;YAED,mEAAmE;YACnE,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEjE,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,MAAM,CACP,CAAC;YAEF,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,GAAG,CAAC,KAAK,GAAG,IAAA,sBAAa,EACvB,uBAAuB,GAAG,CAAC,MAAM,8BAA8B,EAC/D,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;gBACF,OAAO,SAAS,CAAC;aAClB;YAED,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC,CAAA,CAAC;QAEF,OAAO,IAAA,uCAAqB,EAAC,qBAAqB,CAAC,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC;AAlDD,wEAkDC","sourcesContent":["import type { Json } from '@metamask/types';\nimport {\n JsonRpcMiddleware,\n AsyncJsonRpcEngineNextCallback,\n createAsyncMiddleware,\n PendingJsonRpcResponse,\n JsonRpcRequest,\n} from 'json-rpc-engine';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { JsonRpcEngine } from 'json-rpc-engine';\nimport { internalError } from './errors';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { PermissionController } from './PermissionController';\nimport {\n GenericPermissionController,\n PermissionSubjectMetadata,\n RestrictedMethodParameters,\n} from '.';\n\ntype PermissionMiddlewareFactoryOptions = {\n executeRestrictedMethod: GenericPermissionController['_executeRestrictedMethod'];\n getRestrictedMethod: GenericPermissionController['getRestrictedMethod'];\n isUnrestrictedMethod: (method: string) => boolean;\n};\n\n/**\n * Creates a permission middleware function factory. Intended for internal use\n * in the {@link PermissionController}. Like any {@link JsonRpcEngine}\n * middleware, each middleware will only receive requests from a particular\n * subject / origin. However, each middleware also requires access to some\n * `PermissionController` internals, which is why this \"factory factory\" exists.\n *\n * The middlewares returned by the factory will pass through requests for\n * unrestricted methods, and attempt to execute restricted methods. If a method\n * is neither restricted nor unrestricted, a \"method not found\" error will be\n * returned.\n * If a method is restricted, the middleware will first attempt to retrieve the\n * subject's permission for that method. If the permission is found, the method\n * will be executed. Otherwise, an \"unauthorized\" error will be returned.\n *\n * @param options - Options bag.\n * @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.\n * @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.\n * @param options.isUnrestrictedMethod - A function that checks whether a\n * particular method is unrestricted.\n * @returns A permission middleware factory function.\n */\nexport function getPermissionMiddlewareFactory({\n executeRestrictedMethod,\n getRestrictedMethod,\n isUnrestrictedMethod,\n}: PermissionMiddlewareFactoryOptions) {\n return function createPermissionMiddleware(\n subject: PermissionSubjectMetadata,\n ): JsonRpcMiddleware<RestrictedMethodParameters, Json> {\n const { origin } = subject;\n if (typeof origin !== 'string' || !origin) {\n throw new Error('The subject \"origin\" must be a non-empty string.');\n }\n\n const permissionsMiddleware = async (\n req: JsonRpcRequest<RestrictedMethodParameters>,\n res: PendingJsonRpcResponse<Json>,\n next: AsyncJsonRpcEngineNextCallback,\n ): Promise<void> => {\n const { method, params } = req;\n\n // Skip registered unrestricted methods.\n if (isUnrestrictedMethod(method)) {\n return next();\n }\n\n // This will throw if no restricted method implementation is found.\n const methodImplementation = getRestrictedMethod(method, origin);\n\n // This will throw if the permission does not exist.\n const result = await executeRestrictedMethod(\n methodImplementation,\n subject,\n method,\n params,\n );\n\n if (result === undefined) {\n res.error = internalError(\n `Request for method \"${req.method}\" returned undefined result.`,\n { request: req },\n );\n return undefined;\n }\n\n res.result = result;\n return undefined;\n };\n\n return createAsyncMiddleware(permissionsMiddleware);\n };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PermittedHandlerExport } from '@metamask/types';
|
|
2
|
+
import type { PermissionConstraint } from '../Permission';
|
|
3
|
+
import type { SubjectPermissions } from '../PermissionController';
|
|
4
|
+
export declare const getPermissionsHandler: PermittedHandlerExport<GetPermissionsHooks, void, PermissionConstraint[]>;
|
|
5
|
+
export declare type GetPermissionsHooks = {
|
|
6
|
+
getPermissionsForOrigin: () => SubjectPermissions<PermissionConstraint>;
|
|
7
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getPermissionsHandler = void 0;
|
|
13
|
+
const utils_1 = require("../utils");
|
|
14
|
+
exports.getPermissionsHandler = {
|
|
15
|
+
methodNames: [utils_1.MethodNames.getPermissions],
|
|
16
|
+
implementation: getPermissionsImplementation,
|
|
17
|
+
hookNames: {
|
|
18
|
+
getPermissionsForOrigin: true,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Get Permissions implementation to be used in JsonRpcEngine middleware.
|
|
23
|
+
*
|
|
24
|
+
* @param _req - The JsonRpcEngine request - unused
|
|
25
|
+
* @param res - The JsonRpcEngine result object
|
|
26
|
+
* @param _next - JsonRpcEngine next() callback - unused
|
|
27
|
+
* @param end - JsonRpcEngine end() callback
|
|
28
|
+
* @param options - Method hooks passed to the method implementation
|
|
29
|
+
* @param options.getPermissionsForOrigin - The specific method hook needed for this method implementation
|
|
30
|
+
* @returns A promise that resolves to nothing
|
|
31
|
+
*/
|
|
32
|
+
function getPermissionsImplementation(_req, res, _next, end, { getPermissionsForOrigin }) {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
res.result = Object.values(getPermissionsForOrigin() || {});
|
|
35
|
+
return end();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=getPermissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getPermissions.js","sourceRoot":"","sources":["../../src/rpc-methods/getPermissions.ts"],"names":[],"mappings":";;;;;;;;;;;;AAKA,oCAAuC;AAK1B,QAAA,qBAAqB,GAI9B;IACF,WAAW,EAAE,CAAC,mBAAW,CAAC,cAAc,CAAC;IACzC,cAAc,EAAE,4BAA4B;IAC5C,SAAS,EAAE;QACT,uBAAuB,EAAE,IAAI;KAC9B;CACF,CAAC;AAOF;;;;;;;;;;GAUG;AACH,SAAe,4BAA4B,CACzC,IAAa,EACb,GAAmD,EACnD,KAAc,EACd,GAA6B,EAC7B,EAAE,uBAAuB,EAAuB;;QAEhD,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;CAAA","sourcesContent":["import type {\n JsonRpcEngineEndCallback,\n PendingJsonRpcResponse,\n PermittedHandlerExport,\n} from '@metamask/types';\nimport { MethodNames } from '../utils';\n\nimport type { PermissionConstraint } from '../Permission';\nimport type { SubjectPermissions } from '../PermissionController';\n\nexport const getPermissionsHandler: PermittedHandlerExport<\n GetPermissionsHooks,\n void,\n PermissionConstraint[]\n> = {\n methodNames: [MethodNames.getPermissions],\n implementation: getPermissionsImplementation,\n hookNames: {\n getPermissionsForOrigin: true,\n },\n};\n\nexport type GetPermissionsHooks = {\n // This must be bound to the requesting origin.\n getPermissionsForOrigin: () => SubjectPermissions<PermissionConstraint>;\n};\n\n/**\n * Get Permissions implementation to be used in JsonRpcEngine middleware.\n *\n * @param _req - The JsonRpcEngine request - unused\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.getPermissionsForOrigin - The specific method hook needed for this method implementation\n * @returns A promise that resolves to nothing\n */\nasync function getPermissionsImplementation(\n _req: unknown,\n res: PendingJsonRpcResponse<PermissionConstraint[]>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { getPermissionsForOrigin }: GetPermissionsHooks,\n): Promise<void> {\n res.result = Object.values(getPermissionsForOrigin() || {});\n return end();\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RequestPermissionsHooks } from './requestPermissions';
|
|
2
|
+
import { GetPermissionsHooks } from './getPermissions';
|
|
3
|
+
export declare type PermittedRpcMethodHooks = RequestPermissionsHooks & GetPermissionsHooks;
|
|
4
|
+
export declare const handlers: (import("@metamask/types").PermittedHandlerExport<RequestPermissionsHooks, [import("..").RequestedPermissions], import("..").PermissionConstraint[]> | import("@metamask/types").PermittedHandlerExport<GetPermissionsHooks, void, import("..").PermissionConstraint[]>)[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handlers = void 0;
|
|
4
|
+
const requestPermissions_1 = require("./requestPermissions");
|
|
5
|
+
const getPermissions_1 = require("./getPermissions");
|
|
6
|
+
exports.handlers = [requestPermissions_1.requestPermissionsHandler, getPermissions_1.getPermissionsHandler];
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpc-methods/index.ts"],"names":[],"mappings":";;;AAAA,6DAG8B;AAC9B,qDAA8E;AAKjE,QAAA,QAAQ,GAAG,CAAC,8CAAyB,EAAE,sCAAqB,CAAC,CAAC","sourcesContent":["import {\n requestPermissionsHandler,\n RequestPermissionsHooks,\n} from './requestPermissions';\nimport { getPermissionsHandler, GetPermissionsHooks } from './getPermissions';\n\nexport type PermittedRpcMethodHooks = RequestPermissionsHooks &\n GetPermissionsHooks;\n\nexport const handlers = [requestPermissionsHandler, getPermissionsHandler];\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PermittedHandlerExport } from '@metamask/types';
|
|
2
|
+
import type { PermissionConstraint, RequestedPermissions } from '../Permission';
|
|
3
|
+
export declare const requestPermissionsHandler: PermittedHandlerExport<RequestPermissionsHooks, [
|
|
4
|
+
RequestedPermissions
|
|
5
|
+
], PermissionConstraint[]>;
|
|
6
|
+
declare type RequestPermissions = (requestedPermissions: RequestedPermissions, id: string) => Promise<[
|
|
7
|
+
Record<string, PermissionConstraint>,
|
|
8
|
+
{
|
|
9
|
+
id: string;
|
|
10
|
+
origin: string;
|
|
11
|
+
}
|
|
12
|
+
]>;
|
|
13
|
+
export declare type RequestPermissionsHooks = {
|
|
14
|
+
requestPermissionsForOrigin: RequestPermissions;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.requestPermissionsHandler = void 0;
|
|
13
|
+
const eth_rpc_errors_1 = require("eth-rpc-errors");
|
|
14
|
+
const controller_utils_1 = require("@metamask/controller-utils");
|
|
15
|
+
const utils_1 = require("../utils");
|
|
16
|
+
const errors_1 = require("../errors");
|
|
17
|
+
exports.requestPermissionsHandler = {
|
|
18
|
+
methodNames: [utils_1.MethodNames.requestPermissions],
|
|
19
|
+
implementation: requestPermissionsImplementation,
|
|
20
|
+
hookNames: {
|
|
21
|
+
requestPermissionsForOrigin: true,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Request Permissions implementation to be used in JsonRpcEngine middleware.
|
|
26
|
+
*
|
|
27
|
+
* @param req - The JsonRpcEngine request
|
|
28
|
+
* @param res - The JsonRpcEngine result object
|
|
29
|
+
* @param _next - JsonRpcEngine next() callback - unused
|
|
30
|
+
* @param end - JsonRpcEngine end() callback
|
|
31
|
+
* @param options - Method hooks passed to the method implementation
|
|
32
|
+
* @param options.requestPermissionsForOrigin - The specific method hook needed for this method implementation
|
|
33
|
+
* @returns A promise that resolves to nothing
|
|
34
|
+
*/
|
|
35
|
+
function requestPermissionsImplementation(req, res, _next, end, { requestPermissionsForOrigin }) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const { id, params } = req;
|
|
38
|
+
if ((typeof id !== 'number' && typeof id !== 'string') ||
|
|
39
|
+
(typeof id === 'string' && !id)) {
|
|
40
|
+
return end(eth_rpc_errors_1.ethErrors.rpc.invalidRequest({
|
|
41
|
+
message: 'Invalid request: Must specify a valid id.',
|
|
42
|
+
data: { request: req },
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
if (!Array.isArray(params) || !(0, controller_utils_1.isPlainObject)(params[0])) {
|
|
46
|
+
return end((0, errors_1.invalidParams)({ data: { request: req } }));
|
|
47
|
+
}
|
|
48
|
+
const [requestedPermissions] = params;
|
|
49
|
+
const [grantedPermissions] = yield requestPermissionsForOrigin(requestedPermissions, String(id));
|
|
50
|
+
// `wallet_requestPermission` is specified to return an array.
|
|
51
|
+
res.result = Object.values(grantedPermissions);
|
|
52
|
+
return end();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=requestPermissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestPermissions.js","sourceRoot":"","sources":["../../src/rpc-methods/requestPermissions.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAA2C;AAO3C,iEAA2D;AAC3D,oCAAuC;AACvC,sCAA0C;AAG7B,QAAA,yBAAyB,GAIlC;IACF,WAAW,EAAE,CAAC,mBAAW,CAAC,kBAAkB,CAAC;IAC7C,cAAc,EAAE,gCAAgC;IAChD,SAAS,EAAE;QACT,2BAA2B,EAAE,IAAI;KAClC;CACF,CAAC;AAaF;;;;;;;;;;GAUG;AACH,SAAe,gCAAgC,CAC7C,GAA2C,EAC3C,GAAmD,EACnD,KAAc,EACd,GAA6B,EAC7B,EAAE,2BAA2B,EAA2B;;QAExD,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAE3B,IACE,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ,CAAC;YAClD,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,EAC/B;YACA,OAAO,GAAG,CACR,0BAAS,CAAC,GAAG,CAAC,cAAc,CAAC;gBAC3B,OAAO,EAAE,2CAA2C;gBACpD,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE;aACvB,CAAC,CACH,CAAC;SACH;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,gCAAa,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACvD,OAAO,GAAG,CAAC,IAAA,sBAAa,EAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;SACvD;QAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;QACtC,MAAM,CAAC,kBAAkB,CAAC,GAAG,MAAM,2BAA2B,CAC5D,oBAAoB,EACpB,MAAM,CAAC,EAAE,CAAC,CACX,CAAC;QAEF,8DAA8D;QAC9D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC/C,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;CAAA","sourcesContent":["import { ethErrors } from 'eth-rpc-errors';\nimport type {\n JsonRpcEngineEndCallback,\n JsonRpcRequest,\n PendingJsonRpcResponse,\n PermittedHandlerExport,\n} from '@metamask/types';\nimport { isPlainObject } from '@metamask/controller-utils';\nimport { MethodNames } from '../utils';\nimport { invalidParams } from '../errors';\nimport type { PermissionConstraint, RequestedPermissions } from '../Permission';\n\nexport const requestPermissionsHandler: PermittedHandlerExport<\n RequestPermissionsHooks,\n [RequestedPermissions],\n PermissionConstraint[]\n> = {\n methodNames: [MethodNames.requestPermissions],\n implementation: requestPermissionsImplementation,\n hookNames: {\n requestPermissionsForOrigin: true,\n },\n};\n\ntype RequestPermissions = (\n requestedPermissions: RequestedPermissions,\n id: string,\n) => Promise<\n [Record<string, PermissionConstraint>, { id: string; origin: string }]\n>;\n\nexport type RequestPermissionsHooks = {\n requestPermissionsForOrigin: RequestPermissions;\n};\n\n/**\n * Request Permissions implementation to be used in JsonRpcEngine middleware.\n *\n * @param req - The JsonRpcEngine request\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.requestPermissionsForOrigin - The specific method hook needed for this method implementation\n * @returns A promise that resolves to nothing\n */\nasync function requestPermissionsImplementation(\n req: JsonRpcRequest<[RequestedPermissions]>,\n res: PendingJsonRpcResponse<PermissionConstraint[]>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { requestPermissionsForOrigin }: RequestPermissionsHooks,\n): Promise<void> {\n const { id, params } = req;\n\n if (\n (typeof id !== 'number' && typeof id !== 'string') ||\n (typeof id === 'string' && !id)\n ) {\n return end(\n ethErrors.rpc.invalidRequest({\n message: 'Invalid request: Must specify a valid id.',\n data: { request: req },\n }),\n );\n }\n\n if (!Array.isArray(params) || !isPlainObject(params[0])) {\n return end(invalidParams({ data: { request: req } }));\n }\n\n const [requestedPermissions] = params;\n const [grantedPermissions] = await requestPermissionsForOrigin(\n requestedPermissions,\n String(id),\n );\n\n // `wallet_requestPermission` is specified to return an array.\n res.result = Object.values(grantedPermissions);\n return end();\n}\n"]}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CaveatSpecificationConstraint, CaveatSpecificationMap } from './Caveat';
|
|
2
|
+
import { PermissionSpecificationConstraint, PermissionSpecificationMap } from './Permission';
|
|
3
|
+
export declare enum MethodNames {
|
|
4
|
+
requestPermissions = "wallet_requestPermissions",
|
|
5
|
+
getPermissions = "wallet_getPermissions"
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Utility type for extracting a union of all individual caveat or permission
|
|
9
|
+
* specification types from a {@link CaveatSpecificationMap} or
|
|
10
|
+
* {@link PermissionSpecificationMap}.
|
|
11
|
+
*
|
|
12
|
+
* @template SpecificationsMap - The caveat or permission specifications map
|
|
13
|
+
* whose specification type union to extract.
|
|
14
|
+
*/
|
|
15
|
+
export declare type ExtractSpecifications<SpecificationsMap extends CaveatSpecificationMap<CaveatSpecificationConstraint> | PermissionSpecificationMap<PermissionSpecificationConstraint>> = SpecificationsMap[keyof SpecificationsMap];
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MethodNames = void 0;
|
|
4
|
+
var MethodNames;
|
|
5
|
+
(function (MethodNames) {
|
|
6
|
+
MethodNames["requestPermissions"] = "wallet_requestPermissions";
|
|
7
|
+
MethodNames["getPermissions"] = "wallet_getPermissions";
|
|
8
|
+
})(MethodNames = exports.MethodNames || (exports.MethodNames = {}));
|
|
9
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AASA,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,+DAAgD,CAAA;IAChD,uDAAwC,CAAA;AAC1C,CAAC,EAHW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAGtB","sourcesContent":["import {\n CaveatSpecificationConstraint,\n CaveatSpecificationMap,\n} from './Caveat';\nimport {\n PermissionSpecificationConstraint,\n PermissionSpecificationMap,\n} from './Permission';\n\nexport enum MethodNames {\n requestPermissions = 'wallet_requestPermissions',\n getPermissions = 'wallet_getPermissions',\n}\n\n/**\n * Utility type for extracting a union of all individual caveat or permission\n * specification types from a {@link CaveatSpecificationMap} or\n * {@link PermissionSpecificationMap}.\n *\n * @template SpecificationsMap - The caveat or permission specifications map\n * whose specification type union to extract.\n */\nexport type ExtractSpecifications<\n SpecificationsMap extends\n | CaveatSpecificationMap<CaveatSpecificationConstraint>\n | PermissionSpecificationMap<PermissionSpecificationConstraint>,\n> = SpecificationsMap[keyof SpecificationsMap];\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@metamask/permission-controller",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Mediates access to JSON-RPC methods, used to interact with pieces of the MetaMask stack, via middleware for json-rpc-engine",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"MetaMask",
|
|
7
|
+
"Ethereum"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/MetaMask/controllers/tree/main/packages/permission-controller#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/MetaMask/controllers/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/MetaMask/controllers.git"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build:docs": "typedoc",
|
|
25
|
+
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/permission-controller",
|
|
26
|
+
"prepare-manifest:preview": "../../scripts/prepare-preview-manifest.sh",
|
|
27
|
+
"publish:preview": "yarn npm publish --tag preview",
|
|
28
|
+
"test": "jest",
|
|
29
|
+
"test:watch": "jest --watch"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@metamask/approval-controller": "~1.0.0",
|
|
33
|
+
"@metamask/base-controller": "~1.0.0",
|
|
34
|
+
"@metamask/controller-utils": "~1.0.0",
|
|
35
|
+
"@metamask/types": "^1.1.0",
|
|
36
|
+
"@types/deep-freeze-strict": "^1.1.0",
|
|
37
|
+
"deep-freeze-strict": "^1.1.1",
|
|
38
|
+
"eth-rpc-errors": "^4.0.0",
|
|
39
|
+
"immer": "^9.0.6",
|
|
40
|
+
"json-rpc-engine": "^6.1.0",
|
|
41
|
+
"nanoid": "^3.1.31"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@metamask/auto-changelog": "^3.1.0",
|
|
45
|
+
"@types/jest": "^26.0.22",
|
|
46
|
+
"deepmerge": "^4.2.2",
|
|
47
|
+
"jest": "^26.4.2",
|
|
48
|
+
"ts-jest": "^26.5.2",
|
|
49
|
+
"typedoc": "^0.22.15",
|
|
50
|
+
"typedoc-plugin-missing-exports": "^0.22.6",
|
|
51
|
+
"typescript": "~4.6.3"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=14.0.0"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public",
|
|
58
|
+
"registry": "https://registry.npmjs.org/"
|
|
59
|
+
}
|
|
60
|
+
}
|