diff --git a/apis/authCommand/Infrastructure/repositories/mongoose/user.repository.ts b/apis/authCommand/Infrastructure/repositories/mongoose/user.repository.ts index 0b80ad0..ae3f33f 100644 --- a/apis/authCommand/Infrastructure/repositories/mongoose/user.repository.ts +++ b/apis/authCommand/Infrastructure/repositories/mongoose/user.repository.ts @@ -15,12 +15,35 @@ export class UserRepository implements UserRepositoryInterface { this.model = mongoose.model("User",userSchema); } - create(user: User): Promise { - throw new Error("Method not implemented."); - } - async findByEmail(email: string): Promise { const userData = await this.model.findOne({ email }); return userData ? new User(userData.email, userData.password, userData.role, userData.id) : null; } + + async findById(id: string): Promise { + const userData = await this.model.findById(id); + return userData ? new User(userData.email, userData.password, userData.role, userData.id) : null; + } + + async create(user: User): Promise { + const userData = await this.model.create(user); + return new User(userData.email, userData.password, userData.role, userData.id); + } + + // TODO: Implement the update method & Cie + async update(user: User): Promise { + const userData = await this.model.findByIdAndUpdate + (user.id, { email: user.email, password: user.password, role: user.role }, { new: true }); + return new User(userData.email, userData.id); + } + async updateRole(id: string, password: string): Promise { + throw new Error("Method not implemented."); + } + async updatePassword(id: string, password: string): Promise { + throw new Error("Method not implemented."); + } + + async delete(id: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/apis/authCommand/Interface/controllers/auth/delete.controller.ts b/apis/authCommand/Interface/controllers/auth/delete.controller.ts new file mode 100644 index 0000000..c0b7ac2 --- /dev/null +++ b/apis/authCommand/Interface/controllers/auth/delete.controller.ts @@ -0,0 +1 @@ +// TODO: \ No newline at end of file diff --git a/apis/authCommand/Interface/controllers/auth/update.controller.ts b/apis/authCommand/Interface/controllers/auth/update.controller.ts new file mode 100644 index 0000000..c0b7ac2 --- /dev/null +++ b/apis/authCommand/Interface/controllers/auth/update.controller.ts @@ -0,0 +1 @@ +// TODO: \ No newline at end of file diff --git a/apis/authCommand/Interface/routes/auth.routes.ts b/apis/authCommand/Interface/routes/auth.routes.ts index a88a0c0..fa0a6c8 100644 --- a/apis/authCommand/Interface/routes/auth.routes.ts +++ b/apis/authCommand/Interface/routes/auth.routes.ts @@ -3,8 +3,12 @@ import { SignUpController } from "../controllers/auth/sign-up.controller"; const router = express.Router(); -// router.post("/login", AuthController.login); const signUpController = new SignUpController(); router.post("/register", signUpController.register.bind(signUpController)); +// router.post("/change-password", AuthController.changePassword); +// router.put("/update", AuthController.update); +// router.put("/update-role", AuthController.updateRole); +// router.put("/update-password", AuthController.updatePassword); +// router.delete("/delete", AuthController.delete); export default router; diff --git a/apis/authCommand/application/dtos/auth/change.password.user.dto.ts b/apis/authCommand/application/dtos/auth/change.password.user.dto.ts new file mode 100644 index 0000000..ba9b924 --- /dev/null +++ b/apis/authCommand/application/dtos/auth/change.password.user.dto.ts @@ -0,0 +1,5 @@ +export interface ChangePasswordUserDTO { + userId: string; + password: string; + token: string; +} \ No newline at end of file diff --git a/apis/authCommand/application/dtos/auth/change.role.user.dto.ts b/apis/authCommand/application/dtos/auth/change.role.user.dto.ts new file mode 100644 index 0000000..5191002 --- /dev/null +++ b/apis/authCommand/application/dtos/auth/change.role.user.dto.ts @@ -0,0 +1,7 @@ +import { Role } from "../../../domain/enums"; + +export interface ChangeRoleUserDTO { + userId: string; + role: Role; + token: string; +} \ No newline at end of file diff --git a/apis/authCommand/application/dtos/auth/delete.user.dto.ts b/apis/authCommand/application/dtos/auth/delete.user.dto.ts new file mode 100644 index 0000000..1a890be --- /dev/null +++ b/apis/authCommand/application/dtos/auth/delete.user.dto.ts @@ -0,0 +1,4 @@ +export interface DeleteUserDTO { + id: string; + token: string; +} \ No newline at end of file diff --git a/apis/authCommand/application/dtos/auth/index.ts b/apis/authCommand/application/dtos/auth/index.ts index f4e811d..7df341f 100644 --- a/apis/authCommand/application/dtos/auth/index.ts +++ b/apis/authCommand/application/dtos/auth/index.ts @@ -1,2 +1,5 @@ -export * from "./login.user.dto"; -export * from "./register.user.dto"; \ No newline at end of file +export * from "./change.password.user.dto"; +export * from "./change.role.user.dto"; +export * from "./delete.user.dto"; +export * from "./register.user.dto"; +export * from "./update.user.dto"; \ No newline at end of file diff --git a/apis/authCommand/application/dtos/auth/update.user.dto.ts b/apis/authCommand/application/dtos/auth/update.user.dto.ts new file mode 100644 index 0000000..fe6a705 --- /dev/null +++ b/apis/authCommand/application/dtos/auth/update.user.dto.ts @@ -0,0 +1,8 @@ +export interface UpdateUserDTO { + id: string; + email?: string; + firstName?: string; + lastName?: string; + phone?: string; + token: string; +} \ No newline at end of file diff --git a/apis/authCommand/application/ports/user.repository.interface.ts b/apis/authCommand/application/ports/user.repository.interface.ts index acad1ac..b8c956b 100644 --- a/apis/authCommand/application/ports/user.repository.interface.ts +++ b/apis/authCommand/application/ports/user.repository.interface.ts @@ -3,5 +3,10 @@ import { User } from '../../domain/entities'; export interface UserRepositoryInterface { findByEmail(email: string): Promise; - create(user: User): Promise; + findById(id: string): Promise; + create(user: User): Promise; + update(user: User): Promise; + updateRole(id: string, role: string): Promise; + updatePassword(id: string, password: string): Promise; + delete(id: string): Promise; } diff --git a/apis/authCommand/application/usecases/auth/change.password.usecase.ts b/apis/authCommand/application/usecases/auth/change.password.usecase.ts new file mode 100644 index 0000000..5483e11 --- /dev/null +++ b/apis/authCommand/application/usecases/auth/change.password.usecase.ts @@ -0,0 +1,32 @@ +import { NotFoundError } from "../../errors"; +import { AuthServiceInterface, UserRepositoryInterface } from "../../ports"; +import { ChangePasswordUserDTO } from "../../dtos/auth"; +import { Role } from "../../../domain/enums"; + +export class ChangePasswordUseCase { + private userRepository: UserRepositoryInterface; + private authService: AuthServiceInterface; + + constructor(userRepository: UserRepositoryInterface, authService: AuthServiceInterface) { + this.userRepository = userRepository; + this.authService = authService; + } + async execute(dto: ChangePasswordUserDTO): Promise { + if (!dto.userId || !dto.password || !dto.token) { + throw new Error("L'identifiant de l'utilisateur et le mot de passe sont requis"); + } + const token = this.authService.verifyToken(dto.token); + if (!token) { + throw new Error("Invalid token"); + } + if (token.id !== dto.userId || token.role !== Role.ADMIN) { + throw new Error("Permission denied"); + } + const user = await this.userRepository.findById(dto.userId); + if (!user) { + throw new NotFoundError(); + } + user.password = dto.password; + await this.userRepository.updatePassword(dto.userId, dto.password); + } +} \ No newline at end of file diff --git a/apis/authCommand/application/usecases/auth/change.role.usecase.ts b/apis/authCommand/application/usecases/auth/change.role.usecase.ts new file mode 100644 index 0000000..3efbe80 --- /dev/null +++ b/apis/authCommand/application/usecases/auth/change.role.usecase.ts @@ -0,0 +1,37 @@ +import { NotFoundError } from "../../errors"; +import { AuthServiceInterface, UserRepositoryInterface } from "../../ports"; +import { ChangeRoleUserDTO } from "../../dtos/auth"; +import { Role } from "../../../domain/enums"; + +export class ChangeRoleUseCase { + private userRepository: UserRepositoryInterface; + private authService: AuthServiceInterface; + + constructor(userRepository: UserRepositoryInterface, authService: AuthServiceInterface) { + this.userRepository = userRepository; + this.authService = authService; + } + + async execute(dto: ChangeRoleUserDTO): Promise { + if (!dto.userId || !dto.role || !dto.token) { + throw new Error("L'identifiant de l'utilisateur et le rôle sont requis"); + } + + const token = this.authService.verifyToken(dto.token); + if (!token) { + throw new Error("Invalid token"); + } + + if (token.role !== Role.ADMIN) { + throw new Error("Permission denied"); + } + + const user = await this.userRepository.findById(dto.userId); + if (!user) { + throw new NotFoundError(); + } + + user.role = dto.role; + await this.userRepository.update(user); + } +} \ No newline at end of file diff --git a/apis/authCommand/application/usecases/auth/delete.usecase.ts b/apis/authCommand/application/usecases/auth/delete.usecase.ts new file mode 100644 index 0000000..567785d --- /dev/null +++ b/apis/authCommand/application/usecases/auth/delete.usecase.ts @@ -0,0 +1,31 @@ +import { AuthServiceInterface, UserRepositoryInterface } from "../../ports"; + + +export class DeleteUseCase { + + private userRepository: UserRepositoryInterface; + private authService: AuthServiceInterface; + + constructor(userRepository: UserRepositoryInterface, authService: AuthServiceInterface) { + this.userRepository = userRepository; + this.authService = authService; + } + + async execute(id: string): Promise { + if (!id) { + throw new Error("Id is required"); + } + + const isTokenValid = this.authService.verifyToken(id); + if (!isTokenValid) { + throw new Error("Invalid token"); + } + + const user = await this.userRepository.findById(id); + if (!user) { + throw new Error("User not found"); + } + + await this.userRepository.delete(id); + } +} \ No newline at end of file diff --git a/apis/authCommand/application/usecases/auth/index.ts b/apis/authCommand/application/usecases/auth/index.ts new file mode 100644 index 0000000..5df8a26 --- /dev/null +++ b/apis/authCommand/application/usecases/auth/index.ts @@ -0,0 +1,4 @@ +export * from './change.role.usecase'; +export * from './delete.usecase'; +export * from './register.usecase'; +export * from './update.usecase'; \ No newline at end of file diff --git a/apis/authCommand/application/usecases/auth/register.usecase.ts b/apis/authCommand/application/usecases/auth/register.usecase.ts index c1054b2..dfe74ac 100644 --- a/apis/authCommand/application/usecases/auth/register.usecase.ts +++ b/apis/authCommand/application/usecases/auth/register.usecase.ts @@ -14,7 +14,7 @@ export class RegisterUseCase { this.authService = authService; } - async execute(dto: RegisterUserDTO): Promise { + async execute(dto: RegisterUserDTO): Promise { // Fail Fast: Vérifie si les données d’entrée sont valides if (!dto.email || !dto.password) { throw new Error("Email et mot de passe sont requis"); diff --git a/apis/authCommand/application/usecases/auth/update.usecase.ts b/apis/authCommand/application/usecases/auth/update.usecase.ts new file mode 100644 index 0000000..05bce10 --- /dev/null +++ b/apis/authCommand/application/usecases/auth/update.usecase.ts @@ -0,0 +1,49 @@ +import { AuthServiceInterface, UserRepositoryInterface } from "../../ports"; +import { UpdateUserDTO } from "../../dtos/auth"; + +export class UpdateUseCase { + private userRepository: UserRepositoryInterface; + private authService: AuthServiceInterface; + + constructor(userRepository: UserRepositoryInterface, authService: AuthServiceInterface) { + this.userRepository = userRepository; + this.authService = authService; + } + + async execute(dto: UpdateUserDTO): Promise { + if (!dto.id || !dto.token) { + throw new Error("Id is required"); + } + + const token = this.authService.verifyToken(dto.token); + if (!token) { + throw new Error("Invalid token"); + } + if (token.id !== dto.id) { + throw new Error("Invalid token"); + } + + const user = await this.userRepository.findById(dto.id); + if (!user) { + throw new Error("User not found"); + } + + if (dto.email) { + user.email = dto.email; + } + + if (dto.firstName) { + user.firstName = dto.firstName; + } + + if (dto.lastName) { + user.lastName = dto.lastName; + } + + if (dto.phone) { + user.phone = dto.phone; + } + + await this.userRepository.update(user); + } +} \ No newline at end of file diff --git a/apis/authCommand/shared/helpers/token.helper.ts b/apis/authCommand/shared/helpers/token.helper.ts index 30d21a1..1ef8a9c 100644 --- a/apis/authCommand/shared/helpers/token.helper.ts +++ b/apis/authCommand/shared/helpers/token.helper.ts @@ -17,7 +17,7 @@ export class TokenHelper implements AuthServiceInterface { } generateToken(user: User): string { - return sign({email: user.email, role: user.role}, this.secret, { expiresIn: '1h' }); + return sign({id: user.id, email: user.email, role: user.role}, this.secret, { expiresIn: '1h' }); } verifyToken(token: string): any {