Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
11 changes: 7 additions & 4 deletions packages/backend/src/_common/model/app-log/LogAction.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ export type LogAction =
| "DOWNLOAD_IMPORT_TEMPLATE" // Téléchargement modèle Excel
| "DOWNLOAD_IMPORT_GUIDE" // Téléchargement guide PDF
// ADMIN
| "VALIDATE_STRUCTURE" // @deprecated
| "DELETE_STRUCTURE" // @deprecated
| "ADMIN_VALIDATE_STRUCTURE"
| "ADMIN_DELETE_STRUCTURE"
| "ADMIN_STRUCTURE_VALIDATE"
| "ADMIN_STRUCTURE_DELETE"
| "ADMIN_CREATE_USER_STRUCTURE"
| "ADMIN_STRUCTURE_REJECT"
| "ADMIN_CREATE_USER_SUPERVISOR"
| "ADMIN_PATCH_USER_SUPERVISOR"
| "ADMIN_DELETE_USER_SUPERVISOR"
| "ADMIN_ELEVATE_ROLE_USER_SUPERVISOR"
| "ADMIN_USER_ROLE_CHANGE"
| "ADMIN_USER_CREATE"
| "ADMIN_USER_DELETE"
| "ADMIN_PASSWORD_RESET"
// deprecated
| "SUPPRIMER_PIECE_JOINTE"
| "SUPPRIMER_DOMICILIE"
Expand Down
17 changes: 17 additions & 0 deletions packages/backend/src/modules/app-logs/app-log-context.types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import { UserSupervisorRole } from "@domifa/common";

export type FailedUsagerImportLogContext = {
// IMPORT_USAGERS_FAILED
nombreActifs: number;
nombreErreurs: number;
nombreTotal: number;
};

export type SuccessfulUsagerImportLogContext = {
// IMPORT_USAGERS_SUCCESS
nombreActifs: number;
nombreTotal: number;
};

export type AdminUserCrudLogContext = {
// ADMIN_USER_CREATE | ADMIN_USER_DELETE | ADMIN_PASSWORD_RESET
userId: number; // identifiant utilisateur créé // supprimé // modifié
role: UserSupervisorRole;
};

export type AdminUserRoleChangeLogContext = {
// ADMIN_USER_ROLE_CHANGE
userId: number;
oldRole: UserSupervisorRole;
newRole: UserSupervisorRole;
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import { UsersModule } from "../../../users/users.module";
import { AppTestContext, AppTestHelper } from "../../../../util/test";
import { AdminStructuresDeleteController } from "./admin-structures-delete.controller";
import { FileManagerService } from "../../../../util/file-manager/file-manager.service";
import { AppLogsService } from "../../../app-logs/app-logs.service";

describe("Dashboard AdminStructuresDeleteController", () => {
let controller: AdminStructuresDeleteController;

let appLogService: AppLogsService;
let context: AppTestContext;
beforeAll(async () => {
appLogService = {
create: jest.fn(),
};
context = await AppTestHelper.bootstrapTestApp({
controllers: [AdminStructuresDeleteController],
imports: [
Expand All @@ -20,7 +24,13 @@ describe("Dashboard AdminStructuresDeleteController", () => {
forwardRef(() => UsagersModule),
forwardRef(() => InteractionsModule),
],
providers: [FileManagerService],
providers: [
FileManagerService,
{
provide: AppLogsService,
useValue: appLogService,
},
],
});
controller = context.module.get<AdminStructuresDeleteController>(
AdminStructuresDeleteController
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AppLogsService } from "./../../../app-logs/app-logs.service";
import {
Body,
Controller,
Expand Down Expand Up @@ -33,7 +34,10 @@ import { deleteStructureEmailSender } from "../../../mails/services/templates-re
@ApiTags("admin")
@ApiBearerAuth()
export class AdminStructuresDeleteController {
constructor(private readonly fileManagerService: FileManagerService) {}
constructor(
private readonly fileManagerService: FileManagerService,
private readonly appLogsService: AppLogsService
) {}
@AllowUserProfiles("supervisor")
@AllowUserSupervisorRoles("super-admin-domifa")
@ApiBearerAuth()
Expand All @@ -46,7 +50,10 @@ export class AdminStructuresDeleteController {

if (structure) {
return deleteStructureEmailSender.sendMail({ structure }).then(
() => {
async () => {
await this.appLogsService.create({
action: "ADMIN_STRUCTURE_DELETE",
});
return res.status(HttpStatus.OK).json({ message: "OK" });
},
() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import { SmsModule } from "../../../sms/sms.module";

describe("Dashboard AdminStructuresController", () => {
let controller: AdminStructuresController;

let appLogService: AppLogsService;
let context: AppTestContext;
beforeAll(async () => {
appLogService = {
create: jest.fn(),
};
context = await AppTestHelper.bootstrapTestApp({
controllers: [AdminStructuresController],
imports: [
Expand All @@ -23,7 +26,13 @@ describe("Dashboard AdminStructuresController", () => {
forwardRef(() => InteractionsModule),
forwardRef(() => SmsModule),
],
providers: [AdminStructuresService, AppLogsService],
providers: [
AdminStructuresService,
{
provide: AppLogsService,
useValue: appLogService,
},
],
});
controller = context.module.get<AdminStructuresController>(
AdminStructuresController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ export class AdminStructuresController {
structureId: structure.id,
});
await userAccountActivatedEmailSender.sendMail({ user: updatedAdmin });

await this.appLogsService.create({
action: "ADMIN_STRUCTURE_VALIDATE",
});
return res.status(HttpStatus.OK).json({ message: "OK" });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jest.mock("../../../../database", () => ({
describe("AdminUsersController", () => {
let controller: AdminUsersController;
let mockUserStructureRepository: jest.Mocked<typeof userStructureRepository>;

let appLogService: AppLogsService;
const mockCurrentUser = USER_STRUCTURE_AUTH;

const mockUserToElevate = {
Expand All @@ -47,7 +47,9 @@ describe("AdminUsersController", () => {

beforeEach(async () => {
jest.clearAllMocks();

appLogService = {
create: jest.fn(),
};
const module: TestingModule = await Test.createTestingModule({
controllers: [AdminUsersController],
imports: [
Expand All @@ -61,9 +63,7 @@ describe("AdminUsersController", () => {
AdminStructuresService,
{
provide: AppLogsService,
useValue: {
create: jest.fn().mockResolvedValue({}),
},
useValue: appLogService,
},
AdminSuperivorUsersService,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ import { AdminSuperivorUsersService } from "../../services/admin-superivor-users
import { EmailDto } from "../../../users/dto";
import { PatchUserSupervisorDto } from "../../dto/patch-user-supervisor.dto";
import { ElevateUserRoleDto } from "../../dto/elevate-user-role.dto";
import {
AdminUserCrudLogContext,
AdminUserRoleChangeLogContext,
} from "../../../app-logs/app-log-context.types";

@UseGuards(AuthGuard("jwt"), AppUserGuard)
@ApiTags("dashboard")
Expand Down Expand Up @@ -79,7 +83,8 @@ export class AdminUsersController {
uuid,
});

if (user.role === "admin") throw new Error("User is already and admin");
if (userToElevate.role === "admin")
throw new Error("User is already and admin");

await userStructureRepository.update(
{
Expand All @@ -89,7 +94,7 @@ export class AdminUsersController {
role: "admin",
}
);
await this.appLogsService.create({
await this.appLogsService.create<AdminUserRoleChangeLogContext>({
userId: user.id,
action: "ADMIN_ELEVATE_ROLE_USER_SUPERVISOR", // TODO Ajouter du contexte à cette action pour savoir à qui on a fait l'action
});
Expand All @@ -112,6 +117,7 @@ export class AdminUsersController {
@Body() registerUserDto: RegisterUserSupervisorDto
): Promise<ExpressResponse> {
await this.appLogsService.create({
// supprimer ou pas ?
userId: user.id,
action: "ADMIN_CREATE_USER_SUPERVISOR",
});
Expand Down Expand Up @@ -139,7 +145,15 @@ export class AdminUsersController {
userProfile: "supervisor",
})
.then(
() => {
async () => {
await this.appLogsService.create<AdminUserCrudLogContext>({
action: "ADMIN_USER_CREATE",
userId: user.id,
context: {
userId: newUser.id,
role: registerUserDto.role,
},
});
return res.status(HttpStatus.OK).json({ message: "OK" });
},
() => {
Expand Down Expand Up @@ -213,6 +227,18 @@ export class AdminUsersController {
.json({ message: "CANNOT_PATCH_USER_SUPERVISOR" });
}
await userSupervisorRepository.update({ uuid }, { ...patchUserDto });

if (userExist.role !== patchUserDto.role) {
await this.appLogsService.create<AdminUserRoleChangeLogContext>({
action: "ADMIN_USER_ROLE_CHANGE",
userId: user.id,
context: {
userId: userExist.id,
newRole: patchUserDto.role,
oldRole: userExist.role,
},
});
}
return res.status(HttpStatus.OK).json({ message: "OK" });
}

Expand All @@ -237,6 +263,14 @@ export class AdminUsersController {
.json({ message: "CANNOT_PATCH_USER_SUPERVISOR" });
}
await userSupervisorRepository.delete({ uuid });
await this.appLogsService.create<AdminUserCrudLogContext>({
action: "ADMIN_USER_DELETE",
userId: user.id,
context: {
userId: userExist.id,
role: userExist.role,
},
});
return res.status(HttpStatus.OK).json({ message: "OK" });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ import {
userSecurityResetPasswordInitiator,
userSecurityResetPasswordUpdater,
} from "../services";
import { AppLogsService } from "../../app-logs/app-logs.service";
import { AdminUserCrudLogContext } from "../../app-logs/app-log-context.types";
import { userSupervisorRepository } from "../../../database";

const userProfile: UserProfile = "supervisor";

@Controller("users-supervisor")
@ApiTags("users-supervisor")
export class UsersSupervisorController {
constructor(private readonly appLogservice: AppLogsService) {}
@Get("check-password-token/:userId/:token")
public async checkPasswordToken(
@Param("userId", new ParseIntPipe()) userId: number,
Expand Down Expand Up @@ -71,19 +75,35 @@ export class UsersSupervisorController {
@Res() res: ExpressResponse
) {
try {
const { user, userSecurity } =
await userSecurityResetPasswordInitiator.generateResetPasswordToken({
const [userStuperviseur, { user, userSecurity }] = await Promise.all([
userSupervisorRepository.findOneByOrFail({
email: emailDto.email,
}),
userSecurityResetPasswordInitiator.generateResetPasswordToken({
email: emailDto.email,
userProfile,
});
await userResetPasswordEmailSender.sendMail({
user,
token: userSecurity.temporaryTokens.token,
userProfile,
});
}),
]);
await Promise.all([
userResetPasswordEmailSender.sendMail({
user,
token: userSecurity.temporaryTokens.token,
userProfile,
}),
this.appLogservice.create<AdminUserCrudLogContext>({
action: "ADMIN_PASSWORD_RESET",
userId: userStuperviseur.id,
context: {
userId: userStuperviseur.id,
role: userStuperviseur.role,
},
}),
]);
} catch (err) {
appLogger.error("Cannot reset password");
throw err;
}

return res.status(HttpStatus.OK).json({ message: "OK" });
}
}
3 changes: 2 additions & 1 deletion packages/backend/src/modules/users/users.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { UsersController } from "./controllers/users.controller";
import { UsersPublicController } from "./controllers/users.public.controller";
import { MailsModule } from "../mails/mails.module";
import { UsersSupervisorController } from "./controllers/users-supervisor.controller";
import { AppLogsService } from "../app-logs/app-logs.service";

@Module({
controllers: [
Expand All @@ -21,6 +22,6 @@ import { UsersSupervisorController } from "./controllers/users-supervisor.contro
forwardRef(() => MailsModule),
forwardRef(() => StructuresModule),
],
providers: [],
providers: [AppLogsService],
})
export class UsersModule {}