diff --git a/package.json b/package.json index b5ec1e0..5c8e023 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "switcher-resolver-node", - "version": "1.0.0", + "version": "1.0.1", "description": "Resolver API to be used with Switcher API", - "main": "start.js", + "main": "src/start.js", "type": "module", "author": { "name": "Roger Floriano", @@ -49,9 +49,9 @@ "helmet": "^7.1.0", "jsonwebtoken": "^9.0.2", "moment": "^2.30.1", - "mongodb": "^6.5.0", - "mongoose": "^8.3.2", - "pino": "^8.20.0", + "mongodb": "^6.6.1", + "mongoose": "^8.3.4", + "pino": "^9.0.0", "pino-pretty": "^11.0.0", "swagger-ui-express": "^5.0.0", "switcher-client": "^4.0.3", @@ -65,7 +65,7 @@ "node-notifier": "^10.0.1", "nodemon": "^3.1.0", "sinon": "^17.0.1", - "supertest": "^6.3.4" + "supertest": "^7.0.0" }, "repository": { "type": "git", diff --git a/sonar-project.properties b/sonar-project.properties index 903569a..8983c27 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.projectKey=switcherapi_switcher-resolver-node sonar.projectName=switcher-resolver-node sonar.organization=switcherapi -sonar.projectVersion=1.0.0 +sonar.projectVersion=1.0.1 sonar.links.homepage=https://github.com/switcherapi/switcher-resolver-node sonar.testExecutionReportPaths=test-report.xml diff --git a/src/api-docs/swagger-info.js b/src/api-docs/swagger-info.js index fcbbf3d..9fe6203 100644 --- a/src/api-docs/swagger-info.js +++ b/src/api-docs/swagger-info.js @@ -1,6 +1,6 @@ export default { title: 'Switcher Resolver Node', - version: 'v1.0.0', + version: 'v1.0.1', description: 'Resolver Node for Component Switchers.', contact: { name: 'Roger Floriano (petruki)', diff --git a/src/middleware/auth.js b/src/middleware/auth.js index bd2b767..bb76943 100644 --- a/src/middleware/auth.js +++ b/src/middleware/auth.js @@ -1,6 +1,7 @@ import basicAuth from 'express-basic-auth'; import jwt from 'jsonwebtoken'; import { getComponentById } from '../services/component.js'; +import { getEnvironmentByDomainAndName } from '../services/environment.js'; import { responseExceptionSilent } from '../exceptions/index.js'; import Component from '../models/component.js'; import { getRateLimit } from '../external/switcher-api-facade.js'; @@ -40,6 +41,11 @@ export async function appGenerateCredentials(req, res, next) { try { const key = req.header('switcher-api-key'); const { component, domain } = await Component.findByCredentials(req.body.domain, req.body.component, key); + const environment = await getEnvironmentByDomainAndName(component.domain, req.body.environment); + + if (!environment) { + throw new Error('Invalid environment'); + } const rate_limit = await getRateLimit(key, component); const token = await component.generateAuthToken(req.body.environment, rate_limit); diff --git a/src/routers/client-api.js b/src/routers/client-api.js index 22d01c4..5a76b4b 100644 --- a/src/routers/client-api.js +++ b/src/routers/client-api.js @@ -1,5 +1,5 @@ import express from 'express'; -import { body, check, query } from 'express-validator'; +import { body, check, query, header } from 'express-validator'; import jwt from 'jsonwebtoken'; import { checkConfig, checkConfigComponent, validate } from '../middleware/validators.js'; import { appAuth, appGenerateCredentials } from '../middleware/auth.js'; @@ -47,15 +47,13 @@ router.post('/criteria', appAuth, clientLimiter, [ } }); -router.get('/criteria/snapshot_check/:version', appAuth, clientLimiter, async (req, res) => { +router.get('/criteria/snapshot_check/:version', appAuth, clientLimiter, [ + check('version', 'Wrong value for domain version').isNumeric() +], validate, async (req, res) => { try { const domain = await checkDomain(req.domain); const version = req.params.version; - if (isNaN(version)) { - return res.status(400).send({ error: 'Wrong value for domain version' }); - } - if (domain.lastUpdate > version) { res.send({ status: false }); } else { @@ -78,7 +76,12 @@ router.post('/criteria/switchers_check', appAuth, clientLimiter, [ } }); -router.post('/criteria/auth', appGenerateCredentials, clientLimiter, async (req, res) => { +router.post('/criteria/auth', [ + header('switcher-api-key').isString().withMessage('API Key header is required'), + body('domain').isString().withMessage('Domain is required'), + body('component').isString().withMessage('Component is required'), + body('environment').isString().withMessage('Environment is required') +], validate, appGenerateCredentials, clientLimiter, async (req, res) => { try { const { exp } = jwt.decode(req.token); res.send({ token: req.token, exp }); diff --git a/src/services/environment.js b/src/services/environment.js new file mode 100644 index 0000000..380867a --- /dev/null +++ b/src/services/environment.js @@ -0,0 +1,10 @@ +import { Environment } from '../models/environment.js'; + +export async function getEnvironmentByDomainAndName(domain, name) { + const query = Environment.findOne(); + + query.where('domain', domain) + .where('name', name); + + return query.exec(); +} \ No newline at end of file diff --git a/tests/client-api.test.js b/tests/client-api.test.js index 0558c87..8aad439 100644 --- a/tests/client-api.test.js +++ b/tests/client-api.test.js @@ -115,6 +115,17 @@ describe('Testing criteria [GraphQL] ', () => { }).expect(401); }); + test('CLIENT_SUITE - Should NOT authenticate invalid environment', async () => { + await request(app) + .post('/criteria/auth') + .set('switcher-api-key', `${apiKey}`) + .send({ + domain: domainDocument.name, + component: component1.name, + environment: 'UNKNOWN ENVIRONMENT' + }).expect(401); + }); + test('CLIENT_SUITE - Should NOT return success on a simple CRITERIA response - Bad login input', async () => { const req = await request(app) .post('/graphql') @@ -708,9 +719,9 @@ describe('Testing criteria [REST] ', () => { .get('/criteria/snapshot_check/ONLY_NUMBER_ALLOWED') .set('Authorization', `Bearer ${token}`) .send(); - - expect(req.statusCode).toBe(400); - expect(req.body.error).toEqual('Wrong value for domain version'); + + expect(req.statusCode).toBe(422); + expect(req.body.errors[0].msg).toEqual('Wrong value for domain version'); }); test('CLIENT_SUITE - Should return error when validating snapshot version - Invalid token', async () => {