From 8f5cb13cc31bdad63c6c09de9730fb4fde559175 Mon Sep 17 00:00:00 2001 From: marcos-silva-rodrigues Date: Mon, 21 Apr 2025 18:53:34 -0300 Subject: [PATCH 1/3] FEAT: enforce mfa --- docsfera.json | 93 ++++++++++++++++++- package-lock.json | 8 +- package.json | 2 +- src/modules/auth/dtos/login.ts | 2 + src/modules/customers/customers.controller.ts | 11 +++ src/modules/customers/customers.service.ts | 10 ++ src/modules/customers/dtos/enforce-mfa.ts | 6 ++ 7 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 src/modules/customers/dtos/enforce-mfa.ts diff --git a/docsfera.json b/docsfera.json index b256567..fc85ccf 100644 --- a/docsfera.json +++ b/docsfera.json @@ -5473,6 +5473,54 @@ ] } }, + "/customers/{id}/mfa": { + "post": { + "operationId": "CustomersController_enableMfaEnforce", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnforceMfa" + } + } + } + }, + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Customers" + ], + "security": [ + { + "access-token": [] + }, + { + "access-token": [] + } + ] + } + }, "/customers/{id}/links": { "get": { "operationId": "CustomersController_getCustomerLinks", @@ -5620,6 +5668,34 @@ "Customers" ], "security": [ + { + "access-token": [] + }, + { + "access-token": [] + }, + { + "access-token": [] + } + ] + } + }, + "/customers/access-dashboard": { + "get": { + "operationId": "CustomersController_getAccessDashboard", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Customers" + ], + "security": [ + { + "access-token": [] + }, { "access-token": [] }, @@ -5921,6 +5997,9 @@ }, "themeEnabled": { "type": "boolean" + }, + "enforceMfa": { + "type": "boolean" } }, "required": [ @@ -5931,7 +6010,8 @@ "tier", "scheduleLimit", "links", - "themeEnabled" + "themeEnabled", + "enforceMfa" ] }, "AuthUser": { @@ -8600,6 +8680,17 @@ "tags" ] }, + "EnforceMfa": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ] + }, "CustomerLink": { "type": "object", "properties": { diff --git a/package-lock.json b/package-lock.json index 3776d14..0bf3b62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@aws-sdk/client-secrets-manager": "^3.414.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "3.37.0-alpha.20", + "@dadosfera/protospack-v2": "file:../protospack-v2/dadosfera-protospack-v2-0.0.0.tgz", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", @@ -1397,9 +1397,9 @@ } }, "node_modules/@dadosfera/protospack-v2": { - "version": "3.37.0-alpha.20", - "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.37.0-alpha.20.tgz", - "integrity": "sha512-rs8YUgnwA8dTohzSEAeilU7WAscodf26/yrsqC/lq0Dz2s3Hi09TXItnLJ5ktv5xWaBQ/eZjyc5zPjpcWL3myQ==", + "version": "0.0.0", + "resolved": "file:../protospack-v2/dadosfera-protospack-v2-0.0.0.tgz", + "integrity": "sha512-reoXI3vbFXUwzZ/o1tQSH22auXair53bJoozz8nIyYjYyAHtJ9+5IW3SgKyPTFrkiewziFEOwRQ3MJE0B3Haag==", "license": "ISC", "dependencies": { "@grpc/grpc-js": "^1.9.3", diff --git a/package.json b/package.json index d2c3b74..c824a10 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@aws-sdk/client-secrets-manager": "^3.414.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "3.37.0-alpha.20", + "@dadosfera/protospack-v2": "file:../protospack-v2/dadosfera-protospack-v2-0.0.0.tgz", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", diff --git a/src/modules/auth/dtos/login.ts b/src/modules/auth/dtos/login.ts index b3890fe..0cd90ae 100644 --- a/src/modules/auth/dtos/login.ts +++ b/src/modules/auth/dtos/login.ts @@ -87,6 +87,8 @@ export class AuthCustomer { @ApiProperty() themeEnabled: boolean; + @ApiProperty() + enforceMfa: boolean; } export class AuthSignInReq implements AuthSignInRequest { diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index 280dce3..f9f89dc 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -7,6 +7,7 @@ import { HttpStatus, Inject, Param, + Post, Put, Query, UseFilters, @@ -17,6 +18,7 @@ import { Authenticated, RequireAllPermissions, RequireModule, + RequireSomePermission, } from 'src/decorators/authentication.decorator'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; import { CustomersService } from './customers.service'; @@ -24,6 +26,7 @@ import { CustomerLinkRequest, CustomerLinksResponse } from './dtos/customers'; import { RequestUser, User } from 'src/decorators/user.decorator'; import type { StringValue } from 'ms'; import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; +import { EnforceMfa } from './dtos/enforce-mfa'; @ApiTags('Customers') @Controller('customers') @@ -39,6 +42,14 @@ export class CustomersController { this.logger = dadosferaLogger.logger; } + @Post(':id/mfa') + @Authenticated() + @RequireSomePermission(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) + async enableMfaEnforce(@Param('id') id: string, @Body() data: EnforceMfa) { + this.logger.info('enableMfaEnforce', { id }); + return await this.customersService.enableEnforceMfa(id, data.enabled); + } + @Get(':id/links') @Authenticated() @ApiOkResponse({ type: CustomerLinksResponse }) diff --git a/src/modules/customers/customers.service.ts b/src/modules/customers/customers.service.ts index ed302fd..056c5fb 100644 --- a/src/modules/customers/customers.service.ts +++ b/src/modules/customers/customers.service.ts @@ -34,6 +34,7 @@ import DadosferaLogger from '@dadosfera/dadosfera-logs'; // This function will accept any string, which may result in a bug. @Injectable() export class CustomersService implements OnModuleInit { + private customerService: CustomersProtoService; private logger: DadosferaLogger; private pipelineReadService: ReadService.PipelineV2ReadService; @@ -203,4 +204,13 @@ export class CustomersService implements OnModuleInit { ) ); } + + async enableEnforceMfa(id: string, enabled: boolean) { + return await lastValueFrom( + this.customerService.CustomerUpdateEnforceMfa({ + customerId: id, + enforceMfa: enabled + }) + ) + } } diff --git a/src/modules/customers/dtos/enforce-mfa.ts b/src/modules/customers/dtos/enforce-mfa.ts new file mode 100644 index 0000000..4709579 --- /dev/null +++ b/src/modules/customers/dtos/enforce-mfa.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class EnforceMfa { + @ApiProperty() + enabled: boolean +} \ No newline at end of file From 9e87562e23e4dfd78dff25a53055f2846346de2e Mon Sep 17 00:00:00 2001 From: marcos-silva-rodrigues Date: Tue, 22 Apr 2025 09:43:34 -0300 Subject: [PATCH 2/3] FEAT: update protospack --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0bf3b62..898117c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@aws-sdk/client-secrets-manager": "^3.414.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "file:../protospack-v2/dadosfera-protospack-v2-0.0.0.tgz", + "@dadosfera/protospack-v2": "3.37.0-beta.22", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", @@ -1397,9 +1397,9 @@ } }, "node_modules/@dadosfera/protospack-v2": { - "version": "0.0.0", - "resolved": "file:../protospack-v2/dadosfera-protospack-v2-0.0.0.tgz", - "integrity": "sha512-reoXI3vbFXUwzZ/o1tQSH22auXair53bJoozz8nIyYjYyAHtJ9+5IW3SgKyPTFrkiewziFEOwRQ3MJE0B3Haag==", + "version": "3.37.0-beta.22", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.37.0-beta.22.tgz", + "integrity": "sha512-SOu+Z5qc3ms6JjtWpHFYEgYq7Q8Y2GHBewDQj5/Evv4yxpzuANw9Eecd6zzCttV47ceM75A8rnomTj9gGkoTTg==", "license": "ISC", "dependencies": { "@grpc/grpc-js": "^1.9.3", diff --git a/package.json b/package.json index c824a10..643821b 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@aws-sdk/client-secrets-manager": "^3.414.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "file:../protospack-v2/dadosfera-protospack-v2-0.0.0.tgz", + "@dadosfera/protospack-v2": "3.37.0-beta.22", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", From f2437a8b3cc88d84d69b204d308e22a9d5836ebc Mon Sep 17 00:00:00 2001 From: marcos-silva-rodrigues Date: Tue, 22 Apr 2025 14:46:39 -0300 Subject: [PATCH 3/3] FIX: add decorator to require danger zone module --- docsfera.json | 3 +++ src/authentication/permissions.enum.ts | 3 ++- src/modules/customers/customers.controller.ts | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docsfera.json b/docsfera.json index fc85ccf..1b92192 100644 --- a/docsfera.json +++ b/docsfera.json @@ -5515,6 +5515,9 @@ { "access-token": [] }, + { + "access-token": [] + }, { "access-token": [] } diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts index 1e01531..95a313f 100644 --- a/src/authentication/permissions.enum.ts +++ b/src/authentication/permissions.enum.ts @@ -612,7 +612,8 @@ export interface DadosferaModule { export const DADOSFERA_MODULES_KEYS = { LOG_DASHBOARD: 'logs-dashboard', - ACCESS_DASHBOARD: 'access-dashboard' + ACCESS_DASHBOARD: 'access-dashboard', + DANGER_ZONE: 'danger-zone' } export const DADOSFERA_MODULES: Array = [ diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index f9f89dc..bcab557 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -45,6 +45,7 @@ export class CustomersController { @Post(':id/mfa') @Authenticated() @RequireSomePermission(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) + @RequireModule(DADOSFERA_MODULES_KEYS.DANGER_ZONE) async enableMfaEnforce(@Param('id') id: string, @Body() data: EnforceMfa) { this.logger.info('enableMfaEnforce', { id }); return await this.customersService.enableEnforceMfa(id, data.enabled);