Skip to content

Commit 673ba22

Browse files
committed
feat: whitelist siret domain pair
1 parent 74a2102 commit 673ba22

File tree

15 files changed

+255
-15
lines changed

15 files changed

+255
-15
lines changed

cypress/e2e/join_with_free_email_domain/fixtures.sql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@ VALUES
77
INSERT INTO organizations
88
(id, siret, created_at, updated_at)
99
VALUES
10-
(1, '19750663700010', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
10+
(1, '19750663700010', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
11+
(2, '11000201100044', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
1112

1213
INSERT INTO users_organizations
1314
(user_id, organization_id, is_external, verification_type, has_been_greeted)
1415
VALUES
1516
(1, 1, false, 'domain', true);
17+
18+
INSERT INTO email_domains
19+
(organization_id, domain, verification_type, verified_at)
20+
VALUES
21+
(2, 'finances.gouv.fr', 'verified', CURRENT_TIMESTAMP),
22+
(2, 'ext.finances.gouv.fr', 'external', CURRENT_TIMESTAMP)
23+
;

cypress/e2e/join_with_free_email_domain/index.cy.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,19 @@ describe("restrict access for", () => {
154154
"L’accès à ce site est limité aux agentes et agents possédant une adresse email d’une administration publique.",
155155
);
156156
});
157+
158+
it("ChorusPro", function () {
159+
cy.focused().clear().type("11000201100044");
160+
161+
cy.contains("Enregistrer").click();
162+
163+
cy.title().should("include", "Email non autorisé -");
164+
cy.contains("Email non autorisé");
165+
cy.contains(
166+
"Seules les adresses finances.gouv.fr peuvent rejoindre l’organisation « Services de l'etat pour la facturation electronique - Destination etat via chorus pro »..",
167+
);
168+
cy.contains(
169+
"Soyez sûrs d’utiliser le SIRET de l’organisation pour laquelle vous travaillez.",
170+
);
171+
});
157172
});

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//
2+
3+
export const DOMAINS_WHITELIST = new Map<string, string[]>([
4+
[
5+
"11000201100044", // ChorusPro siret
6+
["finances.gouv.fr"], // domains to whitelist
7+
],
8+
]);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//
2+
3+
export * from "./domains-whitelist.js";

packages/identite/src/managers/organization/mark-domain-as-verified.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export function markDomainAsVerifiedFactory({
5858

5959
return match(domain_verification_type)
6060
.with(
61-
...EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES,
61+
...EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES.options,
6262
async (approved_verification_type) => {
6363
await assignUserVerificationTypeToDomain(organization_id, domain);
6464
return markDomainAsApproved({
@@ -69,7 +69,7 @@ export function markDomainAsVerifiedFactory({
6969
},
7070
)
7171
.with(
72-
...EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES,
72+
...EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES.options,
7373
(rejected_verification_type) =>
7474
markDomainAsRejected({
7575
organization_id,
@@ -93,7 +93,7 @@ export function markDomainAsVerifiedFactory({
9393
organization_id,
9494
domain,
9595
domain_verification_types: [
96-
...EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES,
96+
...EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES.options,
9797
null,
9898
],
9999
});
@@ -118,7 +118,7 @@ export function markDomainAsVerifiedFactory({
118118
domain,
119119
domain_verification_types: [
120120
null,
121-
...EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES,
121+
...EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES.options,
122122
],
123123
});
124124
return addDomain({
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
//
2+
3+
export * from "./is-domain-allowed-for-organization.js";
14
export * from "./is-entreprise-unipersonnelle.js";
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { DOMAINS_WHITELIST } from "@gouvfr-lasuite/proconnect.identite/data/organization";
2+
3+
export function isDomainAllowedForOrganization(siret: string, domain: string) {
4+
const whitelist = DOMAINS_WHITELIST.get(siret);
5+
6+
// Allow unknown siret to ignore whitelisting
7+
if (!whitelist) return true;
8+
9+
return whitelist.includes(domain);
10+
}

packages/identite/src/types/email-domain.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
1-
export const EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES = [
1+
//
2+
3+
import { z } from "zod";
4+
5+
//
6+
7+
export const EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES = z.enum([
28
"official_contact",
39
"trackdechets_postal_mail",
410
"verified",
5-
] as const;
11+
]);
12+
13+
export type EmailDomainApprovedVerificationType = z.output<
14+
typeof EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES
15+
>;
16+
17+
//
618

7-
export const EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES = [
19+
export const EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES = z.enum([
820
"blacklisted", // unused
921
"external", // domain used by external employees (eg. ext.numerique.gouv.fr)
1022
"refused",
11-
] as const;
23+
]);
1224

13-
export type EmailDomainApprovedVerificationType =
14-
(typeof EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES)[number];
25+
export type EmailDomainRejectedVerificationType = z.output<
26+
typeof EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES
27+
>;
1528

16-
export type EmailDomainRejectedVerificationType =
17-
(typeof EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES)[number];
29+
//
1830

1931
export type EmailDomainVerificationType =
2032
| EmailDomainApprovedVerificationType
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{
2+
"data": {
3+
"siret": "11000201100044",
4+
"siege_social": true,
5+
"etat_administratif": "A",
6+
"date_fermeture": null,
7+
"enseigne": "DESTINATION ETAT VIA CHORUS PRO",
8+
"activite_principale": {
9+
"code": "84.11Z",
10+
"nomenclature": "NAFRev2",
11+
"libelle": "Administration publique générale"
12+
},
13+
"tranche_effectif_salarie": {
14+
"de": 50,
15+
"a": 99,
16+
"code": "21",
17+
"date_reference": "2022",
18+
"intitule": "50 à 99 salariés"
19+
},
20+
"diffusable_commercialement": true,
21+
"status_diffusion": "diffusible",
22+
"date_creation": 815785200,
23+
"unite_legale": {
24+
"siren": "110002011",
25+
"rna": null,
26+
"siret_siege_social": "11000201100044",
27+
"type": "personne_morale",
28+
"personne_morale_attributs": {
29+
"raison_sociale": "SERVICES DE L'ETAT POUR LA FACTURATION ELECTRONIQUE",
30+
"sigle": null
31+
},
32+
"personne_physique_attributs": {
33+
"pseudonyme": null,
34+
"prenom_usuel": null,
35+
"prenom_1": null,
36+
"prenom_2": null,
37+
"prenom_3": null,
38+
"prenom_4": null,
39+
"nom_usage": null,
40+
"nom_naissance": null,
41+
"sexe": null
42+
},
43+
"categorie_entreprise": "PME",
44+
"status_diffusion": "diffusible",
45+
"diffusable_commercialement": true,
46+
"forme_juridique": {
47+
"code": "7120",
48+
"libelle": "Service central d'un ministère"
49+
},
50+
"activite_principale": {
51+
"code": "84.11Z",
52+
"nomenclature": "NAFRev2",
53+
"libelle": "Administration publique générale"
54+
},
55+
"tranche_effectif_salarie": {
56+
"de": 50,
57+
"a": 99,
58+
"code": "21",
59+
"date_reference": "2022",
60+
"intitule": "50 à 99 salariés"
61+
},
62+
"economie_sociale_et_solidaire": false,
63+
"date_creation": 362095200,
64+
"etat_administratif": "A"
65+
},
66+
"adresse": {
67+
"status_diffusion": "diffusible",
68+
"complement_adresse": null,
69+
"numero_voie": "139",
70+
"indice_repetition_voie": null,
71+
"type_voie": "RUE",
72+
"libelle_voie": "DE BERCY",
73+
"code_postal": "75012",
74+
"libelle_commune": "PARIS",
75+
"libelle_commune_etranger": null,
76+
"distribution_speciale": null,
77+
"code_commune": "75112",
78+
"code_cedex": null,
79+
"libelle_cedex": null,
80+
"code_pays_etranger": null,
81+
"libelle_pays_etranger": null,
82+
"acheminement_postal": {
83+
"l1": "SERVICES DE L'ETAT POUR LA FACTURATION ELECTRONIQUE",
84+
"l2": "",
85+
"l3": "",
86+
"l4": "139 RUE DE BERCY",
87+
"l5": "",
88+
"l6": "75012 PARIS",
89+
"l7": "FRANCE"
90+
}
91+
}
92+
},
93+
"links": {
94+
"unite_legale": "https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/110002011"
95+
},
96+
"meta": {
97+
"date_derniere_mise_a_jour": 1737241200,
98+
"redirect_from_siret": null
99+
}
100+
}

0 commit comments

Comments
 (0)