validating cron when creating or updating input

This commit is contained in:
Gabriel Rosa
2022-05-31 11:34:28 -03:00
parent 4e2e6787a4
commit d3bcbdc43c
6 changed files with 78 additions and 12 deletions
+1
View File
@@ -0,0 +1 @@
18
+40 -7
View File
@@ -19,8 +19,9 @@
"@nestjs/platform-express": "^8.4.3", "@nestjs/platform-express": "^8.4.3",
"@nestjs/schedule": "^1.1.0", "@nestjs/schedule": "^1.1.0",
"@nestjs/swagger": "^5.2.1", "@nestjs/swagger": "^5.2.1",
"@victorradael/protospack": "2.4.1-1", "@victorradael/protospack": "2.4.2-1",
"axios": "^0.25.0", "axios": "^0.25.0",
"cron-parser": "^4.4.0",
"dotenv": "^14.2.0", "dotenv": "^14.2.0",
"helmet": "^5.0.2", "helmet": "^5.0.2",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
@@ -2360,9 +2361,9 @@
} }
}, },
"node_modules/@victorradael/protospack": { "node_modules/@victorradael/protospack": {
"version": "2.4.1-1", "version": "2.4.2-1",
"resolved": "https://registry.npmjs.org/@victorradael/protospack/-/protospack-2.4.1-1.tgz", "resolved": "https://registry.npmjs.org/@victorradael/protospack/-/protospack-2.4.2-1.tgz",
"integrity": "sha512-QpdnjOiSil1sPvOVuSC1mu5Z76ZDF1+QbDDe/RI3WVWo39dxARBxOxp7/biRY6KLxTPvSUOQbrBAg7Bfx0ul+A==", "integrity": "sha512-wdcGaK0DIEJeOHga1br11kq264JNdhdB1G2toy/u6TvAk90wwBKHNs/cZko0p9WFVuqHQOVehoHj7WJbJ3K25Q==",
"dependencies": { "dependencies": {
"rxjs": "^7.5.5" "rxjs": "^7.5.5"
} }
@@ -3541,6 +3542,17 @@
"moment-timezone": "^0.5.x" "moment-timezone": "^0.5.x"
} }
}, },
"node_modules/cron-parser": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.4.0.tgz",
"integrity": "sha512-TrE5Un4rtJaKgmzPewh67yrER5uKM0qI9hGLDBfWb8GGRe9pn/SDkhVrdHa4z7h0SeyeNxnQnogws/H+AQANQA==",
"dependencies": {
"luxon": "^1.28.0"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -6641,6 +6653,14 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==",
"engines": {
"node": "*"
}
},
"node_modules/macos-release": { "node_modules/macos-release": {
"version": "2.5.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz",
@@ -10978,9 +10998,9 @@
} }
}, },
"@victorradael/protospack": { "@victorradael/protospack": {
"version": "2.4.1-1", "version": "2.4.2-1",
"resolved": "https://registry.npmjs.org/@victorradael/protospack/-/protospack-2.4.1-1.tgz", "resolved": "https://registry.npmjs.org/@victorradael/protospack/-/protospack-2.4.2-1.tgz",
"integrity": "sha512-QpdnjOiSil1sPvOVuSC1mu5Z76ZDF1+QbDDe/RI3WVWo39dxARBxOxp7/biRY6KLxTPvSUOQbrBAg7Bfx0ul+A==", "integrity": "sha512-wdcGaK0DIEJeOHga1br11kq264JNdhdB1G2toy/u6TvAk90wwBKHNs/cZko0p9WFVuqHQOVehoHj7WJbJ3K25Q==",
"requires": { "requires": {
"rxjs": "^7.5.5" "rxjs": "^7.5.5"
} }
@@ -11927,6 +11947,14 @@
"moment-timezone": "^0.5.x" "moment-timezone": "^0.5.x"
} }
}, },
"cron-parser": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.4.0.tgz",
"integrity": "sha512-TrE5Un4rtJaKgmzPewh67yrER5uKM0qI9hGLDBfWb8GGRe9pn/SDkhVrdHa4z7h0SeyeNxnQnogws/H+AQANQA==",
"requires": {
"luxon": "^1.28.0"
}
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -14314,6 +14342,11 @@
"yallist": "^4.0.0" "yallist": "^4.0.0"
} }
}, },
"luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
},
"macos-release": { "macos-release": {
"version": "2.5.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz",
+3 -2
View File
@@ -33,6 +33,7 @@
"@nestjs/swagger": "^5.2.1", "@nestjs/swagger": "^5.2.1",
"@victorradael/protospack": "2.4.2-1", "@victorradael/protospack": "2.4.2-1",
"axios": "^0.25.0", "axios": "^0.25.0",
"cron-parser": "^4.4.0",
"dotenv": "^14.2.0", "dotenv": "^14.2.0",
"helmet": "^5.0.2", "helmet": "^5.0.2",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
@@ -42,8 +43,8 @@
"rxjs": "^7.5.5", "rxjs": "^7.5.5",
"swagger-ui-express": "^4.3.0" "swagger-ui-express": "^4.3.0"
}, },
"overrides":{ "overrides": {
"busboy@<1.6.0":"1.6.0" "busboy@<1.6.0": "1.6.0"
}, },
"devDependencies": { "devDependencies": {
"@nestjs/cli": "^8.2.4", "@nestjs/cli": "^8.2.4",
+4 -3
View File
@@ -32,9 +32,10 @@ export class LoggerMiddleware implements NestMiddleware {
const permissions = jwtDecoded.user.permissions; const permissions = jwtDecoded.user.permissions;
const clienId = jwtDecoded.user.customerId; const clientId = jwtDecoded.user.customerId;
const customer = jwtDecoded.user.customer; const customer = jwtDecoded.user.customer;
const userId = jwtDecoded.user.id; const userId = jwtDecoded.user.id;
const customer_tier = jwtDecoded.user.customer_tier;
await verifyToken(accessToken); await verifyToken(accessToken);
@@ -55,11 +56,11 @@ export class LoggerMiddleware implements NestMiddleware {
if (havePermission) { if (havePermission) {
request.body.info = { request.body.info = {
customer_id: clienId, customer_id: clientId,
user_id: userId, user_id: userId,
customer, customer,
customer_tier,
}; };
next(); next();
} else { } else {
throw new ForbiddenException(); throw new ForbiddenException();
+2
View File
@@ -3,6 +3,8 @@ import {
Controller, Controller,
Delete, Delete,
Get, Get,
Header,
Headers,
Param, Param,
Patch, Patch,
Post, Post,
+28
View File
@@ -1,16 +1,43 @@
import { Body, HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { Body, HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Timeout } from '@nestjs/schedule'; import { Timeout } from '@nestjs/schedule';
import CronParser from 'cron-parser';
import { InputsClientService } from 'src/clients/inputs/client.service'; import { InputsClientService } from 'src/clients/inputs/client.service';
import { IIdRequest, Info } from 'src/clients/inputs/interfaces'; import { IIdRequest, Info } from 'src/clients/inputs/interfaces';
@Injectable() @Injectable()
export class InputsService { export class InputsService {
constructor(private inputClient: InputsClientService) {} constructor(private inputClient: InputsClientService) {}
secondsInADay = 60 * 60 * 24;
secondsInAnHour = 60 * 60;
adjustInputPayload(payload) { adjustInputPayload(payload) {
return payload?.input_s3 || payload?.input_jdbc; return payload?.input_s3 || payload?.input_jdbc;
} }
getDifferenceInSeconds(date1, date2) {
const diffInMs = Math.abs(date2 - date1);
return diffInMs / 1000;
}
validateCron(data) {
const { info, cron } = data;
const { customer_tier } = info;
const interval = CronParser.parseExpression(cron);
const nextDate = interval.next().toDate();
const afterNextDate = interval.next().toDate();
const secondsApart = this.getDifferenceInSeconds(nextDate, afterNextDate);
if (customer_tier === 'BASIC' && secondsApart < this.secondsInADay) {
throw new HttpException(
'Não é possível criar um input com intervalo de tempo menor do que um dia.',
HttpStatus.FORBIDDEN,
);
} else if (secondsApart < this.secondsInAnHour) {
throw new HttpException(
'Não é possível criar um input com intervalo de tempo menor do que uma hora.',
HttpStatus.FORBIDDEN,
);
}
}
async create(@Body() data) { async create(@Body() data) {
this.validateCron(data);
try { try {
if ( if (
data.plugin == 'csv' || data.plugin == 'csv' ||
@@ -65,6 +92,7 @@ export class InputsService {
} }
async update(id: string, data, info: Info) { async update(id: string, data, info: Info) {
this.validateCron(data);
try { try {
const updateInputResponse: any = await this.inputClient.update({ const updateInputResponse: any = await this.inputClient.update({
id, id,