mirror of
https://github.com/dadosfera/maestro.git
synced 2026-08-31 19:58:21 +00:00
FEAT: new Customer Get Token Route
This commit is contained in:
@@ -1752,7 +1752,7 @@
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"title": "Maestro - feature/customer-links",
|
||||
"title": "Maestro - feat/generate-token",
|
||||
"description": "This is the Maestro API",
|
||||
"version": "1.0.0",
|
||||
"contact": {}
|
||||
|
||||
+39
-1
@@ -5022,6 +5022,44 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/customers/token": {
|
||||
"get": {
|
||||
"operationId": "CustomersController_getCustomerToken",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "exp",
|
||||
"required": true,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Customers"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"access-token": []
|
||||
},
|
||||
{
|
||||
"access-token": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/health": {
|
||||
"get": {
|
||||
"operationId": "HealthController_check",
|
||||
@@ -5038,7 +5076,7 @@
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"title": "Maestro - main",
|
||||
"title": "Maestro - feat/generate-token",
|
||||
"description": "This is the Maestro API",
|
||||
"version": "1.0.0",
|
||||
"contact": {}
|
||||
|
||||
Generated
+63
-5
@@ -36,6 +36,7 @@
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwk-to-pem": "^2.0.5",
|
||||
"mixpanel": "^0.17.0",
|
||||
"ms": "^3.0.0-canary.1",
|
||||
"passport": "^0.6.0",
|
||||
"passport-facebook": "^3.0.0",
|
||||
"passport-forcedotcom": "^0.2.0",
|
||||
@@ -4570,6 +4571,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/debug/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/decimal.js": {
|
||||
"version": "10.3.1",
|
||||
"dev": true,
|
||||
@@ -6225,6 +6231,11 @@
|
||||
"ms": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/humanize-ms/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"license": "MIT",
|
||||
@@ -7449,6 +7460,11 @@
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "1.4.1",
|
||||
"license": "MIT",
|
||||
@@ -7585,6 +7601,11 @@
|
||||
"triple-beam": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/logform/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "4.0.0",
|
||||
"license": "Apache-2.0"
|
||||
@@ -7858,8 +7879,12 @@
|
||||
"integrity": "sha512-YRIr1exCIfBDLZle8WHOfSo7Xg3M+phcZfq9Fx1L6Abo+atGp7cge5pM7PjyBn4s1oZI/BRD4EMrzQBbPpVb5Q=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"license": "MIT"
|
||||
"version": "3.0.0-canary.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz",
|
||||
"integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==",
|
||||
"engines": {
|
||||
"node": ">=12.13"
|
||||
}
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "1.4.5-lts.1",
|
||||
@@ -9126,7 +9151,8 @@
|
||||
},
|
||||
"node_modules/send/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"license": "MIT"
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/serialize-javascript": {
|
||||
"version": "6.0.1",
|
||||
@@ -13943,6 +13969,13 @@
|
||||
"version": "4.3.4",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"decimal.js": {
|
||||
@@ -15083,6 +15116,13 @@
|
||||
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
|
||||
"requires": {
|
||||
"ms": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
@@ -15908,6 +15948,13 @@
|
||||
"lodash": "^4.17.21",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^7.3.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jwa": {
|
||||
@@ -16010,6 +16057,13 @@
|
||||
"ms": "^2.1.1",
|
||||
"safe-stable-stringify": "^2.3.1",
|
||||
"triple-beam": "^1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"long": {
|
||||
@@ -16195,7 +16249,9 @@
|
||||
"integrity": "sha512-YRIr1exCIfBDLZle8WHOfSo7Xg3M+phcZfq9Fx1L6Abo+atGp7cge5pM7PjyBn4s1oZI/BRD4EMrzQBbPpVb5Q=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2"
|
||||
"version": "3.0.0-canary.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz",
|
||||
"integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g=="
|
||||
},
|
||||
"multer": {
|
||||
"version": "1.4.5-lts.1",
|
||||
@@ -17054,7 +17110,9 @@
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3"
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwk-to-pem": "^2.0.5",
|
||||
"mixpanel": "^0.17.0",
|
||||
"ms": "^3.0.0-canary.1",
|
||||
"passport": "^0.6.0",
|
||||
"passport-facebook": "^3.0.0",
|
||||
"passport-forcedotcom": "^0.2.0",
|
||||
|
||||
@@ -55,6 +55,16 @@ export const PERMISSIONS_GROUPS = {
|
||||
'es-es': '',
|
||||
},
|
||||
},
|
||||
GENERATE_TOKEN: {
|
||||
seqid: 46,
|
||||
claim: 'customer:generate-token',
|
||||
usage: PermissionUsages.PUBLIC,
|
||||
name: {
|
||||
'pt-br': 'Gerar Token de Acesso',
|
||||
'en-us': 'Generate Acess Token',
|
||||
'es-es': 'Gerar Token de Acceso',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Inject,
|
||||
Param,
|
||||
Put,
|
||||
Query,
|
||||
UseFilters,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
@@ -19,6 +20,8 @@ import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator';
|
||||
import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter';
|
||||
import { CustomersService } from './customers.service';
|
||||
import { CustomerDto, CustomerLinksResponse } from './dtos/customers';
|
||||
import { RequestUser, User } from 'src/decorators/user.decorator';
|
||||
import type { StringValue } from 'ms';
|
||||
|
||||
@ApiInternalOnlyController()
|
||||
@ApiTags('Customers')
|
||||
@@ -53,4 +56,19 @@ export class CustomersController {
|
||||
this.logger.info('setCustomerLinks', { id, links });
|
||||
return this.customersService.setLinks(id, links);
|
||||
}
|
||||
|
||||
@Get('token')
|
||||
@RequireAllPermissions(PERMISSIONS_GROUPS.AUTH.permissions.GENERATE_TOKEN)
|
||||
async getCustomerToken(
|
||||
@Query('exp') exp: StringValue,
|
||||
@User() user: RequestUser,
|
||||
): Promise<string> {
|
||||
this.logger.info('getCustomerToken', { exp, user });
|
||||
const data = {
|
||||
customerId: user.customer_id,
|
||||
userId: user.user_id,
|
||||
customerName: user.customer_name,
|
||||
};
|
||||
return this.customersService.generateToken(exp, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Injectable,
|
||||
HttpException,
|
||||
HttpStatus,
|
||||
InternalServerErrorException,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import { firstValueFrom, lastValueFrom } from 'rxjs';
|
||||
@@ -14,7 +15,15 @@ import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc';
|
||||
import { CustomerUpdateRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages';
|
||||
import { CustomersProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service';
|
||||
import ErrorCodes from 'src/utils/errorCodes';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import {
|
||||
GetSecretValueCommand,
|
||||
SecretsManagerClient,
|
||||
} from '@aws-sdk/client-secrets-manager';
|
||||
import getEnv from 'src/utils/getEnv';
|
||||
import { logger } from 'elastic-apm-node';
|
||||
|
||||
// This function will accept any string, which may result in a bug.
|
||||
@Injectable()
|
||||
export class CustomersService implements OnModuleInit {
|
||||
private customerService: CustomersProtoService;
|
||||
@@ -60,4 +69,55 @@ export class CustomersService implements OnModuleInit {
|
||||
else throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async generateToken(
|
||||
expiresIn = '30m',
|
||||
data: { customerId: string; userId: string; customerName: string },
|
||||
) {
|
||||
const { customerId, userId: generatedById, customerName } = data;
|
||||
|
||||
const secretsManagerClient = new SecretsManagerClient({});
|
||||
|
||||
const getSecretComand = new GetSecretValueCommand({
|
||||
SecretId: `${getEnv()}/${customerName}/jwt-signing-key`,
|
||||
});
|
||||
let private_key_pem;
|
||||
await secretsManagerClient
|
||||
.send(getSecretComand)
|
||||
.then((res) => {
|
||||
const secret = JSON.parse(res.SecretString);
|
||||
|
||||
private_key_pem = secret.private_key_pem;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(err.stack);
|
||||
throw new InternalServerErrorException(
|
||||
'Error finding keys for customer',
|
||||
);
|
||||
});
|
||||
let jwt_token;
|
||||
try {
|
||||
jwt_token = jwt.sign(
|
||||
{
|
||||
customerId,
|
||||
generatedById,
|
||||
},
|
||||
private_key_pem,
|
||||
{
|
||||
algorithm: 'RS256',
|
||||
expiresIn,
|
||||
issuer: 'maestro',
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error(err.stack);
|
||||
throw new InternalServerErrorException('Error generating token');
|
||||
}
|
||||
// const verify = jwt.verify(jwt_token, public_key_pem, {
|
||||
// algorithms: ['RS256'],
|
||||
// issuer: 'maestro',
|
||||
// });
|
||||
// const decoded = jwt.decode(jwt_token, { complete: true });
|
||||
return jwt_token;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
const availableLocalEnvs: Array<typeof process.env.ENV> = ['stg', 'test'];
|
||||
|
||||
export default function getEnv(): typeof process.env.ENV {
|
||||
if (process.env.ENV === 'local') {
|
||||
if (availableLocalEnvs.includes(process.env.LOCAL_ENV))
|
||||
return process.env.LOCAL_ENV;
|
||||
return 'stg';
|
||||
}
|
||||
return process.env.ENV;
|
||||
}
|
||||
Reference in New Issue
Block a user