@proconnect-gouv/proconnect.identite 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +96 -0
- package/dist/data/organization/domains-whitelist.d.ts +2 -0
- package/dist/data/organization/domains-whitelist.d.ts.map +1 -0
- package/dist/data/organization/domains-whitelist.js +7 -0
- package/dist/data/organization/index.d.ts +2 -0
- package/dist/data/organization/index.d.ts.map +1 -0
- package/dist/data/organization/index.js +2 -0
- package/dist/errors/index.d.ts +22 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +43 -0
- package/dist/managers/certification/distance.d.ts +4 -0
- package/dist/managers/certification/distance.d.ts.map +1 -0
- package/dist/managers/certification/distance.js +16 -0
- package/dist/managers/certification/index.d.ts +3 -0
- package/dist/managers/certification/index.d.ts.map +1 -0
- package/dist/managers/certification/index.js +3 -0
- package/dist/managers/certification/is-organization-dirigeant.d.ts +15 -0
- package/dist/managers/certification/is-organization-dirigeant.d.ts.map +1 -0
- package/dist/managers/certification/is-organization-dirigeant.js +60 -0
- package/dist/managers/franceconnect/index.d.ts +2 -0
- package/dist/managers/franceconnect/index.d.ts.map +1 -0
- package/dist/managers/franceconnect/index.js +2 -0
- package/dist/managers/franceconnect/openid-client.d.ts +37 -0
- package/dist/managers/franceconnect/openid-client.d.ts.map +1 -0
- package/dist/managers/franceconnect/openid-client.js +54 -0
- package/dist/managers/organization/force-join-organization.d.ts +29 -0
- package/dist/managers/organization/force-join-organization.d.ts.map +1 -0
- package/dist/managers/organization/force-join-organization.js +33 -0
- package/dist/managers/organization/get-organization-info.d.ts +5 -0
- package/dist/managers/organization/get-organization-info.d.ts.map +1 -0
- package/dist/managers/organization/get-organization-info.js +33 -0
- package/dist/managers/organization/index.d.ts +4 -0
- package/dist/managers/organization/index.d.ts.map +1 -0
- package/dist/managers/organization/index.js +4 -0
- package/dist/managers/organization/mark-domain-as-verified.d.ts +20 -0
- package/dist/managers/organization/mark-domain-as-verified.d.ts.map +1 -0
- package/dist/managers/organization/mark-domain-as-verified.js +63 -0
- package/dist/managers/user/assign-user-verification-type-to-domain.d.ts +10 -0
- package/dist/managers/user/assign-user-verification-type-to-domain.d.ts.map +1 -0
- package/dist/managers/user/assign-user-verification-type-to-domain.js +21 -0
- package/dist/managers/user/index.d.ts +2 -0
- package/dist/managers/user/index.d.ts.map +1 -0
- package/dist/managers/user/index.js +1 -0
- package/dist/mappers/certification/index.d.ts +4 -0
- package/dist/mappers/certification/index.d.ts.map +1 -0
- package/dist/mappers/certification/index.js +11 -0
- package/dist/mappers/index.d.ts +2 -0
- package/dist/mappers/index.d.ts.map +1 -0
- package/dist/mappers/index.js +2 -0
- package/dist/mappers/organization/from-siret.d.ts +5 -0
- package/dist/mappers/organization/from-siret.d.ts.map +1 -0
- package/dist/mappers/organization/from-siret.js +51 -0
- package/dist/mappers/organization/index.d.ts +2 -0
- package/dist/mappers/organization/index.d.ts.map +1 -0
- package/dist/mappers/organization/index.js +2 -0
- package/dist/repositories/email-domain/add-domain.d.ts +8 -0
- package/dist/repositories/email-domain/add-domain.d.ts.map +1 -0
- package/dist/repositories/email-domain/add-domain.js +25 -0
- package/dist/repositories/email-domain/delete-email-domains-by-verification-types.d.ts +8 -0
- package/dist/repositories/email-domain/delete-email-domains-by-verification-types.d.ts.map +1 -0
- package/dist/repositories/email-domain/delete-email-domains-by-verification-types.js +21 -0
- package/dist/repositories/email-domain/find-email-domains-by-organization-id.d.ts +4 -0
- package/dist/repositories/email-domain/find-email-domains-by-organization-id.d.ts.map +1 -0
- package/dist/repositories/email-domain/find-email-domains-by-organization-id.js +11 -0
- package/dist/repositories/email-domain/index.d.ts +12 -0
- package/dist/repositories/email-domain/index.d.ts.map +1 -0
- package/dist/repositories/email-domain/index.js +3 -0
- package/dist/repositories/organization/find-by-id.d.ts +4 -0
- package/dist/repositories/organization/find-by-id.d.ts.map +1 -0
- package/dist/repositories/organization/find-by-id.js +11 -0
- package/dist/repositories/organization/find-by-user-id.d.ts +12 -0
- package/dist/repositories/organization/find-by-user-id.d.ts.map +1 -0
- package/dist/repositories/organization/find-by-user-id.js +22 -0
- package/dist/repositories/organization/get-by-id.d.ts +4 -0
- package/dist/repositories/organization/get-by-id.d.ts.map +1 -0
- package/dist/repositories/organization/get-by-id.js +15 -0
- package/dist/repositories/organization/get-users-by-organization.d.ts +12 -0
- package/dist/repositories/organization/get-users-by-organization.d.ts.map +1 -0
- package/dist/repositories/organization/get-users-by-organization.js +23 -0
- package/dist/repositories/organization/index.d.ts +7 -0
- package/dist/repositories/organization/index.d.ts.map +1 -0
- package/dist/repositories/organization/index.js +7 -0
- package/dist/repositories/organization/link-user-to-organization.d.ts +16 -0
- package/dist/repositories/organization/link-user-to-organization.d.ts.map +1 -0
- package/dist/repositories/organization/link-user-to-organization.js +22 -0
- package/dist/repositories/organization/upsert.d.ts +7 -0
- package/dist/repositories/organization/upsert.d.ts.map +1 -0
- package/dist/repositories/organization/upsert.js +103 -0
- package/dist/repositories/user/create.d.ts +7 -0
- package/dist/repositories/user/create.d.ts.map +1 -0
- package/dist/repositories/user/create.js +25 -0
- package/dist/repositories/user/find-by-email.d.ts +4 -0
- package/dist/repositories/user/find-by-email.d.ts.map +1 -0
- package/dist/repositories/user/find-by-email.js +12 -0
- package/dist/repositories/user/find-by-id.d.ts +4 -0
- package/dist/repositories/user/find-by-id.d.ts.map +1 -0
- package/dist/repositories/user/find-by-id.js +13 -0
- package/dist/repositories/user/get-by-id.d.ts +4 -0
- package/dist/repositories/user/get-by-id.d.ts.map +1 -0
- package/dist/repositories/user/get-by-id.js +15 -0
- package/dist/repositories/user/get-franceconnect-user-info.d.ts +15 -0
- package/dist/repositories/user/get-franceconnect-user-info.d.ts.map +1 -0
- package/dist/repositories/user/get-franceconnect-user-info.js +13 -0
- package/dist/repositories/user/index.d.ts +9 -0
- package/dist/repositories/user/index.d.ts.map +1 -0
- package/dist/repositories/user/index.js +9 -0
- package/dist/repositories/user/update-user-organization-link.d.ts +16 -0
- package/dist/repositories/user/update-user-organization-link.d.ts.map +1 -0
- package/dist/repositories/user/update-user-organization-link.js +20 -0
- package/dist/repositories/user/update.d.ts +4 -0
- package/dist/repositories/user/update.d.ts.map +1 -0
- package/dist/repositories/user/update.js +19 -0
- package/dist/repositories/user/upsert-franceconnect-userinfo.d.ts +15 -0
- package/dist/repositories/user/upsert-franceconnect-userinfo.d.ts.map +1 -0
- package/dist/repositories/user/upsert-franceconnect-userinfo.js +23 -0
- package/dist/services/organization/index.d.ts +3 -0
- package/dist/services/organization/index.d.ts.map +1 -0
- package/dist/services/organization/index.js +3 -0
- package/dist/services/organization/is-domain-allowed-for-organization.d.ts +2 -0
- package/dist/services/organization/is-domain-allowed-for-organization.d.ts.map +1 -0
- package/dist/services/organization/is-domain-allowed-for-organization.js +8 -0
- package/dist/services/organization/is-entreprise-unipersonnelle.d.ts +9 -0
- package/dist/services/organization/is-entreprise-unipersonnelle.d.ts.map +1 -0
- package/dist/services/organization/is-entreprise-unipersonnelle.js +18 -0
- package/dist/services/postgres/hash-to-postgres-params.d.ts +6 -0
- package/dist/services/postgres/hash-to-postgres-params.d.ts.map +1 -0
- package/dist/services/postgres/hash-to-postgres-params.js +21 -0
- package/dist/services/postgres/index.d.ts +2 -0
- package/dist/services/postgres/index.d.ts.map +1 -0
- package/dist/services/postgres/index.js +2 -0
- package/dist/types/claims.d.ts +16 -0
- package/dist/types/claims.d.ts.map +1 -0
- package/dist/types/claims.js +16 -0
- package/dist/types/contexts.d.ts +5 -0
- package/dist/types/contexts.d.ts.map +1 -0
- package/dist/types/contexts.js +2 -0
- package/dist/types/dirigeant.d.ts +9 -0
- package/dist/types/dirigeant.d.ts.map +1 -0
- package/dist/types/dirigeant.js +9 -0
- package/dist/types/email-domain.d.ts +25 -0
- package/dist/types/email-domain.d.ts.map +1 -0
- package/dist/types/email-domain.js +14 -0
- package/dist/types/franceconnect.d.ts +28 -0
- package/dist/types/franceconnect.d.ts.map +1 -0
- package/dist/types/franceconnect.js +22 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/organization-info.d.ts +27 -0
- package/dist/types/organization-info.d.ts.map +1 -0
- package/dist/types/organization-info.js +26 -0
- package/dist/types/organization.d.ts +26 -0
- package/dist/types/organization.d.ts.map +1 -0
- package/dist/types/organization.js +2 -0
- package/dist/types/user-organization-link.d.ts +92 -0
- package/dist/types/user-organization-link.d.ts.map +1 -0
- package/dist/types/user-organization-link.js +44 -0
- package/dist/types/user.d.ts +28 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +2 -0
- package/package.json +68 -0
- package/src/data/organization/domains-whitelist.ts +8 -0
- package/src/data/organization/index.ts +3 -0
- package/src/errors/index.ts +50 -0
- package/src/managers/certification/distance.test.ts +109 -0
- package/src/managers/certification/distance.ts +41 -0
- package/src/managers/certification/index.ts +4 -0
- package/src/managers/certification/is-organization-dirigeant.test.ts +125 -0
- package/src/managers/certification/is-organization-dirigeant.ts +136 -0
- package/src/managers/franceconnect/index.ts +3 -0
- package/src/managers/franceconnect/openid-client.ts +131 -0
- package/src/managers/organization/force-join-organization.test.ts +94 -0
- package/src/managers/organization/force-join-organization.ts +90 -0
- package/src/managers/organization/get-organization-info.test.ts +47 -0
- package/src/managers/organization/get-organization-info.test.ts.snapshot +68 -0
- package/src/managers/organization/get-organization-info.ts +58 -0
- package/src/managers/organization/index.ts +5 -0
- package/src/managers/organization/mark-domain-as-verified.test.ts +90 -0
- package/src/managers/organization/mark-domain-as-verified.test.ts.snapshot +52 -0
- package/src/managers/organization/mark-domain-as-verified.ts +140 -0
- package/src/managers/user/assign-user-verification-type-to-domain.ts +50 -0
- package/src/managers/user/index.ts +1 -0
- package/src/mappers/certification/index.ts +18 -0
- package/src/mappers/index.ts +3 -0
- package/src/mappers/organization/from-siret.test.ts +26 -0
- package/src/mappers/organization/from-siret.test.ts.snapshot +68 -0
- package/src/mappers/organization/from-siret.ts +75 -0
- package/src/mappers/organization/index.ts +3 -0
- package/src/repositories/email-domain/add-domain.test.ts +43 -0
- package/src/repositories/email-domain/add-domain.ts +48 -0
- package/src/repositories/email-domain/delete-email-domains-by-verification-types.test.ts +49 -0
- package/src/repositories/email-domain/delete-email-domains-by-verification-types.ts +45 -0
- package/src/repositories/email-domain/find-email-domains-by-organization-id.test.ts +55 -0
- package/src/repositories/email-domain/find-email-domains-by-organization-id.ts +28 -0
- package/src/repositories/email-domain/index.ts +13 -0
- package/src/repositories/organization/find-by-id.test.ts +51 -0
- package/src/repositories/organization/find-by-id.ts +22 -0
- package/src/repositories/organization/find-by-user-id.test.ts +70 -0
- package/src/repositories/organization/find-by-user-id.test.ts.snapshot +102 -0
- package/src/repositories/organization/find-by-user-id.ts +38 -0
- package/src/repositories/organization/get-by-id.test.ts +60 -0
- package/src/repositories/organization/get-by-id.ts +21 -0
- package/src/repositories/organization/get-users-by-organization.test.ts +50 -0
- package/src/repositories/organization/get-users-by-organization.test.ts.snapshot +38 -0
- package/src/repositories/organization/get-users-by-organization.ts +46 -0
- package/src/repositories/organization/index.ts +8 -0
- package/src/repositories/organization/link-user-to-organization.test.ts +65 -0
- package/src/repositories/organization/link-user-to-organization.test.ts.snapshot +31 -0
- package/src/repositories/organization/link-user-to-organization.ts +45 -0
- package/src/repositories/organization/upsert.ts +142 -0
- package/src/repositories/organization/upset.test.ts +95 -0
- package/src/repositories/user/create.test.ts +49 -0
- package/src/repositories/user/create.ts +44 -0
- package/src/repositories/user/find-by-email.test.ts +62 -0
- package/src/repositories/user/find-by-email.ts +22 -0
- package/src/repositories/user/find-by-id.test.ts +64 -0
- package/src/repositories/user/find-by-id.ts +23 -0
- package/src/repositories/user/get-by-id.test.ts +63 -0
- package/src/repositories/user/get-by-id.ts +21 -0
- package/src/repositories/user/get-franceconnect-user-info.test.ts +58 -0
- package/src/repositories/user/get-franceconnect-user-info.ts +25 -0
- package/src/repositories/user/index.ts +10 -0
- package/src/repositories/user/update-user-organization-link.test.ts +46 -0
- package/src/repositories/user/update-user-organization-link.ts +42 -0
- package/src/repositories/user/update.test.ts +26 -0
- package/src/repositories/user/update.ts +34 -0
- package/src/repositories/user/upsert-franceconnect-userinfo.test.ts +100 -0
- package/src/repositories/user/upsert-franceconnect-userinfo.ts +41 -0
- package/src/services/organization/index.ts +4 -0
- package/src/services/organization/is-domain-allowed-for-organization.ts +10 -0
- package/src/services/organization/is-entreprise-unipersonnelle.test.ts +32 -0
- package/src/services/organization/is-entreprise-unipersonnelle.ts +31 -0
- package/src/services/postgres/hash-to-postgres-params.ts +34 -0
- package/src/services/postgres/index.ts +3 -0
- package/src/types/claims.ts +21 -0
- package/src/types/contexts.ts +9 -0
- package/src/types/dirigeant.ts +13 -0
- package/src/types/email-domain.ts +48 -0
- package/src/types/franceconnect.ts +37 -0
- package/src/types/index.ts +11 -0
- package/src/types/organization-info.ts +32 -0
- package/src/types/organization.ts +30 -0
- package/src/types/user-organization-link.ts +71 -0
- package/src/types/user.ts +29 -0
- package/testing/index.ts +31 -0
- package/testing/seed/franceconnect/index.ts +40 -0
- package/testing/seed/insee/index.ts +22 -0
- package/testing/seed/mandataires/index.ts +32 -0
- package/testing/seed/organizations/index.ts +41 -0
- package/tsconfig.json +17 -0
- package/tsconfig.lib.json +9 -0
- package/tsconfig.lib.tsbuildinfo +1 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { NotFoundError } from "#src/errors";
|
|
4
|
+
import {
|
|
5
|
+
LiElJonsonFranceConnectUserInfo,
|
|
6
|
+
RogalDornFranceConnectUserInfo,
|
|
7
|
+
} from "#testing/seed/franceconnect";
|
|
8
|
+
import {
|
|
9
|
+
LiElJonsonEstablishment,
|
|
10
|
+
RogalDornEstablishment,
|
|
11
|
+
} from "#testing/seed/insee";
|
|
12
|
+
import { UlysseToriMandataire } from "#testing/seed/mandataires";
|
|
13
|
+
import {
|
|
14
|
+
Papillon,
|
|
15
|
+
RogalDornEntrepreneur as RogalDornSireneEntrepreneur,
|
|
16
|
+
} from "@proconnect-gouv/proconnect.entreprise/testing/seed/insee/siret";
|
|
17
|
+
import assert from "node:assert/strict";
|
|
18
|
+
import { describe, it } from "node:test";
|
|
19
|
+
import { isOrganizationDirigeantFactory } from "./is-organization-dirigeant.js";
|
|
20
|
+
|
|
21
|
+
//
|
|
22
|
+
|
|
23
|
+
describe("isOrganizationDirigeantFactory", () => {
|
|
24
|
+
it("should recognize a user as executive of a auto-entrepreneur", async () => {
|
|
25
|
+
const isOrganizationDirigeant = isOrganizationDirigeantFactory({
|
|
26
|
+
EntrepriseApiInfogreffeRepository: {
|
|
27
|
+
findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
|
|
28
|
+
},
|
|
29
|
+
EntrepriseApiInseeRepository: {
|
|
30
|
+
findBySiret: () => Promise.resolve(RogalDornSireneEntrepreneur),
|
|
31
|
+
},
|
|
32
|
+
InseeApiRepository: {
|
|
33
|
+
findBySiret: () => Promise.resolve(RogalDornEstablishment),
|
|
34
|
+
},
|
|
35
|
+
getFranceConnectUserInfo: () =>
|
|
36
|
+
Promise.resolve(RogalDornFranceConnectUserInfo),
|
|
37
|
+
});
|
|
38
|
+
const isDirigeant = await isOrganizationDirigeant(
|
|
39
|
+
RogalDornSireneEntrepreneur.siret,
|
|
40
|
+
1,
|
|
41
|
+
);
|
|
42
|
+
assert.equal(isDirigeant, true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should not match another mandataire", async () => {
|
|
46
|
+
const isOrganizationDirigeant = isOrganizationDirigeantFactory({
|
|
47
|
+
EntrepriseApiInfogreffeRepository: {
|
|
48
|
+
findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
|
|
49
|
+
},
|
|
50
|
+
EntrepriseApiInseeRepository: {
|
|
51
|
+
findBySiret: () => Promise.resolve(RogalDornSireneEntrepreneur),
|
|
52
|
+
},
|
|
53
|
+
InseeApiRepository: {
|
|
54
|
+
findBySiret: () => Promise.resolve(LiElJonsonEstablishment),
|
|
55
|
+
},
|
|
56
|
+
getFranceConnectUserInfo: () =>
|
|
57
|
+
Promise.resolve(RogalDornFranceConnectUserInfo),
|
|
58
|
+
});
|
|
59
|
+
const isDirigeant = await isOrganizationDirigeant(
|
|
60
|
+
RogalDornSireneEntrepreneur.siret,
|
|
61
|
+
1,
|
|
62
|
+
);
|
|
63
|
+
assert.equal(isDirigeant, false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("should match Ulysse Tori as an executive of Papillon", async () => {
|
|
67
|
+
const isOrganizationDirigeant = isOrganizationDirigeantFactory({
|
|
68
|
+
EntrepriseApiInfogreffeRepository: {
|
|
69
|
+
findMandatairesSociauxBySiren: () =>
|
|
70
|
+
Promise.resolve([UlysseToriMandataire]),
|
|
71
|
+
},
|
|
72
|
+
EntrepriseApiInseeRepository: {
|
|
73
|
+
findBySiret: () => Promise.resolve(Papillon),
|
|
74
|
+
},
|
|
75
|
+
InseeApiRepository: {
|
|
76
|
+
findBySiret: () => Promise.reject(new Error("💣")),
|
|
77
|
+
},
|
|
78
|
+
getFranceConnectUserInfo: () =>
|
|
79
|
+
Promise.resolve(RogalDornFranceConnectUserInfo),
|
|
80
|
+
});
|
|
81
|
+
const isDirigeant = await isOrganizationDirigeant(Papillon.siret, 1);
|
|
82
|
+
assert.equal(isDirigeant, false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("❎ fail with no franceconnect user info", async () => {
|
|
86
|
+
const isOrganizationDirigeant = isOrganizationDirigeantFactory({
|
|
87
|
+
EntrepriseApiInfogreffeRepository: {
|
|
88
|
+
findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
|
|
89
|
+
},
|
|
90
|
+
EntrepriseApiInseeRepository: {
|
|
91
|
+
findBySiret: () => Promise.resolve(RogalDornSireneEntrepreneur),
|
|
92
|
+
},
|
|
93
|
+
InseeApiRepository: {
|
|
94
|
+
findBySiret: () => Promise.reject(new Error("💣")),
|
|
95
|
+
},
|
|
96
|
+
getFranceConnectUserInfo: () => Promise.resolve(undefined),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
await assert.rejects(
|
|
100
|
+
isOrganizationDirigeant("94957325700019", 1),
|
|
101
|
+
new NotFoundError("FranceConnect UserInfo not found"),
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("❎ fail with no mandataires", async () => {
|
|
106
|
+
const isOrganizationDirigeant = isOrganizationDirigeantFactory({
|
|
107
|
+
EntrepriseApiInfogreffeRepository: {
|
|
108
|
+
findMandatairesSociauxBySiren: () => Promise.resolve([]),
|
|
109
|
+
},
|
|
110
|
+
EntrepriseApiInseeRepository: {
|
|
111
|
+
findBySiret: () => Promise.resolve(Papillon),
|
|
112
|
+
},
|
|
113
|
+
InseeApiRepository: {
|
|
114
|
+
findBySiret: () => Promise.reject(new Error("💣")),
|
|
115
|
+
},
|
|
116
|
+
getFranceConnectUserInfo: () =>
|
|
117
|
+
Promise.resolve(LiElJonsonFranceConnectUserInfo),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await assert.rejects(
|
|
121
|
+
isOrganizationDirigeant(Papillon.siret, 1),
|
|
122
|
+
new NotFoundError("No mandataires found"),
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { NotFoundError } from "#src/errors";
|
|
4
|
+
import { fromInfogreffe } from "#src/mappers/certification";
|
|
5
|
+
import { fromSiret } from "#src/mappers/organization";
|
|
6
|
+
import type { GetFranceConnectUserInfoHandler } from "#src/repositories/user";
|
|
7
|
+
import { isEntrepriseUnipersonnelle } from "#src/services/organization";
|
|
8
|
+
import type { IdentityVector } from "#src/types";
|
|
9
|
+
import type {
|
|
10
|
+
EntrepriseApiInfogreffeRepository,
|
|
11
|
+
EntrepriseApiInseeRepository,
|
|
12
|
+
} from "@proconnect-gouv/proconnect.entreprise/api";
|
|
13
|
+
import type { InseeSireneEstablishmentSiretResponseData } from "@proconnect-gouv/proconnect.entreprise/types";
|
|
14
|
+
import type { InseeApiRepository } from "@proconnect-gouv/proconnect.insee/api";
|
|
15
|
+
import { formatBirthdate } from "@proconnect-gouv/proconnect.insee/formatters";
|
|
16
|
+
import { distance } from "./distance.js";
|
|
17
|
+
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
type IsOrganizationExecutiveFactoryFactoryConfig = {
|
|
21
|
+
EntrepriseApiInfogreffeRepository: EntrepriseApiInfogreffeRepository;
|
|
22
|
+
EntrepriseApiInseeRepository: Pick<
|
|
23
|
+
EntrepriseApiInseeRepository,
|
|
24
|
+
"findBySiret"
|
|
25
|
+
>;
|
|
26
|
+
EQUALITY_THRESHOLD?: number;
|
|
27
|
+
getFranceConnectUserInfo: GetFranceConnectUserInfoHandler;
|
|
28
|
+
InseeApiRepository: Pick<InseeApiRepository, "findBySiret">;
|
|
29
|
+
log?: typeof console.log;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//
|
|
33
|
+
|
|
34
|
+
export function isOrganizationDirigeantFactory(
|
|
35
|
+
config: IsOrganizationExecutiveFactoryFactoryConfig,
|
|
36
|
+
) {
|
|
37
|
+
const {
|
|
38
|
+
EQUALITY_THRESHOLD = 0,
|
|
39
|
+
EntrepriseApiInseeRepository,
|
|
40
|
+
EntrepriseApiInfogreffeRepository,
|
|
41
|
+
InseeApiRepository,
|
|
42
|
+
getFranceConnectUserInfo,
|
|
43
|
+
log = () => {},
|
|
44
|
+
} = config;
|
|
45
|
+
|
|
46
|
+
return async function isOrganizationDirigeant(
|
|
47
|
+
siret: string,
|
|
48
|
+
user_id: number,
|
|
49
|
+
) {
|
|
50
|
+
const establishment = await EntrepriseApiInseeRepository.findBySiret(siret);
|
|
51
|
+
const franceconnectUserInfo = await getFranceConnectUserInfo(user_id);
|
|
52
|
+
if (!franceconnectUserInfo) {
|
|
53
|
+
throw new NotFoundError("FranceConnect UserInfo not found");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const sourceDirigeants =
|
|
57
|
+
await getSourceDirigeantsFromEstablishment(establishment);
|
|
58
|
+
|
|
59
|
+
if (sourceDirigeants.length === 0) {
|
|
60
|
+
throw new NotFoundError("No mandataires found");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const distances = sourceDirigeants.map((sourceDirigeant) =>
|
|
64
|
+
Math.abs(distance(franceconnectUserInfo, sourceDirigeant)),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const closestSourceDirigeantDistance = Math.min(...distances);
|
|
68
|
+
const closestSourceDirigeant =
|
|
69
|
+
sourceDirigeants[distances.indexOf(closestSourceDirigeantDistance)];
|
|
70
|
+
|
|
71
|
+
log(
|
|
72
|
+
closestSourceDirigeant,
|
|
73
|
+
" is the closest source dirigeant to ",
|
|
74
|
+
franceconnectUserInfo,
|
|
75
|
+
" with a distance of ",
|
|
76
|
+
closestSourceDirigeantDistance,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return closestSourceDirigeantDistance === EQUALITY_THRESHOLD;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
async function getSourceDirigeantsFromEstablishment(
|
|
83
|
+
establishment: InseeSireneEstablishmentSiretResponseData,
|
|
84
|
+
): Promise<IdentityVector[]> {
|
|
85
|
+
const organization = fromSiret(establishment);
|
|
86
|
+
|
|
87
|
+
if (
|
|
88
|
+
isEntrepriseUnipersonnelle({
|
|
89
|
+
cached_libelle_categorie_juridique:
|
|
90
|
+
organization.libelleCategorieJuridique,
|
|
91
|
+
cached_tranche_effectifs: organization.trancheEffectifs,
|
|
92
|
+
})
|
|
93
|
+
) {
|
|
94
|
+
return getSourceDirigeantsFromInsseApi(establishment.siret);
|
|
95
|
+
}
|
|
96
|
+
return getSourceDirigeantsFromEntrepriseApi(
|
|
97
|
+
establishment.unite_legale.siren,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function getSourceDirigeantsFromInsseApi(siret: string) {
|
|
102
|
+
const { uniteLegale } = await InseeApiRepository.findBySiret(siret);
|
|
103
|
+
const birthdate = formatBirthdate(
|
|
104
|
+
String(uniteLegale?.dateNaissanceUniteLegale),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return [
|
|
108
|
+
{
|
|
109
|
+
birthplace: uniteLegale?.codeCommuneNaissanceUniteLegale ?? null,
|
|
110
|
+
birthdate: isNaN(birthdate.getTime()) ? null : birthdate,
|
|
111
|
+
family_name: uniteLegale?.nomUniteLegale ?? null,
|
|
112
|
+
given_name: [
|
|
113
|
+
uniteLegale?.prenom1UniteLegale,
|
|
114
|
+
uniteLegale?.prenom2UniteLegale,
|
|
115
|
+
uniteLegale?.prenom3UniteLegale,
|
|
116
|
+
uniteLegale?.prenom4UniteLegale,
|
|
117
|
+
]
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.join(" "),
|
|
120
|
+
} satisfies IdentityVector,
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function getSourceDirigeantsFromEntrepriseApi(siren: string) {
|
|
125
|
+
const mandataires =
|
|
126
|
+
await EntrepriseApiInfogreffeRepository.findMandatairesSociauxBySiren(
|
|
127
|
+
siren,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return mandataires.map((mandataire) => fromInfogreffe(mandataire));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type IsOrganizationDirigeantHandler = ReturnType<
|
|
135
|
+
typeof isOrganizationDirigeantFactory
|
|
136
|
+
>;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
FranceConnectUserInfoResponseSchema,
|
|
5
|
+
type FranceConnectUserInfoResponse,
|
|
6
|
+
} from "#src/types";
|
|
7
|
+
import {
|
|
8
|
+
allowInsecureRequests,
|
|
9
|
+
authorizationCodeGrant,
|
|
10
|
+
buildAuthorizationUrl,
|
|
11
|
+
buildEndSessionUrl,
|
|
12
|
+
ClientSecretBasic,
|
|
13
|
+
discovery,
|
|
14
|
+
fetchUserInfo,
|
|
15
|
+
randomNonce,
|
|
16
|
+
randomState,
|
|
17
|
+
type ClientMetadata,
|
|
18
|
+
} from "openid-client";
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
|
|
21
|
+
//
|
|
22
|
+
|
|
23
|
+
export type FranceConnectConfigurationParams = {
|
|
24
|
+
allowLocalhost?: boolean;
|
|
25
|
+
clientId: string;
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
metadata: Partial<ClientMetadata>;
|
|
28
|
+
server: URL;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function getFranceConnectConfigurationFactory(
|
|
32
|
+
params: FranceConnectConfigurationParams,
|
|
33
|
+
) {
|
|
34
|
+
const { allowLocalhost, clientId, clientSecret, metadata, server } = params;
|
|
35
|
+
return function getFranceConnectConfiguration() {
|
|
36
|
+
return discovery(
|
|
37
|
+
server,
|
|
38
|
+
clientId,
|
|
39
|
+
metadata,
|
|
40
|
+
ClientSecretBasic(clientSecret),
|
|
41
|
+
allowLocalhost ? { execute: [allowInsecureRequests] } : undefined,
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type GetFranceConnectConfigurationHandler = ReturnType<
|
|
47
|
+
typeof getFranceConnectConfigurationFactory
|
|
48
|
+
>;
|
|
49
|
+
|
|
50
|
+
export function createOidcChecks() {
|
|
51
|
+
return {
|
|
52
|
+
state: randomState(),
|
|
53
|
+
nonce: randomNonce(),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function getFranceConnectRedirectUrlFactory(
|
|
58
|
+
getConfiguration: GetFranceConnectConfigurationHandler,
|
|
59
|
+
parameters: {
|
|
60
|
+
callbackUrl: string;
|
|
61
|
+
scope: string;
|
|
62
|
+
},
|
|
63
|
+
) {
|
|
64
|
+
const { callbackUrl, scope } = parameters;
|
|
65
|
+
return async function getFranceConnectUser(nonce: string, state: string) {
|
|
66
|
+
const config = await getConfiguration();
|
|
67
|
+
return buildAuthorizationUrl(
|
|
68
|
+
config,
|
|
69
|
+
new URLSearchParams({
|
|
70
|
+
acr_values: "eidas1",
|
|
71
|
+
nonce,
|
|
72
|
+
redirect_uri: callbackUrl,
|
|
73
|
+
scope,
|
|
74
|
+
state,
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function getFranceConnectUserFactory(
|
|
81
|
+
getConfiguration: GetFranceConnectConfigurationHandler,
|
|
82
|
+
) {
|
|
83
|
+
return async function getFranceConnectUser(parameters: {
|
|
84
|
+
code: string;
|
|
85
|
+
currentUrl: URL;
|
|
86
|
+
expectedNonce: string;
|
|
87
|
+
expectedState: string;
|
|
88
|
+
}) {
|
|
89
|
+
const { code, currentUrl, expectedNonce, expectedState } = parameters;
|
|
90
|
+
const config = await getConfiguration();
|
|
91
|
+
const tokens = await authorizationCodeGrant(
|
|
92
|
+
config,
|
|
93
|
+
currentUrl,
|
|
94
|
+
{
|
|
95
|
+
expectedNonce,
|
|
96
|
+
expectedState,
|
|
97
|
+
},
|
|
98
|
+
{ code },
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const claims = tokens.claims();
|
|
102
|
+
|
|
103
|
+
const { sub } = await z.object({ sub: z.string() }).parseAsync(claims);
|
|
104
|
+
const user_info_response = await fetchUserInfo(
|
|
105
|
+
config,
|
|
106
|
+
tokens.access_token,
|
|
107
|
+
sub,
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const user_info: FranceConnectUserInfoResponse =
|
|
111
|
+
await FranceConnectUserInfoResponseSchema.parseAsync(user_info_response);
|
|
112
|
+
return { user_info, id_token: tokens.id_token };
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function getFranceConnectLogoutRedirectUrlFactory(
|
|
117
|
+
getConfiguration: GetFranceConnectConfigurationHandler,
|
|
118
|
+
) {
|
|
119
|
+
return async function getFranceConnectLogoutRedirectUrl(
|
|
120
|
+
id_token_hint: string,
|
|
121
|
+
post_logout_redirect_uri: string,
|
|
122
|
+
state: string,
|
|
123
|
+
) {
|
|
124
|
+
const config = await getConfiguration();
|
|
125
|
+
return buildEndSessionUrl(config, {
|
|
126
|
+
id_token_hint,
|
|
127
|
+
post_logout_redirect_uri,
|
|
128
|
+
state,
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { NotFoundError } from "#src/errors";
|
|
2
|
+
import type { Organization, User } from "#src/types";
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { suite, test } from "node:test";
|
|
5
|
+
import type { EmailDomain } from "../../types/index.js";
|
|
6
|
+
import { forceJoinOrganizationFactory } from "./force-join-organization.js";
|
|
7
|
+
|
|
8
|
+
suite("forceJoinOrganizationFactory", () => {
|
|
9
|
+
test("should update the organization user link ", async () => {
|
|
10
|
+
const forceJoinOrganization = forceJoinOrganizationFactory({
|
|
11
|
+
findEmailDomainsByOrganizationId: () => Promise.resolve([]),
|
|
12
|
+
getById: () => Promise.resolve({ id: 42 } as Organization),
|
|
13
|
+
getUserById: () =>
|
|
14
|
+
Promise.resolve({ email: "lion.eljonson@darkangels.world" } as User),
|
|
15
|
+
linkUserToOrganization: (values) => Promise.resolve(values as any),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
assert.deepEqual(
|
|
19
|
+
await forceJoinOrganization({
|
|
20
|
+
organization_id: 42,
|
|
21
|
+
user_id: 42,
|
|
22
|
+
}),
|
|
23
|
+
{
|
|
24
|
+
is_external: false,
|
|
25
|
+
organization_id: 42,
|
|
26
|
+
user_id: 42,
|
|
27
|
+
verification_type: "no_validation_means_available",
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("should update the organization user link with domain verification ", async () => {
|
|
33
|
+
const forceJoinOrganization = forceJoinOrganizationFactory({
|
|
34
|
+
findEmailDomainsByOrganizationId: () =>
|
|
35
|
+
Promise.resolve([
|
|
36
|
+
{
|
|
37
|
+
domain: "darkangels.world",
|
|
38
|
+
verification_type: "verified",
|
|
39
|
+
} as EmailDomain,
|
|
40
|
+
]),
|
|
41
|
+
getById: () => Promise.resolve({ id: 42 } as Organization),
|
|
42
|
+
getUserById: () =>
|
|
43
|
+
Promise.resolve({ email: "lion.eljonson@darkangels.world" } as User),
|
|
44
|
+
linkUserToOrganization: (values) => Promise.resolve(values as any),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
assert.deepEqual(
|
|
48
|
+
await forceJoinOrganization({
|
|
49
|
+
organization_id: 42,
|
|
50
|
+
user_id: 42,
|
|
51
|
+
}),
|
|
52
|
+
{
|
|
53
|
+
is_external: false,
|
|
54
|
+
organization_id: 42,
|
|
55
|
+
user_id: 42,
|
|
56
|
+
verification_type: "domain",
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("❎ throws NotFoundError for unknown organization", async () => {
|
|
62
|
+
const forceJoinOrganization = forceJoinOrganizationFactory({
|
|
63
|
+
findEmailDomainsByOrganizationId: () => Promise.resolve([]),
|
|
64
|
+
getById: () => Promise.reject(new NotFoundError("💣")),
|
|
65
|
+
getUserById: () => Promise.resolve({ id: 42 } as User),
|
|
66
|
+
linkUserToOrganization: () => Promise.reject(),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await assert.rejects(
|
|
70
|
+
forceJoinOrganization({
|
|
71
|
+
organization_id: 42,
|
|
72
|
+
user_id: 42,
|
|
73
|
+
}),
|
|
74
|
+
new NotFoundError("💣"),
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("❎ throws NotFoundError for unknown user", async () => {
|
|
79
|
+
const forceJoinOrganization = forceJoinOrganizationFactory({
|
|
80
|
+
findEmailDomainsByOrganizationId: () => Promise.resolve([]),
|
|
81
|
+
getById: () => Promise.resolve({ id: 42 } as Organization),
|
|
82
|
+
getUserById: () => Promise.reject(new NotFoundError("💣")),
|
|
83
|
+
linkUserToOrganization: () => Promise.reject(),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await assert.rejects(
|
|
87
|
+
forceJoinOrganization({
|
|
88
|
+
organization_id: 42,
|
|
89
|
+
user_id: 42,
|
|
90
|
+
}),
|
|
91
|
+
new NotFoundError("💣"),
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import type { FindEmailDomainsByOrganizationIdHandler } from "#src/repositories/email-domain";
|
|
4
|
+
import type {
|
|
5
|
+
GetByIdHandler as GetOrganizationByIdHandler,
|
|
6
|
+
LinkUserToOrganizationHandler,
|
|
7
|
+
} from "#src/repositories/organization";
|
|
8
|
+
import type { GetByIdHandler as GetUserByIdHandler } from "#src/repositories/user";
|
|
9
|
+
import type { BaseUserOrganizationLink } from "#src/types";
|
|
10
|
+
import { getEmailDomain } from "@proconnect-gouv/proconnect.core/services/email";
|
|
11
|
+
import { match } from "ts-pattern";
|
|
12
|
+
import { UserOrganizationLinkVerificationTypeSchema } from "../../types/index.js";
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
type FactoryDependencies = {
|
|
17
|
+
findEmailDomainsByOrganizationId: FindEmailDomainsByOrganizationIdHandler;
|
|
18
|
+
getById: GetOrganizationByIdHandler;
|
|
19
|
+
getUserById: GetUserByIdHandler;
|
|
20
|
+
linkUserToOrganization: LinkUserToOrganizationHandler;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
|
|
25
|
+
export function forceJoinOrganizationFactory({
|
|
26
|
+
findEmailDomainsByOrganizationId,
|
|
27
|
+
getById,
|
|
28
|
+
getUserById,
|
|
29
|
+
linkUserToOrganization,
|
|
30
|
+
}: FactoryDependencies) {
|
|
31
|
+
return async function forceJoinOrganization({
|
|
32
|
+
organization_id,
|
|
33
|
+
user_id,
|
|
34
|
+
is_external = false,
|
|
35
|
+
}: {
|
|
36
|
+
organization_id: number;
|
|
37
|
+
user_id: number;
|
|
38
|
+
is_external?: boolean;
|
|
39
|
+
}) {
|
|
40
|
+
const user = await getUserById(user_id);
|
|
41
|
+
|
|
42
|
+
// Ensure that the organization exists (Ceinture Bretelle)
|
|
43
|
+
await getById(organization_id);
|
|
44
|
+
|
|
45
|
+
const { email } = user;
|
|
46
|
+
const domain = getEmailDomain(email);
|
|
47
|
+
const organizationEmailDomains =
|
|
48
|
+
await findEmailDomainsByOrganizationId(organization_id);
|
|
49
|
+
|
|
50
|
+
const link_verification_type = organizationEmailDomains
|
|
51
|
+
.filter(({ domain: currentDomain }) => currentDomain === domain)
|
|
52
|
+
.reduce(
|
|
53
|
+
(acc, { verification_type }) => {
|
|
54
|
+
if (acc === "domain") {
|
|
55
|
+
return acc;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return match(verification_type)
|
|
59
|
+
.with(
|
|
60
|
+
"verified",
|
|
61
|
+
"trackdechets_postal_mail",
|
|
62
|
+
"external",
|
|
63
|
+
"official_contact",
|
|
64
|
+
() => UserOrganizationLinkVerificationTypeSchema.enum.domain,
|
|
65
|
+
)
|
|
66
|
+
.with(
|
|
67
|
+
null,
|
|
68
|
+
"blacklisted",
|
|
69
|
+
"refused",
|
|
70
|
+
() =>
|
|
71
|
+
UserOrganizationLinkVerificationTypeSchema.enum
|
|
72
|
+
.no_validation_means_available,
|
|
73
|
+
)
|
|
74
|
+
.exhaustive();
|
|
75
|
+
},
|
|
76
|
+
"no_validation_means_available" as BaseUserOrganizationLink["verification_type"],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return await linkUserToOrganization({
|
|
80
|
+
organization_id,
|
|
81
|
+
user_id,
|
|
82
|
+
is_external,
|
|
83
|
+
verification_type: link_verification_type,
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type ForceJoinOrganizationHandler = ReturnType<
|
|
89
|
+
typeof forceJoinOrganizationFactory
|
|
90
|
+
>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { NotFoundError } from "#src/errors";
|
|
2
|
+
import {
|
|
3
|
+
CommunautéDeCommunes,
|
|
4
|
+
RogalDornEntrepreneur,
|
|
5
|
+
} from "@proconnect-gouv/proconnect.entreprise/testing/seed/insee/siret";
|
|
6
|
+
import type { InseeSireneEstablishmentSiretResponseData } from "@proconnect-gouv/proconnect.entreprise/types";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { suite, test } from "node:test";
|
|
9
|
+
import { getOrganizationInfoFactory } from "./get-organization-info.js";
|
|
10
|
+
|
|
11
|
+
suite("getOrganizationInfo", () => {
|
|
12
|
+
test("should return valid payload for diffusible siret", async (t) => {
|
|
13
|
+
const getOrganizationInfo = getOrganizationInfoFactory({
|
|
14
|
+
findBySiren: () => Promise.reject(),
|
|
15
|
+
findBySiret: () => Promise.resolve(CommunautéDeCommunes),
|
|
16
|
+
});
|
|
17
|
+
t.assert.snapshot(await getOrganizationInfo("20007184300060"));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("should return valid payload for diffusible siren", async (t) => {
|
|
21
|
+
const getOrganizationInfo = getOrganizationInfoFactory({
|
|
22
|
+
findBySiren: () => Promise.resolve(CommunautéDeCommunes),
|
|
23
|
+
findBySiret: () => Promise.reject(),
|
|
24
|
+
});
|
|
25
|
+
t.assert.snapshot(await getOrganizationInfo("200071843"));
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("should show partial data for partially non diffusible établissement", async (t) => {
|
|
29
|
+
const getOrganizationInfo = getOrganizationInfoFactory({
|
|
30
|
+
findBySiren: () => Promise.reject(),
|
|
31
|
+
findBySiret: () => Promise.resolve(RogalDornEntrepreneur),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
t.assert.snapshot(await getOrganizationInfo("94957325700019"));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test.skip("should throw for totally non diffusible établissement", async () => {
|
|
38
|
+
const getOrganizationInfo = getOrganizationInfoFactory({
|
|
39
|
+
findBySiren: () => Promise.reject(),
|
|
40
|
+
findBySiret: () =>
|
|
41
|
+
Promise.resolve({
|
|
42
|
+
status_diffusion: "non_diffusible",
|
|
43
|
+
} as InseeSireneEstablishmentSiretResponseData),
|
|
44
|
+
});
|
|
45
|
+
await assert.rejects(getOrganizationInfo("53512638700013"), NotFoundError);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
exports[`getOrganizationInfo > should return valid payload for diffusible siren 1`] = `
|
|
2
|
+
{
|
|
3
|
+
"activitePrincipale": "84.11Z",
|
|
4
|
+
"adresse": "3 rue maison de vatimesnil, 27150 Etrepagny",
|
|
5
|
+
"categorieJuridique": "7346",
|
|
6
|
+
"codeOfficielGeographique": "27226",
|
|
7
|
+
"codePostal": "27150",
|
|
8
|
+
"enseigne": "",
|
|
9
|
+
"estActive": true,
|
|
10
|
+
"estDiffusible": true,
|
|
11
|
+
"etatAdministratif": "A",
|
|
12
|
+
"libelle": "Cc du vexin normand",
|
|
13
|
+
"libelleActivitePrincipale": "84.11Z - Administration publique générale",
|
|
14
|
+
"libelleCategorieJuridique": "Communauté de communes",
|
|
15
|
+
"libelleTrancheEffectif": "100 à 199 salariés, en 2022",
|
|
16
|
+
"nomComplet": "Cc du vexin normand",
|
|
17
|
+
"siret": "20007184300060",
|
|
18
|
+
"statutDiffusion": "diffusible",
|
|
19
|
+
"trancheEffectifs": "22",
|
|
20
|
+
"trancheEffectifsUniteLegale": "22"
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
exports[`getOrganizationInfo > should return valid payload for diffusible siret 1`] = `
|
|
25
|
+
{
|
|
26
|
+
"activitePrincipale": "84.11Z",
|
|
27
|
+
"adresse": "3 rue maison de vatimesnil, 27150 Etrepagny",
|
|
28
|
+
"categorieJuridique": "7346",
|
|
29
|
+
"codeOfficielGeographique": "27226",
|
|
30
|
+
"codePostal": "27150",
|
|
31
|
+
"enseigne": "",
|
|
32
|
+
"estActive": true,
|
|
33
|
+
"estDiffusible": true,
|
|
34
|
+
"etatAdministratif": "A",
|
|
35
|
+
"libelle": "Cc du vexin normand",
|
|
36
|
+
"libelleActivitePrincipale": "84.11Z - Administration publique générale",
|
|
37
|
+
"libelleCategorieJuridique": "Communauté de communes",
|
|
38
|
+
"libelleTrancheEffectif": "100 à 199 salariés, en 2022",
|
|
39
|
+
"nomComplet": "Cc du vexin normand",
|
|
40
|
+
"siret": "20007184300060",
|
|
41
|
+
"statutDiffusion": "diffusible",
|
|
42
|
+
"trancheEffectifs": "22",
|
|
43
|
+
"trancheEffectifsUniteLegale": "22"
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
exports[`getOrganizationInfo > should show partial data for partially non diffusible établissement 1`] = `
|
|
48
|
+
{
|
|
49
|
+
"activitePrincipale": "62.02A",
|
|
50
|
+
"adresse": "06155 Vallauris",
|
|
51
|
+
"categorieJuridique": "1000",
|
|
52
|
+
"codeOfficielGeographique": "06155",
|
|
53
|
+
"codePostal": "06155",
|
|
54
|
+
"enseigne": "",
|
|
55
|
+
"estActive": true,
|
|
56
|
+
"estDiffusible": false,
|
|
57
|
+
"etatAdministratif": "A",
|
|
58
|
+
"libelle": "Nom inconnu",
|
|
59
|
+
"libelleActivitePrincipale": "62.02A - Conseil en systèmes et logiciels informatiques",
|
|
60
|
+
"libelleCategorieJuridique": "Entrepreneur individuel",
|
|
61
|
+
"libelleTrancheEffectif": "",
|
|
62
|
+
"nomComplet": "Nom inconnu",
|
|
63
|
+
"siret": "94957325700019",
|
|
64
|
+
"statutDiffusion": "partiellement_diffusible",
|
|
65
|
+
"trancheEffectifs": null,
|
|
66
|
+
"trancheEffectifsUniteLegale": null
|
|
67
|
+
}
|
|
68
|
+
`;
|