From eef6e6fa97fc9dce79bed2f73366e83b1d97dd62 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 7 Feb 2025 12:14:36 +0100 Subject: [PATCH] . --- .gitignore | 1 + apps/server/src/app.ts | 6 +- .../application/auth-service.interface.ts | 21 ++-- .../contexts/auth/application/auth.service.ts | 42 ++++---- .../domain/aggregates/authenticated-user.ts | 20 ++-- .../contexts/auth/infraestructure/index.ts | 1 - .../auth/infraestructure/passport/index.ts | 12 +-- .../{ => passport}/jwt.helper.ts | 2 + .../passport/passport-auth-provider.ts | 98 ++++++++++++++++--- .../sequelize/auth-user.model.ts | 28 +----- .../sequelize/tab-context.model.ts | 37 +------ .../controllers/login/login.controller.ts | 8 +- .../controllers/login/login.presenter.ts | 8 +- .../auth/presentation/dto/auth.request.dto.ts | 4 - .../presentation/dto/auth.response.dto.ts | 5 +- .../middleware/passport-auth.middleware.ts | 17 ++-- .../middleware/tab-context.middleware.ts | 5 +- apps/server/src/routes/auth.routes.ts | 12 ++- 18 files changed, 173 insertions(+), 154 deletions(-) rename apps/server/src/contexts/auth/infraestructure/{ => passport}/jwt.helper.ts (71%) diff --git a/.gitignore b/.gitignore index ba8771b3..8f3b4a55 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ error-*.log # Misc .DS_Store *.pem +*-audit.json #Jetbrains .idea diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index 4fe7b2b3..410697d1 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -1,6 +1,6 @@ import { logger } from "@common/infrastructure/logger"; import { globalErrorHandler } from "@common/presentation"; -import { initializePassportAuthProvide } from "@contexts/auth/infraestructure"; +import { createAuthProvider } from "@contexts/auth/infraestructure"; import dotenv from "dotenv"; import express, { Application } from "express"; import helmet from "helmet"; @@ -24,9 +24,9 @@ export function createApp(): Application { app.use(responseTime()); // set up the response-time middleware - // Inicializar Passport + // Inicializar Auth Provider app.use((req, res, next) => { - initializePassportAuthProvide(); + createAuthProvider().initialize(); next(); }); diff --git a/apps/server/src/contexts/auth/application/auth-service.interface.ts b/apps/server/src/contexts/auth/application/auth-service.interface.ts index ab8de8fe..f2a72071 100644 --- a/apps/server/src/contexts/auth/application/auth-service.interface.ts +++ b/apps/server/src/contexts/auth/application/auth-service.interface.ts @@ -1,10 +1,17 @@ import { Result, UniqueID } from "@common/domain"; -import { AuthenticatedUser, EmailAddress, HashPassword, PlainPassword, Username } from "../domain"; +import { + AuthenticatedUser, + EmailAddress, + HashPassword, + PlainPassword, + TabContext, + Username, +} from "../domain"; +import { IJWTPayload } from "../infraestructure"; export interface IAuthService { - generateAccessToken(payload: object): string; - generateRefreshToken(payload: object): string; - verifyToken(token: string): Promise; + generateAccessToken(payload: IJWTPayload): string; + generateRefreshToken(payload: IJWTPayload): string; registerUser(params: { username: Username; @@ -20,6 +27,7 @@ export interface IAuthService { Result< { user: AuthenticatedUser; + tabContext: TabContext; tokens: { accessToken: string; refreshToken: string; @@ -31,8 +39,5 @@ export interface IAuthService { logoutUser(params: { email: EmailAddress; tabId: UniqueID }): Promise>; - verifyUser(params: { - email: EmailAddress; - plainPassword: PlainPassword; - }): Promise>; + getUserByEmail(params: { email: EmailAddress }): Promise>; } diff --git a/apps/server/src/contexts/auth/application/auth.service.ts b/apps/server/src/contexts/auth/application/auth.service.ts index 3f1bb567..95092085 100644 --- a/apps/server/src/contexts/auth/application/auth.service.ts +++ b/apps/server/src/contexts/auth/application/auth.service.ts @@ -1,19 +1,18 @@ import { Result, UniqueID } from "@common/domain"; import { ITransactionManager } from "@common/infrastructure/database"; -import jwt from "jsonwebtoken"; import { AuthenticatedUser, EmailAddress, HashPassword, IAuthenticatedUserRepository, - PlainPassword, TabContext, Username, } from "../domain"; import { ITabContextRepository } from "../domain/repositories/tab-context-repository.interface"; +import { JwtHelper } from "../infraestructure/passport/jwt.helper"; +import { IJWTPayload } from "../infraestructure/passport/passport-auth-provider"; import { IAuthService } from "./auth-service.interface"; -const SECRET_KEY = process.env.JWT_SECRET || "supersecretkey"; const ACCESS_EXPIRATION = process.env.JWT_ACCESS_EXPIRATION || "1h"; const REFRESH_EXPIRATION = process.env.JWT_REFRESH_EXPIRATION || "7d"; @@ -32,16 +31,12 @@ export class AuthService implements IAuthService { this._transactionManager = transactionManager; } - generateAccessToken(payload: object): string { - return jwt.sign(payload, SECRET_KEY, { expiresIn: ACCESS_EXPIRATION }); + generateAccessToken(payload: IJWTPayload): string { + return JwtHelper.generateToken(payload, ACCESS_EXPIRATION); } - generateRefreshToken(payload: object): string { - return jwt.sign(payload, SECRET_KEY, { expiresIn: REFRESH_EXPIRATION }); - } - - verifyToken(token: string): any { - return jwt.verify(token, SECRET_KEY); + generateRefreshToken(payload: IJWTPayload): string { + return JwtHelper.generateToken(payload, REFRESH_EXPIRATION); } /** @@ -104,6 +99,7 @@ export class AuthService implements IAuthService { Result< { user: AuthenticatedUser; + tabContext: TabContext; tokens: { accessToken: string; refreshToken: string; @@ -145,7 +141,9 @@ export class AuthService implements IAuthService { return Result.fail(new Error("Error creating user context")); } - await this._tabContactRepo.registerContextByTabId(contextOrError.data, transaction); + const tabContext = contextOrError.data; + + await this._tabContactRepo.registerContextByTabId(tabContext, transaction); // 🔹 Generar Access Token y Refresh Token const accessToken = this.generateAccessToken({ @@ -157,10 +155,14 @@ export class AuthService implements IAuthService { const refreshToken = this.generateRefreshToken({ userId: user.id.toString(), + email: email.toString(), + tabId: tabId.toString(), + roles: ["USER"], }); return Result.ok({ user, + tabContext, tokens: { accessToken, refreshToken, @@ -213,27 +215,17 @@ export class AuthService implements IAuthService { } } - async verifyUser(params: { - email: EmailAddress; - plainPassword: PlainPassword; - }): Promise> { + async getUserByEmail(params: { email: EmailAddress }): Promise> { try { return await this._transactionManager.complete(async (transaction) => { - const { email, plainPassword } = params; + const { email } = params; const userResult = await this._userRepo.getUserByEmail(email, transaction); if (userResult.isFailure || !userResult.data) { return Result.fail(new Error("Invalid email or password")); } - const user = userResult.data; - const isValidPassword = await user.verifyPassword(plainPassword); - - if (!isValidPassword) { - return Result.fail(new Error("Invalid email or password")); - } - - return Result.ok(user); + return Result.ok(userResult.data); }); } catch (error: unknown) { return Result.fail(error as Error); diff --git a/apps/server/src/contexts/auth/domain/aggregates/authenticated-user.ts b/apps/server/src/contexts/auth/domain/aggregates/authenticated-user.ts index 206d33f5..9c7ecb5c 100644 --- a/apps/server/src/contexts/auth/domain/aggregates/authenticated-user.ts +++ b/apps/server/src/contexts/auth/domain/aggregates/authenticated-user.ts @@ -19,9 +19,9 @@ export interface IAuthenticatedUser { isUser: boolean; isAdmin: boolean; - contexts: ICollection; - verifyPassword(candidatePassword: PlainPassword): Promise; + hasRole(role: string): boolean; + hasRoles(roles: string[]): boolean; getRoles(): string[]; toPersistenceData(): any; } @@ -43,10 +43,6 @@ export class AuthenticatedUser return Result.ok(user); } - private _hasRole(role: string): boolean { - return (this._props.roles || []).some((r) => r === role); - } - verifyPassword(candidatePassword: PlainPassword): Promise { return this._props.hashPassword.verifyPassword(candidatePassword.toString()); } @@ -55,6 +51,14 @@ export class AuthenticatedUser return this._props.roles; } + hasRole(role: string): boolean { + return (this._props.roles || []).some((r) => r === role); + } + + hasRoles(roles: string[]): boolean { + return roles.map((rol) => this.hasRole(rol)).some((value) => value != false); + } + get username(): Username { return this._props.username; } @@ -64,11 +68,11 @@ export class AuthenticatedUser } get isUser(): boolean { - return this._hasRole("user"); + return this.hasRole("user"); } get isAdmin(): boolean { - return this._hasRole("admin"); + return this.hasRole("admin"); } /** diff --git a/apps/server/src/contexts/auth/infraestructure/index.ts b/apps/server/src/contexts/auth/infraestructure/index.ts index bcfc98bc..01cd6cb2 100644 --- a/apps/server/src/contexts/auth/infraestructure/index.ts +++ b/apps/server/src/contexts/auth/infraestructure/index.ts @@ -1,4 +1,3 @@ -export * from "./jwt.helper"; export * from "./mappers"; export * from "./passport"; export * from "./sequelize"; diff --git a/apps/server/src/contexts/auth/infraestructure/passport/index.ts b/apps/server/src/contexts/auth/infraestructure/passport/index.ts index ba186208..6e22cbc9 100644 --- a/apps/server/src/contexts/auth/infraestructure/passport/index.ts +++ b/apps/server/src/contexts/auth/infraestructure/passport/index.ts @@ -1,9 +1,7 @@ -import { createAuthService } from "@contexts/auth/application"; -import { PassportAuthProvider } from "./passport-auth-provider"; +import { createAuthService, createTabContextService } from "../../application"; +import { IJWTPayload, PassportAuthProvider } from "./passport-auth-provider"; -export const createPassportAuthProvider = () => { - const _authService = createAuthService(); - return new PassportAuthProvider(_authService); -}; +export { IJWTPayload }; -export const initializePassportAuthProvide = () => createPassportAuthProvider(); +export const createAuthProvider = () => + new PassportAuthProvider(createAuthService(), createTabContextService()); diff --git a/apps/server/src/contexts/auth/infraestructure/jwt.helper.ts b/apps/server/src/contexts/auth/infraestructure/passport/jwt.helper.ts similarity index 71% rename from apps/server/src/contexts/auth/infraestructure/jwt.helper.ts rename to apps/server/src/contexts/auth/infraestructure/passport/jwt.helper.ts index 7f8b09af..308abc40 100644 --- a/apps/server/src/contexts/auth/infraestructure/jwt.helper.ts +++ b/apps/server/src/contexts/auth/infraestructure/passport/jwt.helper.ts @@ -1,6 +1,8 @@ import jwt from "jsonwebtoken"; const SECRET_KEY = process.env.JWT_SECRET || "supersecretkey"; +const ACCESS_EXPIRATION = process.env.JWT_ACCESS_EXPIRATION || "1h"; +const REFRESH_EXPIRATION = process.env.JWT_REFRESH_EXPIRATION || "7d"; export class JwtHelper { static generateToken(payload: object, expiresIn = "1h"): string { diff --git a/apps/server/src/contexts/auth/infraestructure/passport/passport-auth-provider.ts b/apps/server/src/contexts/auth/infraestructure/passport/passport-auth-provider.ts index 617251fc..7c0ac71f 100644 --- a/apps/server/src/contexts/auth/infraestructure/passport/passport-auth-provider.ts +++ b/apps/server/src/contexts/auth/infraestructure/passport/passport-auth-provider.ts @@ -1,4 +1,6 @@ +import { Result, UniqueID } from "@common/domain"; import { IAuthService } from "@contexts/auth/application"; +import { ITabContextService } from "@contexts/auth/application/tab-context-service.interface"; import { AuthenticatedUser, EmailAddress, PlainPassword } from "@contexts/auth/domain"; import passport from "passport"; import { ExtractJwt, Strategy as JwtStrategy } from "passport-jwt"; @@ -6,35 +8,100 @@ import { Strategy as LocalStrategy } from "passport-local"; const SECRET_KEY = process.env.JWT_SECRET || "supersecretkey"; +export interface IJWTPayload { + userId: string; + email: string; + tabId: string; + roles: string[]; +} + export class PassportAuthProvider { private readonly _authService: IAuthService; + private readonly _tabContextService: ITabContextService; - private async _verifyUser(email: string, password: string): Promise { + private async _getUserByEmailAndPassword( + email: string, + password: string + ): Promise> { const emailVO = EmailAddress.create(email); - if (emailVO.isFailure) return Promise.resolve(null); + if (emailVO.isFailure) { + return Result.fail(emailVO.error); + } const plainPasswordVO = PlainPassword.create(password); - if (plainPasswordVO.isFailure) return Promise.resolve(null); + if (plainPasswordVO.isFailure) { + return Result.fail(plainPasswordVO.error); + } - const userResult = await this._authService.verifyUser({ + const userResult = await this._authService.getUserByEmail({ email: emailVO.data, - plainPassword: plainPasswordVO.data, }); if (userResult.isFailure || !userResult.data) { - return Promise.resolve(null); + return Result.fail(new Error("Invalid email or password")); } const user = userResult.data; const isValidPassword = await user.verifyPassword(plainPasswordVO.data); - return !isValidPassword ? Promise.resolve(null) : Promise.resolve(user); + if (!isValidPassword) { + return Result.fail(new Error("Invalid email or password")); + } + + return Result.ok(user); + } + + private async _getUserAndContextByToken(token: IJWTPayload) { + const { userId, email, roles, tabId } = token; + + const userIdVO = UniqueID.create(userId); + const tabIdVO = UniqueID.create(tabId); + const emailVO = EmailAddress.create(email!); + + const okOrError = Result.combine([userIdVO, tabIdVO, emailVO]); + if (okOrError.isFailure) { + return Result.fail(okOrError.error.message); + } + + const userResult = await this._authService.getUserByEmail({ + email: emailVO.data, + }); + + if (userResult.isFailure) { + return Result.fail(new Error("Invalid token data")); + } + + const user = userResult.data; + + const checkUserId = user.id.equals(userIdVO.data); + const checkRoles = user.hasRoles(roles); + + if (!checkUserId || !checkRoles) { + return Result.fail(new Error("Invalid token data")); + } + + const tabResult = await this._tabContextService.getContextByTabId(tabIdVO.data); + if (tabResult.isFailure) { + return Result.fail(new Error("Invalid token data")); + } + + const tabContext = tabResult.data; + + return Result.ok({ + user, + tabContext, + }); + } + + constructor(authService: IAuthService, tabContextService: ITabContextService) { + this._authService = authService; + this._tabContextService = tabContextService; } /** * 🔹 Configura PassportJS */ - initializePassport(): void { + initialize(): void { const jwtOptions = { jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: SECRET_KEY, @@ -42,10 +109,12 @@ export class PassportAuthProvider { passport.use( "jwt", - new JwtStrategy(jwtOptions, (tokenPayload, done) => { + new JwtStrategy(jwtOptions, async (tokenPayload, done) => { try { - console.log(tokenPayload); - return done(null, tokenPayload); + const result = await this._getUserAndContextByToken(tokenPayload); + return result.isSuccess + ? done(null, result) + : done(result.error, false, { message: "Invalid JWT data" }); } catch (error) { return done(error, false); } @@ -58,7 +127,7 @@ export class PassportAuthProvider { { usernameField: "email", passwordField: "password" }, async (email, password, done) => { try { - const user = await this._verifyUser(email, password); + const user = await this._getUserByEmailAndPassword(email, password); return user ? done(null, user) : done(null, false, { message: "Invalid email or password" }); @@ -72,8 +141,7 @@ export class PassportAuthProvider { passport.initialize(); } - constructor(authService: IAuthService) { - this._authService = authService; - this.initializePassport(); + authenticateJWT() { + return passport.authenticate("jwt", { session: false }); } } diff --git a/apps/server/src/contexts/auth/infraestructure/sequelize/auth-user.model.ts b/apps/server/src/contexts/auth/infraestructure/sequelize/auth-user.model.ts index 20a0df6f..8c4c0eef 100644 --- a/apps/server/src/contexts/auth/infraestructure/sequelize/auth-user.model.ts +++ b/apps/server/src/contexts/auth/infraestructure/sequelize/auth-user.model.ts @@ -1,19 +1,6 @@ -import { - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { TabContextCreationAttributes, TabContextModel } from "./tab-context.model"; +import { DataTypes, InferAttributes, InferCreationAttributes, Model, Sequelize } from "sequelize"; -export type AuthUserCreationAttributes = InferCreationAttributes< - AuthUserModel, - { omit: "contexts" } -> & { - contexts: TabContextCreationAttributes[]; -}; +export type AuthUserCreationAttributes = InferCreationAttributes; export class AuthUserModel extends Model< InferAttributes, @@ -24,22 +11,11 @@ export class AuthUserModel extends Model< return Promise.resolve(); }*/ - static associate(connection: Sequelize) { - const { TabContextModel } = connection.models; - - AuthUserModel.hasMany(TabContextModel, { - as: "contexts", - foreignKey: "user_id", - onDelete: "CASCADE", - }); - } declare id: string; declare username: string; declare email: string; declare hash_password: string; declare roles: string[]; - - declare contexts: NonAttribute; } export default (sequelize: Sequelize) => { diff --git a/apps/server/src/contexts/auth/infraestructure/sequelize/tab-context.model.ts b/apps/server/src/contexts/auth/infraestructure/sequelize/tab-context.model.ts index d741af7c..c6e9dd4c 100644 --- a/apps/server/src/contexts/auth/infraestructure/sequelize/tab-context.model.ts +++ b/apps/server/src/contexts/auth/infraestructure/sequelize/tab-context.model.ts @@ -1,21 +1,10 @@ -import { - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, - NonAttribute, - Sequelize, -} from "sequelize"; -import { AuthUserModel } from "./auth-user.model"; +import { DataTypes, InferAttributes, InferCreationAttributes, Model, Sequelize } from "sequelize"; -export type TabContextCreationAttributes = InferCreationAttributes< - TabContextModel, - { omit: "user" } ->; +export type TabContextCreationAttributes = InferCreationAttributes; export class TabContextModel extends Model< - InferAttributes, - InferCreationAttributes + InferAttributes, + InferCreationAttributes > { // To avoid table creation /*static async sync(): Promise { @@ -23,21 +12,11 @@ export class TabContextModel extends Model< }*/ static associate(connection: Sequelize) { const { AuthUserModel } = connection.models; - - TabContextModel.belongsTo(AuthUserModel, { - as: "user", - foreignKey: "user_id", - onDelete: "CASCADE", - }); } declare id: string; declare tab_id: string; declare user_id: string; - declare company_id: string; - declare branch_id: string; - - declare user: NonAttribute; } export default (sequelize: Sequelize) => { @@ -55,14 +34,6 @@ export default (sequelize: Sequelize) => { type: DataTypes.UUID, allowNull: false, }, - company_id: { - type: DataTypes.UUID, - allowNull: false, - }, - branch_id: { - type: DataTypes.UUID, - allowNull: false, - }, }, { sequelize, diff --git a/apps/server/src/contexts/auth/presentation/controllers/login/login.controller.ts b/apps/server/src/contexts/auth/presentation/controllers/login/login.controller.ts index 693454a2..60649032 100644 --- a/apps/server/src/contexts/auth/presentation/controllers/login/login.controller.ts +++ b/apps/server/src/contexts/auth/presentation/controllers/login/login.controller.ts @@ -26,17 +26,17 @@ class LoginController extends ExpressController { return this.clientError("Invalid input data", resultValidation.error); } - const userOrError = await this._authService.loginUser({ + const loginResultOrError = await this._authService.loginUser({ email: emailVO.data, plainPassword: plainPasswordVO.data, tabId: tabIdVO.data, }); - if (userOrError.isFailure) { - return this.unauthorizedError(userOrError.error.message); + if (loginResultOrError.isFailure) { + return this.unauthorizedError(loginResultOrError.error.message); } - return this.created(this._presenter.map(userOrError.data)); + return this.created(this._presenter.map(loginResultOrError.data)); } } diff --git a/apps/server/src/contexts/auth/presentation/controllers/login/login.presenter.ts b/apps/server/src/contexts/auth/presentation/controllers/login/login.presenter.ts index 39ee1a48..ad7818b0 100644 --- a/apps/server/src/contexts/auth/presentation/controllers/login/login.presenter.ts +++ b/apps/server/src/contexts/auth/presentation/controllers/login/login.presenter.ts @@ -1,9 +1,10 @@ -import { AuthenticatedUser } from "@contexts/auth/domain"; +import { AuthenticatedUser, TabContext } from "@contexts/auth/domain"; import { ILoginUserResponseDTO } from "../../dto"; export interface ILoginPresenter { map: (data: { user: AuthenticatedUser; + tabContext: TabContext; tokens: { accessToken: string; refreshToken: string; @@ -14,6 +15,7 @@ export interface ILoginPresenter { export const LoginPresenter: ILoginPresenter = { map: (data: { user: AuthenticatedUser; + tabContext: TabContext; tokens: { accessToken: string; refreshToken: string; @@ -21,16 +23,20 @@ export const LoginPresenter: ILoginPresenter = { }): ILoginUserResponseDTO => { const { user, + tabContext, tokens: { accessToken, refreshToken }, } = data; const userData = user.toPersistenceData(); + const tabContextData = tabContext.toPersistenceData(); + return { user: { id: userData.id, email: userData.email, username: userData.username, + tab_id: tabContextData.tab_id, }, tokens: { access_token: accessToken, diff --git a/apps/server/src/contexts/auth/presentation/dto/auth.request.dto.ts b/apps/server/src/contexts/auth/presentation/dto/auth.request.dto.ts index d2d72b92..c41713f5 100644 --- a/apps/server/src/contexts/auth/presentation/dto/auth.request.dto.ts +++ b/apps/server/src/contexts/auth/presentation/dto/auth.request.dto.ts @@ -8,7 +8,3 @@ export interface ILoginUserRequestDTO { email: string; password: string; } - -export interface ISelectCompanyRequestDTO { - companyId: string; -} diff --git a/apps/server/src/contexts/auth/presentation/dto/auth.response.dto.ts b/apps/server/src/contexts/auth/presentation/dto/auth.response.dto.ts index 47784347..e5bc668f 100644 --- a/apps/server/src/contexts/auth/presentation/dto/auth.response.dto.ts +++ b/apps/server/src/contexts/auth/presentation/dto/auth.response.dto.ts @@ -9,6 +9,7 @@ export interface ILoginUserResponseDTO { id: string; username: string; email: string; + tab_id: string; }; tokens: { access_token: string; @@ -17,6 +18,4 @@ export interface ILoginUserResponseDTO { //tab_id: string; } -export interface ILogoutResponseDTO { - message: string; -} +export interface ILogoutResponseDTO {} diff --git a/apps/server/src/contexts/auth/presentation/middleware/passport-auth.middleware.ts b/apps/server/src/contexts/auth/presentation/middleware/passport-auth.middleware.ts index 5ec38aec..7d906d18 100644 --- a/apps/server/src/contexts/auth/presentation/middleware/passport-auth.middleware.ts +++ b/apps/server/src/contexts/auth/presentation/middleware/passport-auth.middleware.ts @@ -2,19 +2,16 @@ import { UniqueID } from "@common/domain"; import { ApiError, ExpressController } from "@common/presentation"; import { AuthenticatedUser } from "@contexts/auth/domain"; import { NextFunction, Request, Response } from "express"; -import passport from "passport"; // Extender el Request de Express para incluir el usuario autenticado optionalmente interface AuthenticatedRequest extends Request { user?: AuthenticatedUser; } -// Middleware para autenticar usando passport con el local-jwt strategy -const _authenticateJwt = passport.authenticate("jwt", { session: false }); - // Comprueba el rol del usuario const _authorizeUser = (condition: (user: AuthenticatedUser) => boolean) => { return (req: AuthenticatedRequest, res: Response, next: NextFunction) => { + console.log(req.user); const user = req.user as AuthenticatedUser; if (!user || !condition(user)) { return ExpressController.errorResponse( @@ -32,15 +29,19 @@ const _authorizeUser = (condition: (user: AuthenticatedUser) => boolean) => { }; }; +// Middleware para autenticar usando passport con el local-jwt strategy +//export const authenticateJWT = []; + +//export const validateUserRegister = [_authenticateEmail]; + // Verifica que el usuario esté autenticado -export const validateUser = [_authenticateJwt, _authorizeUser((user) => user.isUser)]; +export const authenticateUser = [_authorizeUser((user) => user.isUser)]; // Verifica que el usuario sea administrador -export const validateUserIsAdmin = [_authenticateJwt, _authorizeUser((user) => user.isAdmin)]; +export const authenticateUserIsAdmin = [_authorizeUser((user) => user.isAdmin)]; // Middleware para verificar que el usuario sea administrador o el dueño de los datos (self) -export const validateUserIsAdminOrOwner = [ - _authenticateJwt, +export const checkUserIsAdminOrOwner = [ (req: AuthenticatedRequest, res: Response, next: NextFunction) => { const user = req.user as AuthenticatedUser; const { userId } = req.params; diff --git a/apps/server/src/contexts/auth/presentation/middleware/tab-context.middleware.ts b/apps/server/src/contexts/auth/presentation/middleware/tab-context.middleware.ts index 78e8ccbc..23b2b0a1 100644 --- a/apps/server/src/contexts/auth/presentation/middleware/tab-context.middleware.ts +++ b/apps/server/src/contexts/auth/presentation/middleware/tab-context.middleware.ts @@ -1,6 +1,5 @@ import { UniqueID } from "@common/domain"; import { ApiError, ExpressController } from "@common/presentation"; -import { createTabContextService } from "@contexts/auth/application"; import { TabContext } from "@contexts/auth/domain"; import { NextFunction, Request, Response } from "express"; import httpStatus from "http-status"; @@ -40,7 +39,7 @@ export const validateTabContextHeader = async ( res ); } - const contextOrError = await createTabContextService().getContextByTabId(tabIdOrError.data); + /*const contextOrError = await createTabContextService().getContextByTabId(tabIdOrError.data); if (contextOrError.isFailure) { return ExpressController.errorResponse( new ApiError({ @@ -55,6 +54,6 @@ export const validateTabContextHeader = async ( const context = contextOrError.data; - req.tabContext = context; + req.tabContext = context;*/ next(); }; diff --git a/apps/server/src/routes/auth.routes.ts b/apps/server/src/routes/auth.routes.ts index 9e2bd507..05fcb988 100644 --- a/apps/server/src/routes/auth.routes.ts +++ b/apps/server/src/routes/auth.routes.ts @@ -1,5 +1,6 @@ -import { validateRequest } from "@common/presentation"; -import { validateTabContextHeader, validateUser } from "@contexts/auth/presentation"; +import { validateRequestDTO } from "@common/presentation"; +import { createAuthProvider } from "@contexts/auth/infraestructure"; +import { validateTabContextHeader } from "@contexts/auth/presentation"; import { createLoginController } from "@contexts/auth/presentation/controllers"; import { createLogoutController } from "@contexts/auth/presentation/controllers/logout/logout.controller"; import { createRegisterController } from "@contexts/auth/presentation/controllers/register/register.controller"; @@ -8,6 +9,7 @@ import { NextFunction, Request, Response, Router } from "express"; export const authRouter = (appRouter: Router) => { const authRoutes: Router = Router({ mergeParams: true }); + const authProvider = createAuthProvider(); /** * @api {post} /api/auth/register Register a new user @@ -23,7 +25,7 @@ export const authRouter = (appRouter: Router) => { * * @apiError (400) {String} message Error message. */ - authRoutes.post("/register", validateRequest(RegisterUserSchema), (req, res, next) => { + authRoutes.post("/register", validateRequestDTO(RegisterUserSchema), (req, res, next) => { createRegisterController().execute(req, res, next); }); @@ -44,7 +46,7 @@ export const authRouter = (appRouter: Router) => { */ authRoutes.post( "/login", - validateRequest(LoginUserSchema), + validateRequestDTO(LoginUserSchema), validateTabContextHeader, (req: Request, res: Response, next: NextFunction) => { createLoginController().execute(req, res, next); @@ -64,8 +66,8 @@ export const authRouter = (appRouter: Router) => { */ authRoutes.post( "/logout", - validateUser, validateTabContextHeader, + authProvider.authenticateJWT(), (req: Request, res: Response, next: NextFunction) => { createLogoutController().execute(req, res, next); }