@proconnect-gouv/proconnect.identite 1.7.0 → 2.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 +12 -0
- package/dist/connectors/index.d.ts +110 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +45 -0
- package/dist/managers/organization/adapters/api_entreprise.d.ts +1 -1
- package/dist/managers/organization/mark-domain-as-verified.d.ts +2 -12
- package/dist/managers/organization/mark-domain-as-verified.d.ts.map +1 -1
- package/dist/managers/organization/mark-domain-as-verified.js +9 -10
- package/dist/managers/user/assign-user-verification-type-to-domain.d.ts +2 -9
- package/dist/managers/user/assign-user-verification-type-to-domain.d.ts.map +1 -1
- package/dist/managers/user/assign-user-verification-type-to-domain.js +4 -3
- package/dist/services/organization/is-public-service.d.ts +1 -1
- package/dist/services/organization/is-public-service.d.ts.map +1 -1
- package/dist/types/organization-info.d.ts +1 -1
- package/dist/types/user-organization-link.js +2 -2
- package/package.json +1 -1
- package/src/connectors/index.ts +51 -0
- package/src/managers/organization/mark-domain-as-verified.test.ts +50 -64
- package/src/managers/organization/mark-domain-as-verified.ts +13 -33
- package/src/managers/user/assign-user-verification-type-to-domain.test.ts +87 -78
- package/src/managers/user/assign-user-verification-type-to-domain.ts +5 -16
- package/src/services/organization/is-public-service.ts +4 -1
- package/src/types/user-organization-link.ts +2 -2
- package/testing/index.ts +2 -0
- package/tsconfig.lib.tsbuildinfo +1 -1
- package/src/managers/organization/mark-domain-as-verified.test.ts.snapshot +0 -53
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
+
import type { Context } from "#src/connectors";
|
|
3
4
|
import { NotFoundError } from "#src/errors";
|
|
4
5
|
import { assignUserVerificationTypeToDomainFactory } from "#src/managers/user";
|
|
5
|
-
import type {
|
|
6
|
-
AddDomainHandler,
|
|
7
|
-
DeleteEmailDomainsByVerificationTypesHandler,
|
|
8
|
-
} from "#src/repositories/email-domain";
|
|
9
|
-
import type {
|
|
10
|
-
FindByIdHandler,
|
|
11
|
-
GetUsersByOrganizationHandler,
|
|
12
|
-
} from "#src/repositories/organization";
|
|
13
|
-
import type { UpdateUserOrganizationLinkHandler } from "#src/repositories/user";
|
|
14
6
|
import {
|
|
15
7
|
type EmailDomainApprovedVerificationType,
|
|
16
8
|
EmailDomainApprovedVerificationTypes,
|
|
@@ -26,26 +18,14 @@ import { match } from "ts-pattern";
|
|
|
26
18
|
|
|
27
19
|
//
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
addDomain: AddDomainHandler;
|
|
31
|
-
deleteEmailDomainsByVerificationTypes: DeleteEmailDomainsByVerificationTypesHandler;
|
|
32
|
-
findOrganizationById: FindByIdHandler;
|
|
33
|
-
getUsers: GetUsersByOrganizationHandler;
|
|
34
|
-
updateUserOrganizationLink: UpdateUserOrganizationLinkHandler;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export function markDomainAsVerifiedFactory({
|
|
38
|
-
addDomain,
|
|
39
|
-
deleteEmailDomainsByVerificationTypes,
|
|
40
|
-
findOrganizationById,
|
|
41
|
-
getUsers,
|
|
42
|
-
updateUserOrganizationLink,
|
|
43
|
-
}: FactoryDependencies) {
|
|
21
|
+
export function markDomainAsVerifiedFactory(context: Context) {
|
|
44
22
|
const assignUserVerificationTypeToDomain =
|
|
45
|
-
assignUserVerificationTypeToDomainFactory(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
23
|
+
assignUserVerificationTypeToDomainFactory(context);
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
repository: { email_domains, organizations },
|
|
27
|
+
} = context;
|
|
28
|
+
|
|
49
29
|
return async function markDomainAsVerified({
|
|
50
30
|
organization_id,
|
|
51
31
|
domain,
|
|
@@ -55,7 +35,7 @@ export function markDomainAsVerifiedFactory({
|
|
|
55
35
|
domain: string;
|
|
56
36
|
domain_verification_type: EmailDomainNoPendingVerificationType;
|
|
57
37
|
}) {
|
|
58
|
-
const organization = await
|
|
38
|
+
const organization = await organizations.findById(organization_id);
|
|
59
39
|
|
|
60
40
|
if (isEmpty(organization)) {
|
|
61
41
|
throw new NotFoundError();
|
|
@@ -94,7 +74,7 @@ export function markDomainAsVerifiedFactory({
|
|
|
94
74
|
domain: string;
|
|
95
75
|
domain_verification_type: EmailDomainApprovedVerificationType;
|
|
96
76
|
}) {
|
|
97
|
-
await deleteEmailDomainsByVerificationTypes({
|
|
77
|
+
await email_domains.deleteEmailDomainsByVerificationTypes({
|
|
98
78
|
organization_id,
|
|
99
79
|
domain,
|
|
100
80
|
domain_verification_types: [
|
|
@@ -102,7 +82,7 @@ export function markDomainAsVerifiedFactory({
|
|
|
102
82
|
...EmailDomainPendingVerificationTypes,
|
|
103
83
|
],
|
|
104
84
|
});
|
|
105
|
-
return addDomain({
|
|
85
|
+
return email_domains.addDomain({
|
|
106
86
|
organization_id,
|
|
107
87
|
domain,
|
|
108
88
|
verification_type:
|
|
@@ -119,7 +99,7 @@ export function markDomainAsVerifiedFactory({
|
|
|
119
99
|
domain: string;
|
|
120
100
|
domain_verification_type: EmailDomainRejectedVerificationType;
|
|
121
101
|
}) {
|
|
122
|
-
await deleteEmailDomainsByVerificationTypes({
|
|
102
|
+
await email_domains.deleteEmailDomainsByVerificationTypes({
|
|
123
103
|
organization_id,
|
|
124
104
|
domain,
|
|
125
105
|
domain_verification_types: [
|
|
@@ -127,7 +107,7 @@ export function markDomainAsVerifiedFactory({
|
|
|
127
107
|
...EmailDomainRejectedVerificationTypes,
|
|
128
108
|
],
|
|
129
109
|
});
|
|
130
|
-
return addDomain({
|
|
110
|
+
return email_domains.addDomain({
|
|
131
111
|
organization_id,
|
|
132
112
|
domain,
|
|
133
113
|
verification_type:
|
|
@@ -1,97 +1,106 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
+
import { context, emptyDatabase, migrate, pg } from "#testing";
|
|
3
4
|
import assert from "node:assert/strict";
|
|
4
|
-
import { describe, it
|
|
5
|
+
import { before, beforeEach, describe, it } from "node:test";
|
|
5
6
|
import { assignUserVerificationTypeToDomainFactory } from "./assign-user-verification-type-to-domain.js";
|
|
6
7
|
|
|
7
8
|
//
|
|
8
9
|
|
|
10
|
+
const assignUserVerificationTypeToDomain =
|
|
11
|
+
assignUserVerificationTypeToDomainFactory(context);
|
|
12
|
+
|
|
9
13
|
describe("assignUserVerificationTypeToDomain", () => {
|
|
14
|
+
before(migrate);
|
|
15
|
+
beforeEach(emptyDatabase);
|
|
16
|
+
|
|
10
17
|
it("should update some organization members", async () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
18
|
+
await pg.sql`
|
|
19
|
+
INSERT INTO organizations
|
|
20
|
+
(id, cached_libelle, cached_nom_complet, siret, created_at, updated_at)
|
|
21
|
+
VALUES
|
|
22
|
+
(1, 'Dark Angels', 'Dark Angels Legion', '🦁', '4444-04-04', '4444-04-04')
|
|
23
|
+
;
|
|
24
|
+
`;
|
|
25
|
+
// user from a different domain — should not be updated
|
|
26
|
+
await pg.sql`
|
|
27
|
+
INSERT INTO users (id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
28
|
+
VALUES (1, 'foo@bar.world', '4444-04-04', '4444-04-04', 'Foo', 'Bar', '0', 'None')
|
|
29
|
+
`;
|
|
30
|
+
// user matching domain but already "verified" — should not be updated
|
|
31
|
+
await pg.sql`
|
|
32
|
+
INSERT INTO users (id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
33
|
+
VALUES (2, 'foo@darkangels.world', '4444-04-04', '4444-04-04', 'Foo', 'DA', '0', 'None')
|
|
34
|
+
`;
|
|
35
|
+
// user with no_validation_means_available — should be updated
|
|
36
|
+
await pg.sql`
|
|
37
|
+
INSERT INTO users (id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
38
|
+
VALUES (3, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'Lion', 'El''Jonson', '0', 'Primarque')
|
|
39
|
+
`;
|
|
40
|
+
// user with no_verification_means_for_entreprise_unipersonnelle — should be updated
|
|
41
|
+
await pg.sql`
|
|
42
|
+
INSERT INTO users (id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
43
|
+
VALUES (4, 'cat.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'Cat', 'El''Jonson', '0', 'Scout')
|
|
44
|
+
`;
|
|
45
|
+
// user with no_verification_means_for_small_association — should be updated
|
|
46
|
+
await pg.sql`
|
|
47
|
+
INSERT INTO users (id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
48
|
+
VALUES (5, 'tiger.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'Tiger', 'El''Jonson', '0', 'Scout')
|
|
49
|
+
`;
|
|
50
|
+
// user with domain_not_verified_yet — should be updated
|
|
51
|
+
await pg.sql`
|
|
52
|
+
INSERT INTO users (id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
53
|
+
VALUES (6, 'mouse.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'Mouse', 'El''Jonson', '0', 'Scout')
|
|
54
|
+
`;
|
|
48
55
|
|
|
49
|
-
|
|
56
|
+
// link all users to the organization
|
|
57
|
+
await pg.sql`
|
|
58
|
+
INSERT INTO users_organizations
|
|
59
|
+
(user_id, organization_id, created_at, updated_at, is_external, verification_type, needs_official_contact_email_verification, official_contact_email_verification_token, official_contact_email_verification_sent_at)
|
|
60
|
+
VALUES
|
|
61
|
+
(1, 1, '4444-04-04', '4444-04-04', false, 'no_validation_means_available', false, null, null),
|
|
62
|
+
(2, 1, '4444-04-04', '4444-04-04', false, 'verified', false, null, null),
|
|
63
|
+
(3, 1, '4444-04-04', '4444-04-04', false, 'no_validation_means_available', false, null, null),
|
|
64
|
+
(4, 1, '4444-04-04', '4444-04-04', false, 'no_verification_means_for_entreprise_unipersonnelle', false, null, null),
|
|
65
|
+
(5, 1, '4444-04-04', '4444-04-04', false, 'no_verification_means_for_small_association', false, null, null),
|
|
66
|
+
(6, 1, '4444-04-04', '4444-04-04', false, 'domain_not_verified_yet', false, null, null)
|
|
67
|
+
;
|
|
68
|
+
`;
|
|
50
69
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
44,
|
|
69
|
-
{
|
|
70
|
-
verification_type: "domain",
|
|
71
|
-
},
|
|
72
|
-
]);
|
|
73
|
-
assert.deepEqual(mouse.arguments, [
|
|
74
|
-
111,
|
|
75
|
-
45,
|
|
76
|
-
{
|
|
77
|
-
verification_type: "domain",
|
|
78
|
-
},
|
|
70
|
+
await assignUserVerificationTypeToDomain(1, "darkangels.world");
|
|
71
|
+
|
|
72
|
+
// verify that the 4 matching users were updated to "domain"
|
|
73
|
+
const { rows } = await pg.sql`
|
|
74
|
+
SELECT user_id, verification_type
|
|
75
|
+
FROM users_organizations
|
|
76
|
+
WHERE organization_id = 1
|
|
77
|
+
ORDER BY user_id
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
assert.deepEqual(rows, [
|
|
81
|
+
{ user_id: 1, verification_type: "no_validation_means_available" }, // different domain
|
|
82
|
+
{ user_id: 2, verification_type: "verified" }, // already verified
|
|
83
|
+
{ user_id: 3, verification_type: "domain" },
|
|
84
|
+
{ user_id: 4, verification_type: "domain" },
|
|
85
|
+
{ user_id: 5, verification_type: "domain" },
|
|
86
|
+
{ user_id: 6, verification_type: "domain" },
|
|
79
87
|
]);
|
|
80
|
-
assert.equal(updateUserOrganizationLink.mock.callCount(), 4);
|
|
81
88
|
});
|
|
82
89
|
|
|
83
90
|
it("❎ should update nothing if no organization members", async () => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
});
|
|
91
|
+
await pg.sql`
|
|
92
|
+
INSERT INTO organizations
|
|
93
|
+
(id, cached_libelle, cached_nom_complet, siret, created_at, updated_at)
|
|
94
|
+
VALUES
|
|
95
|
+
(1, 'Empty', 'Empty Org', '🫥', '4444-04-04', '4444-04-04')
|
|
96
|
+
;
|
|
97
|
+
`;
|
|
92
98
|
|
|
93
|
-
await assignUserVerificationTypeToDomain(
|
|
99
|
+
await assignUserVerificationTypeToDomain(1, "darkangels.world");
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
const { rows } = await pg.sql`
|
|
102
|
+
SELECT * FROM users_organizations WHERE organization_id = 1
|
|
103
|
+
`;
|
|
104
|
+
assert.deepEqual(rows, []);
|
|
96
105
|
});
|
|
97
106
|
});
|
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
import type { UpdateUserOrganizationLinkHandler } from "#src/repositories/user";
|
|
3
|
+
import type { Context } from "#src/connectors";
|
|
5
4
|
import { LinkTypes, SuperWeakLinkTypes, UnverifiedLinkTypes } from "#src/types";
|
|
6
5
|
import { getEmailDomain } from "@proconnect-gouv/proconnect.core/services/email";
|
|
7
6
|
import { match } from "ts-pattern";
|
|
8
7
|
|
|
9
8
|
//
|
|
10
9
|
|
|
11
|
-
type FactoryDependencies = {
|
|
12
|
-
getUsers: GetUsersByOrganizationHandler;
|
|
13
|
-
updateUserOrganizationLink: UpdateUserOrganizationLinkHandler;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
10
|
export function assignUserVerificationTypeToDomainFactory({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}: FactoryDependencies) {
|
|
11
|
+
repository: { organizations, users_organizations },
|
|
12
|
+
}: Context) {
|
|
20
13
|
return async function assignUserVerificationTypeToDomain(
|
|
21
14
|
organization_id: number,
|
|
22
15
|
domain: string,
|
|
23
16
|
) {
|
|
24
|
-
const usersInOrganization = await getUsers(organization_id);
|
|
17
|
+
const usersInOrganization = await organizations.getUsers(organization_id);
|
|
25
18
|
|
|
26
19
|
await Promise.all(
|
|
27
20
|
usersInOrganization.map(
|
|
@@ -33,7 +26,7 @@ export function assignUserVerificationTypeToDomainFactory({
|
|
|
33
26
|
.with(...UnverifiedLinkTypes, ...SuperWeakLinkTypes, () => true)
|
|
34
27
|
.otherwise(() => false)
|
|
35
28
|
) {
|
|
36
|
-
return
|
|
29
|
+
return users_organizations.update(organization_id, id, {
|
|
37
30
|
verification_type: LinkTypes.enum.domain,
|
|
38
31
|
});
|
|
39
32
|
}
|
|
@@ -44,7 +37,3 @@ export function assignUserVerificationTypeToDomainFactory({
|
|
|
44
37
|
);
|
|
45
38
|
};
|
|
46
39
|
}
|
|
47
|
-
|
|
48
|
-
export type AssignUserVerificationTypeToDomainFactoryHandler = ReturnType<
|
|
49
|
-
typeof assignUserVerificationTypeToDomainFactory
|
|
50
|
-
>;
|
|
@@ -12,7 +12,10 @@ export const isPublicService = ({
|
|
|
12
12
|
cached_categorie_juridique,
|
|
13
13
|
cached_etat_administratif,
|
|
14
14
|
siret,
|
|
15
|
-
}:
|
|
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;
|
|
@@ -75,11 +75,11 @@ export const InsertUserOrganizationLinkSchema = UserOrganizationLinkSchema.pick(
|
|
|
75
75
|
user_id: true,
|
|
76
76
|
verification_type: true,
|
|
77
77
|
},
|
|
78
|
-
).
|
|
78
|
+
).extend(
|
|
79
79
|
UserOrganizationLinkSchema.pick({
|
|
80
80
|
is_external: true,
|
|
81
81
|
needs_official_contact_email_verification: true,
|
|
82
|
-
}).partial(),
|
|
82
|
+
}).partial().shape,
|
|
83
83
|
);
|
|
84
84
|
|
|
85
85
|
export type InsertUserOrganizationLink = z.output<
|
package/testing/index.ts
CHANGED
|
@@ -4,10 +4,12 @@ import { PGlite } from "@electric-sql/pglite";
|
|
|
4
4
|
import { noop } from "lodash-es";
|
|
5
5
|
import { runner } from "node-pg-migrate";
|
|
6
6
|
import { join } from "path";
|
|
7
|
+
import { createContext } from "../src/connectors/index.js";
|
|
7
8
|
|
|
8
9
|
//
|
|
9
10
|
|
|
10
11
|
export const pg = new PGlite();
|
|
12
|
+
export const context = createContext(pg as any);
|
|
11
13
|
|
|
12
14
|
export function migrate() {
|
|
13
15
|
return runner({
|