feat: Securisation du téléchargement de fichier

This commit is contained in:
Luc SORIGNET
2026-04-04 13:44:57 +02:00
parent 5f6c015d02
commit a3291262d8
17 changed files with 1176 additions and 566 deletions

View File

@ -8,7 +8,8 @@ import GradesDomainBarChart from '@/components/Grades/GradesDomainBarChart';
import { EvaluationStudentView } from '@/components/Evaluation';
import Button from '@/components/Form/Button';
import logger from '@/utils/logger';
import { FE_ADMIN_GRADES_STUDENT_COMPETENCIES_URL, BASE_URL } from '@/utils/Url';
import { FE_ADMIN_GRADES_STUDENT_COMPETENCIES_URL } from '@/utils/Url';
import { getSecureFileUrl } from '@/utils/fileUrl';
import {
fetchStudents,
fetchStudentCompetencies,
@ -147,21 +148,33 @@ export default function StudentGradesPage() {
// Load evaluations for the student
useEffect(() => {
if (student?.associated_class_id && selectedPeriod && selectedEstablishmentId) {
if (
student?.associated_class_id &&
selectedPeriod &&
selectedEstablishmentId
) {
const periodString = getPeriodString(
selectedPeriod,
selectedEstablishmentEvaluationFrequency
);
// Load evaluations for the class
fetchEvaluations(selectedEstablishmentId, student.associated_class_id, periodString)
fetchEvaluations(
selectedEstablishmentId,
student.associated_class_id,
periodString
)
.then((data) => setEvaluations(data))
.catch((error) => logger.error('Erreur lors du fetch des évaluations:', error));
.catch((error) =>
logger.error('Erreur lors du fetch des évaluations:', error)
);
// Load student's evaluation scores
fetchStudentEvaluations(studentId, null, periodString, null)
.then((data) => setStudentEvaluationsData(data))
.catch((error) => logger.error('Erreur lors du fetch des notes:', error));
.catch((error) =>
logger.error('Erreur lors du fetch des notes:', error)
);
}
}, [student, selectedPeriod, selectedEstablishmentId]);
@ -182,8 +195,12 @@ export default function StudentGradesPage() {
const handleToggleJustify = (absence) => {
const newReason =
absence.type === 'Absence'
? absence.justified ? 2 : 1
: absence.justified ? 4 : 3;
? absence.justified
? 2
: 1
: absence.justified
? 4
: 3;
editAbsences(absence.id, { ...absence, reason: newReason }, csrfToken)
.then(() => {
@ -193,7 +210,9 @@ export default function StudentGradesPage() {
)
);
})
.catch((e) => logger.error('Erreur lors du changement de justification', e));
.catch((e) =>
logger.error('Erreur lors du changement de justification', e)
);
};
const handleDeleteAbsence = (absence) => {
@ -210,8 +229,16 @@ export default function StudentGradesPage() {
try {
await updateStudentEvaluation(studentEvalId, data, csrfToken);
// Reload student evaluations
const periodString = getPeriodString(selectedPeriod, selectedEstablishmentEvaluationFrequency);
const updatedData = await fetchStudentEvaluations(studentId, null, periodString, null);
const periodString = getPeriodString(
selectedPeriod,
selectedEstablishmentEvaluationFrequency
);
const updatedData = await fetchStudentEvaluations(
studentId,
null,
periodString,
null
);
setStudentEvaluationsData(updatedData);
} catch (error) {
logger.error('Erreur lors de la modification de la note:', error);
@ -237,7 +264,7 @@ export default function StudentGradesPage() {
<div className="bg-stone-50 rounded-lg shadow-sm border border-gray-100 p-4 md:p-6 flex flex-col sm:flex-row items-center sm:items-start gap-4">
{student.photo ? (
<img
src={`${BASE_URL}${student.photo}`}
src={getSecureFileUrl(student.photo)}
alt={`${student.first_name} ${student.last_name}`}
className="w-24 h-24 object-cover rounded-full border-4 border-emerald-200 shadow"
/>