diff --git a/package.json b/package.json index cb34b62..b677fff 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "axios": "^1.6.8", "bcryptjs": "^2.4.3", "cors": "^2.8.5", - "express": "^4.19.1", + "express": "^4.19.2", "express-basic-auth": "^1.2.1", "express-rate-limit": "^7.2.0", "express-validator": "^7.0.1", @@ -41,7 +41,7 @@ "jsonwebtoken": "^9.0.2", "moment": "^2.30.1", "mongodb": "^6.5.0", - "mongoose": "^8.2.2", + "mongoose": "^8.2.4", "pino": "^8.19.0", "pino-pretty": "^11.0.0", "swagger-ui-express": "^5.0.0", diff --git a/src/helpers/index.js b/src/helpers/index.js index 191b280..194ae65 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -4,6 +4,10 @@ import { getDomainById } from '../services/domain'; import { getEnvironments } from '../services/environment'; import { getTeams } from '../services/team'; import { verifyPermissions, verifyPermissionsCascade } from './permission'; +import { some } from 'lodash'; + +const PATTERN_ALPHANUMERIC_SPACE = /^[a-zA-Z0-9_\- ]*$/; +const PATTERN_ALPHANUMERIC = /^[a-zA-Z0-9_-]*$/; export async function checkEnvironmentStatusRemoval(domainId, environmentName, strategy = false) { const environment = await getEnvironments({ domain: domainId }, ['_id', 'name']); @@ -41,7 +45,10 @@ export function parseJSON(str) { } export function containsValue(arr, value) { - return arr?.filter(item => item.match(value)).length > 0; + return some(arr, item => { + const regex = new RegExp(value); + return regex.test(item); + }); } export function formatInput(input, @@ -54,12 +61,13 @@ export function formatInput(input, let regexStr; if (options.autoUnderscore) { - regexStr = /^[a-zA-Z0-9_\- ]*$/; + regexStr = PATTERN_ALPHANUMERIC_SPACE; } else { - regexStr = options.allowSpace ? /^[a-zA-Z0-9_\- ]*$/ : /^[a-zA-Z0-9_-]*$/; + regexStr = options.allowSpace ? PATTERN_ALPHANUMERIC_SPACE : PATTERN_ALPHANUMERIC; } - if (!input.match(regexStr)) { + const regex = new RegExp(regexStr); + if (!regex.test(input)) { throw new Error('Invalid input format. Use only alphanumeric digits.'); } diff --git a/tests/client-api.test.js b/tests/client-api.test.js index 5ea7650..beba9d0 100644 --- a/tests/client-api.test.js +++ b/tests/client-api.test.js @@ -940,12 +940,12 @@ describe('Testing domain [Adm-GraphQL] ', () => { const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminMasterAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, undefined, `"UPDATE","DELETE"`, RouterTypes.GROUP)); + .send(graphqlUtils.permissionsQuery(domainId, undefined, '"UPDATE","DELETE"', RouterTypes.GROUP)); const exptected = '[{"action":"UPDATE","result":"ok"},{"action":"DELETE","result":"ok"}]'; expect(req.statusCode).toBe(200); expect(JSON.parse(req.text)).not.toBe(null); - expect(JSON.parse(req.text).data.permission[0].name).toBe("Group Test"); + expect(JSON.parse(req.text).data.permission[0].name).toBe('Group Test'); expect(JSON.parse(req.text).data.permission[0].permissions).toMatchObject(JSON.parse(exptected)); }); @@ -956,20 +956,20 @@ describe('Testing domain [Adm-GraphQL] ', () => { await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminMasterAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, undefined, `"UPDATE","DELETE"`, RouterTypes.GROUP)); + .send(graphqlUtils.permissionsQuery(domainId, undefined, '"UPDATE","DELETE"', RouterTypes.GROUP)); expect(cacheSpy.callCount).toBe(0); const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminMasterAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, undefined, `"UPDATE","DELETE"`, RouterTypes.GROUP)); + .send(graphqlUtils.permissionsQuery(domainId, undefined, '"UPDATE","DELETE"', RouterTypes.GROUP)); const exptected = '[{"action":"UPDATE","result":"ok"},{"action":"DELETE","result":"ok"}]'; expect(req.statusCode).toBe(200); expect(cacheSpy.callCount).toBe(1); expect(JSON.parse(req.text)).not.toBe(null); - expect(JSON.parse(req.text).data.permission[0].name).toBe("Group Test"); + expect(JSON.parse(req.text).data.permission[0].name).toBe('Group Test'); expect(JSON.parse(req.text).data.permission[0].permissions).toMatchObject(JSON.parse(exptected)); }); @@ -977,12 +977,12 @@ describe('Testing domain [Adm-GraphQL] ', () => { const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, undefined, `"CREATE"`, RouterTypes.GROUP, EnvType.DEFAULT)); + .send(graphqlUtils.permissionsQuery(domainId, undefined, '"CREATE"', RouterTypes.GROUP, EnvType.DEFAULT)); const exptected = '[{"action":"CREATE","result":"ok"}]'; expect(req.statusCode).toBe(200); expect(JSON.parse(req.text)).not.toBe(null); - expect(JSON.parse(req.text).data.permission[0].name).toBe("Group Test"); + expect(JSON.parse(req.text).data.permission[0].name).toBe('Group Test'); expect(JSON.parse(req.text).data.permission[0].permissions).toMatchObject(JSON.parse(exptected)); }); @@ -990,12 +990,12 @@ describe('Testing domain [Adm-GraphQL] ', () => { const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, undefined, `"UPDATE","DELETE"`, RouterTypes.GROUP)); + .send(graphqlUtils.permissionsQuery(domainId, undefined, '"UPDATE","DELETE"', RouterTypes.GROUP)); const exptected = '[{"action":"UPDATE","result":"nok"},{"action":"DELETE","result":"nok"}]'; expect(req.statusCode).toBe(200); expect(JSON.parse(req.text)).not.toBe(null); - expect(JSON.parse(req.text).data.permission[0].name).toBe("Group Test"); + expect(JSON.parse(req.text).data.permission[0].name).toBe('Group Test'); expect(JSON.parse(req.text).data.permission[0].permissions).toMatchObject(JSON.parse(exptected)); }); @@ -1003,13 +1003,13 @@ describe('Testing domain [Adm-GraphQL] ', () => { const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminMasterAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, groupConfigId, `"UPDATE","DELETE"`, RouterTypes.CONFIG)); + .send(graphqlUtils.permissionsQuery(domainId, groupConfigId, '"UPDATE","DELETE"', RouterTypes.CONFIG)); const exptected = '[{"action":"UPDATE","result":"ok"},{"action":"DELETE","result":"ok"}]'; expect(req.statusCode).toBe(200); expect(JSON.parse(req.text)).not.toBe(null); - expect(JSON.parse(req.text).data.permission[0].name).toBe("TEST_CONFIG_KEY"); - expect(JSON.parse(req.text).data.permission[1].name).toBe("TEST_CONFIG_KEY_PRD_QA"); + expect(JSON.parse(req.text).data.permission[0].name).toBe('TEST_CONFIG_KEY'); + expect(JSON.parse(req.text).data.permission[1].name).toBe('TEST_CONFIG_KEY_PRD_QA'); expect(JSON.parse(req.text).data.permission[0].permissions).toMatchObject(JSON.parse(exptected)); expect(JSON.parse(req.text).data.permission[1].permissions).toMatchObject(JSON.parse(exptected)); }); @@ -1018,13 +1018,13 @@ describe('Testing domain [Adm-GraphQL] ', () => { const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, groupConfigId, `"UPDATE","DELETE"`, RouterTypes.CONFIG)); + .send(graphqlUtils.permissionsQuery(domainId, groupConfigId, '"UPDATE","DELETE"', RouterTypes.CONFIG)); const exptected = '[{"action":"UPDATE","result":"nok"},{"action":"DELETE","result":"nok"}]'; expect(req.statusCode).toBe(200); expect(JSON.parse(req.text)).not.toBe(null); - expect(JSON.parse(req.text).data.permission[0].name).toBe("TEST_CONFIG_KEY"); - expect(JSON.parse(req.text).data.permission[1].name).toBe("TEST_CONFIG_KEY_PRD_QA"); + expect(JSON.parse(req.text).data.permission[0].name).toBe('TEST_CONFIG_KEY'); + expect(JSON.parse(req.text).data.permission[1].name).toBe('TEST_CONFIG_KEY_PRD_QA'); expect(JSON.parse(req.text).data.permission[0].permissions).toMatchObject(JSON.parse(exptected)); expect(JSON.parse(req.text).data.permission[1].permissions).toMatchObject(JSON.parse(exptected)); }); @@ -1033,7 +1033,7 @@ describe('Testing domain [Adm-GraphQL] ', () => { const req = await request(app) .post('/adm-graphql') .set('Authorization', `Bearer ${adminAccountToken}`) - .send(graphqlUtils.permissionsQuery(domainId, undefined, `"UPDATE","DELETE"`, RouterTypes.DOMAIN)); + .send(graphqlUtils.permissionsQuery(domainId, undefined, '"UPDATE","DELETE"', RouterTypes.DOMAIN)); expect(req.statusCode).toBe(200); expect(JSON.parse(req.text)).not.toBe(null); diff --git a/tests/unit-test/cache.test.js b/tests/unit-test/cache.test.js index 7358176..9999ccb 100644 --- a/tests/unit-test/cache.test.js +++ b/tests/unit-test/cache.test.js @@ -1,14 +1,14 @@ -import { permissionCache } from "../../src/helpers/cache"; -import { EnvType } from "../../src/models/environment"; -import { ActionTypes, RouterTypes } from "../../src/models/permission"; +import { permissionCache } from '../../src/helpers/cache'; +import { EnvType } from '../../src/models/environment'; +import { ActionTypes, RouterTypes } from '../../src/models/permission'; -describe("Test permissionCache", () => { +describe('Test permissionCache', () => { beforeEach(() => { permissionCache.cache.clear(); }); - it("UNIT_CACHE - Should set and get cache", () => { + it('UNIT_CACHE - Should set and get cache', () => { const cacheKey = permissionCache.permissionKey( 'adminId', 'domainId', @@ -23,7 +23,7 @@ describe("Test permissionCache", () => { expect(result).toEqual('value'); }); - it("UNIT_CACHE - Should reload cache", () => { + it('UNIT_CACHE - Should reload cache', () => { const cacheKey = permissionCache.permissionKey( 'adminId', 'domainId', @@ -38,7 +38,7 @@ describe("Test permissionCache", () => { expect(result).toBeUndefined(); }); - it("UNIT_CACHE - Should NOT reload cache", () => { + it('UNIT_CACHE - Should NOT reload cache', () => { const cacheKey = permissionCache.permissionKey( 'adminId', 'domainId', @@ -53,7 +53,7 @@ describe("Test permissionCache", () => { expect(result).toEqual('value'); }); - it("UNIT_CACHE - Should NOT reload cache - empty router/action", () => { + it('UNIT_CACHE - Should NOT reload cache - empty router/action', () => { const cacheKey = permissionCache.permissionKey( 'adminId', 'domainId', @@ -68,7 +68,7 @@ describe("Test permissionCache", () => { expect(result).toEqual('value'); }); - it("UNIT_CACHE - Should NOT get from cache - different environment", () => { + it('UNIT_CACHE - Should NOT get from cache - different environment', () => { const cacheKey = permissionCache.permissionKey( 'adminId', 'domainId', diff --git a/tests/unit-test/switcher-api-facade.test.js b/tests/unit-test/switcher-api-facade.test.js index 1e87693..5fffbb0 100644 --- a/tests/unit-test/switcher-api-facade.test.js +++ b/tests/unit-test/switcher-api-facade.test.js @@ -1,5 +1,4 @@ -// eslint-disable-next-line no-unused-vars -import app from '../../src/app'; +import '../../src/app'; import mongoose from 'mongoose'; import { checkDomain, diff --git a/tests/unit-test/try-match.test.js b/tests/unit-test/try-match.test.js index c8e58d9..6fabe89 100644 --- a/tests/unit-test/try-match.test.js +++ b/tests/unit-test/try-match.test.js @@ -4,7 +4,7 @@ describe('Test tryMatch', () => { const evilRE = '^(([a-z])+.)+[A-Z]([a-z])+$'; const evilInput1 = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; - const evilInput2 = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + const evilInput2 = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; beforeEach(() => { TimedMatch.setMaxBlackListed(50); diff --git a/tests/unit-test/verify-ownership.test.js b/tests/unit-test/verify-ownership.test.js index a7061ff..9a68290 100644 --- a/tests/unit-test/verify-ownership.test.js +++ b/tests/unit-test/verify-ownership.test.js @@ -1,5 +1,4 @@ -// eslint-disable-next-line no-unused-vars -import app from '../../src/app'; +import '../../src/app'; import mongoose from 'mongoose'; import GroupConfig from '../../src/models/group-config'; import { Team } from '../../src/models/team'; @@ -313,7 +312,7 @@ describe('Error tests', () => { domainDocument, ActionTypes.READ, RouterTypes.GROUP); - }).rejects.toThrow(new PermissionError(`Action forbidden`)); + }).rejects.toThrow(new PermissionError('Action forbidden')); }); test('UNIT_TEAM_PERMISSION_SUITE - Should NOT allow access - Permission not found', async () => { @@ -324,7 +323,7 @@ describe('Error tests', () => { domainDocument, ActionTypes.CREATE, RouterTypes.GROUP); - }).rejects.toThrow(new PermissionError(`Action forbidden`)); + }).rejects.toThrow(new PermissionError('Action forbidden')); }); test('UNIT_TEAM_PERMISSION_SUITE - Should NOT allow access - Permission does not match', async () => { @@ -335,7 +334,7 @@ describe('Error tests', () => { domainDocument, ActionTypes.READ, RouterTypes.CONFIG); - }).rejects.toThrow(new PermissionError(`Action forbidden`)); + }).rejects.toThrow(new PermissionError('Action forbidden')); }); test('UNIT_TEAM_PERMISSION_SUITE - Should NOT allow access - Member does not belong to a team', async () => { @@ -346,7 +345,7 @@ describe('Error tests', () => { domainDocument, ActionTypes.READ, RouterTypes.DOMAIN); - }).rejects.toThrow(new PermissionError(`It was not possible to find any team that allows you to proceed with this operation`)); + }).rejects.toThrow(new PermissionError('It was not possible to find any team that allows you to proceed with this operation')); }); test('UNIT_TEAM_PERMISSION_SUITE - Should NOT allow access - Team not active', async () => { @@ -359,7 +358,7 @@ describe('Error tests', () => { domainDocument, ActionTypes.READ, RouterTypes.GROUP); - }).rejects.toThrow(new PermissionError(`Action forbidden`)); + }).rejects.toThrow(new PermissionError('Action forbidden')); // tearDown await changeTeamStatus(team1Id, true); @@ -380,7 +379,7 @@ describe('Error tests', () => { domainDocument, ActionTypes.READ, RouterTypes.GROUP); - }).rejects.toThrow(new PermissionError(`Action forbidden`)); + }).rejects.toThrow(new PermissionError('Action forbidden')); }); test('UNIT_TEAM_PERMISSION_SUITE - Should NOT allow access - Member does not have permission to environment', async () => { @@ -397,7 +396,7 @@ describe('Error tests', () => { RouterTypes.CONFIG, false, 'default'); - }).rejects.toThrow(new PermissionError(`Action forbidden`)); + }).rejects.toThrow(new PermissionError('Action forbidden')); }); }); \ No newline at end of file