diff --git a/packages/applications/document-builder/src/candidature/attestation/attestation.saga.ts b/packages/applications/document-builder/src/candidature/attestation/attestation.saga.ts index c3092c2799..5c34f2f09b 100644 --- a/packages/applications/document-builder/src/candidature/attestation/attestation.saga.ts +++ b/packages/applications/document-builder/src/candidature/attestation/attestation.saga.ts @@ -5,7 +5,7 @@ import { getLogger } from '@potentiel-libraries/monitoring'; import { Candidature } from '@potentiel-domain/candidature'; import { Option } from '@potentiel-libraries/monads'; import { AppelOffre } from '@potentiel-domain/appel-offre'; -import { IdentifiantProjet } from '@potentiel-domain/common'; +import { Email, IdentifiantProjet } from '@potentiel-domain/common'; import { buildCertificate, BuildCertificateProps } from './buildCertificate'; @@ -170,7 +170,7 @@ export const register = () => { const mapCorrectionToCandidature = ( payload: Candidature.CandidatureCorrigéeEvent['payload'], ): BuildCertificateProps['candidature'] => ({ - emailContact: payload.emailContact, + emailContact: Email.convertirEnValueType(payload.emailContact), evaluationCarboneSimplifiée: payload.evaluationCarboneSimplifiée, localité: payload.localité, nomCandidat: payload.nomCandidat, diff --git a/packages/applications/document-builder/src/candidature/attestation/buildCertificate.ts b/packages/applications/document-builder/src/candidature/attestation/buildCertificate.ts index 833d80dc45..c0dcf2aba6 100644 --- a/packages/applications/document-builder/src/candidature/attestation/buildCertificate.ts +++ b/packages/applications/document-builder/src/candidature/attestation/buildCertificate.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import ReactPDF, { Font } from '@react-pdf/renderer'; import { AppelOffre } from '@potentiel-domain/appel-offre'; -import { DateTime, IdentifiantProjet } from '@potentiel-domain/common'; +import { DateTime, Email, IdentifiantProjet } from '@potentiel-domain/common'; import { Candidature } from '@potentiel-domain/candidature'; import { fontsFolderPath, imagesFolderPath } from '../../assets'; @@ -48,7 +48,7 @@ export type BuildCertificateProps = { }; nomCandidat: string; nomReprésentantLégal: string; - emailContact: string; + emailContact: Email.ValueType; puissanceProductionAnnuelle: number; prixReference: number; technologie: Candidature.TypeTechnologie.ValueType; @@ -133,7 +133,7 @@ const mapToCertificateData = ({ nomCandidat: candidature.nomCandidat, nomRepresentantLegal: candidature.nomReprésentantLégal, - email: candidature.emailContact, + email: candidature.emailContact.formatter(), evaluationCarbone: candidature.evaluationCarboneSimplifiée, prixReference: candidature.prixReference, diff --git a/packages/applications/notifications/src/subscribers/candidature/candidature.notification.ts b/packages/applications/notifications/src/subscribers/candidature/candidature.notification.ts index 802bb7ec8d..616b25a8a1 100644 --- a/packages/applications/notifications/src/subscribers/candidature/candidature.notification.ts +++ b/packages/applications/notifications/src/subscribers/candidature/candidature.notification.ts @@ -49,7 +49,10 @@ export const register = ({ sendEmail }: RegisterCandidatureNotificationDependenc templateId: templateId.attestationRegénéréePorteur, messageSubject: `Potentiel - Une nouvelle attestation est disponible pour le projet ${candidature.nomProjet}`, recipients: [ - { email: candidature.emailContact, fullName: candidature.nomReprésentantLégal }, + { + email: candidature.emailContact.formatter(), + fullName: candidature.nomReprésentantLégal, + }, ], variables: { nom_projet: candidature.nomProjet, diff --git "a/packages/applications/notifications/src/subscribers/p\303\251riode/p\303\251riode.notification.ts" "b/packages/applications/notifications/src/subscribers/p\303\251riode/p\303\251riode.notification.ts" index 0184ed9ee2..b7d56a68fa 100644 --- "a/packages/applications/notifications/src/subscribers/p\303\251riode/p\303\251riode.notification.ts" +++ "b/packages/applications/notifications/src/subscribers/p\303\251riode/p\303\251riode.notification.ts" @@ -109,7 +109,7 @@ async function getEmailPayloads( templateId: templateId.notifierPorteur, recipients: [ { - email, + email: email.formatter(), fullName, }, ], diff --git a/packages/applications/request-context/src/convertToken.ts b/packages/applications/request-context/src/convertToken.ts index 67c078bcef..7d82dcf004 100644 --- a/packages/applications/request-context/src/convertToken.ts +++ b/packages/applications/request-context/src/convertToken.ts @@ -2,8 +2,9 @@ import { z } from 'zod'; import { jwtVerify } from 'jose'; import { PlainType } from '@potentiel-domain/core'; -import { Role, Groupe, IdentifiantUtilisateur, Utilisateur } from '@potentiel-domain/utilisateur'; +import { Role, Groupe, Utilisateur } from '@potentiel-domain/utilisateur'; import { Option } from '@potentiel-libraries/monads'; +import { Email } from '@potentiel-domain/common'; import { getJwks } from './openid'; @@ -36,6 +37,6 @@ export const convertToken = async ( role: Role.convertirEnValueType(role ?? ''), groupe: groupe ? Groupe.convertirEnValueType(groupe) : Option.none, nom, - identifiantUtilisateur: IdentifiantUtilisateur.convertirEnValueType(email), + identifiantUtilisateur: Email.convertirEnValueType(email), }; }; diff --git a/packages/applications/ssr/src/app/candidatures/[identifiant]/corriger/page.tsx b/packages/applications/ssr/src/app/candidatures/[identifiant]/corriger/page.tsx index 5fe0f47672..34140e6e79 100644 --- a/packages/applications/ssr/src/app/candidatures/[identifiant]/corriger/page.tsx +++ b/packages/applications/ssr/src/app/candidatures/[identifiant]/corriger/page.tsx @@ -52,7 +52,7 @@ const mapToProps: MapToProps = (candidature) => ({ nomProjet: candidature.nomProjet, nomCandidat: candidature.nomCandidat, nomRepresentantLegal: candidature.nomReprésentantLégal, - emailContact: candidature.emailContact, + emailContact: candidature.emailContact.formatter(), puissanceProductionAnnuelle: candidature.puissanceProductionAnnuelle, prixReference: candidature.prixReference, societeMere: candidature.sociétéMère, diff --git "a/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.page.tsx" "b/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.page.tsx" index 2f7401a9a1..b24156fc23 100644 --- "a/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.page.tsx" +++ "b/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.page.tsx" @@ -142,7 +142,9 @@ export const DétailsCandidaturePage: FC = ({ {candidature.nomReprésentantLégal} - {candidature.emailContact} + + {candidature.emailContact.email} + diff --git "a/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.stories.tsx" "b/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.stories.tsx" index 40787b8dc6..fc5f87da71 100644 --- "a/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.stories.tsx" +++ "b/packages/applications/ssr/src/components/pages/candidature/d\303\251tails/D\303\251tailsCandidature.stories.tsx" @@ -25,7 +25,7 @@ export const CandidatureNonNotifiée: Story = { statut: Candidature.StatutCandidature.classé, nomProjet: 'Nom projet', nomCandidat: 'Candidat', - emailContact: 'porteur@test.test', + emailContact: Email.convertirEnValueType('porteur@test.test'), localité: { commune: 'Commune', département: 'Département', @@ -63,7 +63,7 @@ export const CandidatureNotifiée: Story = { statut: Candidature.StatutCandidature.classé, nomProjet: 'Nom projet', nomCandidat: 'Candidat', - emailContact: 'porteur@test.test', + emailContact: Email.convertirEnValueType('porteur@test.test'), localité: { commune: 'Commune', département: 'Département', diff --git a/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureList.stories.tsx b/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureList.stories.tsx index 5355b7b4c3..d8600a813a 100644 --- a/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureList.stories.tsx +++ b/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureList.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { IdentifiantProjet } from '@potentiel-domain/common'; +import { Email, IdentifiantProjet } from '@potentiel-domain/common'; import { Candidature } from '@potentiel-domain/candidature'; import { CandidatureListPage, CandidatureListPageProps } from './CandidatureList.page'; @@ -29,7 +29,7 @@ const commonItem: CommonItem = { statut: Candidature.StatutCandidature.classé, nomProjet: 'Nom projet', nomCandidat: 'Candidat', - emailContact: 'porteur@test.test', + emailContact: Email.convertirEnValueType('porteur@test.test'), localité: { commune: 'Commune', département: 'Département', diff --git a/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureListItem.tsx b/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureListItem.tsx index 4f2e65f433..d988237f7f 100644 --- a/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureListItem.tsx +++ b/packages/applications/ssr/src/components/pages/candidature/lister/CandidatureListItem.tsx @@ -1,7 +1,7 @@ import { FC } from 'react'; import { PlainType } from '@potentiel-domain/core'; -import { IdentifiantProjet } from '@potentiel-domain/common'; +import { Email, IdentifiantProjet } from '@potentiel-domain/common'; import { Candidature } from '@potentiel-domain/candidature'; import { AppelOffre } from '@potentiel-domain/appel-offre'; @@ -21,7 +21,7 @@ export type CandidatureListItemProps = { nomProjet: Candidature.ConsulterCandidatureReadModel['nomProjet']; nomCandidat: Candidature.ConsulterCandidatureReadModel['nomCandidat']; nomReprésentantLégal: Candidature.ConsulterCandidatureReadModel['nomReprésentantLégal']; - emailContact: Candidature.ConsulterCandidatureReadModel['emailContact']; + emailContact: PlainType; puissanceProductionAnnuelle: Candidature.ConsulterCandidatureReadModel['puissanceProductionAnnuelle']; prixReference: Candidature.ConsulterCandidatureReadModel['prixReference']; evaluationCarboneSimplifiée: Candidature.ConsulterCandidatureReadModel['evaluationCarboneSimplifiée']; @@ -91,8 +91,8 @@ export const CandidatureListItem: FC = ({ />
{nomReprésentantLégal}
-
- {emailContact} +
+ {emailContact.email}
diff --git a/packages/domain/candidature/src/consulter/consulterCandidature.query.ts b/packages/domain/candidature/src/consulter/consulterCandidature.query.ts index a178b1db8f..db4f318911 100644 --- a/packages/domain/candidature/src/consulter/consulterCandidature.query.ts +++ b/packages/domain/candidature/src/consulter/consulterCandidature.query.ts @@ -27,7 +27,7 @@ export type ConsulterCandidatureReadModel = { }; nomCandidat: string; nomReprésentantLégal: string; - emailContact: string; + emailContact: Email.ValueType; puissanceProductionAnnuelle: number; prixReference: number; technologie: TypeTechnologie.ValueType; @@ -115,7 +115,7 @@ export const mapToReadModel = ({ localité, nomCandidat, nomReprésentantLégal, - emailContact, + emailContact: Email.convertirEnValueType(emailContact), puissanceProductionAnnuelle, prixReference, sociétéMère, diff --git a/packages/domain/candidature/src/importer/importerCandidature.behavior.ts b/packages/domain/candidature/src/importer/importerCandidature.behavior.ts index f91245ecc7..acca1804bb 100644 --- a/packages/domain/candidature/src/importer/importerCandidature.behavior.ts +++ b/packages/domain/candidature/src/importer/importerCandidature.behavior.ts @@ -30,7 +30,7 @@ export type CandidatureImportéeEventCommonPayload = { prixReference: number; noteTotale: number; nomReprésentantLégal: string; - emailContact: string; + emailContact: Email.RawType; localité: { adresse1: string; adresse2: string; @@ -70,7 +70,7 @@ export type ImporterCandidatureBehaviorCommonOptions = { prixReference: number; noteTotale: number; nomReprésentantLégal: string; - emailContact: string; + emailContact: Email.ValueType; localité: { adresse1: string; adresse2: string; @@ -194,7 +194,7 @@ export const mapToEventPayload = (candidature: ImporterCandidatureBehaviorCommon prixReference: candidature.prixReference, noteTotale: candidature.noteTotale, nomReprésentantLégal: candidature.nomReprésentantLégal, - emailContact: candidature.emailContact, + emailContact: candidature.emailContact.formatter(), localité: candidature.localité, motifÉlimination: candidature.motifÉlimination, puissanceALaPointe: candidature.puissanceALaPointe, diff --git a/packages/domain/candidature/src/importer/importerCandidature.command.ts b/packages/domain/candidature/src/importer/importerCandidature.command.ts index 4914c59b61..9d19fbeaf5 100644 --- a/packages/domain/candidature/src/importer/importerCandidature.command.ts +++ b/packages/domain/candidature/src/importer/importerCandidature.command.ts @@ -22,7 +22,7 @@ export type ImporterCandidatureCommandCommonOptions = { prixReference: number; noteTotale: number; nomReprésentantLégal: string; - emailContact: string; + emailContact: Email.ValueType; localité: { adresse1: string; adresse2: string; diff --git a/packages/domain/candidature/src/importer/importerCandidature.usecase.ts b/packages/domain/candidature/src/importer/importerCandidature.usecase.ts index 92f72deed9..50a54883a2 100644 --- a/packages/domain/candidature/src/importer/importerCandidature.usecase.ts +++ b/packages/domain/candidature/src/importer/importerCandidature.usecase.ts @@ -105,7 +105,7 @@ export const mapPayloadForCommand = (payload: ImporterCandidatureUseCaseCommonPa historiqueAbandon: HistoriqueAbandon.convertirEnValueType(payload.historiqueAbandonValue), nomProjet: payload.nomProjetValue, localité: payload.localitéValue, - emailContact: payload.emailContactValue, + emailContact: Email.convertirEnValueType(payload.emailContactValue), evaluationCarboneSimplifiée: payload.evaluationCarboneSimplifiéeValue, nomCandidat: payload.nomCandidatValue, nomReprésentantLégal: payload.nomReprésentantLégalValue, diff --git a/packages/domain/candidature/src/lister/listerCandidatures.query.ts b/packages/domain/candidature/src/lister/listerCandidatures.query.ts index b1353f471f..d01cb28581 100644 --- a/packages/domain/candidature/src/lister/listerCandidatures.query.ts +++ b/packages/domain/candidature/src/lister/listerCandidatures.query.ts @@ -1,7 +1,7 @@ import { Message, MessageHandler, mediator } from 'mediateur'; import { List, RangeOptions, Where } from '@potentiel-domain/entity'; -import { IdentifiantProjet } from '@potentiel-domain/common'; +import { Email, IdentifiantProjet } from '@potentiel-domain/common'; import { DocumentProjet } from '@potentiel-domain/document'; import * as StatutCandidature from '../statutCandidature.valueType'; @@ -120,7 +120,7 @@ export const mapToReadModel = ({ nomProjet, nomCandidat, nomReprésentantLégal, - emailContact, + emailContact: Email.convertirEnValueType(emailContact), puissanceProductionAnnuelle, prixReference, evaluationCarboneSimplifiée, diff --git a/packages/domain/common/src/valueTypes/email.valueType.ts b/packages/domain/common/src/valueTypes/email.valueType.ts index 3d3d039757..e4e1daa8d1 100644 --- a/packages/domain/common/src/valueTypes/email.valueType.ts +++ b/packages/domain/common/src/valueTypes/email.valueType.ts @@ -22,11 +22,11 @@ export const bind = ({ email }: PlainType): ValueType => { export const convertirEnValueType = (value: string): ValueType => { return bind({ - email: value, + email: value.toLowerCase(), }); }; -const regexEmail = /^[a-zA-Z0-9.+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; +const regexEmail = /^[a-z0-9.+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9-]+)*$/; export const system = () => convertirEnValueType('system@system'); diff --git a/packages/domain/utilisateur/src/identifiantUtilisateur.valueType.ts b/packages/domain/utilisateur/src/identifiantUtilisateur.valueType.ts index 21f9950ee9..e6be57d99c 100644 --- a/packages/domain/utilisateur/src/identifiantUtilisateur.valueType.ts +++ b/packages/domain/utilisateur/src/identifiantUtilisateur.valueType.ts @@ -34,14 +34,14 @@ export const bind = ({ email }: PlainType): ValueType => { */ export const convertirEnValueType = (value: string): ValueType => { return bind({ - email: value, + email: value.toLowerCase(), }); }; /** * @deprecated Use potentiel-domain/common Email ValueType instead */ -const regexEmail = /^[a-zA-Z0-9.+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; +const regexEmail = /^[a-z0-9.+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9-]+)*$/; /** * @deprecated Use potentiel-domain/common Email ValueType instead diff --git a/packages/domain/utilisateur/src/utilisateur.valueType.ts b/packages/domain/utilisateur/src/utilisateur.valueType.ts index 9322dc8302..b1db68441c 100644 --- a/packages/domain/utilisateur/src/utilisateur.valueType.ts +++ b/packages/domain/utilisateur/src/utilisateur.valueType.ts @@ -1,13 +1,13 @@ import { PlainType, ReadonlyValueType } from '@potentiel-domain/core'; import { Option } from '@potentiel-libraries/monads'; +import { Email } from '@potentiel-domain/common'; import * as Role from './role.valueType'; import * as Groupe from './groupe.valueType'; -import * as IdentifiantUtilisateur from './identifiantUtilisateur.valueType'; export type ValueType = ReadonlyValueType<{ nom: string; - identifiantUtilisateur: IdentifiantUtilisateur.ValueType; + identifiantUtilisateur: Email.ValueType; role: Role.ValueType; groupe: Option.Type; }>; @@ -18,7 +18,7 @@ export const bind = ({ groupe, role, }: PlainType): ValueType => { - const _identifiantUtilisateur = IdentifiantUtilisateur.bind(identifiantUtilisateur); + const _identifiantUtilisateur = Email.bind(identifiantUtilisateur); return { nom, role: Role.bind(role), diff --git a/packages/specifications/src/candidature/candidature.world.ts b/packages/specifications/src/candidature/candidature.world.ts index 34d60f2f25..c8d29161da 100644 --- a/packages/specifications/src/candidature/candidature.world.ts +++ b/packages/specifications/src/candidature/candidature.world.ts @@ -1,5 +1,5 @@ import { Candidature } from '@potentiel-domain/candidature'; -import { DateTime, IdentifiantProjet } from '@potentiel-domain/common'; +import { DateTime, Email, IdentifiantProjet } from '@potentiel-domain/common'; import { DocumentProjet } from '@potentiel-domain/document'; import { CorrigerCandidatureFixture } from './fixtures/corrigerCandidature.fixture'; @@ -91,7 +91,7 @@ export class CandidatureWorld { dateÉchéanceGf: expectedValues.dateÉchéanceGfValue ? DateTime.convertirEnValueType(expectedValues.dateÉchéanceGfValue) : undefined, - emailContact: expectedValues.emailContactValue, + emailContact: Email.convertirEnValueType(expectedValues.emailContactValue), evaluationCarboneSimplifiée: expectedValues.evaluationCarboneSimplifiéeValue, historiqueAbandon: Candidature.HistoriqueAbandon.convertirEnValueType( expectedValues.historiqueAbandonValue, diff --git a/packages/specifications/src/notification/notification.world.ts b/packages/specifications/src/notification/notification.world.ts index ee008e9250..cec321fe25 100644 --- a/packages/specifications/src/notification/notification.world.ts +++ b/packages/specifications/src/notification/notification.world.ts @@ -1,6 +1,7 @@ import { assert } from 'chai'; import { EmailPayload } from '@potentiel-applications/notifications'; +import { Email } from '@potentiel-domain/common'; export class NotificationWorld { #notifications: EmailPayload[] = []; @@ -9,10 +10,11 @@ export class NotificationWorld { this.#notifications.push(notification); } - récupérerNotification(email: string, sujet?: string) { + récupérerNotification(emailValue: string, sujet?: string) { + const email = Email.convertirEnValueType(emailValue); const notif = this.#notifications.find( (notif) => - notif.recipients.find((r) => r.email === email) && + notif.recipients.find((r) => Email.convertirEnValueType(r.email).estÉgaleÀ(email)) && (!sujet || notif.messageSubject.match(new RegExp(sujet))), ); assert(notif, 'Pas de notification'); diff --git a/packages/specifications/src/utilisateur/fixtures/utilisateur.ts b/packages/specifications/src/utilisateur/fixtures/utilisateur.ts index 00f10b71bb..288b40df08 100644 --- a/packages/specifications/src/utilisateur/fixtures/utilisateur.ts +++ b/packages/specifications/src/utilisateur/fixtures/utilisateur.ts @@ -39,7 +39,7 @@ export abstract class AbstractUtilisateur implements Utilisateur { protected créer(partial?: Partial'>>>): Readonly { const utilisateur: Utilisateur = { - email: faker.internet.email(), + email: faker.internet.email().toLowerCase(), nom: faker.person.fullName(), id: faker.string.uuid(), ...partial,