@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,64 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { emptyDatabase, migrate, pg } from "#testing";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { before, beforeEach, mock, suite, test } from "node:test";
|
|
6
|
+
import { findByIdFactory } from "./find-by-id.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
const findById = findByIdFactory({ pg: pg as any });
|
|
11
|
+
|
|
12
|
+
suite("findByIdFactory", () => {
|
|
13
|
+
before(migrate);
|
|
14
|
+
beforeEach(emptyDatabase);
|
|
15
|
+
|
|
16
|
+
test("should find a user by id", async () => {
|
|
17
|
+
mock.timers.enable({ apis: ["Date"], now: new Date("4444-04-04") });
|
|
18
|
+
|
|
19
|
+
await pg.sql`
|
|
20
|
+
INSERT INTO users
|
|
21
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
22
|
+
VALUES
|
|
23
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'i', 'primarque'),
|
|
24
|
+
(2, 'perturabo@ironwarriors.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'iv', 'primarque')
|
|
25
|
+
;
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
const user = await findById(1);
|
|
29
|
+
|
|
30
|
+
assert.deepEqual(user, {
|
|
31
|
+
created_at: new Date("4444-04-04"),
|
|
32
|
+
current_challenge: null,
|
|
33
|
+
email: "lion.eljonson@darkangels.world",
|
|
34
|
+
email_verified: false,
|
|
35
|
+
email_verified_at: null,
|
|
36
|
+
encrypted_password: "",
|
|
37
|
+
encrypted_totp_key: null,
|
|
38
|
+
family_name: "el'jonson",
|
|
39
|
+
force_2fa: false,
|
|
40
|
+
given_name: "lion",
|
|
41
|
+
id: 1,
|
|
42
|
+
job: "primarque",
|
|
43
|
+
last_sign_in_at: null,
|
|
44
|
+
magic_link_sent_at: null,
|
|
45
|
+
magic_link_token: null,
|
|
46
|
+
needs_inclusionconnect_onboarding_help: false,
|
|
47
|
+
needs_inclusionconnect_welcome_page: false,
|
|
48
|
+
phone_number: "i",
|
|
49
|
+
reset_password_sent_at: null,
|
|
50
|
+
reset_password_token: null,
|
|
51
|
+
sign_in_count: 0,
|
|
52
|
+
totp_key_verified_at: null,
|
|
53
|
+
updated_at: new Date("4444-04-04"),
|
|
54
|
+
verify_email_sent_at: null,
|
|
55
|
+
verify_email_token: null,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("❎ fail to find the God-Emperor of Mankind", async () => {
|
|
60
|
+
const user = await findById(42);
|
|
61
|
+
|
|
62
|
+
assert.equal(user, undefined);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import type { DatabaseContext, User } from "#src/types";
|
|
4
|
+
import { type QueryResult } from "pg";
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
export function findByIdFactory({ pg }: DatabaseContext) {
|
|
9
|
+
return async function findById(id: number) {
|
|
10
|
+
const { rows }: QueryResult<User> = await pg.query(
|
|
11
|
+
`
|
|
12
|
+
SELECT *
|
|
13
|
+
FROM users
|
|
14
|
+
WHERE id = $1
|
|
15
|
+
`,
|
|
16
|
+
[id],
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return rows.shift();
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type FindByIdHandler = ReturnType<typeof findByIdFactory>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { UserNotFoundError } from "#src/errors";
|
|
4
|
+
import { emptyDatabase, migrate, pg } from "#testing";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { before, beforeEach, mock, suite, test } from "node:test";
|
|
7
|
+
import { getByIdFactory } from "./get-by-id.js";
|
|
8
|
+
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
const getById = getByIdFactory({ pg: pg as any });
|
|
12
|
+
|
|
13
|
+
suite("getByIdFactory", () => {
|
|
14
|
+
before(migrate);
|
|
15
|
+
beforeEach(emptyDatabase);
|
|
16
|
+
|
|
17
|
+
test("should find a user by id", async () => {
|
|
18
|
+
mock.timers.enable({ apis: ["Date"], now: new Date("4444-04-04") });
|
|
19
|
+
|
|
20
|
+
await pg.sql`
|
|
21
|
+
INSERT INTO users
|
|
22
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
23
|
+
VALUES
|
|
24
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'i', 'primarque'),
|
|
25
|
+
(2, 'perturabo@ironwarriors.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'iv', 'primarque')
|
|
26
|
+
;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
const user = await getById(1);
|
|
30
|
+
|
|
31
|
+
assert.deepEqual(user, {
|
|
32
|
+
created_at: new Date("4444-04-04"),
|
|
33
|
+
current_challenge: null,
|
|
34
|
+
email: "lion.eljonson@darkangels.world",
|
|
35
|
+
email_verified: false,
|
|
36
|
+
email_verified_at: null,
|
|
37
|
+
encrypted_password: "",
|
|
38
|
+
encrypted_totp_key: null,
|
|
39
|
+
family_name: "el'jonson",
|
|
40
|
+
force_2fa: false,
|
|
41
|
+
given_name: "lion",
|
|
42
|
+
id: 1,
|
|
43
|
+
job: "primarque",
|
|
44
|
+
last_sign_in_at: null,
|
|
45
|
+
magic_link_sent_at: null,
|
|
46
|
+
magic_link_token: null,
|
|
47
|
+
needs_inclusionconnect_onboarding_help: false,
|
|
48
|
+
needs_inclusionconnect_welcome_page: false,
|
|
49
|
+
phone_number: "i",
|
|
50
|
+
reset_password_sent_at: null,
|
|
51
|
+
reset_password_token: null,
|
|
52
|
+
sign_in_count: 0,
|
|
53
|
+
totp_key_verified_at: null,
|
|
54
|
+
updated_at: new Date("4444-04-04"),
|
|
55
|
+
verify_email_sent_at: null,
|
|
56
|
+
verify_email_token: null,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("❎ fail to find the God-Emperor of Mankind", async () => {
|
|
61
|
+
await assert.rejects(getById(42), new UserNotFoundError("User not found"));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { UserNotFoundError } from "#src/errors";
|
|
4
|
+
import type { DatabaseContext } from "#src/types";
|
|
5
|
+
import { isEmpty } from "lodash-es";
|
|
6
|
+
import { findByIdFactory } from "./find-by-id.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
export function getByIdFactory({ pg }: DatabaseContext) {
|
|
11
|
+
const findById = findByIdFactory({ pg });
|
|
12
|
+
return async function getById(id: number) {
|
|
13
|
+
const user = await findById(id);
|
|
14
|
+
if (isEmpty(user)) {
|
|
15
|
+
throw new UserNotFoundError("User not found");
|
|
16
|
+
}
|
|
17
|
+
return user;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type GetByIdHandler = ReturnType<typeof getByIdFactory>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { emptyDatabase, migrate, pg } from "#testing";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { before, beforeEach, describe, it, mock } from "node:test";
|
|
6
|
+
import { getFranceConnectUserInfoFactory } from "./get-franceconnect-user-info.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
const getFranceConnectUserInfo = getFranceConnectUserInfoFactory({
|
|
11
|
+
pg: pg as any,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe("getFranceConnectUserInfo", () => {
|
|
15
|
+
before(migrate);
|
|
16
|
+
beforeEach(emptyDatabase);
|
|
17
|
+
before(() => {
|
|
18
|
+
mock.timers.enable({ apis: ["Date"], now: new Date("4444-04-04") });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should get franceconnect user info", async () => {
|
|
22
|
+
await pg.sql`
|
|
23
|
+
INSERT INTO users
|
|
24
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
25
|
+
VALUES
|
|
26
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'i', 'primarque')
|
|
27
|
+
;
|
|
28
|
+
`;
|
|
29
|
+
await pg.sql`
|
|
30
|
+
INSERT INTO franceconnect_userinfo
|
|
31
|
+
(user_id, birthdate, birthplace, family_name, gender, given_name, preferred_username, sub, created_at, updated_at)
|
|
32
|
+
VALUES
|
|
33
|
+
(1, '8888-08-08', 'Caliban', 'El’Jonson', 'male', 'Li', 'Li', 'abcdefghijklmnopqrstuvwxyz', '4444-04-04', '4444-04-04')
|
|
34
|
+
;
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const user = await getFranceConnectUserInfo(1);
|
|
38
|
+
assert.ok(user);
|
|
39
|
+
assert.deepEqual(user, {
|
|
40
|
+
birthdate: new Date("8888-08-08"),
|
|
41
|
+
birthplace: "Caliban",
|
|
42
|
+
created_at: new Date("4444-04-04"),
|
|
43
|
+
family_name: "El’Jonson",
|
|
44
|
+
gender: "male",
|
|
45
|
+
given_name: "Li",
|
|
46
|
+
preferred_username: "Li",
|
|
47
|
+
sub: "abcdefghijklmnopqrstuvwxyz",
|
|
48
|
+
updated_at: new Date(),
|
|
49
|
+
user_id: 1,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("❎ fail to get an unknown user", async () => {
|
|
54
|
+
const user = await getFranceConnectUserInfo(42);
|
|
55
|
+
|
|
56
|
+
assert.equal(user, undefined);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import type { DatabaseContext, FranceConnectUserInfo } from "#src/types";
|
|
4
|
+
import { type QueryResult } from "pg";
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
export function getFranceConnectUserInfoFactory({ pg }: DatabaseContext) {
|
|
9
|
+
return async function getFranceConnectUserInfo(user_id: number) {
|
|
10
|
+
const { rows }: QueryResult<FranceConnectUserInfo> = await pg.query(
|
|
11
|
+
`
|
|
12
|
+
SELECT *
|
|
13
|
+
FROM franceconnect_userinfo
|
|
14
|
+
WHERE user_id = $1
|
|
15
|
+
`,
|
|
16
|
+
[user_id],
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return rows.shift();
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type GetFranceConnectUserInfoHandler = ReturnType<
|
|
24
|
+
typeof getFranceConnectUserInfoFactory
|
|
25
|
+
>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
export * from "./create.js";
|
|
4
|
+
export * from "./find-by-email.js";
|
|
5
|
+
export * from "./find-by-id.js";
|
|
6
|
+
export * from "./get-by-id.js";
|
|
7
|
+
export * from "./get-franceconnect-user-info.js";
|
|
8
|
+
export * from "./update-user-organization-link.js";
|
|
9
|
+
export * from "./update.js";
|
|
10
|
+
export * from "./upsert-franceconnect-userinfo.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { emptyDatabase, migrate, pg } from "#testing";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { before, beforeEach, suite, test } from "node:test";
|
|
6
|
+
import { updateUserOrganizationLinkFactory } from "./update-user-organization-link.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
const updateUserOrganizationLink = updateUserOrganizationLinkFactory({
|
|
11
|
+
pg: pg as any,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
suite("updateUserOrganizationLink", () => {
|
|
15
|
+
before(migrate);
|
|
16
|
+
beforeEach(emptyDatabase);
|
|
17
|
+
|
|
18
|
+
test("should update the user organization link", async () => {
|
|
19
|
+
await pg.sql`
|
|
20
|
+
INSERT INTO organizations
|
|
21
|
+
(cached_libelle, cached_nom_complet, id, siret, created_at, updated_at)
|
|
22
|
+
VALUES
|
|
23
|
+
('Necron', 'Necrontyr', 1, '⚰️', '1967-12-19', '1967-12-19')
|
|
24
|
+
;
|
|
25
|
+
`;
|
|
26
|
+
await pg.sql`
|
|
27
|
+
INSERT INTO users
|
|
28
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
29
|
+
VALUES
|
|
30
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'Lion', 'El''Jonson', 'I', 'Primarque')
|
|
31
|
+
;
|
|
32
|
+
`;
|
|
33
|
+
await pg.sql`
|
|
34
|
+
INSERT INTO users_organizations
|
|
35
|
+
(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)
|
|
36
|
+
VALUES
|
|
37
|
+
(1, 1, '4444-04-04', '4444-04-04', false, 'no_verification_means_available', false, null, null)
|
|
38
|
+
;
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
const user = await updateUserOrganizationLink(1, 1, {
|
|
42
|
+
is_external: true,
|
|
43
|
+
});
|
|
44
|
+
assert.ok(user.is_external);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { hashToPostgresParams } from "#src/services/postgres";
|
|
4
|
+
import type { DatabaseContext, User, UserOrganizationLink } from "#src/types";
|
|
5
|
+
import type { QueryResult } from "pg";
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
export function updateUserOrganizationLinkFactory({ pg }: DatabaseContext) {
|
|
10
|
+
return async function updateUserOrganizationLink(
|
|
11
|
+
organization_id: number,
|
|
12
|
+
user_id: number,
|
|
13
|
+
fieldsToUpdate: Partial<UserOrganizationLink>,
|
|
14
|
+
) {
|
|
15
|
+
const connection = pg;
|
|
16
|
+
|
|
17
|
+
const fieldsToUpdateWithTimestamps = {
|
|
18
|
+
...fieldsToUpdate,
|
|
19
|
+
updated_at: new Date(),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const { paramsString, valuesString, values } = hashToPostgresParams<User>(
|
|
23
|
+
fieldsToUpdateWithTimestamps,
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const { rows }: QueryResult<UserOrganizationLink> = await connection.query(
|
|
27
|
+
`
|
|
28
|
+
UPDATE users_organizations SET ${paramsString} = ${valuesString}
|
|
29
|
+
WHERE organization_id = $${values.length + 1}
|
|
30
|
+
AND user_id = $${values.length + 2}
|
|
31
|
+
RETURNING *
|
|
32
|
+
`,
|
|
33
|
+
[...values, organization_id, user_id],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return rows.shift()!;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type UpdateUserOrganizationLinkHandler = ReturnType<
|
|
41
|
+
typeof updateUserOrganizationLinkFactory
|
|
42
|
+
>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { emptyDatabase, migrate, pg } from "#testing";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { before, beforeEach, it, suite } from "node:test";
|
|
6
|
+
import { updateUserFactory } from "./update.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
const updateUser = updateUserFactory({ pg: pg as any });
|
|
11
|
+
|
|
12
|
+
suite("updateUserFactory", () => {
|
|
13
|
+
before(migrate);
|
|
14
|
+
beforeEach(emptyDatabase);
|
|
15
|
+
|
|
16
|
+
it("should update the user job", async () => {
|
|
17
|
+
await pg.sql`
|
|
18
|
+
INSERT INTO users
|
|
19
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
20
|
+
VALUES
|
|
21
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'Lion', 'El''Jonson', 'I', 'Primarque');
|
|
22
|
+
`;
|
|
23
|
+
const user = await updateUser(1, { job: "Chevalier de l'Ordre" });
|
|
24
|
+
assert.equal(user.job, "Chevalier de l'Ordre");
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { hashToPostgresParams } from "#src/services/postgres";
|
|
4
|
+
import type { DatabaseContext, User } from "#src/types";
|
|
5
|
+
import type { QueryResult } from "pg";
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
export function updateUserFactory({ pg }: DatabaseContext) {
|
|
10
|
+
return async function updateUser(id: number, fieldsToUpdate: Partial<User>) {
|
|
11
|
+
const fieldsToUpdateWithTimestamps = {
|
|
12
|
+
...fieldsToUpdate,
|
|
13
|
+
updated_at: new Date(),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const { paramsString, valuesString, values } = hashToPostgresParams<User>(
|
|
17
|
+
fieldsToUpdateWithTimestamps,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const { rows }: QueryResult<User> = await pg.query(
|
|
21
|
+
`
|
|
22
|
+
UPDATE users
|
|
23
|
+
SET ${paramsString} = ${valuesString}
|
|
24
|
+
WHERE id = $${values.length + 1}
|
|
25
|
+
RETURNING *
|
|
26
|
+
`,
|
|
27
|
+
[...values, id],
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return rows.shift()!;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type UpdateUserHandler = ReturnType<typeof updateUserFactory>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { emptyDatabase, migrate, pg } from "#testing";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { before, beforeEach, describe, it, mock } from "node:test";
|
|
6
|
+
import { upsertFranceconnectUserinfoFactory } from "./upsert-franceconnect-userinfo.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
const upsertFranceconnectUserinfo = upsertFranceconnectUserinfoFactory({
|
|
11
|
+
pg: pg as any,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe("upsertFranceconnectUserinfo", () => {
|
|
15
|
+
before(migrate);
|
|
16
|
+
beforeEach(emptyDatabase);
|
|
17
|
+
before(() => {
|
|
18
|
+
mock.timers.enable({ apis: ["Date"], now: new Date("4444-04-04") });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should insert a user franceconnect userinfo", async () => {
|
|
22
|
+
await pg.sql`
|
|
23
|
+
INSERT INTO users
|
|
24
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
25
|
+
VALUES
|
|
26
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'i', 'primarque')
|
|
27
|
+
;
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
const user = await upsertFranceconnectUserinfo({
|
|
31
|
+
birthdate: new Date("8888-08-08"),
|
|
32
|
+
birthplace: "Caliban",
|
|
33
|
+
created_at: new Date("4444-04-01"),
|
|
34
|
+
family_name: "El’Jonson",
|
|
35
|
+
gender: "male",
|
|
36
|
+
given_name: "Lion",
|
|
37
|
+
preferred_username: "Li",
|
|
38
|
+
sub: "abcdefghijklmnopqrstuvwxyz",
|
|
39
|
+
updated_at: new Date("4444-04-02"),
|
|
40
|
+
user_id: 1,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
assert.deepEqual(user, {
|
|
44
|
+
birthdate: new Date("8888-08-08"),
|
|
45
|
+
birthplace: "Caliban",
|
|
46
|
+
created_at: new Date("4444-04-01"),
|
|
47
|
+
family_name: "El’Jonson",
|
|
48
|
+
gender: "male",
|
|
49
|
+
given_name: "Lion",
|
|
50
|
+
preferred_username: "Li",
|
|
51
|
+
sub: "abcdefghijklmnopqrstuvwxyz",
|
|
52
|
+
updated_at: new Date("4444-04-04"),
|
|
53
|
+
user_id: 1,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should update a user Verification link", async () => {
|
|
58
|
+
await pg.sql`
|
|
59
|
+
INSERT INTO users
|
|
60
|
+
(id, email, created_at, updated_at, given_name, family_name, phone_number, job)
|
|
61
|
+
VALUES
|
|
62
|
+
(1, 'lion.eljonson@darkangels.world', '4444-04-04', '4444-04-04', 'lion', 'el''jonson', 'i', 'primarque')
|
|
63
|
+
;
|
|
64
|
+
`;
|
|
65
|
+
await pg.sql`
|
|
66
|
+
INSERT INTO franceconnect_userinfo
|
|
67
|
+
(user_id, created_at, updated_at, given_name)
|
|
68
|
+
VALUES
|
|
69
|
+
(1, '4444-04-01', '4444-04-02', 'Lion')
|
|
70
|
+
;
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
const user = await upsertFranceconnectUserinfo({
|
|
74
|
+
user_id: 1,
|
|
75
|
+
preferred_username: "Li",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
assert.deepEqual(user, {
|
|
79
|
+
birthdate: null,
|
|
80
|
+
birthplace: null,
|
|
81
|
+
created_at: new Date("4444-04-01"),
|
|
82
|
+
family_name: null,
|
|
83
|
+
gender: null,
|
|
84
|
+
given_name: "Lion",
|
|
85
|
+
preferred_username: "Li",
|
|
86
|
+
sub: null,
|
|
87
|
+
updated_at: new Date("4444-04-04"),
|
|
88
|
+
user_id: 1,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("❎ fail to update an unknown user", async () => {
|
|
93
|
+
await assert.rejects(
|
|
94
|
+
upsertFranceconnectUserinfo({
|
|
95
|
+
user_id: 42,
|
|
96
|
+
}),
|
|
97
|
+
`error: insert or update on table "franceconnect_userinfo" violates foreign key constraint "franceconnect_userinfo_user_id_fkey"`,
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { hashToPostgresParams } from "#src/services/postgres";
|
|
4
|
+
import type { DatabaseContext, FranceConnectUserInfo } from "#src/types";
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
export function upsertFranceconnectUserinfoFactory({ pg }: DatabaseContext) {
|
|
9
|
+
return async function upsertFranceconnectUserinfo(
|
|
10
|
+
value: Pick<FranceConnectUserInfo, "user_id"> &
|
|
11
|
+
Partial<FranceConnectUserInfo>,
|
|
12
|
+
) {
|
|
13
|
+
const fieldsWithTimestamps = {
|
|
14
|
+
...value,
|
|
15
|
+
updated_at: new Date(),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const { paramsString, valuesString, values } =
|
|
19
|
+
hashToPostgresParams<FranceConnectUserInfo>(fieldsWithTimestamps);
|
|
20
|
+
|
|
21
|
+
const { rows } = await pg.query<FranceConnectUserInfo>(
|
|
22
|
+
`
|
|
23
|
+
INSERT INTO franceconnect_userinfo
|
|
24
|
+
${paramsString}
|
|
25
|
+
VALUES
|
|
26
|
+
${valuesString}
|
|
27
|
+
ON CONFLICT (user_id)
|
|
28
|
+
DO UPDATE
|
|
29
|
+
SET ${paramsString} = ${valuesString}
|
|
30
|
+
RETURNING *
|
|
31
|
+
`,
|
|
32
|
+
[...values],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return rows.shift()!;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type UpsetFranceconnectUserinfoHandler = ReturnType<
|
|
40
|
+
typeof upsertFranceconnectUserinfoFactory
|
|
41
|
+
>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DOMAINS_WHITELIST } from "@proconnect-gouv/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
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { isEntrepriseUnipersonnelle } from "#src/services/organization";
|
|
4
|
+
import type { Organization } from "#src/types";
|
|
5
|
+
import {
|
|
6
|
+
association_org_info,
|
|
7
|
+
entreprise_unipersonnelle_org_info,
|
|
8
|
+
small_association_org_info,
|
|
9
|
+
} from "#testing/seed/organizations";
|
|
10
|
+
import assert from "node:assert/strict";
|
|
11
|
+
import { describe, it } from "node:test";
|
|
12
|
+
|
|
13
|
+
describe("isEntrepriseUnipersonnelle", () => {
|
|
14
|
+
it("should return false for bad call", () => {
|
|
15
|
+
assert.equal(isEntrepriseUnipersonnelle({} as Organization), false);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should return true for unipersonnelle organization", () => {
|
|
19
|
+
assert.equal(
|
|
20
|
+
isEntrepriseUnipersonnelle(entreprise_unipersonnelle_org_info),
|
|
21
|
+
true,
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("should return false for association", () => {
|
|
26
|
+
assert.equal(isEntrepriseUnipersonnelle(association_org_info), false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should return false for small association", () => {
|
|
30
|
+
assert.equal(isEntrepriseUnipersonnelle(small_association_org_info), false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import type { Organization } from "#src/types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* These fonctions return approximate results. As the data tranche effectifs is
|
|
7
|
+
* two years old. Consequently, an organization that growths quickly within the
|
|
8
|
+
* first two years of his existence can be miss-identified as unipersonnelle by
|
|
9
|
+
* this fonction.
|
|
10
|
+
*/
|
|
11
|
+
export function isEntrepriseUnipersonnelle({
|
|
12
|
+
cached_libelle_categorie_juridique,
|
|
13
|
+
cached_tranche_effectifs,
|
|
14
|
+
}: Pick<
|
|
15
|
+
Organization,
|
|
16
|
+
"cached_libelle_categorie_juridique" | "cached_tranche_effectifs"
|
|
17
|
+
>): boolean {
|
|
18
|
+
// check that the organization has the right catégorie juridique
|
|
19
|
+
const cat_jur_ok = [
|
|
20
|
+
"Entrepreneur individuel",
|
|
21
|
+
"Société à responsabilité limitée (sans autre indication)",
|
|
22
|
+
"SAS, société par actions simplifiée",
|
|
23
|
+
].includes(cached_libelle_categorie_juridique || "");
|
|
24
|
+
|
|
25
|
+
// check that the organization has the right tranche effectifs
|
|
26
|
+
const tra_eff_ok = [null, "NN", "00", "01"].includes(
|
|
27
|
+
cached_tranche_effectifs,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return cat_jur_ok && tra_eff_ok;
|
|
31
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { chain } from "lodash-es";
|
|
4
|
+
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
export function hashToPostgresParams<T>(fieldsToUpdate: Partial<T>): {
|
|
8
|
+
// postgres column-list syntax
|
|
9
|
+
paramsString: string;
|
|
10
|
+
// postgres column-list syntax for prepared statement
|
|
11
|
+
valuesString: string;
|
|
12
|
+
values: any[];
|
|
13
|
+
} {
|
|
14
|
+
const paramsString = "(" + Object.keys(fieldsToUpdate).join(", ") + ")";
|
|
15
|
+
// 'email, encrypted_password'
|
|
16
|
+
|
|
17
|
+
const valuesString =
|
|
18
|
+
"(" +
|
|
19
|
+
chain(fieldsToUpdate)
|
|
20
|
+
// { email: 'email@xy.z', encrypted_password: 'hash' }
|
|
21
|
+
.toPairs()
|
|
22
|
+
// [[ 'email', 'email@xy.z'], ['encrypted_password', 'hash' ]]
|
|
23
|
+
.map((_value, index) => `$${index + 1}`)
|
|
24
|
+
// [ '$1', '$2' ]
|
|
25
|
+
.join(", ")
|
|
26
|
+
// '$1, $2'
|
|
27
|
+
.value() +
|
|
28
|
+
")";
|
|
29
|
+
|
|
30
|
+
const values = Object.values(fieldsToUpdate);
|
|
31
|
+
// [ 'email@xy.z', 'hash' ]
|
|
32
|
+
|
|
33
|
+
return { paramsString, valuesString, values };
|
|
34
|
+
}
|