Skip to content

Commit

Permalink
refactor external api into folder
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Sherman <[email protected]>
  • Loading branch information
usingtechnology committed Jun 14, 2024
1 parent 673a3c5 commit 3b29bd9
Show file tree
Hide file tree
Showing 15 changed files with 928 additions and 664 deletions.
8 changes: 7 additions & 1 deletion app/src/forms/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ const _ = require('lodash');

const setupMount = (type, app, routes) => {
const p = `/${type}`;
app.use(p, routes);
if (Array.isArray(routes)) {
for (let r of routes) {
app.use(p, r);
}
} else {
app.use(p, routes);
}

return p;
};
Expand Down
48 changes: 0 additions & 48 deletions app/src/forms/form/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,52 +387,4 @@ module.exports = {
next(error);
}
},
listExternalAPIs: async (req, res, next) => {
try {
const response = await service.listExternalAPIs(req.params.formId);
res.status(200).json(response);
} catch (error) {
next(error);
}
},
listExternalAPIAlgorithms: async (req, res, next) => {
try {
const response = await service.listExternalAPIAlgorithms();
res.status(200).json(response);
} catch (error) {
next(error);
}
},
listExternalAPIStatusCodes: async (req, res, next) => {
try {
const response = await service.listExternalAPIStatusCodes();
res.status(200).json(response);
} catch (error) {
next(error);
}
},
createExternalAPI: async (req, res, next) => {
try {
const response = await service.createExternalAPI(req.params.formId, req.body, req.currentUser);
res.status(201).json(response);
} catch (error) {
next(error);
}
},
updateExternalAPI: async (req, res, next) => {
try {
const response = await service.updateExternalAPI(req.params.formId, req.params.externalAPIId, req.body, req.currentUser);
res.status(200).json(response);
} catch (error) {
next(error);
}
},
deleteExternalAPI: async (req, res, next) => {
try {
await service.deleteExternalAPI(req.params.formId, req.params.externalAPIId);
res.status(204).send();
} catch (error) {
next(error);
}
},
};
52 changes: 52 additions & 0 deletions app/src/forms/form/externalApi/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const service = require('./service');

module.exports = {
listExternalAPIs: async (req, res, next) => {
try {
const response = await service.listExternalAPIs(req.params.formId);
res.status(200).json(response);
} catch (error) {
next(error);
}
},
listExternalAPIAlgorithms: async (req, res, next) => {
try {
const response = await service.listExternalAPIAlgorithms();
res.status(200).json(response);
} catch (error) {
next(error);
}
},
listExternalAPIStatusCodes: async (req, res, next) => {
try {
const response = await service.listExternalAPIStatusCodes();
res.status(200).json(response);
} catch (error) {
next(error);
}
},
createExternalAPI: async (req, res, next) => {
try {
const response = await service.createExternalAPI(req.params.formId, req.body, req.currentUser);
res.status(201).json(response);
} catch (error) {
next(error);
}
},
updateExternalAPI: async (req, res, next) => {
try {
const response = await service.updateExternalAPI(req.params.formId, req.params.externalAPIId, req.body, req.currentUser);
res.status(200).json(response);
} catch (error) {
next(error);
}
},
deleteExternalAPI: async (req, res, next) => {
try {
await service.deleteExternalAPI(req.params.formId, req.params.externalAPIId);
res.status(204).send();
} catch (error) {
next(error);
}
},
};
Empty file.
36 changes: 36 additions & 0 deletions app/src/forms/form/externalApi/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const routes = require('express').Router();
const { currentUser, hasFormPermissions } = require('../../auth/middleware/userAccess');
const validateParameter = require('../../common/middleware/validateParameter');
const P = require('../../common/constants').Permissions;

const controller = require('./controller');

routes.use(currentUser);

routes.param('formId', validateParameter.validateFormId);

routes.get('/:formId/externalAPIs', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.listExternalAPIs(req, res, next);
});

routes.post('/:formId/externalAPIs', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.createExternalAPI(req, res, next);
});

routes.get('/:formId/externalAPIs/algorithms', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.listExternalAPIAlgorithms(req, res, next);
});

routes.get('/:formId/externalAPIs/statusCodes', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.listExternalAPIStatusCodes(req, res, next);
});

routes.put('/:formId/externalAPIs/:externalAPIId', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.updateExternalAPI(req, res, next);
});

routes.delete('/:formId/externalAPIs/:externalAPIId', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.deleteExternalAPI(req, res, next);
});

module.exports = routes;
120 changes: 120 additions & 0 deletions app/src/forms/form/externalApi/service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const Problem = require('api-problem');

const { v4: uuidv4 } = require('uuid');
const { ExternalAPIStatuses } = require('../../common/constants');

const { ExternalAPI, ExternalAPIStatusCode } = require('../../common/models');

const { ENCRYPTION_ALGORITHMS } = require('../../../components/encryptionService');

const service = {
// -----------------------------------------------------------------------------
// External API
// -----------------------------------------------------------------------------

listExternalAPIs: (formId) => {
return ExternalAPI.query().modify('filterFormId', formId);
},

listExternalAPIAlgorithms: () => {
return Object.values(ENCRYPTION_ALGORITHMS).map((x) => ({
code: x,
display: x,
}));
},

listExternalAPIStatusCodes: () => {
return ExternalAPIStatusCode.query();
},

validateExternalAPI: (data) => {
if (!data) {
throw new Problem(422, `'externalAPI record' cannot be empty.`);
}
if (data.sendApiKey) {
if (!data.apiKeyHeader || !data.apiKey) {
throw new Problem(422, `'apiKeyHeader' and 'apiKey' are required when 'sendApiKey' is true.`);
}
}
if (data.sendUserToken) {
if (!data.userTokenHeader) {
throw new Problem(422, `'userTokenHeader' is required when 'sendUserToken' is true.`);
}
}
if (data.sendUserInfo) {
if (data.userInfoEncrypted && !data.userInfoHeader) {
throw new Problem(422, `'userInfoHeader' is required when 'sendUserInfo' and 'userInfoEncrypted' are true.`);
}
if (data.userInfoEncrypted) {
if (!Object.values(ENCRYPTION_ALGORITHMS).includes(data.userInfoEncryptionAlgo)) {
throw new Problem(422, `'${data.userInfoEncryptionAlgo}' is not a valid Encryption Algorithm.`);
}
if (!data.userInfoEncryptionKey) {
throw new Problem(422, `'userInfoEncryptionKey' is required when 'userInfoEncrypted' is true.`);
}
}
}
},

createExternalAPI: async (formId, data, currentUser) => {
service.validateExternalAPI(data);

let trx;
try {
trx = await ExternalAPI.startTransaction();
data.id = uuidv4();
// set status to SUBMITTED
data.code = ExternalAPIStatuses.SUBMITTED;
await ExternalAPI.query(trx).insert({
...data,
createdBy: currentUser.usernameIdp,
});

await trx.commit();
return ExternalAPI.query().findById(data.id);
} catch (err) {
if (trx) await trx.rollback();
throw err;
}
},

updateExternalAPI: async (formId, externalAPIId, data, currentUser) => {
service.validateExternalAPI(data);

let trx;
try {
const existing = await ExternalAPI.query().modify('findByIdAndFormId', externalAPIId, formId).first().throwIfNotFound();
trx = await ExternalAPI.startTransaction();
// let's use a different method for the administrators to update status code.
// this method should not change the status code.
data.code = existing.code;
await ExternalAPI.query(trx)
.modify('findByIdAndFormId', externalAPIId, formId)
.update({
...data,
updatedBy: currentUser.usernameIdp,
});

await trx.commit();
return ExternalAPI.query().findById(externalAPIId);
} catch (err) {
if (trx) await trx.rollback();
throw err;
}
},

deleteExternalAPI: async (formId, externalAPIId) => {
let trx;
try {
await ExternalAPI.query().modify('findByIdAndFormId', externalAPIId, formId).first().throwIfNotFound();
trx = await ExternalAPI.startTransaction();
await ExternalAPI.query().deleteById(externalAPIId);
await trx.commit();
} catch (err) {
if (trx) await trx.rollback();
throw err;
}
},
};

module.exports = service;
5 changes: 4 additions & 1 deletion app/src/forms/form/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const routes = require('./routes');
const setupMount = require('../common/utils').setupMount;

const externalApiRoutes = require('./externalApi/routes');

module.exports.mount = (app) => {
return setupMount('forms', app, routes);
const p = setupMount('forms', app, [routes, externalApiRoutes]);
return p;
};
24 changes: 0 additions & 24 deletions app/src/forms/form/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,28 +171,4 @@ routes.put('/:formId/subscriptions', hasFormPermissions([P.FORM_READ, P.FORM_UPD
await controller.createOrUpdateSubscriptionDetails(req, res, next);
});

routes.get('/:formId/externalAPIs', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.listExternalAPIs(req, res, next);
});

routes.post('/:formId/externalAPIs', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.createExternalAPI(req, res, next);
});

routes.get('/:formId/externalAPIs/algorithms', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.listExternalAPIAlgorithms(req, res, next);
});

routes.get('/:formId/externalAPIs/statusCodes', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.listExternalAPIStatusCodes(req, res, next);
});

routes.put('/:formId/externalAPIs/:externalAPIId', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.updateExternalAPI(req, res, next);
});

routes.delete('/:formId/externalAPIs/:externalAPIId', hasFormPermissions([P.FORM_READ, P.FORM_UPDATE]), async (req, res, next) => {
await controller.deleteExternalAPI(req, res, next);
});

module.exports = routes;
Loading

0 comments on commit 3b29bd9

Please sign in to comment.