Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,35 @@ export class UserRepository implements UserRepositoryInterface {
this.model = mongoose.model("User",userSchema);
}

create(user: User): Promise<void> {
throw new Error("Method not implemented.");
}

async findByEmail(email: string): Promise<User | null> {
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<User | null> {
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<User> {
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<User> {
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<User> {
throw new Error("Method not implemented.");
}
async updatePassword(id: string, password: string): Promise<User> {
throw new Error("Method not implemented.");
}

async delete(id: string): Promise<void> {
throw new Error("Method not implemented.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// TODO:
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// TODO:
6 changes: 5 additions & 1 deletion apis/authCommand/Interface/routes/auth.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ChangePasswordUserDTO {
userId: string;
password: string;
token: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Role } from "../../../domain/enums";

export interface ChangeRoleUserDTO {
userId: string;
role: Role;
token: string;
}
4 changes: 4 additions & 0 deletions apis/authCommand/application/dtos/auth/delete.user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface DeleteUserDTO {
id: string;
token: string;
}
7 changes: 5 additions & 2 deletions apis/authCommand/application/dtos/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from "./login.user.dto";
export * from "./register.user.dto";
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";
8 changes: 8 additions & 0 deletions apis/authCommand/application/dtos/auth/update.user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface UpdateUserDTO {
id: string;
email?: string;
firstName?: string;
lastName?: string;
phone?: string;
token: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,10 @@ import { User } from '../../domain/entities';
export interface UserRepositoryInterface {

findByEmail(email: string): Promise<User | null>;
create(user: User): Promise<void>;
findById(id: string): Promise<User | null>;
create(user: User): Promise<User | null>;
update(user: User): Promise<User | null>;
updateRole(id: string, role: string): Promise<User | null>;
updatePassword(id: string, password: string): Promise<User | null>;
delete(id: string): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -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<void | Error> {
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);
}
}
37 changes: 37 additions & 0 deletions apis/authCommand/application/usecases/auth/change.role.usecase.ts
Original file line number Diff line number Diff line change
@@ -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<void | Error> {
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);
}
}
31 changes: 31 additions & 0 deletions apis/authCommand/application/usecases/auth/delete.usecase.ts
Original file line number Diff line number Diff line change
@@ -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<void | Error> {
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);
}
}
4 changes: 4 additions & 0 deletions apis/authCommand/application/usecases/auth/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './change.role.usecase';
export * from './delete.usecase';
export * from './register.usecase';
export * from './update.usecase';
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class RegisterUseCase {
this.authService = authService;
}

async execute(dto: RegisterUserDTO): Promise<string> {
async execute(dto: RegisterUserDTO): Promise<string | Error> {
// 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");
Expand Down
49 changes: 49 additions & 0 deletions apis/authCommand/application/usecases/auth/update.usecase.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
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);
}
}
2 changes: 1 addition & 1 deletion apis/authCommand/shared/helpers/token.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down