Compare commits

...
76 Commits
Author SHA1 Message Date
Gabriel Amorim cdba41dffa Merge pull request #203 from dadosfera/force-deploy
FIX: force deploy
2023-02-03 17:24:13 -03:00
Gabriel Rosa 5020e8913e FIX: force deploy 2023-02-03 17:21:53 -03:00
Gabriel Amorim 89369270b9 Merge pull request #202 from dadosfera/feat/embed-private
Feat/embed private
2023-02-03 17:14:14 -03:00
Gabriel Rosa 6da213aebc starting module strategy 2023-02-03 11:14:15 -03:00
Gabriel Rosa a353a1b45c FIX: new permission 2023-02-02 14:00:24 -03:00
Gabriel Rosa b36ff624b5 FIX: add logic for fetching shared data_assets 2023-02-01 18:00:36 -03:00
Gabriel Amorim 9ea610a405 Merge pull request #201 from dadosfera/fix/oauth-facebook
FIX: add all scopes to facebook oauth
2023-01-31 16:08:15 -03:00
Gabriel Rosa cd97bcbac0 FIX: add all scopes to facebook oauth 2023-01-31 16:04:57 -03:00
Anderson Feitosa 28efdf95d9 Merge pull request #200 from dadosfera/feature/upload-to-s3-presigned
feature/upload-to-s3-presigned
2023-01-24 06:39:49 -03:00
Anderson Feitosa 1ef9fd4298 FEAT: update packages 2023-01-23 13:56:51 -03:00
Anderson Feitosa 5c24ec5560 FEAT: fix upload id 2023-01-20 10:05:36 -03:00
Anderson Feitosa 962e094a65 FEAT: add upload init multi part upload 2023-01-19 17:17:33 -03:00
Anderson Feitosa 131b166d8d REFACTOR: get data from body 2023-01-16 10:56:03 -03:00
Anderson Feitosa 5419f3690c FEAT: update endpoint to get signed url to upload csv file 2023-01-16 10:55:27 -03:00
Gabriel Amorim 6f3eb7965b Merge pull request #199 from dadosfera/fix/can-untoggle
FIX: canUntoggle logic
2023-01-12 18:10:23 -03:00
Gabriel Rosa 909f0d4a4e new protospack version 2023-01-12 17:59:02 -03:00
Gabriel Rosa 8c8fdf5f88 FIX: canUntoggle logic 2023-01-12 16:47:43 -03:00
Anderson Feitosa e9582a51c2 Merge pull request #198 from dadosfera/feature/mixpanel-first-name
feature/mixpanel-first-name
2023-01-12 12:28:24 -03:00
Anderson Feitosa 0590c20af8 FEAT: add more prefixed values 2023-01-12 12:03:04 -03:00
Anderson Feitosa 05eefe866b FEAT: add suffix on email 2023-01-12 12:02:16 -03:00
Anderson Feitosa fa023756c7 FEAT: replace dadosfera with empty string 2023-01-12 11:56:47 -03:00
Anderson Feitosa 7f967e5e75 FEAT: update hardcoded separator 2023-01-12 11:52:51 -03:00
Anderson Feitosa 2a0b17e45a FEAT: add more prefixed values 2023-01-12 11:49:32 -03:00
Anderson Feitosa b1f6d765b2 FEAT: add more prefixed values 2023-01-12 11:47:04 -03:00
Anderson Feitosa 3c9ed08515 FEAT: split email into fist name and last name 2023-01-12 11:40:14 -03:00
Gabriel Amorim c7ca8297c9 Merge pull request #197 from dadosfera/fix/reset-password-email
FIX: send language on reset password email
2023-01-10 20:29:58 -03:00
Gabriel Rosa d269e9efe4 FIX: send language on reset password email 2023-01-10 18:50:32 -03:00
Gabriel Amorim 61cc238891 Merge pull request #196 from dadosfera/feat/cognito-mailing
FIX: send language on create users and resend invite
2023-01-10 18:06:06 -03:00
Gabriel Rosa b5df916511 Merge branch 'main' into feat/cognito-mailing 2023-01-10 15:05:18 -03:00
Gabriel Amorim 95da106fb8 Merge pull request #195 from dadosfera/fix/customer-schedule-limit
fix/customer-schedule-limit
2023-01-06 18:29:57 -03:00
Gabriel Rosa 5730402312 update protospack 2023-01-06 18:04:16 -03:00
Gabriel Rosa c2ea8b69da FIX: customer scheduleLimit on login 2023-01-06 15:24:01 -03:00
Gabriel Rosa 14081bb9ca FIX: send language on create users and resend invite 2023-01-06 15:18:49 -03:00
Victor Radael 82d9024f24 Merge pull request #193 from dadosfera/feat/update-connection
Feat/update connection
2022-12-27 17:21:25 -03:00
Gabriel Rosa 53a6d3957a Merge branch 'main' into feat/update-connection 2022-12-27 17:01:32 -03:00
Anderson Feitosa 7dab555009 Merge pull request #194 from dadosfera/feature/download-logs
feature/download-logs
2022-12-27 16:41:11 -03:00
Anderson Feitosa 27dacf1257 FEAT: update protospack version 2022-12-27 12:24:15 -03:00
Anderson Feitosa f71bb523ff FEAT: add download logs api route 2022-12-27 12:23:03 -03:00
Victor Radael db55a8abde FEAT: Update OAuth Connection 2022-12-26 17:47:30 -03:00
Victor Radael 8f40b159d6 FEAT: MERGE main to deploy 2022-12-26 17:43:31 -03:00
Anderson Feitosa 5c6f36a760 Merge pull request #192 from dadosfera/feature/pipeline-object-to-data-asset
feature/pipeline-object-to-data-asset
2022-12-23 14:07:33 -03:00
Anderson Feitosa db4a2d9d2e FEAT: update protospack version 2022-12-22 17:43:54 -03:00
Anderson Feitosa 9a1b3e0bf4 FEAT: update protospack 2022-12-22 17:38:58 -03:00
Gabriel Rosa 67d9b3a06e Send metabaseUserId undefined to user update 2022-12-22 17:14:51 -03:00
Anderson Feitosa 1150d21763 FEAT: remove metabase user id 2022-12-22 17:02:03 -03:00
Anderson Feitosa b38e9f26c3 FEAT: add route to get data asset by pipeline and object 2022-12-22 17:00:56 -03:00
Anderson Feitosa 5a23923e53 DOCS: docsfera 2022-12-22 13:16:56 -03:00
Anderson Feitosa 3db7e99d9e FEAT: parse objects 2022-12-22 13:16:44 -03:00
Anderson Feitosa c85cd37f3a FEAT: add new api route to get pipeline objects 2022-12-22 13:08:08 -03:00
Victor Radael 190a63f0eb FEAT: Update OAuth Connection 2022-12-20 17:01:00 -03:00
Gabriel Amorim 0fc8c427a2 Merge pull request #191 from dadosfera/fix/refresh-token
Fix/refresh token
2022-12-16 09:40:56 -03:00
Gabriel Rosa 59c3ce7ed9 FIX: do not use User() on non-authenticated routes 2022-12-16 08:09:20 -03:00
Victor Radael c5c428d3d4 FIX: Refresh token 2022-12-15 19:57:52 -03:00
Victor Radael cda7f9a9b5 FEAT: Edit connection 2022-12-15 16:01:24 -03:00
Victor Radael bb3b71d5f0 Merge remote-tracking branch 'origin' into feat/upload-csv 2022-12-15 16:01:02 -03:00
Victor Radael e47459eb9a FEAT: Edit connection 2022-12-15 16:00:54 -03:00
Gabriel Amorim a2de729e0e Merge pull request #190 from dadosfera/feat/cognito-app-client
Feat/cognito app client
2022-12-14 13:20:29 -03:00
Gabriel Rosa e2cb02e51a new protospack version 2022-12-14 10:49:33 -03:00
Gabriel Rosa 8a0c91eca5 new protospack version 2022-12-14 10:02:02 -03:00
Gabriel Rosa 15302d80bc Merge branch 'main' into feat/cognito-app-client 2022-12-13 16:12:19 -03:00
Gabriel Rosa 5aa63154c5 new protospack version 2022-12-13 15:34:57 -03:00
Gabriel Rosa 48af897e79 FEAT: send customer_name on refresh token 2022-12-13 09:28:42 -03:00
Victor Radael 9eb61a0ac9 Merge pull request #189 from dadosfera/feat/upload-csv
FIX: Upload CSV
2022-12-12 17:41:44 -03:00
Victor Radael 4a9e5b0ffc FIX: Upload CSV 2022-12-12 17:04:16 -03:00
Victor Radael 23fe522cc1 Merge pull request #188 from dadosfera/feat/upload-csv
Feat/upload csv
2022-12-09 17:14:36 -03:00
Victor Radael ea8dfa2e12 FEAT: Deploy Merge 2022-12-09 17:10:50 -03:00
Anderson Feitosa 9477223bec Merge pull request #187 from dadosfera/hotfix/semantic-release
hotfix/semantic-release
2022-12-09 11:32:54 -03:00
Anderson Feitosa 519070bd82 FIX: change docs 2022-12-09 11:32:23 -03:00
Victor Radael ff5e735121 FEAT: Find a file pipeline 2022-12-09 08:29:27 -03:00
Victor Radael eaddca7eb3 FEAT: Creat a Upload CSV Pipeline 2022-12-06 18:06:32 -03:00
Victor Radael 98e865c48a FEAT: Create Upload CSV Pipeline 2022-12-05 20:35:35 -03:00
Victor Radael 2c207f068c FEAT: Create Upload CSV Pipeline 2022-12-05 20:34:04 -03:00
Victor Radael ea7ec52e1f FEAT: upload 50MB file 2022-12-01 18:55:48 -03:00
Victor Radael be228b7425 FEAT: upload 50MB file 2022-12-01 17:50:44 -03:00
Victor Radael 90edc6552a FEAT: Upload CSV 2022-12-01 14:57:44 -03:00
Victor Radael ed96609011 FEAT: Upload CSV 2022-12-01 14:56:41 -03:00
30 changed files with 1636 additions and 407 deletions
+2 -1
View File
@@ -290,7 +290,7 @@ Example: `FIX: ensure Range headers adhere more closely to RFC 2616`
### Making a Pull Request
1. Commit your changes
2. Open the Pull Request on GitHub
3. Send Pull Request link in microsfera Google Chat Group for review and possible approval
3. Send Pull Request link in Microsfera Google Chat Group for review and possible approval
## 🛠️ Built with
Some technologies used in this project:
@@ -299,3 +299,4 @@ Some technologies used in this project:
## ⚙️ Back-end Architecture
The architecture can be found at [this link](https://sites.google.com/dadosfera.ai/wikidoproduto/time/back-end).
+1028 -220
View File
File diff suppressed because it is too large Load Diff
+26 -95
View File
@@ -12,7 +12,7 @@
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.112.0",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.4",
"@dadosfera/protospack-v2": "3.22.0",
"@dadosfera/protospack-v2": "3.28.0",
"@grpc/grpc-js": "^1.6.7",
"@grpc/proto-loader": "^0.6.13",
"@nestjs/common": "^8.4.7",
@@ -31,7 +31,7 @@
"dotenv": "^14.3.2",
"elastic-apm-node": "^3.36.0",
"helmet": "^5.1.0",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"jwk-to-pem": "^2.0.5",
"mixpanel": "^0.17.0",
"passport": "^0.6.0",
@@ -1727,9 +1727,9 @@
}
},
"node_modules/@dadosfera/protospack-v2": {
"version": "3.22.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.22.0.tgz",
"integrity": "sha512-tkHqNiSeuiGtuFieOOaTTaB1OOKzcFd+7bTlDXj6FdorIHXt+FtHxslWX5b9XERzkQg7nseak1gFw2w4krOdbg==",
"version": "3.28.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.28.0.tgz",
"integrity": "sha512-JZYYhoaXFUpb5W/fBVt4XYe1Hlef2x9aLlM2Yv0erYn9QAu+/Pb99YnXbkgawQVlmJojSRrAvSwq1o9yOgKCrg==",
"dependencies": {
"@grpc/grpc-js": "^1.6.7",
"rxjs": "^7.5.5",
@@ -7786,30 +7786,18 @@
}
},
"node_modules/jsonwebtoken": {
"version": "8.5.1",
"license": "MIT",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
"semver": "^7.3.8"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/jsonwebtoken/node_modules/semver": {
"version": "5.7.1",
"license": "ISC",
"bin": {
"semver": "bin/semver"
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/jwa": {
@@ -7908,30 +7896,6 @@
"version": "4.3.0",
"license": "MIT"
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"license": "MIT"
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"license": "MIT"
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"license": "MIT"
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"license": "MIT"
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"dev": true,
@@ -7942,10 +7906,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/lodash.once": {
"version": "4.1.1",
"license": "MIT"
},
"node_modules/lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -9484,9 +9444,9 @@
"license": "MIT"
},
"node_modules/semver": {
"version": "7.3.7",
"dev": true,
"license": "ISC",
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -12324,9 +12284,9 @@
}
},
"@dadosfera/protospack-v2": {
"version": "3.22.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.22.0.tgz",
"integrity": "sha512-tkHqNiSeuiGtuFieOOaTTaB1OOKzcFd+7bTlDXj6FdorIHXt+FtHxslWX5b9XERzkQg7nseak1gFw2w4krOdbg==",
"version": "3.28.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.28.0.tgz",
"integrity": "sha512-JZYYhoaXFUpb5W/fBVt4XYe1Hlef2x9aLlM2Yv0erYn9QAu+/Pb99YnXbkgawQVlmJojSRrAvSwq1o9yOgKCrg==",
"requires": {
"@grpc/grpc-js": "^1.6.7",
"rxjs": "^7.5.5",
@@ -16455,23 +16415,14 @@
}
},
"jsonwebtoken": {
"version": "8.5.1",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"semver": {
"version": "5.7.1"
}
"semver": "^7.3.8"
}
},
"jwa": {
@@ -16544,24 +16495,6 @@
"lodash.camelcase": {
"version": "4.3.0"
},
"lodash.includes": {
"version": "4.3.0"
},
"lodash.isboolean": {
"version": "3.0.3"
},
"lodash.isinteger": {
"version": "4.0.4"
},
"lodash.isnumber": {
"version": "3.0.3"
},
"lodash.isplainobject": {
"version": "4.0.6"
},
"lodash.isstring": {
"version": "4.0.1"
},
"lodash.memoize": {
"version": "4.1.2",
"dev": true
@@ -16570,9 +16503,6 @@
"version": "4.6.2",
"dev": true
},
"lodash.once": {
"version": "4.1.1"
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -17584,8 +17514,9 @@
}
},
"semver": {
"version": "7.3.7",
"dev": true,
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"requires": {
"lru-cache": "^6.0.0"
}
+2 -2
View File
@@ -28,7 +28,7 @@
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.112.0",
"@dadosfera/dadosfera-logs": "^1.0.0-beta.4",
"@dadosfera/protospack-v2": "3.22.0",
"@dadosfera/protospack-v2": "3.28.0",
"@grpc/grpc-js": "^1.6.7",
"@grpc/proto-loader": "^0.6.13",
"@nestjs/common": "^8.4.7",
@@ -47,7 +47,7 @@
"dotenv": "^14.3.2",
"elastic-apm-node": "^3.36.0",
"helmet": "^5.1.0",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"jwk-to-pem": "^2.0.5",
"mixpanel": "^0.17.0",
"passport": "^0.6.0",
+43 -1
View File
@@ -336,6 +336,16 @@ export const PERMISSIONS_GROUPS = {
'es-es': 'Gestor de catálogos. Puede ver y editar todos los activos.',
},
},
EMBED_ANALYTICS: {
seqid: 44,
claim: 'catalog:embed',
usage: PermissionUsages.INTERNAL,
name: {
'pt-br': 'Acessar Módulo de Incorporação de Ativos',
'en-us': 'Access Embedding analytics Module',
'es-es': 'Acceder al Módulo de Incorporación de Activos',
},
},
},
},
@@ -556,7 +566,34 @@ export const PERMISSIONS_GROUPS = {
},
},
};
export interface DadosferaModule {
name: string;
description: string;
key: string;
permissionSeqId: number;
}
export const DADOSFERA_MODULES: Array<DadosferaModule> = [
{
name: 'Intelligence Module',
description: 'Orchest Module',
key: 'intelligence',
permissionSeqId: PERMISSIONS_GROUPS.ANALYZE.permissions.INTELLIGENCE.seqid,
},
{
name: 'Proccessing Module',
description: 'Proccessing Module',
key: 'process',
permissionSeqId:
PERMISSIONS_GROUPS.PROCESS.permissions.TRANSFORMATION.seqid,
},
{
name: 'Embedded Analytics',
description: 'Embedded Analytics Module',
key: 'embedded-analytics',
permissionSeqId:
PERMISSIONS_GROUPS.PROCESS.permissions.TRANSFORMATION.seqid,
},
];
// traverses the object searching for duplicate seqids or claims (executes at runtime)
let nextAvailableSeqid = 0;
const seqids = Object.values(PERMISSIONS_GROUPS).flatMap((namespace) =>
@@ -576,4 +613,9 @@ Object.values(PERMISSIONS_GROUPS).map((namespace) =>
}),
);
DADOSFERA_MODULES.map((m) => m.key).forEach((m, i, arr) => {
if (arr.indexOf(m) !== i)
throw new Error(`DADOSFERA_MODULES[${i}] does not have a unique key`);
});
logger.log(`next available seqid ${nextAvailableSeqid + 1}`);
+22 -10
View File
@@ -11,7 +11,6 @@ import {
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import {
AuthRefreshAccessTokenRequest,
AuthChangePasswordRequest,
AuthResetPasswordRequest,
AuthVerifyResetPasswordCodeRequest,
@@ -30,8 +29,12 @@ import { AuthClientService } from './auth.service';
import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter';
import { RequestUser, User } from 'src/authentication/user.decorator';
import { Metadata } from '@grpc/grpc-js';
import { AuthSignInReq, AuthSignInRes } from './dtos/login';
import {
AuthRefreshAccessTokenReq,
AuthSignInReq,
AuthSignInRes,
} from './dtos/login';
import { PackTheMetadata } from 'src/utils/ PackTheMetadata';
@ApiTags('Auth')
@UseFilters(new GrpcToHttpExceptionFilter())
@@ -54,8 +57,7 @@ export class AuthController {
@Headers('Dadosfera-Lang') language: string,
): Promise<AuthSignInRes> {
this.logger.info('/auth - SignIn');
const metadata = new Metadata();
metadata.add('language', language || 'pt-br');
const metadata = PackTheMetadata({ language: language || 'pt-br' });
return this.authClient.signIn({ username, password, totp }, metadata);
}
@@ -77,12 +79,16 @@ export class AuthController {
@Post('refresh-access-token')
@HttpCode(HttpStatus.OK)
async refreshAccessToken(
@Body() { refreshToken }: AuthRefreshAccessTokenRequest,
@Body()
{ refreshToken, customerName: customer_name }: AuthRefreshAccessTokenReq,
@Headers('Dadosfera-Lang') language: string,
) {
this.logger.info('/auth - RefreshAccessToken');
const metadata = new Metadata();
metadata.add('language', language || 'pt-br');
const metadata = PackTheMetadata({
customer_name,
language,
});
return this.authClient.refreshAccessToken({ refreshToken }, metadata);
}
@@ -107,12 +113,18 @@ export class AuthController {
@Post('reset-password')
@HttpCode(HttpStatus.OK)
async resetPassword(@Body() body: AuthResetPasswordRequest) {
async resetPassword(
@Body() body: AuthResetPasswordRequest,
@Headers('dadosfera-lang') language,
) {
this.logger.info('/auth - reset-password');
const metadata = PackTheMetadata({
language: language,
});
const { username } = body;
return this.authClient.resetPassword({ username });
return this.authClient.resetPassword({ username }, metadata);
}
@Post('verify-reset-password-code')
+7 -2
View File
@@ -90,10 +90,15 @@ export class AuthClientService implements OnModuleInit {
);
}
async resetPassword({ username }: AuthResetPasswordRequest) {
async resetPassword(
{ username }: AuthResetPasswordRequest,
metadata: Metadata,
) {
this.logger.info('resetPassword');
return lastValueFrom(this.authService.AuthResetPassword({ username }));
return lastValueFrom(
this.authService.AuthResetPassword({ username }, metadata),
);
}
async verifyResetPasswordCode({
+9
View File
@@ -72,6 +72,8 @@ export class AuthCustomer {
name: string;
@ApiProperty()
tier: string;
@ApiProperty()
scheduleLimit: string;
}
export class AuthSignInReq implements AuthSignInRequest {
@@ -97,3 +99,10 @@ export class AuthSignInRes implements AuthSignInResponse {
@ApiPropertyOptional()
termsOfUse?: TermsOfUseStatus;
}
export class AuthRefreshAccessTokenReq {
@ApiProperty()
refreshToken: string;
@ApiProperty()
customerName: string;
}
+78 -24
View File
@@ -1,11 +1,14 @@
import {
BadRequestException,
Body,
Controller,
Delete,
ForbiddenException,
Get,
Headers,
HttpException,
Inject,
NotFoundException,
Param,
Post,
Put,
@@ -88,6 +91,59 @@ export class CatalogController {
return res;
}
@Get('data-asset')
async findByPipelineAndObject(@User() user: RequestUser, @Query() query) {
const { username, user_id, customer_id, customer_name, permissions } = user;
const { pipeline, object } = query;
this.logger.info(`/catalog - ON GET DATA ASSET BY PIPELINE AND OBJECT`, {
username,
customer_name,
});
if (!pipeline || !object) {
throw new BadRequestException('Query params not provided');
}
const is_data_manager = permissions.includes(
PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER.seqid,
);
let has_permission = false;
const metadata = PackTheMetadata({
username,
user_id: undefined,
customer_id,
customer_name,
});
const user_roles = await this.catalogService.getUserRolesIds(user_id);
const { data_asset } =
await this.catalogService.getOneDataAssetByPipelineAndObject({
pipeline: query.pipeline,
object: query.object,
customer_id,
metadata,
});
if (data_asset?.owner === username) has_permission = true;
for (const role of user_roles) {
if (data_asset.p_roles.includes(role)) has_permission = true;
}
if (data_asset.p_users.includes(user_id)) has_permission = true;
if (is_data_manager || has_permission) {
delete data_asset.p_roles;
delete data_asset.p_users;
return { data_asset };
}
throw new ForbiddenException(
'You do not have permission to access this data asset.',
);
}
@Get('tags')
@RequireSomePermission(
PERMISSIONS_GROUPS.CATALOG.permissions.GET,
@@ -118,12 +174,12 @@ export class CatalogController {
)
async getDataAsset(
@User() user: RequestUser,
@Headers() headers,
@Param('id') id,
@Query('shared') shared?: 'true',
) {
const { username, user_id, customer_id, customer_name, permissions } = user;
this.logger.info(`/catalog - ON GET ONE DASHBOARD METABASE ROUTE`, {
this.logger.info(`GET /data-asset/${id}`, {
username,
customer_name,
});
@@ -146,25 +202,24 @@ export class CatalogController {
id,
metadata,
});
has_permission =
is_data_manager ||
data_asset?.owner === username ||
(user_roles as Array<any>).some((r) => data_asset.p_roles.includes(r)) ||
data_asset.p_users.includes(user_id);
if (
shared === 'true' &&
(data_asset.share_type === undefined || data_asset.share_type === 'none')
)
throw new NotFoundException();
if (!has_permission)
throw new ForbiddenException(
'You do not have permission to access this data asset.',
);
delete data_asset.p_roles;
delete data_asset.p_users;
if (data_asset?.owner === username) has_permission = true;
for (const role of user_roles) {
if (data_asset.p_roles.includes(role)) has_permission = true;
}
if (data_asset.p_users.includes(user_id)) has_permission = true;
if (is_data_manager || has_permission) {
delete data_asset.p_roles;
delete data_asset.p_users;
return { data_asset };
}
throw new HttpException(
'You do not have permission to access this data asset.',
403,
);
return { data_asset };
}
@Get('data-asset/rls/:id')
@@ -217,9 +272,8 @@ export class CatalogController {
return { data_asset };
}
throw new HttpException(
throw new ForbiddenException(
'You do not have permission to access this data asset.',
403,
);
}
@@ -322,7 +376,7 @@ export class CatalogController {
async updateDataAsset(
@User() user: RequestUser,
@Headers('Dadosfera-Lang') language,
@Param('id') id,
@Param('id') data_asset_id,
@Body() body: IUpdateDataRequest,
): Promise<IOneDataAsset> {
const { customer_id, customer_name, user_id, username } = user;
@@ -336,7 +390,7 @@ export class CatalogController {
const result = await this.catalogService.updateOneDataAsset({
body,
data_asset_id: id,
data_asset_id,
customer_id,
metadata,
});
+24
View File
@@ -197,6 +197,30 @@ class CatalogService implements OnModuleInit {
return { data_asset: asset[0] };
}
async getOneDataAssetByPipelineAndObject(data: {
customer_id: string;
pipeline: string;
object: string;
metadata: Metadata;
}) {
const { customer_id, metadata, pipeline, object } = data;
const { data_asset } = await lastValueFrom(
this.catalogReadService.GetOneDataAssetByPipelineAndObject(
{ pipeline, object },
metadata,
),
);
let asset = JSON.parse(data_asset);
asset = {
...asset,
p_roles: asset.roles,
p_users: asset.users,
};
asset = await this.getAssetsUsersAndRoles([asset], customer_id);
return { data_asset: asset[0] };
}
async updateOneDataAsset(data: {
data_asset_id: string;
customer_id: string;
+7
View File
@@ -1,6 +1,11 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { CreateDataAssetRequest } from '@dadosfera/protospack-v2/dist/lib/Catalog/interfaces/messages';
export enum DataAssetShareType {
none = 'none',
public = 'public',
private = 'private',
}
export class EmbedObject {
@ApiProperty()
url: string;
@@ -135,6 +140,8 @@ export class IUpdateDataRequest {
tags: string[];
@ApiPropertyOptional()
embed: EmbedObject;
@ApiPropertyOptional({ enum: DataAssetShareType })
share_type: DataAssetShareType;
}
export class ICreateDataAsset implements CreateDataAssetRequest {
@ApiProperty()
@@ -164,11 +164,15 @@ export class ConnectionController {
@Headers('Dadosfera-Lang') language,
@User() user: RequestUser,
@Param('id') id,
@Query('details') details,
@Query() queries,
): Promise<ConnectionDetailsRes> {
this.logger.info('/connections - Get Connection Details');
if (!language) language = 'en-us';
console.log(queries);
const { details, sensitive } = queries;
const { user_id, customer_id, customer_name, username } = user;
const metadata = PackTheMetadata({
user_id,
@@ -177,6 +181,7 @@ export class ConnectionController {
username,
details,
language,
sensitive,
});
const response: any = await this.clientService.getConnectionDetails({
+3 -4
View File
@@ -9,6 +9,8 @@ import {
ProtoPaths,
} from '@dadosfera/protospack-v2/dist/lib/Duc';
const isLocalConnection = !!process.env.DUC_URL?.includes('0.0.0.0');
export class DucClient {
public name = 'DucClient';
@@ -17,10 +19,7 @@ export class DucClient {
options: {
url: process.env.DUC_URL,
package: [ProtoPackages.WritePackage, ProtoPackages.ReadPackage],
credentials:
process.env.LOCAL_ENV || process.env.ENV === 'local'
? undefined
: credentials.createSsl(),
credentials: isLocalConnection ? undefined : credentials.createSsl(),
protoPath: [ProtoPaths.WriteFilePath, ProtoPaths.ReadFilePath],
loader: {
keepCase: true,
+3 -5
View File
@@ -2,10 +2,11 @@ import { Input } from '@dadosfera/protospack-v2';
import { credentials } from '@grpc/grpc-js';
import {
ClientProviderOptions,
GrpcOptions,
Transport,
type GrpcOptions,
} from '@nestjs/microservices';
const isLocalConnection = !!process.env.INFACTORY_URL?.includes('0.0.0.0');
export class InputsGrpcClient {
public readonly name = 'InputsGrpcClient';
private config: GrpcOptions = {
@@ -16,10 +17,7 @@ export class InputsGrpcClient {
Input.ProtoPackages.WritePackage,
Input.ProtoPackages.ReadPackage,
],
credentials:
process.env.LOCAL_ENV || process.env.ENV === 'local'
? undefined
: credentials.createSsl(),
credentials: isLocalConnection ? undefined : credentials.createSsl(),
protoPath: [
Input.ProtoPaths.WriteFilePath,
Input.ProtoPaths.ReadFilePath,
+60 -2
View File
@@ -15,9 +15,55 @@ export class MixpanelController {
delete body.info;
const mixpanel = init(this.mixpanelToken);
const separator = user.username.includes('-') ? '-' : '.';
const removeValues = [
'.dadosferatech.dadosfera',
'.demo.dadosfera',
'.dadosferademo',
'.dadosferarh.dadosfera',
'.dadosferatech.dadosfera2',
'.dadosferatech.dadosfera',
'.dadosfera.fin',
'.dadosferafin.dadosfera',
'.praxio.dadosfera',
'.dadosfera.tech',
'.treinamentos@dadosfera.ai',
'.dadosfera2',
'.treinamentosfera',
'.dadosfera',
];
let username = user.username;
removeValues.forEach((value) => {
username = username.replace(value, '');
});
username = username.split('@')?.[0];
username = username.split('+')?.[0];
let firstName = username
.substring(0, username.indexOf(separator))
.replace('dadosfera', '');
let lastName = username
.substring(username.lastIndexOf(separator) + 1)
.replace('dadosfera', '');
if (!firstName) {
firstName = lastName;
lastName = '';
}
firstName = this.capitalize(firstName);
lastName = this.capitalize(lastName);
await mixpanel.people.set(user.username, {
$name: user.username,
$email: user.username,
$first_name: firstName,
$last_name: lastName,
$name: this.getFullName(firstName, lastName),
$email: user.username.includes('@')
? user.username
: user.username + '@dadosfera.ai',
customer_name: user.customer_name,
});
@@ -30,4 +76,16 @@ export class MixpanelController {
return { id, body, user: user.username };
}
capitalize(sentence: string): string {
if (!sentence) {
return '';
}
return sentence[0].toUpperCase() + sentence.substring(1);
}
getFullName(firstName: string, lastName: string) {
return `${firstName}${lastName ? ' ' + lastName : ''}`;
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { getSecreteFromSecreteManager } from 'src/utils/SecretManager';
import { getSecretFromSecretsManager } from 'src/utils/SecretManager';
import { MixpanelController } from './mixpanel.controller';
@Module({
@@ -7,7 +7,7 @@ import { MixpanelController } from './mixpanel.controller';
providers: [
{
provide: 'MIXPANEL_TOKEN',
useValue: getSecreteFromSecreteManager(
useValue: getSecretFromSecretsManager(
`${process.env.ENV}/root/mixpanel_token`,
),
},
+10 -4
View File
@@ -148,10 +148,16 @@ export class OauthController {
const { customer_id, customer_name, user_id } = connectionInfo;
try {
const response = await this.connectionService.createConnection(
connectionInfo,
PackTheMetadata({ customer_id, customer_name, user_id }),
);
const response = connectionInfo.id
? await this.connectionService.updateConnection(
connectionInfo.id,
connectionInfo,
PackTheMetadata({ customer_id, customer_name, user_id }),
)
: await this.connectionService.createConnection(
connectionInfo,
PackTheMetadata({ customer_id, customer_name, user_id }),
);
url.searchParams.set('connection_id', response.connection.id);
return { url: url.href };
} catch (error) {
+2
View File
@@ -23,6 +23,7 @@ export class OauthService {
user_id,
customer_id,
customer_name,
id,
} = query;
const properties = { plugin, credentials_type: 'oauth' };
@@ -45,6 +46,7 @@ export class OauthService {
type,
properties,
plugin,
id,
};
return jwt.sign({ ...newConnection }, process.env.JWT_PRIVATE_KEY);
}
@@ -44,7 +44,8 @@ export class FacebookStrategy extends PassportStrategy(Strategy) {
req,
'application',
);
options.scope = 'ads_read ads_management';
options.scope =
'pages_show_list ads_read pages_read_engagement ads_management';
super.authenticate(req, options);
}
}
+39
View File
@@ -66,3 +66,42 @@ export interface IGetPipelineLogsRequest {
id: string;
details: string;
}
export class IInitUploadCSVFile {
@ApiProperty()
file_name: string;
@ApiProperty()
parts: number;
}
export class ICompleteUploadCSVFile {
@ApiProperty()
upload_id: string;
@ApiProperty()
file_name: string;
@ApiProperty()
parts: { ETag: string; PartNumber: number }[];
}
export class ICreatePipelineCSVFile {
@ApiProperty()
name: string;
@ApiProperty()
file_name: string;
@ApiProperty()
description: string;
@ApiProperty()
encoding: string;
@ApiProperty()
sep: string;
@ApiProperty()
header: boolean;
}
+149 -2
View File
@@ -13,13 +13,17 @@ import {
HttpCode,
HttpStatus,
Patch,
HttpException,
} from '@nestjs/common';
import {
ApiCreatedResponse,
ApiNoContentResponse,
ApiTags,
} from '@nestjs/swagger';
import { AuthenticateCondition } from 'src/authentication/authentication.decorator';
import {
AuthenticateCondition,
RequireAllPermissions,
} from 'src/authentication/authentication.decorator';
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
import { PipelinesService } from './pipelines.service';
import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
@@ -28,7 +32,13 @@ import { RequestUser, User } from 'src/authentication/user.decorator';
import { PackTheMetadata } from 'src/utils/ PackTheMetadata';
import { PipelinesService as OldPipelineService } from 'src/modules/pipelines/pipelines.service';
import { ICreatePipelineV2Req, IPipelineV2 } from './interfaces';
import {
ICompleteUploadCSVFile,
ICreatePipelineCSVFile,
ICreatePipelineV2Req,
IPipelineV2,
IInitUploadCSVFile,
} from './interfaces';
import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter';
@UseFilters(new GrpcToHttpExceptionFilter())
@@ -121,6 +131,39 @@ export class PipelinesController {
};
}
@Get('/download-logs')
async downloadLogs(
@User() user: RequestUser,
@Headers('Dadosfera-Lang') language,
@Query() query,
) {
this.logger.info('PipelinesController - downloadLogs', { user });
if (!language) language = 'en-us';
if (!query) {
throw new HttpException('Query params not provided', 400);
}
const { customer_id, customer_name, user_id, username } = user;
const metadata = PackTheMetadata({
customer_id,
customer_name,
user_id,
username,
language,
});
const url = await this.pipelinesClientService.downloadLogs(
query.pipeline_run_id,
metadata,
);
return {
url,
};
}
@Get(':id/config')
async getPipelineproperties(
@Headers('Dadosfera-Lang') language,
@@ -135,6 +178,20 @@ export class PipelinesController {
return this.pipelinesClientService.findOneProperties(id, metadata);
}
@Get(':id/objects')
async getPipelineObjects(
@Headers('Dadosfera-Lang') language,
@User() user: RequestUser,
@Param('id') id,
) {
this.logger.info('PipelinesController - getPipelineObjects', { user });
const metadata = PackTheMetadata({
...user,
language: language || 'pt-br',
});
return this.pipelinesClientService.findOneObjects(id, metadata);
}
@Get('/:id')
async findOne(
@Headers('Dadosfera-Lang') language,
@@ -240,4 +297,94 @@ export class PipelinesController {
await this.pipelinesClientService.remove({ id, metadata, user });
this.logger.info('PipelinesController - delete: OK');
}
@Post('/init-upload')
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
async initUploadFile(
@User() user: RequestUser,
@Body() body: IInitUploadCSVFile,
) {
this.logger.info('/upload - Init Upload File Route');
const metadata = PackTheMetadata({ ...user });
const { file_name, parts } = body;
const { urls, upload_id } =
await this.pipelinesClientService.initUploadFile(
{
name: file_name,
parts: String(parts),
},
metadata,
);
if (!urls) {
this.logger.info('pipeline/upload - Failed File pipeline');
throw new HttpException(
'Upload failed, try again in a few minutes, if the problem persists, contact support.',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
return { urls: JSON.parse(urls), upload_id };
}
@Post('/complete-upload')
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
async completeUploadFile(
@User() user: RequestUser,
@Body() body: ICompleteUploadCSVFile,
) {
this.logger.info('/upload - Complete Upload File Route');
const metadata = PackTheMetadata({ ...user });
const { upload_id, parts, file_name } = body;
return await this.pipelinesClientService.completeUploadFile(
{ upload_id, parts, file_name },
metadata,
);
}
@Post('/file')
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.CREATE)
async uploadedFile(
@User() user: RequestUser,
@Body() body: ICreatePipelineCSVFile,
) {
this.logger.info('/upload - Upload Connector Route');
const metadata = PackTheMetadata({ ...user });
const { name, sep, header, encoding, description, file_name } = body;
const source_prefix = `${user.customer_name}/${file_name}`;
const upload_pipeline = {
connection_id: process.env.UPLOAD_FILE_AGENT_CONNECTION,
connector_name: 'Amazon S3',
connector_plugin: 'aws_s3',
connector_version: '1.0.0',
image_url: 'https://assets.dadosfera.ai/images/connectors/csv.svg',
name,
description,
transformations_ids: [],
tags: [],
cron: '@once',
config: { cron: '@once', tables: [] },
properties: {
engine: 'csv',
source_bucket: process.env.BUCKET_CUSTOMER_CSV_ASSETS,
source_prefix,
file_format_params: { sep, encoding, header: Boolean(header) },
is_a_upload_csv: true,
},
input_id: undefined,
};
const pipeline = await this.pipelinesClientService.create(
upload_pipeline,
metadata,
);
return pipeline;
}
}
+65 -1
View File
@@ -1,4 +1,10 @@
import { BadRequestException, Inject, OnModuleInit } from '@nestjs/common';
import {
BadRequestException,
HttpException,
HttpStatus,
Inject,
OnModuleInit,
} from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import {
Messages,
@@ -243,4 +249,62 @@ export class PipelinesService implements OnModuleInit {
},
};
}
async findOneObjects(id: string, metadata: Metadata) {
this.logger.info('PipelinesClientService - FindOneObjects');
const { objects } = await lastValueFrom(
this.pipelineReadService.PipelineV2FindObjects({ id }, metadata),
);
this.logger.info('Done');
return { objects: JSON.parse(objects) };
}
async initUploadFile(uploadFile, metadata) {
const body: Messages.PipelineV2UploadFileRequest = {
name: uploadFile.name,
parts: uploadFile.parts,
};
return lastValueFrom(
this.pipelineWriteService.PipelineV2UploadFile(body, metadata),
).catch((err) => {
throw new HttpException(
err.details,
err.code === 6 ? HttpStatus.CONFLICT : 400,
);
});
}
async downloadLogs(pipeline_run_id: string, metadata: Metadata) {
this.logger.info('PipelinesClientService - DownloadLogs');
const { url } = await lastValueFrom(
this.pipelineReadService.PipelineV2DownloadLogs(
{ pipeline_run_id },
metadata,
),
);
this.logger.info('Done');
return url;
}
async completeUploadFile(uploadFile, metadata) {
const body: Messages.PipelineV2CompleteUploadFileRequest = {
upload_id: uploadFile.upload_id,
parts: JSON.stringify(uploadFile.parts),
name: uploadFile.file_name,
};
return lastValueFrom(
this.pipelineWriteService.PipelineV2CompleteUploadFile(body, metadata),
).catch((err) => {
throw new HttpException(
err.details,
err.code === 6 ? HttpStatus.CONFLICT : 400,
);
});
}
}
@@ -2,7 +2,7 @@ import { Body, Controller, HttpException, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import axios from 'axios';
import { User, RequestUser } from 'src/authentication/user.decorator';
import { getSecreteFromSecreteManager } from 'src/utils/SecretManager';
import { getSecretFromSecretsManager } from 'src/utils/SecretManager';
import { INote } from './dtos';
@ApiTags('Productboard')
@@ -18,7 +18,7 @@ export class ProductboardController {
: username + `@${customer_name}.default`;
const path = process.env.PB_TOKEN_PATH;
const token = await getSecreteFromSecreteManager(path);
const token = await getSecretFromSecretsManager(path);
const response = await axios
.post(
+8
View File
@@ -25,6 +25,8 @@ export class RoleDto {
customer?: Customer;
@ApiProperty()
usage: string;
@ApiPropertyOptional({ description: 'Whether this role can be untoggled' })
canUntoggle?: boolean;
}
export class CustomerRole extends OmitType(RoleDto, ['customer']) {}
@@ -34,11 +36,17 @@ export enum TrueOrFalseEnum {
true = 'true',
false = 'false',
}
export enum CanUntoggleLogicEnum {
data_assets_sharing = 'data_assets_sharing',
}
export class GetRolesByCustomerReq {
@ApiPropertyOptional()
permissionId?: string[];
@ApiPropertyOptional({ enum: TrueOrFalseEnum })
getUsers?: TrueOrFalseEnum;
@ApiPropertyOptional({ enum: CanUntoggleLogicEnum })
canUntoggleLogic?: CanUntoggleLogicEnum;
}
export class GetRolesByCustomerRes {
+2 -2
View File
@@ -71,12 +71,12 @@ export class RolesController {
@ApiOkResponse({ type: GetRolesByCustomerRes })
async searchRoles(
@User() user: RequestUser,
@Query() filters: GetRolesByCustomerReq,
@Query() params: GetRolesByCustomerReq,
@Headers('dadosfera-lang') language,
) {
this.logger.info('searchRoles', { user });
this.rolesService.setLanguage(language);
return await this.rolesService.roleSearch(filters, user);
return await this.rolesService.roleSearch(params, user);
}
@Post()
+8 -15
View File
@@ -70,12 +70,7 @@ export class RolesService {
return { role: roleTreated };
}
async roleSearch(
filters: GetRolesByCustomerReq,
{ customer_id, access_token }: any,
) {
const meta = new Metadata();
meta.add('access_token', access_token);
async roleSearch(filters: GetRolesByCustomerReq, { customer_id }) {
let { permissionId: permissionIds } = filters;
if (permissionIds && !Array.isArray(permissionIds))
permissionIds = [permissionIds];
@@ -89,15 +84,13 @@ export class RolesService {
return seqId;
}) || [];
const roles = await lastValueFrom(
this.rolesClientService.RoleSearch(
{
customerId: customer_id,
getUsers: isGetUsers,
permissionIds: [],
permissionSeqIds,
},
meta,
),
this.rolesClientService.RoleSearch({
customerId: customer_id,
getUsers: isGetUsers,
permissionIds: [],
permissionSeqIds,
canUntoggleLogic: filters.canUntoggleLogic,
}),
);
const rolesTreated = this.getRolesPermissionsName(roles.roles);
return { roles: rolesTreated };
+18 -8
View File
@@ -48,9 +48,9 @@ import {
IUserByCustomer,
} from './dtos/entities';
import { UsersService } from './users.service';
import { Metadata } from '@grpc/grpc-js';
import ErrorBuilder from 'src/utils/ErrorBuilder';
import ErrorCodes from 'src/utils/errorCodes';
import { PackTheMetadata } from 'src/utils/ PackTheMetadata';
@ApiTags('Users')
@Controller('users')
@@ -149,12 +149,14 @@ export class UsersController {
@Body() body: CreateUserReq,
@Headers('dadosfera-lang') language,
) {
const meta = new Metadata();
meta.add('access_token', user.access_token);
const metadata = PackTheMetadata({
access_token: user.access_token,
language,
});
this.logger.info('createUser', { user });
this.userService.setLanguage(language);
return await this.userService.createUser(body, meta);
return await this.userService.createUser(body, metadata);
}
@Post('batch')
@@ -165,11 +167,15 @@ export class UsersController {
@Body() body: BatchCreateUserReq,
@Headers('dadosfera-lang') language,
) {
const meta = new Metadata();
meta.add('access_token', user.access_token);
this.logger.info('batchCreateUser', { user });
this.userService.setLanguage(language);
return await this.userService.batchCreateUser(body, meta);
const metadata = PackTheMetadata({
access_token: user.access_token,
language,
});
return await this.userService.batchCreateUser(body, metadata);
}
@Post(':id/resend-invite')
@@ -182,7 +188,11 @@ export class UsersController {
) {
this.logger.info('resendInvite', { user });
this.userService.setLanguage(language);
return this.userService.resendInvite({ id });
const metadata = PackTheMetadata({
language,
});
return this.userService.resendInvite({ id }, metadata);
}
@Delete('role')
+6 -2
View File
@@ -122,6 +122,7 @@ export class UsersService implements OnModuleInit {
if (roleNames) {
await this.setRoles({ roleNames, userId: id }, customerId);
}
const { user } = await lastValueFrom(
this.usersClientService.UserUpdate({
name,
@@ -131,6 +132,7 @@ export class UsersService implements OnModuleInit {
hierarchy,
jobTitle,
email,
metabaseUserId: undefined,
}),
);
return { user: this.adjustUsersPayload([user])[0] };
@@ -183,8 +185,10 @@ export class UsersService implements OnModuleInit {
};
}
async resendInvite(body: IdRequest) {
return lastValueFrom(this.usersClientService.UserResendInvite(body));
async resendInvite(body: IdRequest, metadata: Metadata) {
return lastValueFrom(
this.usersClientService.UserResendInvite(body, metadata),
);
}
async assignRoleToUser(body: AssignRoleToUserRequest) {
+2
View File
@@ -7,8 +7,10 @@ interface IMetadata {
user_id?: string;
language?: string;
details?: string;
sensitive?: string;
roles?: string[];
is_data_manager?: boolean;
access_token?: string;
}
export function PackTheMetadata(info: IMetadata): Metadata {
+1 -1
View File
@@ -3,7 +3,7 @@ import {
GetSecretValueCommand,
} from '@aws-sdk/client-secrets-manager';
export async function getSecreteFromSecreteManager(path: string) {
export async function getSecretFromSecretsManager(path: string) {
const secretsManagerClient = new SecretsManagerClient({});
const getSecretComand = new GetSecretValueCommand({