Skip to content

Commit 080f75f

Browse files
committed
Refactor new meter creation code.
1 parent 638ef78 commit 080f75f

File tree

4 files changed

+36
-52
lines changed

4 files changed

+36
-52
lines changed

lib/config.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* Copyright (c) 2019-2023 Digital Bazaar, Inc. All rights reserved.
2+
* Copyright (c) 2019-2026 Digital Bazaar, Inc. All rights reserved.
33
*/
44
import {config} from '@bedrock/core';
55
import {fileURLToPath} from 'node:url';
@@ -21,4 +21,16 @@ cfg.routes = {
2121

2222
cfg.autoLoginNewAccounts = false;
2323

24+
cfg.accountPolicies = {
25+
/*
26+
"<accountId>": {
27+
"meters": {
28+
"<policyAction, e.g., `create`>": {
29+
"<productId>": true|false
30+
}
31+
}
32+
}
33+
*/
34+
};
35+
2436
config.validation.schema.paths.push(path.join(__dirname, '..', 'schemas'));

lib/handlers.js

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ import assert from 'assert-plus';
77
const {util: {BedrockError}} = bedrock;
88

99
const HANDLERS = {
10-
// this handler must be called when creating a new meter
11-
createMeter: null,
10+
/**
11+
* @function createMeter
12+
* @param {object} options - The meter creation options.
13+
* @param {object} options.meter - The meter to create.
14+
* @description Called to create a meter after a meter policy check has
15+
* been passed.
16+
*/
17+
createMeter: null
1218
};
1319

14-
/* The createMeter is an optional handler for now. */
15-
// bedrock.events.on('bedrock.start', async () => {
16-
// _checkHandlerSet({name: 'createMeter', handler: HANDLERS.createMeter});
17-
// });
18-
1920
export function setCreateMeterHandler({handler} = {}) {
2021
assert.func(handler, 'handler');
2122
_checkHandlerNotSet({name: 'createMeter', handler: HANDLERS.createMeter});
@@ -25,19 +26,13 @@ export function setCreateMeterHandler({handler} = {}) {
2526
// expose HANDLERS for testing and internal use only
2627
export const _HANDLERS = HANDLERS;
2728

28-
// function _checkHandlerSet({name, handler}) {
29-
// if(!handler) {
30-
// throw new BedrockError(
31-
// 'Account HTTP handler not set.',
32-
// 'InvalidStateError', {name});
33-
// }
34-
// }
35-
3629
function _checkHandlerNotSet({name, handler}) {
3730
// can only set handlers once
3831
if(handler) {
3932
throw new BedrockError(
40-
'Account HTTP handler already set.',
41-
'DuplicateError', {name});
33+
`Account HTTP handler "${name}" already set.`, {
34+
name: 'DuplicateError',
35+
details: {name}
36+
});
4237
}
4338
}

lib/http.js

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,53 +38,29 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
3838
ensureAuthenticated,
3939
createValidateMiddleware({bodySchema: validators.createMeter()}),
4040
asyncHandler(async (req, res) => {
41-
/**
42-
* @function createMeter
43-
* @param {object} req - The request.
44-
* @param {object} res - The response.
45-
* @param {object} req.body - The request body.
46-
* @param {string} req.body.meter - Meter to create.
47-
* @param {string} req.user.account.id - User account ID.
48-
* @description Check if the request user's account ID is in a list of
49-
* meter creation policies. If account ID is found pass meter to create
50-
* meter handler and return the result.
51-
*/
5241
if(!HANDLERS.createMeter) {
5342
throw new BedrockError(
54-
'Missing required createMeter handler.', 'NotFoundError', {
55-
httpStatusCode: 404,
56-
public: true,
43+
'Meter creation not supported.', {
44+
name: 'NotSupportedError',
45+
details: {httpStatusCode: 400, public: true}
5746
});
5847
}
5948

6049
const meter = req.body.meter;
6150
const productId = meter.product.id;
6251
const accountId = req.user.account.id;
63-
const accountPolicies = cfg.meterCreationPolicies[accountId];
64-
const missingPolicy = !(accountPolicies && accountPolicies.create);
52+
const accountPolicy = cfg.accountPolicies[accountId];
53+
const productAllowed = accountPolicy?.meters?.create?.[productId];
6554

66-
// check for account meter creation policy
67-
if(missingPolicy) {
55+
if(!productAllowed) {
6856
throw new BedrockError(
69-
`Meter creation policy does not include account ID: ${accountId}`,
70-
'NotAllowedError', {
71-
httpStatusCode: 403,
72-
public: true,
57+
`Creation of a meter for product "${productId}" by account ` +
58+
`"${accountId}" is not allowed.`, {
59+
name: 'NotAllowedError',
60+
details: {httpStatusCode: 403, public: true}
7361
});
7462
}
7563

76-
// ensure product ID is listed in policy & creation is permitted
77-
const productInPolicy = accountPolicies.create[productId];
78-
79-
if(!(productInPolicy && productInPolicy.allowed)) {
80-
throw new BedrockError(
81-
`Policy is missing product ID: ${productId}`, 'NotAllowedError', {
82-
httpStatusCode: 403,
83-
public: true
84-
}
85-
);
86-
}
87-
8864
// pass meter to create meter handler
8965
const response = await HANDLERS.createMeter({meter});
9066

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
import '@bedrock/express';
55

66
import './http.js';
7+
78
export * as handlers from './handlers.js';

0 commit comments

Comments
 (0)