diff --git a/app/apollo/resolvers/channel.js b/app/apollo/resolvers/channel.js index a1f136240..131ecc0ec 100644 --- a/app/apollo/resolvers/channel.js +++ b/app/apollo/resolvers/channel.js @@ -17,9 +17,10 @@ const _ = require('lodash'); const { v4: UUID } = require('uuid'); const crypto = require('crypto'); +const { UserInputError, ValidationError } = require('apollo-server'); const { ACTIONS, TYPES } = require('../models/const'); -const { whoIs, validAuth } = require ('./common'); +const { whoIs, validAuth, NotFoundError} = require ('./common'); const { encryptOrgData, decryptOrgData} = require('../../utils/orgs'); @@ -65,18 +66,18 @@ const channelResolvers = { const channel = await models.Channel.findOne({ uuid: channel_uuid, org_id }); if(!channel){ - throw `Could not find the channel with uuid "${channel_uuid}"`; + throw new NotFoundError(`Could not find the channel with uuid ${channel_uuid}.`); } const versionObj = channel.versions.find(v => v.uuid === version_uuid); if (!versionObj) { - throw `versionObj "${version_uuid}" is not found for ${channel.name}:${channel.uuid}.`; + throw NotFoundError(`versionObj "${version_uuid}" is not found for ${channel.name}:${channel.uuid}`); } if (versionObj.location === 'mongo') { const deployableVersionObj = await models.DeployableVersion.findOne({org_id, channel_id: channel_uuid, uuid: version_uuid }); if (!deployableVersionObj) { - throw `DeployableVersion is not found for ${channel.name}:${channel.uuid}/${versionObj.name}:${versionObj.uuid}.`; + throw new NotFoundError(`DeployableVersion is not found for ${channel.name}:${channel.uuid}/${versionObj.name}:${versionObj.uuid}.`); } deployableVersionObj.content = await decryptOrgData(orgKey, deployableVersionObj.content); return deployableVersionObj; @@ -121,7 +122,7 @@ const channelResolvers = { try{ const channel = await models.Channel.findOne({ uuid, org_id }); if(!channel){ - throw `channel uuid "${uuid}" not found`; + throw new NotFoundError(`channel uuid "${uuid}" not found`); } await models.Channel.updateOne({ org_id, uuid }, { $set: { name } }); @@ -147,7 +148,7 @@ const channelResolvers = { const orgKey = _.first(org.orgKeys); if(!name){ - throw 'A name was not included'; + throw new UserInputError('A name was not included'); } if(!type){ throw 'A "type" of application/json or application/yaml must be included'; @@ -158,7 +159,7 @@ const channelResolvers = { const channel = await models.Channel.findOne({ uuid: channel_uuid, org_id }); if(!channel){ - throw `channel uuid "${channel_uuid}" not found`; + throw new NotFoundError(`channel uuid "${channel_uuid}" not found`); } const versions = await models.DeployableVersion.find({ org_id, channel_id: channel_uuid }); @@ -167,7 +168,7 @@ const channelResolvers = { }); if(versionNameExists) { - throw `The version name ${name} already exists`; + throw new ValidationError(`The version name ${name} already exists`); } const iv = crypto.randomBytes(16); @@ -253,14 +254,14 @@ const channelResolvers = { try{ const channel = await models.Channel.findOne({ uuid, org_id }); if(!channel){ - throw `channel uuid "${uuid}" not found`; + throw new NotFoundError(`channel uuid "${uuid}" not found`); } const channel_uuid = channel.uuid; const subCount = await models.Subscription.count({ org_id, channel_uuid }); if(subCount > 0){ - throw `${subCount} subscriptions depend on this channel. Please update/remove them before removing this channel.`; + throw new ValidationError(`${subCount} subscriptions depend on this channel. Please update/remove them before removing this channel.`); } await models.Channel.deleteOne({ org_id, uuid }); diff --git a/app/apollo/resolvers/common.js b/app/apollo/resolvers/common.js index 17e8a9131..8230edb6c 100644 --- a/app/apollo/resolvers/common.js +++ b/app/apollo/resolvers/common.js @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const { AuthenticationError } = require('apollo-server'); +const { ForbiddenError, ApolloError } = require('apollo-server'); + const whoIs = me => { if (me === null || me === undefined) return 'null'; @@ -27,12 +28,20 @@ const whoIs = me => { const validAuth = async (me, org_id, action, type, queryName, context) => { const {req_id, models, logger} = context; if (me === null || !(await models.User.isAuthorized(me, org_id, action, type, null, context))) { - logger.error({req_id, me: whoIs(me), org_id, action, type}, `AuthenticationError - ${queryName}`); - throw new AuthenticationError( + logger.error({req_id, me: whoIs(me), org_id, action, type}, `ForbiddenError - ${queryName}`); + throw new ForbiddenError( `You are not allowed to ${action} on ${type} under organization ${org_id} for the query ${queryName}.`, ); } }; -module.exports = { whoIs, validAuth }; +// Not Found Error when look up db +class NotFoundError extends ApolloError { + constructor(message) { + super(message, 'NOT_FOUND'); + Object.defineProperty(this, 'name', { value: 'NotFoundError' }); + } +} + +module.exports = { whoIs, validAuth, NotFoundError }; diff --git a/app/apollo/resolvers/subscription.js b/app/apollo/resolvers/subscription.js index 0387828f8..5c0e59c40 100644 --- a/app/apollo/resolvers/subscription.js +++ b/app/apollo/resolvers/subscription.js @@ -19,7 +19,7 @@ const { v4: UUID } = require('uuid'); const { pub } = require('../../utils/pubsub'); const { ACTIONS, TYPES } = require('../models/const'); -const { whoIs, validAuth } = require ('./common'); +const { whoIs, validAuth, NotFoundError} = require ('./common'); const resourceResolvers = { @@ -77,7 +77,7 @@ const resourceResolvers = { // loads the channel var channel = await models.Channel.findOne({ org_id, uuid: channel_uuid }); if(!channel){ - throw `channel uuid "${channel_uuid}" not found`; + throw new NotFoundError(`channel uuid "${channel_uuid}" not found`); } // loads the version @@ -85,7 +85,7 @@ const resourceResolvers = { return (version.uuid == version_uuid); }); if(!version){ - throw `version uuid "${version_uuid}" not found`; + throw new NotFoundError(`version uuid "${version_uuid}" not found`); } await models.Subscription.create({ @@ -118,13 +118,13 @@ const resourceResolvers = { try{ var subscription = await models.Subscription.findOne({ org_id, uuid }); if(!subscription){ - throw `subscription { uuid: "${uuid}", org_id:${org_id} } not found`; + throw new NotFoundError(`subscription { uuid: "${uuid}", org_id:${org_id} } not found`); } // loads the channel var channel = await models.Channel.findOne({ org_id, uuid: channel_uuid }); if(!channel){ - throw `channel uuid "${channel_uuid}" not found`; + throw new NotFoundError(`channel uuid "${channel_uuid}" not found`); } // loads the version @@ -132,7 +132,7 @@ const resourceResolvers = { return (version.uuid == version_uuid); }); if(!version){ - throw `version uuid "${version_uuid}" not found`; + throw new NotFoundError(`version uuid "${version_uuid}" not found`); } var sets = { @@ -168,7 +168,7 @@ const resourceResolvers = { try{ var subscription = await models.Subscription.findOne({ org_id, uuid }); if(!subscription){ - throw `subscription uuid "${uuid}" not found`; + throw new NotFoundError(`subscription uuid "${uuid}" not found`); } await subscription.deleteOne();