Skip to content

Commit 067e637

Browse files
committed
Refactor interactions to use "interaction types" terminology.
1 parent e4b11ef commit 067e637

File tree

5 files changed

+50
-53
lines changed

5 files changed

+50
-53
lines changed

lib/config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ cc(`${meterServiceName}.url`, () => `${bedrock.config.server.baseUri}/meters`);
4848
// ensure meter service config is overridden in deployments
4949
config.ensureConfigOverride.fields.push(meterServiceName);
5050

51-
// optional interaction config
51+
// optional interactions config
5252
cfg.interactions = {
5353
// FIXME: add qr-code route fallback for non-accept-json "protocols" requests
5454
enabled: false,
55-
// named workflows for interactions
55+
// types of interactions, type name => definition
5656
/* Spec:
5757
{
58-
<workflow name>: {
58+
<interaction type name>: {
5959
...,
6060
// a unique local interaction ID for use in interaction URLs
6161
localInteractionId,
@@ -65,5 +65,5 @@ cfg.interactions = {
6565
}
6666
}
6767
*/
68-
workflows: {}
68+
types: {}
6969
};

lib/interactions.js

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,52 @@ import {ZCAP_CLIENT as zcapClient} from './zcapClient.js';
1313

1414
const {config, util: {BedrockError}} = bedrock;
1515

16-
let WORKFLOWS_BY_NAME_MAP;
17-
let WORKFLOWS_BY_ID_MAP;
16+
let DEFINITIONS_BY_TYPE_MAP;
17+
let DEFINITIONS_BY_ID_MAP;
1818

1919
bedrock.events.on('bedrock.init', () => {
2020
const cfg = config['profile-http'];
2121

2222
// interactions feature is optional, return early if not enabled
23-
const {interactions} = cfg;
24-
if(!interactions?.enabled) {
23+
if(!cfg.interactions?.enabled) {
2524
return;
2625
}
2726

28-
// parse workflow configs when interactions are enabled
29-
const {workflows = {}} = interactions;
30-
WORKFLOWS_BY_NAME_MAP = new Map();
31-
WORKFLOWS_BY_ID_MAP = new Map();
32-
for(const workflowName in workflows) {
33-
const {localInteractionId, zcaps} = workflows[workflowName];
27+
// parse interaction types when enabled
28+
const {types = {}} = cfg.interactions;
29+
DEFINITIONS_BY_TYPE_MAP = new Map();
30+
DEFINITIONS_BY_ID_MAP = new Map();
31+
for(const typeName in types) {
32+
const {localInteractionId, zcaps} = types[typeName];
3433
if(!localInteractionId) {
3534
throw new TypeError(
36-
'"bedrock.config.profile-http.interactions.workflows" must each ' +
35+
'"bedrock.config.profile-http.interaction.types" must each ' +
3736
'have "localInteractionId".');
3837
}
39-
const workflow = {
38+
const definition = {
39+
name: typeName,
4040
localInteractionId,
41-
name: workflowName,
4241
zcaps: new Map()
4342
};
4443
for(const zcapName in zcaps) {
4544
const zcap = zcaps[zcapName];
46-
workflow.zcaps.set(zcapName, JSON.parse(zcap));
45+
definition.zcaps.set(zcapName, JSON.parse(zcap));
4746
}
48-
if(!workflow.zcaps.has('readWriteExchanges')) {
47+
if(!definition.zcaps.has('readWriteExchanges')) {
4948
throw new TypeError(
50-
'"bedrock.config.profile-http.interactions.workflows" must each ' +
49+
'"bedrock.config.profile-http.interaction.types" must each ' +
5150
'have "zcaps.readWriteExchanges".');
5251
}
53-
WORKFLOWS_BY_NAME_MAP.set(workflowName, workflow);
54-
WORKFLOWS_BY_ID_MAP.set(localInteractionId, workflow);
52+
DEFINITIONS_BY_TYPE_MAP.set(typeName, definition);
53+
DEFINITIONS_BY_ID_MAP.set(localInteractionId, definition);
5554
}
5655
});
5756

5857
bedrock.events.on('bedrock-express.configure.routes', app => {
5958
const cfg = config['profile-http'];
6059

61-
// interactions feature is optional, return early if not enabled
62-
const {interactions} = cfg;
63-
if(!interactions?.enabled) {
60+
// interaction feature is optional, return early if not enabled
61+
if(!cfg.interactions?.enabled) {
6462
return;
6563
}
6664

@@ -77,11 +75,11 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
7775
validate({bodySchema: schemas.createInteraction}),
7876
asyncHandler(async (req, res) => {
7977
const {id: accountId} = req.user.account || {};
80-
const {workflowName, exchange: {variables}} = req.body;
78+
const {type, exchange: {variables}} = req.body;
8179

82-
const workflow = WORKFLOWS_BY_NAME_MAP.get(workflowName);
83-
if(!workflow) {
84-
throw new BedrockError(`Workflow "${workflowName}" not found.`, {
80+
const definition = DEFINITIONS_BY_TYPE_MAP.get(type);
81+
if(!definition) {
82+
throw new BedrockError(`Interaction type "${type}" not found.`, {
8583
name: 'NotFoundError',
8684
details: {
8785
httpStatusCode: 404,
@@ -101,18 +99,18 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
10199
accountId
102100
}
103101
};
104-
const capability = workflow.zcaps.get('readWriteExchanges');
102+
const capability = definition.zcaps.get('readWriteExchanges');
105103
const response = await zcapClient.write({json: exchange, capability});
106104
const exchangeId = response.headers.get('location');
107-
const {localInteractionId} = workflow;
105+
const {localInteractionId} = definition;
108106
// reuse `localExchangeId` in path
109107
const localExchangeId = exchangeId.slice(exchangeId.lastIndexOf('/'));
110108
const id = `${config.server.baseUri}/${routes.interactions}/` +
111109
`${localInteractionId}/${localExchangeId}`;
112110
res.json({interactionId: id, exchangeId});
113111
}));
114112

115-
// gets an interaction by its "id"
113+
// gets an interaction
116114
app.get(
117115
routes.interaction,
118116
ensureAuthenticated,
@@ -124,20 +122,18 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
124122
query: {iuv}
125123
} = req;
126124

127-
const workflow = WORKFLOWS_BY_ID_MAP.get(localInteractionId);
128-
if(!workflow) {
125+
// get interaction definition
126+
const definition = DEFINITIONS_BY_ID_MAP.get(localInteractionId);
127+
if(!definition) {
129128
throw new BedrockError(
130-
`Workflow "${localInteractionId}" not found.`, {
129+
`Interaction type for "${localInteractionId}" not found.`, {
131130
name: 'NotFoundError',
132-
details: {
133-
httpStatusCode: 404,
134-
public: true
135-
}
131+
details: {httpStatusCode: 404, public: true}
136132
});
137133
}
138134

139135
// determine full exchange ID based on related capability
140-
const capability = workflow.zcaps.get('readWriteExchanges');
136+
const capability = definition.zcaps.get('readWriteExchanges');
141137
const exchangeId = `${capability.invocationTarget}/${localExchangeId}`;
142138

143139
// if an "Interaction URL Version" is present send "protocols"
@@ -172,10 +168,10 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
172168
filterExchange({exchange/*, previousPollResult*/}) {
173169
// ensure `accountId` matches exchange variables
174170
if(exchange?.variables.accountId !== accountId) {
175-
throw new BedrockError(
176-
'Not authorized.',
177-
'NotAllowedError',
178-
{httpStatusCode: 403, public: true});
171+
throw new BedrockError('Not authorized.', {
172+
name: 'NotAllowedError',
173+
details: {httpStatusCode: 403, public: true}
174+
});
179175
}
180176
// return only information that should be accessible to client
181177
return {

schemas/bedrock-profile-http.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* Copyright (c) 2020-2024 Digital Bazaar, Inc. All rights reserved.
2+
* Copyright (c) 2020-2025 Digital Bazaar, Inc. All rights reserved.
33
*/
44
const account = {
55
title: 'Account',
@@ -165,10 +165,10 @@ const delegateCapability = {
165165
const createInteraction = {
166166
title: 'Create Interaction',
167167
type: 'object',
168-
required: ['workflowName', 'exchange'],
168+
required: ['type', 'exchange'],
169169
additionalProperties: false,
170170
properties: {
171-
workflowName: {
171+
type: {
172172
type: 'string'
173173
},
174174
exchange: {

test/mocha/10-api.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ describe('bedrock-profile-http', () => {
848848
});
849849
});
850850
describe('interactions', () => {
851-
// FIXME: create workflow instance
851+
// FIXME: create associated workflow instance
852852
// before()
853853
it('fails to create a new interaction with bad post data', async () => {
854854
let result;
@@ -865,12 +865,12 @@ describe('bedrock-profile-http', () => {
865865
result.data.message.should.equal(
866866
`A validation error occurred in the 'Create Interaction' validator.`);
867867
});
868-
it('fails to create a new interaction with unknown workflow', async () => {
868+
it('fails to create a new interaction with unknown type', async () => {
869869
let result;
870870
let error;
871871
try {
872872
result = await api.post('/interactions', {
873-
workflowName: 'does-not-exist',
873+
type: 'does-not-exist',
874874
exchange: {
875875
variables: {}
876876
}
@@ -883,7 +883,8 @@ describe('bedrock-profile-http', () => {
883883
result.status.should.equal(404);
884884
result.ok.should.equal(false);
885885
result.data.name.should.equal('NotFoundError');
886-
result.data.message.should.equal('Workflow "does-not-exist" not found.');
886+
result.data.message.should.equal(
887+
'Interaction type "does-not-exist" not found.');
887888
});
888889
it.skip('creates a new interaction', async () => {
889890
let interactionId;
@@ -892,7 +893,7 @@ describe('bedrock-profile-http', () => {
892893
let error;
893894
try {
894895
result = await api.post('/interactions', {
895-
workflowName: 'test',
896+
type: 'test',
896897
exchange: {
897898
variables: {}
898899
}

test/test.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ config['profile-http'].additionalEdvs = {
3939

4040
// enable optional `interactions`
4141
config['profile-http'].interactions.enabled = true;
42-
config['profile-http'].interactions.workflows.test = {
42+
config['profile-http'].interactions.types.test = {
4343
localInteractionId: '1d35d09b-94c8-44d5-9d10-8dd3460a5fc4',
4444
zcaps: {
4545
// FIXME:

0 commit comments

Comments
 (0)