From 4b0f48c4644ce14e5024219361548c3b858e664c Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 10 Dec 2020 18:04:48 +0200 Subject: [PATCH 1/2] Augment error object with metadata and Update Terms Error Response --- docs/swagger.yaml | 21 +++++++++++++++++++++ src/common/errors.js | 4 +++- src/common/helper.js | 12 ++++++++++-- src/services/ResourceService.js | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/swagger.yaml b/docs/swagger.yaml index aa1b1fe..f7341c2 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -577,6 +577,9 @@ definitions: type: string description: The unauthorized error message. example: Unable to authenticate the user. + metadata: + type: object + description: freeform metadata object NotFound: type: object description: The not found error entity. @@ -585,6 +588,9 @@ definitions: type: string description: The not found error message. example: A resource with the name could not be found. + metadata: + type: object + description: freeform metadata object ServerError: type: object description: The server error entity. @@ -596,6 +602,9 @@ definitions: Something went wrong while processing your request. We’re sorry for the trouble. We’ve been notified of the error and will correct it as soon as possible. Please try your request again in a moment. + metadata: + type: object + description: freeform metadata object ServiceUnavailable: type: object description: The server is unavailable @@ -604,6 +613,9 @@ definitions: type: string description: The server error message. example: Something went wrong with the server. + metadata: + type: object + description: freeform metadata object BadRequest: type: object description: The bad request error entity. @@ -612,6 +624,9 @@ definitions: type: string description: The bad request error message. example: Invalid input. + metadata: + type: object + description: freeform metadata object Forbidden: type: object description: The permission error entity. @@ -620,6 +635,9 @@ definitions: type: string description: The forbidden error message. example: You are not allowed to access the request. + metadata: + type: object + description: freeform metadata object Conflict: type: object description: The conflict error entity. @@ -630,3 +648,6 @@ definitions: type: string description: The conflict error message. example: Creating a resource with a name already exists. + metadata: + type: object + description: freeform metadata object diff --git a/src/common/errors.js b/src/common/errors.js index 9908c72..bdd7ffe 100644 --- a/src/common/errors.js +++ b/src/common/errors.js @@ -15,13 +15,15 @@ function createError (name, statusCode) { * The error constructor * @param {String} message the error message * @param {String} [cause] the error cause + * @param {Object} metadata the metadata * @constructor */ - function ErrorCtor (message, cause) { + function ErrorCtor (message, cause, metadata) { Error.call(this) Error.captureStackTrace(this) this.message = message || name this.cause = cause + this.metadata = metadata this.httpStatus = statusCode } diff --git a/src/common/helper.js b/src/common/helper.js index 27e8224..ac4769e 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -427,18 +427,26 @@ function partialMatch (filter, value) { * Check if the user has agreed to all challenge terms * @param {Number} userId the user ID * @param {Array} terms an array of term UUIDs to check + * @param {String} roleId the role ID */ -async function checkAgreedTerms (userId, terms) { +async function checkAgreedTerms (userId, terms, roleId) { const unAgreedTerms = [] + const unAgreedTermIds = [] for (const term of terms) { const res = await getRequest(`${config.TERMS_API_URL}/${term.id}`, { userId }) if (!_.get(res, 'body.agreed', false)) { unAgreedTerms.push(_.get(res, 'body.title', term)) + unAgreedTermIds.push({ + termId: term.id, + roleId + }) } } if (unAgreedTerms.length > 0) { - throw new errors.ForbiddenError(`The user has not yet agreed to the following terms: [${unAgreedTerms.join(', ')}]`) + throw new errors.ForbiddenError(`The user has not yet agreed to the following terms: [${unAgreedTerms.join(', ')}]`, null, { + missingTerms: unAgreedTermIds + }) } } diff --git a/src/services/ResourceService.js b/src/services/ResourceService.js index 6132977..82615fe 100644 --- a/src/services/ResourceService.js +++ b/src/services/ResourceService.js @@ -252,7 +252,7 @@ async function init (currentUser, challengeId, resource, isCreated) { let resources // Verify the member has agreed to the challenge terms if (isCreated) { - await helper.checkAgreedTerms(memberId, _.filter(_.get(challenge, 'terms', []), t => t.roleId === resourceRole.id)) + await helper.checkAgreedTerms(memberId, _.filter(_.get(challenge, 'terms', []), t => t.roleId === resourceRole.id), resourceRole.id) } if (!currentUser.isMachine && !helper.hasAdminRole(currentUser)) { // Check if user has agreed to the challenge terms From a4207282c02f20eed0fd1d4f145c3380d81a31ff Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 10 Dec 2020 18:11:22 +0200 Subject: [PATCH 2/2] fixes --- app.js | 4 ++++ src/common/helper.js | 13 +++++-------- src/services/ResourceService.js | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app.js b/app.js index f565aab..4a57a85 100644 --- a/app.js +++ b/app.js @@ -92,6 +92,10 @@ app.use((err, req, res, next) => { } } + if (!_.isUndefined(err.metadata)) { + errorResponse.metadata = err.metadata + } + res.status(status).json(errorResponse) }) diff --git a/src/common/helper.js b/src/common/helper.js index ac4769e..5cc1f2b 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -427,26 +427,23 @@ function partialMatch (filter, value) { * Check if the user has agreed to all challenge terms * @param {Number} userId the user ID * @param {Array} terms an array of term UUIDs to check - * @param {String} roleId the role ID */ -async function checkAgreedTerms (userId, terms, roleId) { +async function checkAgreedTerms (userId, terms) { const unAgreedTerms = [] - const unAgreedTermIds = [] + const missingTerms = [] for (const term of terms) { const res = await getRequest(`${config.TERMS_API_URL}/${term.id}`, { userId }) if (!_.get(res, 'body.agreed', false)) { unAgreedTerms.push(_.get(res, 'body.title', term)) - unAgreedTermIds.push({ + missingTerms.push({ termId: term.id, - roleId + roleId: term.roleId }) } } if (unAgreedTerms.length > 0) { - throw new errors.ForbiddenError(`The user has not yet agreed to the following terms: [${unAgreedTerms.join(', ')}]`, null, { - missingTerms: unAgreedTermIds - }) + throw new errors.ForbiddenError(`The user has not yet agreed to the following terms: [${unAgreedTerms.join(', ')}]`, null, { missingTerms }) } } diff --git a/src/services/ResourceService.js b/src/services/ResourceService.js index 82615fe..6132977 100644 --- a/src/services/ResourceService.js +++ b/src/services/ResourceService.js @@ -252,7 +252,7 @@ async function init (currentUser, challengeId, resource, isCreated) { let resources // Verify the member has agreed to the challenge terms if (isCreated) { - await helper.checkAgreedTerms(memberId, _.filter(_.get(challenge, 'terms', []), t => t.roleId === resourceRole.id), resourceRole.id) + await helper.checkAgreedTerms(memberId, _.filter(_.get(challenge, 'terms', []), t => t.roleId === resourceRole.id)) } if (!currentUser.isMachine && !helper.hasAdminRole(currentUser)) { // Check if user has agreed to the challenge terms