From 36ff2e4b7e1d4a81d96efae6b6b822b6ee520319 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Tue, 17 Sep 2024 16:08:24 +0200 Subject: [PATCH 1/7] chore(tsc): allow entry point of type library Allow importing all types from the package with : ```json { "compilerOptions": { "types": ["@numerique-gouv/moncomptepro/src/types"] } } ``` --- package-lock.json | 7 +++---- package.json | 2 +- src/types/index.d.ts | 13 ++++++++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1d274a65c..0d09c9ac4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@types/ejs": "^3.1.5", "@types/express": "^4.17.21", "@types/express-session": "^1.18.0", + "@types/lodash-es": "^4.17.12", "@types/morgan": "^1.9.9", "@zootools/email-spell-checker": "^1.12.0", "await-to-js": "^3.0.0", @@ -73,7 +74,6 @@ "@types/chai-as-promised": "^7.1.8", "@types/http-errors": "^2.0.4", "@types/lodash": "^4.17.0", - "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.7", "@types/node": "^22.1.0", "@types/oidc-provider": "^8.5.2", @@ -1709,14 +1709,13 @@ "node_modules/@types/lodash": { "version": "4.17.0", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", - "dev": true + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==" }, "node_modules/@types/lodash-es": { "version": "4.17.12", "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", - "dev": true, + "license": "MIT", "dependencies": { "@types/lodash": "*" } diff --git a/package.json b/package.json index f61a4f24e..eb574c8f9 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@types/ejs": "^3.1.5", "@types/express": "^4.17.21", "@types/express-session": "^1.18.0", + "@types/lodash-es": "^4.17.12", "@types/morgan": "^1.9.9", "@zootools/email-spell-checker": "^1.12.0", "await-to-js": "^3.0.0", @@ -99,7 +100,6 @@ "@types/chai-as-promised": "^7.1.8", "@types/http-errors": "^2.0.4", "@types/lodash": "^4.17.0", - "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.7", "@types/node": "^22.1.0", "@types/oidc-provider": "^8.5.2", diff --git a/src/types/index.d.ts b/src/types/index.d.ts index c2849eb93..84613d2af 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1,3 +1,14 @@ +/// +/// +/// /// -/// +/// +/// +/// +/// +/// +/// /// +/// +/// +/// From 64c63f32f3735c1fa650d9065e486fdeba0dcccd Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Tue, 17 Sep 2024 16:26:52 +0200 Subject: [PATCH 2/7] debug: move markDomainAsVerified --- src/controllers/api.ts | 2 +- src/managers/organization/join.ts | 3 +- src/managers/organization/main.ts | 63 +------------------ .../organization/markDomainAsVerified.ts | 61 ++++++++++++++++++ 4 files changed, 66 insertions(+), 63 deletions(-) create mode 100644 src/managers/organization/markDomainAsVerified.ts diff --git a/src/controllers/api.ts b/src/controllers/api.ts index 0aafb1988..30762cb0b 100644 --- a/src/controllers/api.ts +++ b/src/controllers/api.ts @@ -10,7 +10,7 @@ import notificationMessages from "../config/notification-messages"; import { getOrganizationInfo } from "../connectors/api-sirene"; import { sendModerationProcessedEmail } from "../managers/moderation"; import { forceJoinOrganization } from "../managers/organization/join"; -import { markDomainAsVerified } from "../managers/organization/main"; +import { markDomainAsVerified } from "../managers/organization/markDomainAsVerified"; import { getUserOrganizationLink } from "../repositories/organization/getters"; import { idSchema, diff --git a/src/managers/organization/join.ts b/src/managers/organization/join.ts index 7bc9d1d87..5c1518dc3 100644 --- a/src/managers/organization/join.ts +++ b/src/managers/organization/join.ts @@ -51,7 +51,8 @@ import { } from "../../services/organization"; import { isEmailValid } from "../../services/security"; import { unableToAutoJoinOrganizationMd } from "../../views/mails/unable-to-auto-join-organization"; -import { getOrganizationsByUserId, markDomainAsVerified } from "./main"; +import { getOrganizationsByUserId } from "./main"; +import { markDomainAsVerified } from "./markDomainAsVerified"; export const doSuggestOrganizations = async ({ user_id, diff --git a/src/managers/organization/main.ts b/src/managers/organization/main.ts index a3ae80dae..248646ac5 100644 --- a/src/managers/organization/main.ts +++ b/src/managers/organization/main.ts @@ -1,21 +1,12 @@ -import { isEmpty, some } from "lodash-es"; +import { isEmpty } from "lodash-es"; import { NotFoundError } from "../../config/errors"; -import { - addDomain, - findEmailDomainsByOrganizationId, -} from "../../repositories/email-domain"; import { findByUserId, findById as findOrganizationById, findPendingByUserId, - getUsers, } from "../../repositories/organization/getters"; -import { - deleteUserOrganization, - updateUserOrganizationLink, -} from "../../repositories/organization/setters"; +import { deleteUserOrganization } from "../../repositories/organization/setters"; import { setSelectedOrganizationId } from "../../repositories/redis/selected-organization"; -import { getEmailDomain } from "../../services/email"; export const getOrganizationsByUserId = findByUserId; export const getOrganizationById = findOrganizationById; @@ -50,56 +41,6 @@ export const quitOrganization = async ({ return true; }; -export const markDomainAsVerified = async ({ - organization_id, - domain, - domain_verification_type, -}: { - organization_id: number; - domain: string; - domain_verification_type: EmailDomain["verification_type"]; -}) => { - const organization = await findOrganizationById(organization_id); - if (isEmpty(organization)) { - throw new NotFoundError(); - } - const emailDomains = await findEmailDomainsByOrganizationId(organization_id); - - if ( - !some(emailDomains, { domain, verification_type: domain_verification_type }) - ) { - await addDomain({ - organization_id, - domain, - verification_type: domain_verification_type, - }); - } - - const usersInOrganization = await getUsers(organization_id); - - await Promise.all( - usersInOrganization.map( - ({ id, email, verification_type: link_verification_type }) => { - const userDomain = getEmailDomain(email); - if ( - userDomain === domain && - [ - null, - "no_verification_means_available", - "no_verification_means_for_entreprise_unipersonnelle", - ].includes(link_verification_type) - ) { - return updateUserOrganizationLink(organization_id, id, { - verification_type: "domain", - }); - } - - return null; - }, - ), - ); -}; - export const selectOrganization = async ({ user_id, organization_id, diff --git a/src/managers/organization/markDomainAsVerified.ts b/src/managers/organization/markDomainAsVerified.ts new file mode 100644 index 000000000..a8c313da2 --- /dev/null +++ b/src/managers/organization/markDomainAsVerified.ts @@ -0,0 +1,61 @@ +import { isEmpty, some } from "lodash"; +import { NotFoundError } from "../../config/errors"; +import { + addDomain, + findEmailDomainsByOrganizationId, +} from "../../repositories/email-domain"; +import { findById, getUsers } from "../../repositories/organization/getters"; +import { updateUserOrganizationLink } from "../../repositories/organization/setters"; +import { getEmailDomain } from "../../services/email"; + +// + +export const markDomainAsVerified = async ({ + organization_id, + domain, + domain_verification_type, +}: { + organization_id: number; + domain: string; + domain_verification_type: EmailDomain["verification_type"]; +}) => { + const organization = await findById(organization_id); + if (isEmpty(organization)) { + throw new NotFoundError(); + } + const emailDomains = await findEmailDomainsByOrganizationId(organization_id); + + if ( + !some(emailDomains, { domain, verification_type: domain_verification_type }) + ) { + await addDomain({ + organization_id, + domain, + verification_type: domain_verification_type, + }); + } + + const usersInOrganization = await getUsers(organization_id); + + await Promise.all( + usersInOrganization.map( + ({ id, email, verification_type: link_verification_type }) => { + const userDomain = getEmailDomain(email); + if ( + userDomain === domain && + [ + null, + "no_verification_means_available", + "no_verification_means_for_entreprise_unipersonnelle", + ].includes(link_verification_type) + ) { + return updateUserOrganizationLink(organization_id, id, { + verification_type: "domain", + }); + } + + return null; + }, + ), + ); +}; From 7428b2c203a8b1042a8c96d5a6700c5ac82754c4 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Thu, 19 Sep 2024 18:03:53 +0200 Subject: [PATCH 3/7] chore(tsc): add declaration files --- tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.json b/tsconfig.json index a48c63f19..a1ef50dd6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, + "declaration": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "module": "Preserve", From 04beeb38891787619c40010feda13e7d84f2cb22 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Thu, 19 Sep 2024 18:14:39 +0200 Subject: [PATCH 4/7] ci(github): ensure that tsc declaration works --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f1ee492f..4343fe3c5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,5 +22,5 @@ jobs: node-version-file: package.json - run: CYPRESS_INSTALL_BINARY=0 npm ci --include=dev - run: npm run test:lint - - run: npm run test:type-check + - run: npm exec tsc - run: npm run test:unit From a1cb88e12e46e7fe4f20934bf7769a8b7008dfc5 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Thu, 19 Sep 2024 18:18:50 +0200 Subject: [PATCH 5/7] chore(pkg): add connector and manager exports --- package.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/package.json b/package.json index eb574c8f9..70e19dd7b 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,20 @@ "imports": { "#cypress/*": "./cypress/*.ts" }, + "exports": { + "./connectors/*": { + "default": "./build/connectors/*.js" + }, + "./managers/*": { + "default": "./build/managers/*.js" + }, + "./types": { + "default": "./src/types/index.d.ts" + }, + ".": { + "default": "./src/index.ts" + } + }, "main": "src/index.js", "scripts": { "build": "run-s build:**", From be03264c4ee54cb005ef838f32b1c566ef185852 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Thu, 19 Sep 2024 18:48:15 +0200 Subject: [PATCH 6/7] chore(managers): add necessary type annotation --- src/managers/webauthn.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/managers/webauthn.ts b/src/managers/webauthn.ts index 72cad24c2..97a4ddec8 100644 --- a/src/managers/webauthn.ts +++ b/src/managers/webauthn.ts @@ -8,6 +8,8 @@ import { } from "@simplewebauthn/server"; import type { AuthenticationResponseJSON, + PublicKeyCredentialCreationOptionsJSON, + PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON, } from "@simplewebauthn/types"; import { isEmpty } from "lodash-es"; @@ -115,7 +117,10 @@ export const deleteUserAuthenticator = async ( return true; }; -export const getRegistrationOptions = async (email: string) => { +export const getRegistrationOptions: (email: string) => Promise<{ + updatedUser: User; + registrationOptions: PublicKeyCredentialCreationOptionsJSON; +}> = async (email) => { const user = await findUserByEmail(email); if (isEmpty(user)) { @@ -232,10 +237,13 @@ export const verifyRegistration = async ({ return { userVerified: user_verified, user: await enableForce2fa(user.id) }; }; -export const getAuthenticationOptions = async ( +export const getAuthenticationOptions: ( email: string | undefined, isSecondFactorAuthentication: boolean, -) => { +) => Promise<{ + updatedUser: User; + authenticationOptions: PublicKeyCredentialRequestOptionsJSON; +}> = async (email, isSecondFactorAuthentication) => { if (!email) { throw new NotFoundError(); } From 0769297f523ad4a57ba878cb57be27dcecbbf896 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Fri, 20 Sep 2024 14:17:16 +0200 Subject: [PATCH 7/7] fix(manager): wrong lodash import --- src/managers/organization/markDomainAsVerified.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/organization/markDomainAsVerified.ts b/src/managers/organization/markDomainAsVerified.ts index a8c313da2..79b53099e 100644 --- a/src/managers/organization/markDomainAsVerified.ts +++ b/src/managers/organization/markDomainAsVerified.ts @@ -1,4 +1,4 @@ -import { isEmpty, some } from "lodash"; +import { isEmpty, some } from "lodash-es"; import { NotFoundError } from "../../config/errors"; import { addDomain,