@proconnect-gouv/proconnect.identite 1.6.2 → 1.7.1

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/managers/organization/index.d.ts +0 -1
  3. package/dist/managers/organization/index.d.ts.map +1 -1
  4. package/dist/managers/organization/index.js +0 -1
  5. package/dist/managers/organization/mark-domain-as-verified.d.ts +12 -3
  6. package/dist/managers/organization/mark-domain-as-verified.d.ts.map +1 -1
  7. package/dist/managers/organization/mark-domain-as-verified.js +7 -7
  8. package/dist/repositories/email-domain/add-domain.d.ts +12 -3
  9. package/dist/repositories/email-domain/add-domain.d.ts.map +1 -1
  10. package/dist/repositories/email-domain/delete-email-domains-by-verification-types.d.ts +2 -2
  11. package/dist/repositories/email-domain/delete-email-domains-by-verification-types.d.ts.map +1 -1
  12. package/dist/repositories/email-domain/delete-email-domains-by-verification-types.js +1 -3
  13. package/dist/repositories/email-domain/find-email-domains-by-organization-id.d.ts +11 -2
  14. package/dist/repositories/email-domain/find-email-domains-by-organization-id.d.ts.map +1 -1
  15. package/dist/repositories/organization/find-by-user-id.d.ts +1 -1
  16. package/dist/repositories/organization/get-users-by-organization.d.ts +1 -1
  17. package/dist/repositories/organization/index.d.ts +0 -1
  18. package/dist/repositories/organization/index.d.ts.map +1 -1
  19. package/dist/repositories/organization/index.js +0 -1
  20. package/dist/repositories/organization/link-user-to-organization.d.ts +1 -1
  21. package/dist/repositories/user/update-user-organization-link.d.ts +1 -1
  22. package/dist/services/organization/is-public-service.d.ts +1 -1
  23. package/dist/services/organization/is-public-service.d.ts.map +1 -1
  24. package/dist/types/email-domain.d.ts +37 -16
  25. package/dist/types/email-domain.d.ts.map +1 -1
  26. package/dist/types/email-domain.js +30 -7
  27. package/dist/types/user-organization-link.d.ts +7 -6
  28. package/dist/types/user-organization-link.d.ts.map +1 -1
  29. package/dist/types/user-organization-link.js +2 -2
  30. package/package.json +1 -1
  31. package/src/managers/organization/index.ts +0 -1
  32. package/src/managers/organization/mark-domain-as-verified.test.ts.snapshot +2 -1
  33. package/src/managers/organization/mark-domain-as-verified.ts +16 -17
  34. package/src/managers/user/assign-user-verification-type-to-domain.test.ts +97 -0
  35. package/src/repositories/email-domain/add-domain.ts +6 -2
  36. package/src/repositories/email-domain/delete-email-domains-by-verification-types.test.ts +2 -2
  37. package/src/repositories/email-domain/delete-email-domains-by-verification-types.ts +7 -7
  38. package/src/repositories/email-domain/find-email-domains-by-organization-id.test.ts +3 -3
  39. package/src/repositories/organization/index.ts +0 -1
  40. package/src/services/organization/is-public-service.ts +4 -1
  41. package/src/types/email-domain.ts +44 -27
  42. package/src/types/user-organization-link.ts +4 -2
  43. package/tsconfig.lib.tsbuildinfo +1 -1
  44. package/dist/managers/organization/force-join-organization.d.ts +0 -29
  45. package/dist/managers/organization/force-join-organization.d.ts.map +0 -1
  46. package/dist/managers/organization/force-join-organization.js +0 -32
  47. package/dist/repositories/organization/get-by-id.d.ts +0 -4
  48. package/dist/repositories/organization/get-by-id.d.ts.map +0 -1
  49. package/dist/repositories/organization/get-by-id.js +0 -15
  50. package/src/managers/organization/force-join-organization.test.ts +0 -94
  51. package/src/managers/organization/force-join-organization.ts +0 -87
  52. package/src/repositories/organization/get-by-id.test.ts +0 -61
  53. package/src/repositories/organization/get-by-id.ts +0 -21
@@ -0,0 +1,97 @@
1
+ //
2
+
3
+ import assert from "node:assert/strict";
4
+ import { describe, it, mock } from "node:test";
5
+ import { assignUserVerificationTypeToDomainFactory } from "./assign-user-verification-type-to-domain.js";
6
+
7
+ //
8
+
9
+ describe("assignUserVerificationTypeToDomain", () => {
10
+ it("should update some organization members", async () => {
11
+ const updateUserOrganizationLink = mock.fn(() =>
12
+ Promise.resolve({} as any),
13
+ );
14
+ const assignUserVerificationTypeToDomain =
15
+ assignUserVerificationTypeToDomainFactory({
16
+ getUsers: () =>
17
+ Promise.resolve([
18
+ { email: "foo@bar.world" },
19
+ { email: "foo@darkangels.world" },
20
+ {
21
+ email: "foo@darkangels.world",
22
+ verification_type: "verified",
23
+ },
24
+ {
25
+ id: 42,
26
+ email: "lion.eljonson@darkangels.world",
27
+ verification_type: "no_validation_means_available",
28
+ },
29
+ {
30
+ id: 43,
31
+ email: "cat.eljonson@darkangels.world",
32
+ verification_type:
33
+ "no_verification_means_for_entreprise_unipersonnelle",
34
+ },
35
+ {
36
+ id: 44,
37
+ email: "tiger.eljonson@darkangels.world",
38
+ verification_type: "no_verification_means_for_small_association",
39
+ },
40
+ {
41
+ id: 45,
42
+ email: "mouse.eljonson@darkangels.world",
43
+ verification_type: "domain_not_verified_yet",
44
+ },
45
+ ] as any),
46
+ updateUserOrganizationLink,
47
+ });
48
+
49
+ await assignUserVerificationTypeToDomain(111, "darkangels.world");
50
+
51
+ const [lion, cat, tiger, mouse] = updateUserOrganizationLink.mock.calls;
52
+ assert.deepEqual(lion.arguments, [
53
+ 111,
54
+ 42,
55
+ {
56
+ verification_type: "domain",
57
+ },
58
+ ]);
59
+ assert.deepEqual(cat.arguments, [
60
+ 111,
61
+ 43,
62
+ {
63
+ verification_type: "domain",
64
+ },
65
+ ]);
66
+ assert.deepEqual(tiger.arguments, [
67
+ 111,
68
+ 44,
69
+ {
70
+ verification_type: "domain",
71
+ },
72
+ ]);
73
+ assert.deepEqual(mouse.arguments, [
74
+ 111,
75
+ 45,
76
+ {
77
+ verification_type: "domain",
78
+ },
79
+ ]);
80
+ assert.equal(updateUserOrganizationLink.mock.callCount(), 4);
81
+ });
82
+
83
+ it("❎ should update nothing if no organization members", async () => {
84
+ const updateUserOrganizationLink = mock.fn(() =>
85
+ Promise.reject(new Error("💣")),
86
+ );
87
+ const assignUserVerificationTypeToDomain =
88
+ assignUserVerificationTypeToDomainFactory({
89
+ getUsers: () => Promise.resolve([]),
90
+ updateUserOrganizationLink,
91
+ });
92
+
93
+ await assignUserVerificationTypeToDomain(42, "darkangels.world");
94
+
95
+ assert.deepEqual(updateUserOrganizationLink.mock.calls, []);
96
+ });
97
+ });
@@ -1,7 +1,11 @@
1
1
  //
2
2
 
3
3
  import { hashToPostgresParams } from "#src/services/postgres";
4
- import type { DatabaseContext, EmailDomain } from "#src/types";
4
+ import type {
5
+ DatabaseContext,
6
+ EmailDomain,
7
+ EmailDomainVerificationType,
8
+ } from "#src/types";
5
9
  import type { QueryResult } from "pg";
6
10
 
7
11
  //
@@ -14,7 +18,7 @@ export function addDomainFactory({ pg }: DatabaseContext) {
14
18
  }: {
15
19
  organization_id: number;
16
20
  domain: string;
17
- verification_type: EmailDomain["verification_type"];
21
+ verification_type: EmailDomainVerificationType;
18
22
  }) {
19
23
  const connection = pg;
20
24
 
@@ -29,7 +29,7 @@ describe("deleteEmailDomainsByVerificationTypesFactory", function () {
29
29
  INSERT INTO email_domains
30
30
  (domain, organization_id, verification_type)
31
31
  VALUES
32
- ('darkangels.world', 1, NULL),
32
+ ('darkangels.world', 1, 'not_verified_yet'),
33
33
  ('darkangels.world', 1, 'verified')
34
34
  ;
35
35
  `;
@@ -37,7 +37,7 @@ describe("deleteEmailDomainsByVerificationTypesFactory", function () {
37
37
  const result = await deleteEmailDomainsByVerificationTypes({
38
38
  domain: "darkangels.world",
39
39
  organization_id: 1,
40
- domain_verification_types: [null, "verified"],
40
+ domain_verification_types: ["not_verified_yet", "verified"],
41
41
  });
42
42
 
43
43
  assert.deepEqual(result, {
@@ -1,6 +1,10 @@
1
1
  //
2
2
 
3
- import type { DatabaseContext, EmailDomain } from "#src/types";
3
+ import type {
4
+ DatabaseContext,
5
+ EmailDomain,
6
+ EmailDomainVerificationType,
7
+ } from "#src/types";
4
8
 
5
9
  //
6
10
 
@@ -13,15 +17,11 @@ export function deleteEmailDomainsByVerificationTypesFactory({
13
17
  domain_verification_types,
14
18
  }: {
15
19
  organization_id: EmailDomain["organization_id"];
16
- domain_verification_types: EmailDomain["verification_type"][];
20
+ domain_verification_types: EmailDomainVerificationType[];
17
21
  domain: EmailDomain["domain"];
18
22
  }) {
19
23
  const SQL_VERIFICATION_TYPES = domain_verification_types
20
- .map((type) =>
21
- type === null
22
- ? "verification_type IS NULL"
23
- : `verification_type = '${type}'`,
24
- )
24
+ .map((type) => `verification_type = '${type}'`)
25
25
  .join(" OR ");
26
26
 
27
27
  return pg.query(
@@ -25,9 +25,9 @@ describe("findEmailDomainsByOrganizationIdFactory", () => {
25
25
 
26
26
  await pg.sql`
27
27
  INSERT INTO email_domains
28
- (id, domain, organization_id, created_at, updated_at)
28
+ (id, domain, organization_id, created_at, updated_at, verification_type)
29
29
  VALUES
30
- (1, 'darkangels.world', 1, '4444-04-04', '4444-04-04')
30
+ (1, 'darkangels.world', 1, '4444-04-04', '4444-04-04', 'not_verified_yet')
31
31
  ;
32
32
  `;
33
33
 
@@ -41,7 +41,7 @@ describe("findEmailDomainsByOrganizationIdFactory", () => {
41
41
  id: 1,
42
42
  organization_id: 1,
43
43
  updated_at: new Date("4444-04-04"),
44
- verification_type: null,
44
+ verification_type: "not_verified_yet",
45
45
  verified_at: null,
46
46
  },
47
47
  ]);
@@ -2,7 +2,6 @@
2
2
 
3
3
  export * from "./find-by-id.js";
4
4
  export * from "./find-by-user-id.js";
5
- export * from "./get-by-id.js";
6
5
  export * from "./get-users-by-organization.js";
7
6
  export * from "./link-user-to-organization.js";
8
7
  export * from "./upsert.js";
@@ -12,7 +12,10 @@ export const isPublicService = ({
12
12
  cached_categorie_juridique,
13
13
  cached_etat_administratif,
14
14
  siret,
15
- }: Organization): boolean => {
15
+ }: Pick<
16
+ Organization,
17
+ "cached_categorie_juridique" | "cached_etat_administratif" | "siret"
18
+ >): boolean => {
16
19
  // Check if nature juridique is undefined/null
17
20
  if (!cached_categorie_juridique) {
18
21
  return false;
@@ -1,48 +1,65 @@
1
- //
2
-
3
1
  import { z } from "zod";
4
2
 
5
- //
6
-
7
- export const EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES = z.enum([
3
+ export const EmailDomainApprovedVerificationTypes = [
8
4
  "official_contact",
9
5
  "trackdechets_postal_mail",
10
6
  "verified",
11
- ]);
7
+ "external", // domain used by external employees (eg. ext.numerique.gouv.fr)
8
+ ] as const;
12
9
 
13
10
  export type EmailDomainApprovedVerificationType = z.output<
14
- typeof EMAIL_DOMAIN_APPROVED_VERIFICATION_TYPES
11
+ typeof EmailDomainApprovedVerificationTypes
15
12
  >;
16
13
 
17
- //
14
+ // domain is not verified, but users are still permitted to use it
15
+ export const EmailDomainPendingVerificationTypes = [
16
+ "not_verified_yet",
17
+ ] as const;
18
18
 
19
- export const EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES = z.enum([
19
+ export type EmailDomainPendingVerificationType = z.output<
20
+ typeof EmailDomainPendingVerificationTypes
21
+ >;
22
+
23
+ export const EmailDomainRejectedVerificationTypes = [
20
24
  "blacklisted", // unused
21
- "external", // domain used by external employees (eg. ext.numerique.gouv.fr)
22
25
  "refused",
23
- ]);
26
+ ] as const;
24
27
 
25
28
  export type EmailDomainRejectedVerificationType = z.output<
26
- typeof EMAIL_DOMAIN_REJECTED_VERIFICATION_TYPES
29
+ typeof EmailDomainRejectedVerificationTypes
27
30
  >;
28
31
 
29
- //
32
+ export const EmailDomainNoPendingVerificationTypes = z.enum([
33
+ ...EmailDomainApprovedVerificationTypes,
34
+ ...EmailDomainRejectedVerificationTypes,
35
+ ]);
36
+
37
+ export type EmailDomainNoPendingVerificationType = z.output<
38
+ typeof EmailDomainNoPendingVerificationTypes
39
+ >;
30
40
 
31
- export type EmailDomainVerificationType =
32
- | EmailDomainApprovedVerificationType
33
- | EmailDomainRejectedVerificationType
34
- | null; // domain is not verified, but users are still permitted to use it
41
+ export const EmailDomainVerificationTypes = z.enum([
42
+ ...EmailDomainApprovedVerificationTypes,
43
+ ...EmailDomainPendingVerificationTypes,
44
+ ...EmailDomainRejectedVerificationTypes,
45
+ ]);
35
46
 
36
- export interface EmailDomain {
37
- id: number;
38
- organization_id: number;
39
- domain: string;
40
- verification_type: EmailDomainVerificationType;
47
+ export type EmailDomainVerificationType = z.output<
48
+ typeof EmailDomainVerificationTypes
49
+ >;
50
+
51
+ export const EmailDomainSchema = z.object({
52
+ id: z.number(),
53
+ organization_id: z.number(),
54
+ domain: z.string(),
55
+ verification_type: EmailDomainVerificationTypes,
41
56
  // Unused.
42
- can_be_suggested: boolean;
57
+ can_be_suggested: z.boolean(),
43
58
  // Can be updated when verification_type changes.
44
59
  // In practice, entries are deleted and recreated rather than updated directly
45
- verified_at: Date | null;
46
- created_at: Date;
47
- updated_at: Date;
48
- }
60
+ verified_at: z.date().nullable(),
61
+ created_at: z.date(),
62
+ updated_at: z.date(),
63
+ });
64
+
65
+ export type EmailDomain = z.output<typeof EmailDomainSchema>;
@@ -37,6 +37,8 @@ export const UnverifiedLinkTypes = [
37
37
 
38
38
  export const LinkTypes = z.enum([...VerifiedLinkTypes, ...UnverifiedLinkTypes]);
39
39
 
40
+ export type LinkType = z.output<typeof LinkTypes>;
41
+
40
42
  export const BaseUserOrganizationLinkSchema = z.object({
41
43
  is_external: z.boolean(),
42
44
  verification_type: LinkTypes,
@@ -73,11 +75,11 @@ export const InsertUserOrganizationLinkSchema = UserOrganizationLinkSchema.pick(
73
75
  user_id: true,
74
76
  verification_type: true,
75
77
  },
76
- ).merge(
78
+ ).extend(
77
79
  UserOrganizationLinkSchema.pick({
78
80
  is_external: true,
79
81
  needs_official_contact_email_verification: true,
80
- }).partial(),
82
+ }).partial().shape,
81
83
  );
82
84
 
83
85
  export type InsertUserOrganizationLink = z.output<