forked from bcgov/common-hosted-form-service
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Jason Sherman <[email protected]>
- Loading branch information
1 parent
673a3c5
commit 3b29bd9
Showing
15 changed files
with
928 additions
and
664 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.