From ba23b26503ec928e183f9e9b449adba4834665aa Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Fri, 18 Oct 2024 11:53:54 +0200 Subject: [PATCH] feat(email): use smtp protocol --- cypress/e2e/delete_totp/index.cy.ts | 65 +++------ package-lock.json | 200 +++++++++++++++++++++++++++ package.json | 7 + src/config/env.ts | 1 + src/config/env.zod.ts | 1 + src/connectors/mail.ts | 22 +++ src/managers/user.ts | 27 ++-- src/views/mails/delete-free-totp.ejs | 18 --- tsconfig.json | 3 +- 9 files changed, 268 insertions(+), 76 deletions(-) create mode 100644 src/connectors/mail.ts delete mode 100644 src/views/mails/delete-free-totp.ejs diff --git a/cypress/e2e/delete_totp/index.cy.ts b/cypress/e2e/delete_totp/index.cy.ts index 19a4003c..a494618d 100644 --- a/cypress/e2e/delete_totp/index.cy.ts +++ b/cypress/e2e/delete_totp/index.cy.ts @@ -1,17 +1,4 @@ describe("delete TOTP connexion", () => { - before(() => { - cy.mailslurp().then((mailslurp) => - mailslurp.inboxController.deleteAllInboxEmails({ - inboxId: "eab4ab97-875d-4ec7-bdcc-04323948ee63", - }), - ); - cy.mailslurp().then((mailslurp) => - mailslurp.inboxController.deleteAllInboxEmails({ - inboxId: "c9fabb94-9274-4ece-a3d0-54b1987c8588", - }), - ); - }); - it("should delete TOTP application", function () { cy.visit("/connection-and-account"); @@ -23,21 +10,15 @@ describe("delete TOTP connexion", () => { cy.contains("L’application d’authentification a bien été supprimée."); - cy.mailslurp() - // use inbox id and a timeout of 30 seconds - .then((mailslurp) => - mailslurp.waitForLatestEmail( - "eab4ab97-875d-4ec7-bdcc-04323948ee63", - 60000, - true, - ), - ) - // check subject of deletion email - .then((email) => { - expect(email.subject).to.include( - "Suppression d'une application d'authentification à double facteur", - ); - }); + cy.maildevGetLastMessage().then((email) => { + expect(email.subject).to.equal( + "Suppression d'une application d'authentification à double facteur", + ); + cy.maildevVisitMessageById(email.id); + cy.contains( + "L'application a été supprimée comme étape de connexion à deux facteurs.", + ); + }); }); it("should not be ask to sign with TOTP", function () { @@ -57,26 +38,22 @@ describe("delete TOTP connexion", () => { cy.contains("Désactiver la validation en deux étapes").click(); - cy.mailslurp() - // use inbox id and a timeout of 30 seconds - .then((mailslurp) => - mailslurp.waitForLatestEmail( - "c9fabb94-9274-4ece-a3d0-54b1987c8588", - 60000, - true, - ), - ) - // check subject of deletion email - .then((email) => { - expect(email.subject).to.include( - "Désactivation de la validation en deux étapes", - ); - }); + cy.maildevGetLastMessage().then((email) => { + console.log(email); + + expect(email.subject).to.equal( + "Suppression d'une application d'authentification à double facteur", + ); + cy.maildevVisitMessageById(email.id); + cy.contains( + "Votre compte MonComptePro n'est plus protégé par la validation en deux", + ); + }); }); it("should not be ask to sign with TOTP", function () { cy.visit("http://localhost:4000"); - cy.get("button.proconnect-button").click(); + cy.get("button.œproconnect-button").click(); cy.login("c9fabb94-9274-4ece-a3d0-54b1987c8588@mailslurp.com"); cy.contains('"amr": [\n "pwd"\n ],'); diff --git a/package-lock.json b/package-lock.json index 93d77d1e..28da1683 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,10 @@ "@dotenvx/dotenvx": "^1.19.2", "@fullhuman/postcss-purgecss": "^6.0.0", "@gouvfr/dsfr": "^1.12.1", + "@kitajs/html": "^4.2.4", + "@kitajs/ts-html-plugin": "^4.1.0", "@numerique-gouv/crisp": "https://github.com/douglasduteil/crisp/releases/download/v1.6.1/douglasduteil-crisp-1.6.1.tgz", + "@numerique-gouv/moncomptepro.email": "workspaces:*", "@panva/jose": "^1.9.3", "@sentry/node": "^7.112.2", "@sentry/tracing": "^7.114.0", @@ -46,6 +49,7 @@ "express-basic-auth": "^1.2.1", "express-session": "^1.18.1", "helmet": "^7.1.0", + "html-to-text": "^9.0.5", "http-errors": "^2.0.0", "ioredis": "^5.4.1", "is-disposable-email-domain": "^1.0.7", @@ -57,6 +61,7 @@ "nanoid": "^3.3.6", "nocache": "^4.0.0", "node-pg-migrate": "^7.6.1", + "nodemailer": "^6.9.15", "npm-run-all2": "^6.1.2", "oidc-provider": "^8.5.1", "pg": "^8.13.0", @@ -74,11 +79,13 @@ "@sinonjs/fake-timers": "^11.2.2", "@types/chai": "^5.0.0", "@types/chai-as-promised": "^7.1.8", + "@types/html-to-text": "^9.0.4", "@types/http-errors": "^2.0.4", "@types/lodash": "^4.17.10", "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.7", "@types/node": "^22.1.0", + "@types/nodemailer": "^6.4.16", "@types/oidc-provider": "^8.5.2", "@types/qrcode": "^1.5.5", "@types/sinonjs__fake-timers": "^8.1.5", @@ -1286,6 +1293,19 @@ "win32" ] }, + "node_modules/@selderee/plugin-htmlparser2": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", + "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "selderee": "^0.11.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/@sentry-internal/tracing": { "version": "7.112.2", "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.112.2.tgz", @@ -1703,6 +1723,13 @@ "@types/express": "*" } }, + "node_modules/@types/html-to-text": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/html-to-text/-/html-to-text-9.0.4.tgz", + "integrity": "sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/http-assert": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz", @@ -1796,6 +1823,16 @@ "undici-types": "~6.19.2" } }, + "node_modules/@types/nodemailer": { + "version": "6.4.16", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.16.tgz", + "integrity": "sha512-uz6hN6Pp0upXMcilM61CoKyjT7sskBoOWpptkjjJp8jIMlTdc3xG01U7proKkXzruMS4hS0zqtHNkNPFB20rKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/oidc-provider": { "version": "8.5.2", "resolved": "https://registry.npmjs.org/@types/oidc-provider/-/oidc-provider-8.5.2.tgz", @@ -3455,6 +3492,15 @@ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==" }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", @@ -3543,6 +3589,61 @@ "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -3757,6 +3858,18 @@ "node": ">=8.6" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -4664,6 +4777,41 @@ "node": ">=16.0.0" } }, + "node_modules/html-to-text": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", + "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", + "license": "MIT", + "dependencies": { + "@selderee/plugin-htmlparser2": "^0.11.0", + "deepmerge": "^4.3.1", + "dom-serializer": "^2.0.0", + "htmlparser2": "^8.0.2", + "selderee": "^0.11.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/http-assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", @@ -5348,6 +5496,15 @@ "node": "> 0.8" } }, + "node_modules/leac": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", + "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -6068,6 +6225,15 @@ } } }, + "node_modules/nodemailer": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", + "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6415,6 +6581,19 @@ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" }, + "node_modules/parseley": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", + "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", + "license": "MIT", + "dependencies": { + "leac": "^0.6.0", + "peberminta": "^0.9.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -6487,6 +6666,15 @@ "node": ">= 14.16" } }, + "node_modules/peberminta": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", + "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -7317,6 +7505,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/selderee": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", + "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", + "license": "MIT", + "dependencies": { + "parseley": "^0.12.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", diff --git a/package.json b/package.json index fa566362..007e1b01 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,9 @@ "@fullhuman/postcss-purgecss": "^6.0.0", "@gouvfr/dsfr": "^1.12.1", "@numerique-gouv/crisp": "https://github.com/douglasduteil/crisp/releases/download/v1.6.1/douglasduteil-crisp-1.6.1.tgz", + "@numerique-gouv/moncomptepro.email": "workspaces:*", + "@kitajs/html": "^4.2.4", + "@kitajs/ts-html-plugin": "^4.1.0", "@panva/jose": "^1.9.3", "@sentry/node": "^7.112.2", "@sentry/tracing": "^7.114.0", @@ -72,6 +75,7 @@ "express-basic-auth": "^1.2.1", "express-session": "^1.18.1", "helmet": "^7.1.0", + "html-to-text": "^9.0.5", "http-errors": "^2.0.0", "ioredis": "^5.4.1", "is-disposable-email-domain": "^1.0.7", @@ -83,6 +87,7 @@ "nanoid": "^3.3.6", "nocache": "^4.0.0", "node-pg-migrate": "^7.6.1", + "nodemailer": "^6.9.15", "npm-run-all2": "^6.1.2", "oidc-provider": "^8.5.1", "pg": "^8.13.0", @@ -100,11 +105,13 @@ "@sinonjs/fake-timers": "^11.2.2", "@types/chai": "^5.0.0", "@types/chai-as-promised": "^7.1.8", + "@types/html-to-text": "^9.0.4", "@types/http-errors": "^2.0.4", "@types/lodash": "^4.17.10", "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.7", "@types/node": "^22.1.0", + "@types/nodemailer": "^6.4.16", "@types/oidc-provider": "^8.5.2", "@types/qrcode": "^1.5.5", "@types/sinonjs__fake-timers": "^8.1.5", diff --git a/src/config/env.ts b/src/config/env.ts index 973376aa..c59a8036 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -70,6 +70,7 @@ export const { SENTRY_DSN, SESSION_COOKIE_SECRET, SESSION_MAX_AGE_IN_SECONDS, + SMTP_URL, SYMMETRIC_ENCRYPTION_KEY, TEST_CONTACT_EMAIL, TRUSTED_BROWSER_COOKIE_MAX_AGE_IN_SECONDS, diff --git a/src/config/env.zod.ts b/src/config/env.zod.ts index 7da09100..f0fc05ec 100644 --- a/src/config/env.zod.ts +++ b/src/config/env.zod.ts @@ -18,6 +18,7 @@ export const connectorEnvSchema = z.object({ INSEE_CONSUMER_SECRET: z.string(), REDIS_URL: z.string().url().default("redis://:@127.0.0.1:6379"), SENTRY_DSN: z.string().default(""), + SMTP_URL: z.string().default("smtp://localhost:1025"), }); export const featureTogglesEnvSchema = z.object({ diff --git a/src/connectors/mail.ts b/src/connectors/mail.ts new file mode 100644 index 00000000..efc6780f --- /dev/null +++ b/src/connectors/mail.ts @@ -0,0 +1,22 @@ +// + +import { convert } from "html-to-text"; +import { createTransport, type SendMailOptions } from "nodemailer"; +import { SMTP_URL } from "../config/env"; + +// + +const transporter = createTransport({ + url: SMTP_URL, +}); + +// + +export function sendMail(options: Omit) { + return transporter.sendMail({ + text: + typeof options.html === "string" ? convert(options.html) : options.text, + ...options, + from: "nepasrepondre@email.moncomptepro.beta.gouv.fr", + }); +} diff --git a/src/managers/user.ts b/src/managers/user.ts index 44ec3930..b5e95784 100644 --- a/src/managers/user.ts +++ b/src/managers/user.ts @@ -1,3 +1,4 @@ +import { DeleteFreeTotpMail } from "@numerique-gouv/moncomptepro.email"; import { isEmpty } from "lodash-es"; import { EmailUnavailableError, @@ -11,8 +12,9 @@ import { UserNotFoundError, WeakPasswordError, } from "../config/errors"; -import { sendMail } from "../connectors/brevo"; +import { sendMail as legacySendMail } from "../connectors/brevo"; import { isEmailSafeToSendTransactional } from "../connectors/debounce"; +import { sendMail } from "../connectors/mail"; import { MAGIC_LINK_TOKEN_EXPIRATION_DURATION_IN_MINUTES, @@ -178,7 +180,7 @@ export const sendEmailAddressVerificationEmail = async ({ verify_email_sent_at: new Date(), }); - await sendMail({ + await legacySendMail({ to: [user.email], subject: "Vérification de votre adresse email", template: "verify-email", @@ -197,7 +199,7 @@ export const sendDeleteUserEmail = async ({ user_id }: { user_id: number }) => { } const { given_name, family_name, email } = user; - return sendMail({ + return legacySendMail({ to: [email], subject: "Suppression de compte", template: "delete-account", @@ -220,8 +222,7 @@ export const sendDeleteFreeTOTPApplicationEmail = async ({ to: [email], subject: "Suppression d'une application d'authentification à double facteur", - template: "delete-free-totp", - params: { given_name, family_name }, + html: DeleteFreeTotpMail({ given_name, family_name }), }); }; @@ -232,7 +233,7 @@ export const sendDisable2faMail = async ({ user_id }: { user_id: number }) => { } const { given_name, family_name, email } = user; - return sendMail({ + return legacySendMail({ to: [email], subject: "Désactivation de la validation en deux étapes", template: "delete-2fa-protection", @@ -250,7 +251,7 @@ export const sendChangeAppliTotpEmail = async ({ throw new UserNotFoundError(); } const { given_name, family_name, email } = user; - return sendMail({ + return legacySendMail({ to: [email], subject: "Changement d'application d’authentification", template: "update-totp-application", @@ -269,7 +270,7 @@ export const sendDeleteAccessKeyMail = async ({ } const { given_name, family_name, email } = user; - return sendMail({ + return legacySendMail({ to: [email], subject: "Alerte de sécurité", template: "delete-access-key", @@ -288,7 +289,7 @@ export const sendAddFreeTOTPEmail = async ({ } const { given_name, family_name, email } = user; - return sendMail({ + return legacySendMail({ to: [email], subject: "Validation en deux étapes activée", template: "add-2fa", @@ -307,7 +308,7 @@ export const sendActivateAccessKeyMail = async ({ } const { given_name, family_name, email } = user; - return sendMail({ + return legacySendMail({ to: [email], subject: "Alerte de sécurité", template: "add-access-key", @@ -354,7 +355,7 @@ export const sendUpdatePersonalInformationEmail = async ({ } if (previousInformations !== newInformation) { - return sendMail({ + return legacySendMail({ to: [email], subject: "Mise à jour de vos données personnelles", template: "update-personal-data", @@ -428,7 +429,7 @@ export const sendSendMagicLinkEmail = async ( magic_link_sent_at: new Date(), }); - await sendMail({ + await legacySendMail({ to: [user.email], subject: "Lien de connexion à ProConnect", template: "magic-link", @@ -487,7 +488,7 @@ export const sendResetPasswordEmail = async ( reset_password_sent_at: new Date(), }); - await sendMail({ + await legacySendMail({ to: [user.email], subject: "Instructions pour la réinitialisation du mot de passe", template: "reset-password", diff --git a/src/views/mails/delete-free-totp.ejs b/src/views/mails/delete-free-totp.ejs deleted file mode 100644 index c6a25f27..00000000 --- a/src/views/mails/delete-free-totp.ejs +++ /dev/null @@ -1,18 +0,0 @@ -Bonjour <%= given_name %> <%= family_name %>,

-L'application a été supprimée comme étape de connexion à deux facteurs. -

- - - - Si vous n'avez pas supprimé cette application, quelqu'un utilise peut-être - votre compte. Faites-le nous savoir en répondant à cet email. - - - -

-Cordialement, -

-L’équipe ProConnect diff --git a/tsconfig.json b/tsconfig.json index 61fa99de..a4ce8b07 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,8 @@ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, + "jsx": "react-jsx", + "jsxImportSource": "@kitajs/html", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "isolatedModules": true, @@ -16,6 +18,5 @@ "rootDir": ".", "verbatimModuleSyntax": true }, - "exclude": ["packages/*"], "extends": "@tsconfig/node20/tsconfig.json" }