mirror of
https://github.com/dadosfera/maestro.git
synced 2026-11-03 03:19:07 +00:00
Merge branch 'beta' into feature/auth-session
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
AuthConfirmResetPasswordRequest,
|
||||
AuthEnableTotpMfaRequest,
|
||||
AuthDisableTotpMfaRequest,
|
||||
AuthVerifyTotpMfaRequest,
|
||||
AuthVerifyTotpMfaRequest
|
||||
} from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages';
|
||||
|
||||
import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum';
|
||||
@@ -54,6 +54,13 @@ import jwt, { JwtPayload } from 'jsonwebtoken';
|
||||
import { LanguageEnum } from 'src/utils/languages.enum';
|
||||
import { Language } from 'src/decorators/language.decorator';
|
||||
import { ApiInternalOnlyEndpoint } from 'src/decorators/swagger.decorator';
|
||||
import { Cookie } from 'express-session';
|
||||
|
||||
type CookiesValues = {
|
||||
accessToken?: string;
|
||||
refreshToken?: string;
|
||||
userId?: string
|
||||
}
|
||||
|
||||
@ApiTags('Auth')
|
||||
@ApiHeaders([{ name: 'dadosfera-lang', enum: LanguageEnum, required: false }])
|
||||
@@ -94,7 +101,11 @@ export class AuthController {
|
||||
const metadata = PackTheMetadata({ language });
|
||||
this.logger.info('metadata: ' + JSON.stringify(metadata.toJSON()));
|
||||
const data = await this.authClient.signIn({ username, password, totp }, metadata);
|
||||
this.addTokenInCookie(res, data.tokens);
|
||||
this.addTokenInCookie(res, {
|
||||
accessToken: data.tokens.accessToken,
|
||||
refreshToken: data.tokens.refreshToken,
|
||||
userId: data.user.id
|
||||
});
|
||||
|
||||
return res.send(data);
|
||||
} catch (error) {
|
||||
@@ -150,17 +161,19 @@ export class AuthController {
|
||||
@Res() res: Response,
|
||||
) {
|
||||
this.logger.info('/auth - RefreshAccessToken');
|
||||
const { refreshToken, customerName: customer_name } = body;
|
||||
const frontHost = origin.replace(/^https?:\/\//, '');
|
||||
const { refreshToken, userId } = body;
|
||||
|
||||
const metadata = PackTheMetadata({
|
||||
language,
|
||||
customer_name,
|
||||
custom_host: frontHost,
|
||||
});
|
||||
|
||||
const data = await this.authClient.refreshAccessToken({ refreshToken }, metadata);
|
||||
const data = await this.authClient.refreshAccessToken({ refreshToken, userId }, metadata);
|
||||
|
||||
this.addTokenInCookie(res, {
|
||||
accessToken: data.accessToken,
|
||||
userId
|
||||
});
|
||||
|
||||
return res.send(data);
|
||||
@@ -477,7 +490,7 @@ export class AuthController {
|
||||
this.logger.info('GET /auth/me ')
|
||||
// Lê cookies
|
||||
const accessToken = req.cookies['ddf-auth'];
|
||||
let customerName = '';
|
||||
const userId = req.cookies['ddf-user-id'];
|
||||
|
||||
this.logger.info('Has cookie: ' + Boolean(accessToken))
|
||||
let payload: any;
|
||||
@@ -487,7 +500,6 @@ export class AuthController {
|
||||
const decoded: any = accessToken && jwt.decode(accessToken, { complete: true });
|
||||
if (!decoded) throw new Error('Invalid token')
|
||||
const { kid } = decoded.header;
|
||||
customerName = decoded.payload.customer_name;
|
||||
// Busca a chave pública
|
||||
const { keys } = await this.authClient.getPublicKeys();
|
||||
const pemValue = keys.find((k) => k.kid === kid)?.pem;
|
||||
@@ -511,21 +523,21 @@ export class AuthController {
|
||||
this.logger.info('Token is invalid')
|
||||
this.logger.info('Has Refresh Token: '+ Boolean(refreshToken))
|
||||
// Se access token inválido, tenta refresh
|
||||
if (!refreshToken || !customerName) {
|
||||
if (!refreshToken || !userId) {
|
||||
this.logger.error('Invalid refresh token or customer name');
|
||||
return res.status(401).json({ error: 'Not authenticated' });
|
||||
}
|
||||
try {
|
||||
// Chama refreshAccessToken
|
||||
const metadata = PackTheMetadata({
|
||||
customer_name: customerName
|
||||
});
|
||||
this.logger.info('Call Refresh Token')
|
||||
const data = await this.authClient.refreshAccessToken({ refreshToken }, metadata);
|
||||
const data = await this.authClient.refreshAccessToken({ refreshToken, userId }, metadata);
|
||||
this.logger.info('Finish Refresh Token')
|
||||
// Retorna novo access token e dados mínimos
|
||||
this.addTokenInCookie(res, {
|
||||
accessToken: data.accessToken,
|
||||
userId
|
||||
});
|
||||
// Decodifica novo token
|
||||
const decoded: any = jwt.decode(data.accessToken, { complete: true });
|
||||
@@ -547,16 +559,16 @@ export class AuthController {
|
||||
}
|
||||
}
|
||||
|
||||
private addTokenInCookie(res: Response, tokens: { accessToken?: string, refreshToken?: string }) {
|
||||
private addTokenInCookie(res: Response, data: CookiesValues) {
|
||||
let exp = 1000 * 60 * 5; // 5 minutes
|
||||
|
||||
if (tokens.accessToken) {
|
||||
const { exp: expiration } = jwt.decode(tokens.accessToken) as JwtPayload;
|
||||
if (data.accessToken) {
|
||||
const { exp: expiration } = jwt.decode(data.accessToken) as JwtPayload;
|
||||
exp = (expiration - 30) * 1000; // exp em segundos, maxAge em ms
|
||||
|
||||
this.logger.info('Set Cookie ddf-auth')
|
||||
res.cookie('ddf-auth', tokens.accessToken, {
|
||||
domain: 'dadosfera.local',
|
||||
res.cookie('ddf-auth', data.accessToken, {
|
||||
domain: 'dadosfera.ai',
|
||||
maxAge: exp,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
@@ -564,10 +576,21 @@ export class AuthController {
|
||||
});
|
||||
}
|
||||
|
||||
if (tokens.refreshToken) {
|
||||
if (data.refreshToken) {
|
||||
this.logger.info('Set Cookie ddf-refresh-auth')
|
||||
res.cookie('ddf-refresh-auth', tokens.refreshToken, {
|
||||
domain: 'dadosfera.local',
|
||||
res.cookie('ddf-refresh-auth', data.refreshToken, {
|
||||
domain: 'dadosfera.ai',
|
||||
maxAge: exp,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: 'none', // Necessário para cookies em requisições cross-site
|
||||
});
|
||||
}
|
||||
|
||||
if (data.userId) {
|
||||
this.logger.info('Set Cookie ddf-refresh-auth')
|
||||
res.cookie('ddf-user-id', data.userId, {
|
||||
domain: 'dadosfera.ai',
|
||||
maxAge: exp,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
|
||||
Reference in New Issue
Block a user