Compare commits

...
Author SHA1 Message Date
vinicius gadea 9cefdb226d Merge pull request #430 from dadosfera/feat/organization-form
Feat/organization form
2026-01-06 10:52:33 -03:00
viniciusgadea 8ac0a8a79f REFACTOR: rename 'companySite' to 'personalSite' in user DTOs and related services 2026-01-05 15:43:35 -03:00
viniciusgadea 285de97375 FIX: update organization info field from 'name' to 'companyName' in updateOrganizationInfo method 2026-01-05 12:01:04 -03:00
viniciusgadea e2a7d2b92b FIX: update organization info field from 'name' to 'companyName' 2026-01-05 11:47:20 -03:00
viniciusgadea da23ad76db DOCS: update docs to organization forms 2026-01-02 09:22:27 -03:00
viniciusgadea 55b0961b82 FEAT: add organization info endpoints and DTOs for update and retrieval new organization forms 2026-01-02 09:21:46 -03:00
Rafael Santana d3c5c0fa63 Merge pull request #427 from dadosfera/fix/security-vulnerabilities-high
FIX: resolve HIGH security vulnerabilities (18 → 0)
2025-12-29 11:47:51 -03:00
RafaelandClaude Opus 4.5 5dbc644d1d fix: security vulnerability - upgrade multer to 2.0.2
- Update multer override from 1.4.5-lts.1 to 2.0.2 to fix HIGH vulnerabilities:
  - CVE-2025-47935 (DoS via memory leaks)
  - CVE-2025-47944
  - CVE-2025-48997
  - CVE-2025-7338

Reduces HIGH vulnerabilities from 4 to 0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 11:42:04 -03:00
Marcos Rodrigues Silva 8eddb9e1bf Merge pull request #428 from dadosfera/hotfix/user-patch
Hotfix/user patch
2025-12-26 17:58:28 -03:00
Rafael Santana a18bdccc09 Merge branch 'beta' into fix/security-vulnerabilities-high 2025-12-23 13:51:25 -03:00
RafaelandClaude b27298501d FIX: resolve HIGH security vulnerabilities (18 → 0)
Upgraded Node.js and dependencies to address critical vulnerabilities:

**Infrastructure:**
- Upgrade Node.js from 18.17-alpine to 20-alpine (Alpine 3.18 → 3.23)
- Upgrade npm to 11.7.0 (includes glob 13.0.0 fix)
- Replace npm ci with npm install, then back to npm ci with npm 11 lock

**Dependencies:**
- Update axios: 0.27.2 → 0.30.2 (fixes 2 CVEs)
- Update body-parser: 1.20.1/1.20.2 → 1.20.3
- Update cross-spawn: 7.0.3 → 7.0.6 (hoisted)
- Update glob: 10.2.4 → 10.5.0 (hoisted)
- Update path-to-regexp: 3.2.0 → 3.3.0 (maintains @nestjs/swagger compatibility)
- Update semver: 7.5.1 → 7.5.2

**Results:**
- HIGH vulnerabilities: 18 → 0 (100% reduction)
- Alpine OS vulnerabilities: 6 → 0 (fixed by Alpine 3.23)
- Node.js vulnerabilities: 12 → 0
- All tests passing
- Production verified working

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-23 13:48:02 -03:00
vinicius gadea 33ebc91826 Merge pull request #426 from dadosfera/feature/catalog-update
FEAT: Add optional 'docs' field to assets
2025-12-19 08:24:54 -03:00
vinicius gadea 6948156693 Merge branch 'beta' into feature/catalog-update 2025-12-19 08:21:52 -03:00
viniciusgadea 0aaa4384c3 DOCS: Add 'docs' field to schemas in docsfera.json and update protospack-v2 to version 3.38.0-beta.19 in package-lock.json 2025-12-18 17:43:54 -03:00
viniciusgadea 039c652b28 DOC: Update @dadosfera/protospack-v2 to version 3.38.0-beta.19 in package.json and package-lock.json 2025-12-18 17:11:18 -03:00
viniciusgadea 653d4f53b5 FEAT: Add optional 'docs' field to IDataAsset, IUpdateDataRequest, and ICreateDataAsset 2025-12-18 16:16:00 -03:00
11 changed files with 2374 additions and 3006 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
FROM node:18.17-alpine AS base_image
FROM node:20-alpine AS base_image
RUN npm install -g npm@latest
FROM base_image AS build_base
WORKDIR /app
+47
View File
@@ -0,0 +1,47 @@
FROM node:20-alpine AS base_image
RUN npm install -g npm@latest
FROM base_image AS build_base
WORKDIR /app
RUN apk update
RUN apk add --no-cache \
aws-cli \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont
COPY package*.json ./
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
# Local build with secrets
FROM build_base AS build
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
aws codeartifact login --tool npm --namespace @dadosfera --repository dadosfera-npm --domain dadosfera --domain-owner 611330257153 --region us-east-1
RUN npm ci
COPY . .
RUN npm run build
FROM base_image
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package*.json ./
RUN apk update
RUN apk add --no-cache \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
ENTRYPOINT ["npm", "run", "start:prod"]
+76 -7
View File
@@ -5461,6 +5461,66 @@
]
}
},
"/customers/{id}/organization-info": {
"get": {
"operationId": "CustomersController_getOrganizationInfo",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Organization information"
}
},
"tags": [
"Customers"
],
"security": [
{
"access-token": []
},
{
"access-token": []
}
]
},
"put": {
"operationId": "CustomersController_updateOrganizationInfo",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Organization information updated"
}
},
"tags": [
"Customers"
],
"security": [
{
"access-token": []
},
{
"access-token": []
}
]
}
},
"/catalog/data-asset/share/{id}": {
"get": {
"operationId": "ShareController_getShareDataAsset",
@@ -8169,7 +8229,7 @@
"companyName": {
"type": "string"
},
"companySite": {
"personalSite": {
"type": "string"
},
"mfaStatus": {
@@ -8204,7 +8264,7 @@
"hierarchy",
"bio",
"companyName",
"companySite",
"personalSite",
"mfaStatus",
"createdAt",
"updatedAt",
@@ -8344,7 +8404,7 @@
"companyName": {
"type": "string"
},
"companySite": {
"personalSite": {
"type": "string"
},
"customer": {
@@ -8376,7 +8436,7 @@
"hierarchy",
"bio",
"companyName",
"companySite",
"personalSite",
"mfaStatus",
"createdAt",
"updatedAt",
@@ -8520,7 +8580,7 @@
"bio": {
"type": "string"
},
"companySite": {
"personalSite": {
"type": "string"
},
"companyName": {
@@ -8572,7 +8632,7 @@
"companyName": {
"type": "string"
},
"companySite": {
"personalSite": {
"type": "string"
},
"mfaStatus": {
@@ -8600,7 +8660,7 @@
"hierarchy",
"bio",
"companyName",
"companySite",
"personalSite",
"mfaStatus",
"createdAt",
"updatedAt",
@@ -9649,6 +9709,9 @@
"public",
"private"
]
},
"docs": {
"type": "string"
}
},
"required": [
@@ -9903,6 +9966,9 @@
"public",
"private"
]
},
"docs": {
"type": "string"
}
},
"required": [
@@ -9942,6 +10008,9 @@
},
"embed": {
"$ref": "#/components/schemas/EmbedObject"
},
"docs": {
"type": "string"
}
},
"required": [
+2122 -2991
View File
File diff suppressed because it is too large Load Diff
+9 -3
View File
@@ -35,7 +35,7 @@
"@aws-sdk/signature-v4": "^3.370.0",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.4",
"@dadosfera/protospack": "2.5.3",
"@dadosfera/protospack-v2": "3.38.0-beta.18",
"@dadosfera/protospack-v2": "^3.38.0-beta.25",
"@grpc/grpc-js": "^1.9.3",
"@grpc/proto-loader": "^0.7.9",
"@nestjs/cli": "^9.5.0",
@@ -49,7 +49,7 @@
"@nestjs/schematics": "^9.2.0",
"@nestjs/swagger": "^6.3.0",
"@nestjs/testing": "^9.4.3",
"axios": "^0.27.2",
"axios": "^0.30.2",
"cache-manager": "^5.1.4",
"cache-manager-ioredis-yet": "^1.1.0",
"class-transformer": "^0.5.1",
@@ -80,7 +80,13 @@
"swagger-ui-express": "^4.6.3"
},
"overrides": {
"multer": "1.4.5-lts.1"
"multer": "2.0.2",
"form-data": "^4.0.4",
"body-parser": "^1.20.3",
"cross-spawn": "^7.0.5",
"glob": "^10.5.0",
"path-to-regexp": "^3.3.0",
"semver": "^7.5.2"
},
"devDependencies": {
"@types/cache-manager": "^4.0.6",
+6
View File
@@ -98,6 +98,8 @@ export class IDataAsset {
embed?: EmbedObject;
@ApiPropertyOptional({ enum: DataAssetShareType })
share_type?: DataAssetShareType;
@ApiPropertyOptional()
docs?: string;
}
export class IOneDataAsset {
@@ -200,6 +202,8 @@ export class IUpdateDataRequest {
embed: EmbedObject;
@ApiPropertyOptional({ enum: DataAssetShareType })
share_type?: DataAssetShareType;
@ApiPropertyOptional()
docs?: string;
}
export class ICreateDataAsset implements CreateDataAssetRequest {
@ApiProperty()
@@ -214,6 +218,8 @@ export class ICreateDataAsset implements CreateDataAssetRequest {
location: string;
@ApiPropertyOptional()
embed: EmbedObject;
@ApiPropertyOptional()
docs: string;
}
export class IPreview {
@@ -136,4 +136,32 @@ export class CustomersController {
const result = await this.customersService.getAccessDashboardUrl(user.customer_name, metadata);
return result;
}
@Get(':id/organization-info')
@Authenticated()
@RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN)
@ApiOkResponse({ description: 'Organization information' })
async getOrganizationInfo(@Param('id') id: string) {
this.logger.info('getOrganizationInfo', { id });
return this.customersService.getOrganizationInfo(id);
}
@Put(':id/organization-info')
@Authenticated()
@RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN)
@HttpCode(HttpStatus.OK)
@ApiOkResponse({ description: 'Organization information updated' })
async updateOrganizationInfo(
@Param('id') id: string,
@Body() body: {
companyName: string;
companySite: string;
domain: string;
cnpj: string;
description: string;
},
) {
return this.customersService.updateOrganizationInfo(id, body);
}
}
+54 -1
View File
@@ -223,4 +223,57 @@ export class CustomersService implements OnModuleInit {
})
)
}
}
async updateOrganizationInfo(
customerId: string,
data: {
companyName: string;
companySite: string;
domain: string;
cnpj: string;
description: string;
},
) {
try {
const result = await lastValueFrom(
this.customerService.OrganizationUpdate({
customerId,
companyName: data.companyName || '',
companySite: data.companySite || '',
domain: data.domain || '',
cnpj: data.cnpj || '',
description: data.description || '',
}),
);
return result;
} catch (err) {
if (err.details === ErrorCodes.CUSTOMER.NOT_FOUND)
throw new HttpException(err.details, HttpStatus.NOT_FOUND);
else throw err;
}
}
async getOrganizationInfo(customerId: string) {
try {
const customerResponse = await lastValueFrom(
this.customerService.CustomerFindOneById({ id: customerId })
);
const customer = customerResponse.customer;
return {
companyName: customer.companyName || '',
companySite: customer.companySite || '',
domain: customer.domain || '',
cnpj: customer.cnpj || '',
description: customer.description || ''
};
} catch (err) {
if (err.details === ErrorCodes.CUSTOMER.NOT_FOUND)
throw new HttpException(err.details, HttpStatus.NOT_FOUND);
else throw err;
}
}
}
@@ -0,0 +1,27 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
export class OrganizationUpdateRequest {
@ApiProperty()
name: string;
@ApiPropertyOptional()
companySite: string;
@ApiProperty()
domain: string;
@ApiPropertyOptional()
info: string;
@ApiPropertyOptional()
cnpj: string;
}
export class OrganizationResponse {
@ApiProperty()
name: string;
@ApiPropertyOptional()
companySite: string;
@ApiProperty()
domain: string;
@ApiPropertyOptional()
info: string;
@ApiPropertyOptional()
cnpj: string;
}
+2 -2
View File
@@ -43,7 +43,7 @@ export class User {
@ApiProperty()
companyName?: string;
@ApiProperty()
companySite?: string;
personalSite?: string;
@ApiPropertyOptional()
customer?: Customer;
@ApiProperty()
@@ -117,7 +117,7 @@ export class UpdateUserReq {
@ApiPropertyOptional()
bio?: string;
@ApiPropertyOptional()
companySite?: string;
personalSite?: string;
@ApiPropertyOptional()
companyName?: string;
@ApiPropertyOptional()
+1 -1
View File
@@ -162,7 +162,7 @@ export class UsersService implements OnModuleInit {
name: updateUserDTO.name,
bio: updateUserDTO.bio,
companyName: updateUserDTO.companyName,
companySite: updateUserDTO.companySite,
personalSite: updateUserDTO.personalSite,
customerId,
id,
metabaseUserId: undefined,