Skip to content

Commit 4a0d1b3

Browse files
committed
[REMANIEMENT][AIDANTS] Expose la nouvelle route pour valider les CGU
1 parent 2be5d53 commit 4a0d1b3

File tree

6 files changed

+189
-3
lines changed

6 files changed

+189
-3
lines changed

mon-aide-cyber-api/src/api/hateoas/contextesUtilisateur.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Options } from './hateoas';
22

33
type ClefContexte =
4+
| 'aidant'
45
| 'demande-devenir-aidant'
56
| 'demande-etre-aide'
67
| 'solliciter-aide'

mon-aide-cyber-api/src/api/routesAPIUtilisateur.ts

+43-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import express, { Request, Response } from 'express';
33
import { RequeteUtilisateur } from './routesAPI';
44
import * as core from 'express-serve-static-core';
55
import { NextFunction } from 'express-serve-static-core';
6-
import { constructeurActionsHATEOAS, ReponseHATEOAS } from './hateoas/hateoas';
6+
import {
7+
constructeurActionsHATEOAS,
8+
ReponseHATEOAS,
9+
ReponseHATEOASEnErreur,
10+
} from './hateoas/hateoas';
711
import { ErreurMAC } from '../domaine/erreurMAC';
812
import { ServiceUtilisateur } from '../authentification/ServiceUtilisateur';
913
import { validateursDeCreationDeMotDePasse } from './validateurs/motDePasse';
@@ -12,12 +16,14 @@ import {
1216
FieldValidationError,
1317
Meta,
1418
Result,
19+
body,
1520
validationResult,
1621
} from 'express-validator';
1722
import { EntrepotUtilisateur } from '../authentification/Utilisateur';
1823
import { ServiceDeChiffrement } from '../securite/ServiceDeChiffrement';
1924
import { CommandeReinitialisationMotDePasse } from '../authentification/reinitialisation-mot-de-passe/CapteurCommandeReinitialisationMotDePasse';
2025
import { adaptateurConfigurationLimiteurTraffic } from './adaptateurLimiteurTraffic';
26+
import { unServiceAidant } from '../espace-aidant/ServiceAidantMAC';
2127

2228
type CorpsRequeteReinitialiserMotDePasse = core.ParamsDictionary & {
2329
token: string;
@@ -160,5 +166,41 @@ export const routesAPIUtilisateur = (configuration: ConfigurationServeur) => {
160166
}
161167
);
162168

169+
routes.post(
170+
'/valider-signature-cgu',
171+
session.verifie('Valide les CGU'),
172+
express.json(),
173+
body('cguValidees')
174+
.custom((value: boolean) => value)
175+
.withMessage('Veuillez valider les CGU'),
176+
async (
177+
requete: RequeteUtilisateur,
178+
reponse: Response<ReponseHATEOAS | ReponseHATEOASEnErreur>
179+
) => {
180+
const resultatsValidation: Result<FieldValidationError> =
181+
validationResult(requete) as Result<FieldValidationError>;
182+
if (!resultatsValidation.isEmpty()) {
183+
return reponse.status(422).json({
184+
message: resultatsValidation
185+
.array()
186+
.map((resultatValidation) => resultatValidation.msg)
187+
.join(', '),
188+
...constructeurActionsHATEOAS()
189+
.pour({ contexte: 'valider-signature-cgu' })
190+
.construis(),
191+
});
192+
}
193+
return unServiceAidant(entrepots.aidants())
194+
.valideLesCGU(requete.identifiantUtilisateurCourant!)
195+
.then(() =>
196+
reponse.status(200).json({
197+
...constructeurActionsHATEOAS()
198+
.pour({ contexte: 'aidant:acceder-au-profil' })
199+
.construis(),
200+
})
201+
);
202+
}
203+
);
204+
163205
return routes;
164206
};

mon-aide-cyber-api/src/domaine/erreurMAC.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ export type Contexte =
1919
| 'Modifie le profil Aidant'
2020
| 'Modifie les préférences de l’Aidant'
2121
| "Recherche d'un Aidé"
22-
| 'Réinitialisation mot de passe';
22+
| 'Réinitialisation mot de passe'
23+
| 'Valide les CGU';
2324

2425
export class ErreurMAC<T extends Error> extends Error {
2526
private constructor(

mon-aide-cyber-api/src/espace-aidant/ServiceAidant.ts

+2
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ export interface ServiceAidant {
1212
rechercheParMail(mailAidant: string): Promise<AidantDTO | undefined>;
1313

1414
parIdentifiant(identifiant: crypto.UUID): Promise<AidantDTO | undefined>;
15+
16+
valideLesCGU(identifiantAidant: crypto.UUID): Promise<void>;
1517
}

mon-aide-cyber-api/src/espace-aidant/ServiceAidantMAC.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import crypto from 'crypto';
22
import { EntrepotAidant } from './Aidant';
33
import { AidantDTO, ServiceAidant } from './ServiceAidant';
4+
import { FournisseurHorloge } from '../infrastructure/horloge/FournisseurHorloge';
45

56
class ServiceAidantMAC implements ServiceAidant {
67
constructor(private readonly entrepotAidant: EntrepotAidant) {}
@@ -31,6 +32,13 @@ class ServiceAidantMAC implements ServiceAidant {
3132
.catch(() => undefined);
3233
}
3334

35+
valideLesCGU(identifiantAidant: crypto.UUID): Promise<void> {
36+
return this.entrepotAidant.lis(identifiantAidant).then(async (aidant) => {
37+
aidant.dateSignatureCGU = FournisseurHorloge.maintenant();
38+
return await this.entrepotAidant.persiste(aidant);
39+
});
40+
}
41+
3442
private formateLeNom(nomPrenom: string): string {
3543
const [prenom, nom] = nomPrenom.split(' ');
3644
return `${prenom} ${nom ? `${nom[0]}.` : ''}`.trim();

mon-aide-cyber-api/test/api/routesAPIUtilisateur.spec.ts

+133-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { executeRequete } from './executeurRequete';
55
import { AdaptateurDeVerificationDeSessionAvecContexteDeTest } from '../adaptateurs/AdaptateurDeVerificationDeSessionAvecContexteDeTest';
66
import { AdaptateurDeVerificationDeSessionDeTest } from '../adaptateurs/AdaptateurDeVerificationDeSessionDeTest';
77

8-
import { unUtilisateur } from '../constructeurs/constructeursAidantUtilisateur';
8+
import {
9+
unAidant,
10+
unCompteAidantRelieAUnCompteUtilisateur,
11+
unUtilisateur,
12+
} from '../constructeurs/constructeursAidantUtilisateur';
913
import {
1014
CorpsReponseReinitialiserMotDePasseEnErreur,
1115
ReponseReinitialisationMotDePasseEnErreur,
@@ -16,6 +20,7 @@ import { FournisseurHorlogeDeTest } from '../infrastructure/horloge/FournisseurH
1620
import { add } from 'date-fns';
1721
import { AdaptateurGestionnaireErreursMemoire } from '../../src/infrastructure/adaptateurs/AdaptateurGestionnaireErreursMemoire';
1822
import { liensPublicsAttendus } from './hateoas/liensAttendus';
23+
import { ReponseHATEOASEnErreur } from '../../src/api/hateoas/hateoas';
1924

2025
describe('le serveur MAC sur les routes /api/utilisateur', () => {
2126
const testeurMAC = testeurIntegration();
@@ -33,6 +38,7 @@ describe('le serveur MAC sur les routes /api/utilisateur', () => {
3338
});
3439

3540
describe('quand une requête GET est reçue sur /', () => {
41+
beforeEach(() => adaptateurDeVerificationDeSession.reinitialise());
3642
it("retourne l'utilisateur connecté", async () => {
3743
const utilisateur = unUtilisateur().construis();
3844
await testeurMAC.entrepots.utilisateurs().persiste(utilisateur);
@@ -318,4 +324,130 @@ describe('le serveur MAC sur les routes /api/utilisateur', () => {
318324
});
319325
});
320326
});
327+
328+
describe("Lorsqu'une requête POST est reçue sur /utilisateur/valider-signature-cgu", () => {
329+
const testeurMAC = testeurIntegration();
330+
let donneesServeur: { portEcoute: number; app: Express };
331+
beforeEach(() => {
332+
testeurMAC.adaptateurDeVerificationDeSession =
333+
new AdaptateurDeVerificationDeSessionDeTest();
334+
donneesServeur = testeurMAC.initialise();
335+
});
336+
337+
afterEach(() => {
338+
testeurMAC.arrete();
339+
});
340+
341+
it('Ajoute la date de signature des CGU', async () => {
342+
FournisseurHorlogeDeTest.initialise(new Date());
343+
const { utilisateur } = await unCompteAidantRelieAUnCompteUtilisateur({
344+
entrepotUtilisateur: testeurMAC.entrepots.utilisateurs(),
345+
constructeurAidant: unAidant().sansCGUSignees(),
346+
entrepotAidant: testeurMAC.entrepots.aidants(),
347+
constructeurUtilisateur: unUtilisateur(),
348+
});
349+
testeurMAC.adaptateurDeVerificationDeSession.utilisateurConnecte(
350+
utilisateur
351+
);
352+
353+
const reponse = await executeRequete(
354+
donneesServeur.app,
355+
'POST',
356+
`/api/utilisateur/valider-signature-cgu`,
357+
donneesServeur.portEcoute,
358+
{
359+
cguValidees: true,
360+
}
361+
);
362+
363+
expect(reponse.statusCode).toBe(200);
364+
const aidantModifie = await testeurMAC.entrepots
365+
.aidants()
366+
.lis(utilisateur.identifiant);
367+
expect(aidantModifie.dateSignatureCGU).toStrictEqual(
368+
FournisseurHorloge.maintenant()
369+
);
370+
});
371+
372+
it("Accepte la requête et renvoie les actions possibles pour l'Aidant", async () => {
373+
const { utilisateur } = await unCompteAidantRelieAUnCompteUtilisateur({
374+
entrepotUtilisateur: testeurMAC.entrepots.utilisateurs(),
375+
constructeurAidant: unAidant().sansCGUSignees(),
376+
entrepotAidant: testeurMAC.entrepots.aidants(),
377+
constructeurUtilisateur: unUtilisateur(),
378+
});
379+
testeurMAC.adaptateurDeVerificationDeSession.utilisateurConnecte(
380+
utilisateur
381+
);
382+
383+
const reponse = await executeRequete(
384+
donneesServeur.app,
385+
'POST',
386+
`/api/utilisateur/valider-signature-cgu`,
387+
donneesServeur.portEcoute,
388+
{
389+
cguValidees: true,
390+
}
391+
);
392+
393+
expect(await reponse.json()).toStrictEqual({
394+
liens: {
395+
'afficher-tableau-de-bord': {
396+
methode: 'GET',
397+
url: '/api/espace-aidant/tableau-de-bord',
398+
},
399+
'lancer-diagnostic': {
400+
methode: 'POST',
401+
url: '/api/diagnostic',
402+
},
403+
'modifier-mot-de-passe': {
404+
methode: 'POST',
405+
url: '/api/profil/modifier-mot-de-passe',
406+
},
407+
'modifier-profil': {
408+
methode: 'PATCH',
409+
url: '/api/profil',
410+
},
411+
'se-deconnecter': {
412+
methode: 'DELETE',
413+
url: '/api/token',
414+
},
415+
},
416+
});
417+
});
418+
419+
it('Vérifie la présence de la date de signature des CGU', async () => {
420+
FournisseurHorlogeDeTest.initialise(new Date());
421+
const { utilisateur } = await unCompteAidantRelieAUnCompteUtilisateur({
422+
entrepotUtilisateur: testeurMAC.entrepots.utilisateurs(),
423+
constructeurAidant: unAidant().sansCGUSignees(),
424+
entrepotAidant: testeurMAC.entrepots.aidants(),
425+
constructeurUtilisateur: unUtilisateur(),
426+
});
427+
testeurMAC.adaptateurDeVerificationDeSession.utilisateurConnecte(
428+
utilisateur
429+
);
430+
431+
const reponse = await executeRequete(
432+
donneesServeur.app,
433+
'POST',
434+
`/api/utilisateur/valider-signature-cgu`,
435+
donneesServeur.portEcoute,
436+
{
437+
cguValidees: false,
438+
}
439+
);
440+
441+
expect(reponse.statusCode).toBe(422);
442+
expect(await reponse.json()).toStrictEqual<ReponseHATEOASEnErreur>({
443+
message: 'Veuillez valider les CGU',
444+
liens: {
445+
'valider-signature-cgu': {
446+
url: '/api/utilisateur/valider-signature-cgu',
447+
methode: 'POST',
448+
},
449+
},
450+
});
451+
});
452+
});
321453
});

0 commit comments

Comments
 (0)