mirror of
https://github.com/dadosfera/maestro.git
synced 2026-11-03 08:59:08 +00:00
128 lines
3.3 KiB
TypeScript
128 lines
3.3 KiB
TypeScript
import { Request, Response, NextFunction } from 'express';
|
|
import axios from 'axios';
|
|
import {
|
|
ForbiddenException,
|
|
InternalServerErrorException,
|
|
NestMiddleware,
|
|
UnauthorizedException,
|
|
UseFilters,
|
|
} from '@nestjs/common';
|
|
import jwkToPem from 'jwk-to-pem';
|
|
import { decode, verify } from 'jsonwebtoken';
|
|
import { HttpExceptionFilter } from 'src/error/http-exception.filter';
|
|
|
|
@UseFilters(new HttpExceptionFilter())
|
|
export class LoggerMiddleware implements NestMiddleware {
|
|
use = async (request: Request, response: Response, next: NextFunction) => {
|
|
const idToken = request.get('Dadosfera-User');
|
|
const accessToken = request.get('Authorization');
|
|
const privateKey = process.env.JWT_PRIVATE_KEY;
|
|
|
|
const requiredMethod = request.method.trim();
|
|
const requiredRoute = request.route.path.split('/')[1].trim();
|
|
|
|
verify(idToken, privateKey, (err) => {
|
|
if (err) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
});
|
|
const jwtDecoded: any = decode(idToken);
|
|
|
|
const permissions = jwtDecoded.user.permissions;
|
|
const clienId = jwtDecoded.user.customerId;
|
|
const customer = jwtDecoded.user.customer;
|
|
const userId = jwtDecoded.user.id;
|
|
|
|
await verifyToken(accessToken);
|
|
|
|
let havePermission = false;
|
|
permissions.forEach((permission) => {
|
|
permission = permission.split('/');
|
|
const method = permission[0].trim();
|
|
const route = permission[1].trim();
|
|
|
|
if (method === requiredMethod && route === requiredRoute) {
|
|
havePermission = true;
|
|
}
|
|
});
|
|
|
|
if (havePermission) {
|
|
request.body.info = {
|
|
customer_id: clienId,
|
|
user_id: userId,
|
|
customer,
|
|
};
|
|
|
|
next();
|
|
} else {
|
|
throw new ForbiddenException();
|
|
}
|
|
};
|
|
}
|
|
|
|
let pems: { [key: string]: Record<string, unknown> }[];
|
|
|
|
const setUp = async (region: string, id: string) => {
|
|
const URL = `https://cognito-idp.${region}.amazonaws.com/${id}/.well-known/jwks.json`;
|
|
|
|
try {
|
|
const response = await axios.get(URL);
|
|
|
|
if (response.status !== 200) {
|
|
throw new InternalServerErrorException();
|
|
}
|
|
const data = await response.data;
|
|
const { keys } = data;
|
|
|
|
pems = keys.map((key: any) => {
|
|
const modulus = key.n;
|
|
const exponent = key.e;
|
|
const keyType = key.kty;
|
|
const jwk = { kty: keyType, n: modulus, e: exponent };
|
|
const pem = jwkToPem(jwk);
|
|
const keyId = key.kid;
|
|
|
|
return { [keyId]: pem };
|
|
});
|
|
} catch (error) {
|
|
// console.log(error);
|
|
// console.log('Error! Unable to download JWKs');
|
|
}
|
|
};
|
|
|
|
const verifyToken = async (accessToken: string) => {
|
|
const awsRegion = process.env.AWS_REGION;
|
|
const awsPoolId = process.env.AWS_IDENTITY_POOL_ID;
|
|
|
|
try {
|
|
await setUp(awsRegion, awsPoolId);
|
|
if (!accessToken) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
|
|
const user: any = decode(accessToken, { complete: true });
|
|
|
|
if (user === null) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
|
|
const { kid } = user.header;
|
|
const pem = pems.filter((item: any) => item[kid]);
|
|
const pemValue: any = pem[0][kid];
|
|
|
|
if (!pem) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
|
|
verify(accessToken, pemValue, (err: any) => {
|
|
if (err) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
|
|
return;
|
|
});
|
|
} catch (error) {
|
|
throw new UnauthorizedException();
|
|
}
|
|
};
|