From 285860ec9ea16b16b999860905f54aaecd82d492 Mon Sep 17 00:00:00 2001 From: Luke Vella Date: Fri, 10 Jan 2025 14:27:08 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Use=20mailp?= =?UTF-8?q?it=20as=20dev/test=20smtp=20server=20(#1486)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 3 +- apps/web/.env.test | 2 +- apps/web/package.json | 1 - apps/web/tests/authentication.spec.ts | 31 +--- apps/web/tests/create-delete-poll.spec.ts | 11 +- apps/web/tests/edit-options.spec.ts | 8 - apps/web/tests/mailpit/mailpit.ts | 56 +++++++ apps/web/tests/mailpit/types.ts | 46 ++++++ apps/web/tests/new-poll-page.ts | 2 +- apps/web/tests/vote-and-comment.spec.ts | 21 +-- docker-compose.dev.yml | 4 +- yarn.lock | 181 +--------------------- 12 files changed, 124 insertions(+), 242 deletions(-) create mode 100644 apps/web/tests/mailpit/mailpit.ts create mode 100644 apps/web/tests/mailpit/types.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ff9c6223..828218b14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,8 +69,7 @@ jobs: - uses: ./.github/actions/yarn-install - name: Install system dependencies - run: | - sudo apt-get update + run: sudo apt-get update - name: Install playwright dependencies run: yarn playwright install --with-deps chromium diff --git a/apps/web/.env.test b/apps/web/.env.test index 1364428fe..772461260 100644 --- a/apps/web/.env.test +++ b/apps/web/.env.test @@ -5,4 +5,4 @@ SECRET_PASSWORD=abcdef1234567890abcdef1234567890 DATABASE_URL=postgres://postgres:postgres@localhost:5450/rallly SUPPORT_EMAIL=support@rallly.co SMTP_HOST=localhost -SMTP_PORT=4025 \ No newline at end of file +SMTP_PORT=1025 \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index d5b1dcbf3..a418276a2 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -97,7 +97,6 @@ "cross-env": "^7.0.3", "i18next-scanner": "^4.2.0", "i18next-scanner-typescript": "^1.1.1", - "smtp-tester": "^2.1.0", "vitest": "^2.1.1", "wait-on": "^6.0.1" } diff --git a/apps/web/tests/authentication.spec.ts b/apps/web/tests/authentication.spec.ts index 59005d313..43c874df5 100644 --- a/apps/web/tests/authentication.spec.ts +++ b/apps/web/tests/authentication.spec.ts @@ -1,33 +1,24 @@ import { expect, test } from "@playwright/test"; import { prisma } from "@rallly/database"; import { load } from "cheerio"; -import smtpTester from "smtp-tester"; + +import { captureEmailHTML } from "./mailpit/mailpit"; const testUserEmail = "test@example.com"; -let mailServer: smtpTester.MailServer; + /** * Get the 6-digit code from the email * @returns 6-digit code */ const getCode = async () => { - const { email } = await mailServer.captureOne(testUserEmail, { - wait: 5000, - }); + const html = await captureEmailHTML(testUserEmail); - if (!email.html) { - throw new Error("Email doesn't contain HTML"); - } - - const $ = load(email.html); + const $ = load(html); return $("#code").text().trim(); }; test.describe.serial(() => { - test.beforeAll(() => { - mailServer = smtpTester.init(4025); - }); - test.afterAll(async () => { try { await prisma.user.deleteMany({ @@ -38,8 +29,6 @@ test.describe.serial(() => { } catch { // User doesn't exist } - - mailServer.stop(() => {}); }); test.describe("new user", () => { @@ -110,15 +99,9 @@ test.describe.serial(() => { await page.getByRole("button", { name: "Login with Email" }).click(); - const { email } = await mailServer.captureOne(testUserEmail, { - wait: 5000, - }); + const html = await captureEmailHTML(testUserEmail); - if (!email.html) { - throw new Error("Email doesn't contain HTML"); - } - - const $ = load(email.html); + const $ = load(html); const magicLink = $("#magicLink").attr("href"); diff --git a/apps/web/tests/create-delete-poll.spec.ts b/apps/web/tests/create-delete-poll.spec.ts index f29b715fb..e4cb110cd 100644 --- a/apps/web/tests/create-delete-poll.spec.ts +++ b/apps/web/tests/create-delete-poll.spec.ts @@ -1,20 +1,15 @@ import type { Page } from "@playwright/test"; import { expect, test } from "@playwright/test"; -import type { MailServer } from "smtp-tester"; -import smtpTester from "smtp-tester"; import { NewPollPage } from "tests/new-poll-page"; +import { deleteAllMessages } from "./mailpit/mailpit"; + test.describe.serial(() => { let page: Page; - let mailServer: MailServer; test.beforeAll(async ({ browser }) => { page = await browser.newPage(); - mailServer = smtpTester.init(4025); - }); - - test.afterAll(async () => { - mailServer.stop(() => {}); + await deleteAllMessages(); // Clean the mailbox before tests }); test("create a new poll", async () => { diff --git a/apps/web/tests/edit-options.spec.ts b/apps/web/tests/edit-options.spec.ts index 7e3058bfd..02cb503d0 100644 --- a/apps/web/tests/edit-options.spec.ts +++ b/apps/web/tests/edit-options.spec.ts @@ -1,18 +1,14 @@ import type { Page } from "@playwright/test"; import { expect, test } from "@playwright/test"; -import type { MailServer } from "smtp-tester"; -import smtpTester from "smtp-tester"; import type { EditOptionsPage } from "tests/edit-options-page"; import { NewPollPage } from "tests/new-poll-page"; test.describe("edit options", () => { let page: Page; let editOptionsPage: EditOptionsPage; - let mailServer: MailServer; test.beforeAll(async ({ browser }) => { page = await browser.newPage(); - mailServer = smtpTester.init(4025); const newPollPage = new NewPollPage(page); await newPollPage.goto(); const pollPage = await newPollPage.createPollAndCloseDialog(); @@ -20,10 +16,6 @@ test.describe("edit options", () => { editOptionsPage = await pollPage.editOptions(); }); - test.afterAll(async () => { - mailServer.stop(() => {}); - }); - test("should show warning when deleting options with votes in them", async () => { editOptionsPage.switchToSpecifyTimes(); diff --git a/apps/web/tests/mailpit/mailpit.ts b/apps/web/tests/mailpit/mailpit.ts new file mode 100644 index 000000000..a251b4e52 --- /dev/null +++ b/apps/web/tests/mailpit/mailpit.ts @@ -0,0 +1,56 @@ +import type { MailpitListMessagesResponse, MailpitMessage } from "./types"; + +const MAILPIT_API_URL = "http://localhost:8025/api"; + +export async function getMessages(): Promise { + const response = await fetch(`${MAILPIT_API_URL}/v1/messages`); + const data = (await response.json()) as MailpitListMessagesResponse; + return data; +} + +export async function getMessage(id: string): Promise { + const response = await fetch(`${MAILPIT_API_URL}/v1/message/${id}`); + const data = (await response.json()) as MailpitMessage; + return data; +} + +export async function deleteAllMessages(): Promise { + await fetch(`${MAILPIT_API_URL}/v1/messages`, { + method: "DELETE", + }); +} + +export async function captureOne( + to: string, + options: { wait?: number } = {}, +): Promise<{ email: MailpitMessage }> { + const startTime = Date.now(); + const timeout = options.wait ?? 5000; + + while (Date.now() - startTime < timeout) { + const { messages } = await getMessages(); + const message = messages.find( + (msg) => + new Date(msg.Created) > new Date(startTime) && + msg.To.some((recipient) => recipient.Address === to), + ); + + if (message) { + const fullMessage = await getMessage(message.ID); + return { email: fullMessage }; + } + + // Wait a bit before trying again + await new Promise((resolve) => setTimeout(resolve, 100)); + } + + throw new Error(`No email received for ${to} within ${timeout}ms`); +} + +export async function captureEmailHTML(to: string): Promise { + const { email } = await captureOne(to); + if (!email.HTML) { + throw new Error("Email doesn't contain HTML"); + } + return email.HTML; +} diff --git a/apps/web/tests/mailpit/types.ts b/apps/web/tests/mailpit/types.ts new file mode 100644 index 000000000..92861bc42 --- /dev/null +++ b/apps/web/tests/mailpit/types.ts @@ -0,0 +1,46 @@ +export interface MailpitAttachment { + ContentID: string; + ContentType: string; + FileName: string; + PartID: string; + Size: number; +} + +export interface MailpitEmailAddress { + Address: string; + Name: string; +} + +export interface MailpitMessageSummary { + Attachments: number; + Bcc: MailpitEmailAddress[]; + Cc: MailpitEmailAddress[]; + Created: string; + From: MailpitEmailAddress; + ID: string; + MessageID: string; + Read: boolean; + ReplyTo: MailpitEmailAddress[]; + Size: number; + Snippet: string; + Subject: string; + Tags: string[]; + To: MailpitEmailAddress[]; +} + +export interface MailpitMessage extends MailpitMessageSummary { + HTML: string; + Text: string; + Inline: MailpitAttachment[]; + ReturnPath: string; + Date: string; +} + +export interface MailpitListMessagesResponse { + messages: MailpitMessageSummary[]; + messages_count: number; + start: number; + tags: string[]; + total: number; + unread: number; +} diff --git a/apps/web/tests/new-poll-page.ts b/apps/web/tests/new-poll-page.ts index 0fee36b86..9d1151d13 100644 --- a/apps/web/tests/new-poll-page.ts +++ b/apps/web/tests/new-poll-page.ts @@ -16,7 +16,7 @@ export class NewPollPage { async createPoll() { const page = this.page; - await page.type('[placeholder="Monthly Meetup"]', "Monthly Meetup"); + await page.fill('[placeholder="Monthly Meetup"]', "Monthly Meetup"); // click on label to focus on input await page.click('text="Location"'); await page.keyboard.type("Joe's Coffee Shop"); diff --git a/apps/web/tests/vote-and-comment.spec.ts b/apps/web/tests/vote-and-comment.spec.ts index c2f01cc0f..0345b6785 100644 --- a/apps/web/tests/vote-and-comment.spec.ts +++ b/apps/web/tests/vote-and-comment.spec.ts @@ -1,10 +1,9 @@ import type { Page, Request } from "@playwright/test"; import { expect, test } from "@playwright/test"; import { load } from "cheerio"; -import type { MailServer } from "smtp-tester"; -import smtpTester from "smtp-tester"; import type { PollPage } from "tests/poll-page"; +import { captureOne } from "./mailpit/mailpit"; import { NewPollPage } from "./new-poll-page"; test.describe(() => { @@ -13,9 +12,7 @@ test.describe(() => { let touchRequest: Promise; let editSubmissionUrl: string; - let mailServer: MailServer; test.beforeAll(async ({ browser }) => { - mailServer = smtpTester.init(4025); page = await browser.newPage(); touchRequest = page.waitForRequest( (request) => @@ -27,10 +24,6 @@ test.describe(() => { pollPage = await newPollPage.createPollAndCloseDialog(); }); - test.afterAll(async () => { - mailServer.stop(() => {}); - }); - test("should call touch endpoint", async () => { // make sure call to touch RPC is made expect(await touchRequest).not.toBeNull(); @@ -54,17 +47,15 @@ test.describe(() => { await invitePage.addParticipant("Anne", "test@example.com"); - await expect(page.locator("text='Anne'")).toBeVisible(); - - const { email } = await mailServer.captureOne("test@example.com", { + const { email } = await captureOne("test@example.com", { wait: 5000, }); - expect(email.headers.subject).toBe( - "Thanks for responding to Monthly Meetup", - ); + await expect(page.locator("text='Anne'")).toBeVisible(); - const $ = load(email.html as string); + expect(email.Subject).toBe("Thanks for responding to Monthly Meetup"); + + const $ = load(email.HTML); const href = $("#editSubmissionUrl").attr("href"); if (!href) { diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 13f319907..946704f45 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -45,8 +45,8 @@ services: MINIO_ROOT_PASSWORD: minio123 volumes: - s3-data:/data - mailhog: - image: mailhog/mailhog + mailpit: + image: axllent/mailpit ports: - "8025:8025" - "1025:1025" diff --git a/yarn.lock b/yarn.lock index 2cd7754cb..49c1a5edb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4732,14 +4732,6 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz#5f1b518ec5fa54437c0b7c4a821546c64fed6922" integrity sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA== -"@selderee/plugin-htmlparser2@^0.10.0": - version "0.10.0" - resolved "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.10.0.tgz" - integrity sha512-gW69MEamZ4wk1OsOq1nG1jcyhXIQcnrsX5JwixVw/9xaiav8TCyjESAruu1Rz9yyInhgBXxkNwMeygKnN2uxNA== - dependencies: - domhandler "^5.0.3" - selderee "^0.10.0" - "@selderee/plugin-htmlparser2@^0.11.0": version "0.11.0" resolved "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz" @@ -6633,14 +6625,6 @@ resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz" integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== -"@types/mailparser@^3.4.0": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@types/mailparser/-/mailparser-3.4.4.tgz#0bd71e205573b9dd9a445e10a8b8cb0e45420998" - integrity sha512-C6Znp2QVS25JqtuPyxj38Qh+QoFcLycdxsvcc6IZCGekhaMBzbdTXzwGzhGoYb3TfKu8IRCNV0sV1o3Od97cEQ== - dependencies: - "@types/node" "*" - iconv-lite "^0.6.3" - "@types/mdast@^4.0.0": version "4.0.4" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" @@ -6704,13 +6688,6 @@ resolved "https://registry.npmjs.org/@types/node/-/node-18.15.10.tgz" integrity sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ== -"@types/nodemailer@*": - version "6.4.10" - resolved "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.10.tgz" - integrity sha512-oPW/IdhkU3FyZc1dzeqmS+MBjrjZNiiINnrEOrWALzccJlP5xTlbkNr2YnTnnyj9Eqm5ofjRoASEbrCYpA7BrA== - dependencies: - "@types/node" "*" - "@types/nodemailer@^6.4.14": version "6.4.14" resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.14.tgz#5c81a5e856db7f8ede80013e6dbad7c5fb2283e2" @@ -6847,14 +6824,6 @@ resolved "https://registry.npmjs.org/@types/smoothscroll-polyfill/-/smoothscroll-polyfill-0.3.1.tgz" integrity sha512-+KkHw4y+EyeCtVXET7woHUhIbfWFCflc0E0mZnSV+ZdjPQeHt/9KPEuT7gSW/kFQ8O3EG30PLO++YhChDt8+Ag== -"@types/smtp-server@^3.5.7": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/smtp-server/-/smtp-server-3.5.10.tgz#06d0338aea519469529847a12b0903678fdd6bea" - integrity sha512-i3Jx7sJ2qF52vjaOf3HguulXlWRFf6BSfsRLsIdmytDyVGv7KkhSs+gR9BXJnJWg1Ljkh/56Fh1Xqwa6u6X7zw== - dependencies: - "@types/node" "*" - "@types/nodemailer" "*" - "@types/unist@*", "@types/unist@^2.0.0": version "2.0.6" resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" @@ -7718,11 +7687,6 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base32.js@0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz" - integrity sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ== - base64-js@^1.3.1: version "1.5.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" @@ -8740,11 +8704,6 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -encoding-japanese@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.0.0.tgz" - integrity sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ== - end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" @@ -10074,11 +10033,6 @@ hast-util-whitespace@^3.0.0: dependencies: "@types/hast" "^3.0.0" -he@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" @@ -10098,17 +10052,6 @@ html-parse-stringify@^3.0.1: dependencies: void-elements "3.1.0" -html-to-text@9.0.3: - version "9.0.3" - resolved "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.3.tgz" - integrity sha512-hxDF1kVCF2uw4VUJ3vr2doc91pXf2D5ngKcNviSitNkhP9OMOaJkDrFIFL6RMvko7NisWTEiqGpQ9LAxcVok1w== - dependencies: - "@selderee/plugin-htmlparser2" "^0.10.0" - deepmerge "^4.2.2" - dom-serializer "^2.0.0" - htmlparser2 "^8.0.1" - selderee "^0.10.0" - html-to-text@9.0.5: version "9.0.5" resolved "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz" @@ -10235,13 +10178,6 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.6.3, iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - ics@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/ics/-/ics-3.1.0.tgz" @@ -10375,11 +10311,6 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ipv6-normalize@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/ipv6-normalize/-/ipv6-normalize-1.0.1.tgz" - integrity sha512-Bm6H79i01DjgGTCWjUuCjJ6QDo1HB96PT/xCYuyJUP9WFbVDrLSbG4EZCvOCun2rNswZb0c3e4Jt/ws795esHA== - iron-session@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/iron-session/-/iron-session-6.3.1.tgz" @@ -10976,26 +10907,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -libbase64@1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/libbase64/-/libbase64-1.2.1.tgz" - integrity sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew== - -libmime@5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/libmime/-/libmime-5.2.0.tgz" - integrity sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw== - dependencies: - encoding-japanese "2.0.0" - iconv-lite "0.6.3" - libbase64 "1.2.1" - libqp "2.0.1" - -libqp@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/libqp/-/libqp-2.0.1.tgz" - integrity sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg== - lilconfig@^2.0.5, lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" @@ -11006,13 +10917,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkify-it@4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz" - integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== - dependencies: - uc.micro "^1.0.1" - linkify-react@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/linkify-react/-/linkify-react-4.1.3.tgz#461d348b4bdab3fcd0452ae1b5bbc22536395b97" @@ -11169,30 +11073,6 @@ magic-string@^0.30.3: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -mailparser@^3.5.0: - version "3.6.3" - resolved "https://registry.npmjs.org/mailparser/-/mailparser-3.6.3.tgz" - integrity sha512-Yi6poKSsZsmjEcUexv3H4w4+TIeyN9u3+TCdC43VK7fe4rUOGDJ3wL4kMhNLiTOScCA1Rpzldv1hcf6g1MLtZQ== - dependencies: - encoding-japanese "2.0.0" - he "1.2.0" - html-to-text "9.0.3" - iconv-lite "0.6.3" - libmime "5.2.0" - linkify-it "4.0.1" - mailsplit "5.4.0" - nodemailer "6.8.0" - tlds "1.236.0" - -mailsplit@5.4.0: - version "5.4.0" - resolved "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.0.tgz" - integrity sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA== - dependencies: - libbase64 "1.2.1" - libmime "5.2.0" - libqp "2.0.1" - map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -11959,16 +11839,6 @@ node-releases@^2.0.8: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== -nodemailer@6.7.3: - version "6.7.3" - resolved "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz" - integrity sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g== - -nodemailer@6.8.0: - version "6.8.0" - resolved "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz" - integrity sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ== - nodemailer@^6.9.9: version "6.9.9" resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.9.tgz#4549bfbf710cc6addec5064dd0f19874d24248d9" @@ -12315,14 +12185,6 @@ parse5@^7.0.0: dependencies: entities "^4.4.0" -parseley@^0.11.0: - version "0.11.0" - resolved "https://registry.npmjs.org/parseley/-/parseley-0.11.0.tgz" - integrity sha512-VfcwXlBWgTF+unPcr7yu3HSSA6QUdDaDnrHcytVfj5Z8azAyKBDrYnSIfeSxlrEayndNcLmrXzg+Vxbo6DWRXQ== - dependencies: - leac "^0.6.0" - peberminta "^0.8.0" - parseley@^0.12.0: version "0.12.1" resolved "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz" @@ -12399,11 +12261,6 @@ pathval@^2.0.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== -peberminta@^0.8.0: - version "0.8.0" - resolved "https://registry.npmjs.org/peberminta/-/peberminta-0.8.0.tgz" - integrity sha512-YYEs+eauIjDH5nUEGi18EohWE0nV2QbGTqmxQcqgZ/0g+laPCQmuIqq7EBLVi9uim9zMgfJv0QBZEnQ3uHw/Tw== - peberminta@^0.9.0: version "0.9.0" resolved "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz" @@ -13453,7 +13310,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -13487,13 +13344,6 @@ section-matter@^1.0.0: extend-shallow "^2.0.1" kind-of "^6.0.0" -selderee@^0.10.0: - version "0.10.0" - resolved "https://registry.npmjs.org/selderee/-/selderee-0.10.0.tgz" - integrity sha512-DEL/RW/f4qLw/NrVg97xKaEBC8IpzIG2fvxnzCp3Z4yk4jQ3MXom+Imav9wApjxX2dfS3eW7x0DXafJr85i39A== - dependencies: - parseley "^0.11.0" - selderee@^0.11.0: version "0.11.0" resolved "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz" @@ -13642,25 +13492,6 @@ smoothscroll-polyfill@^0.4.4: resolved "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz" integrity sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg== -smtp-server@^3.11.0: - version "3.11.0" - resolved "https://registry.npmjs.org/smtp-server/-/smtp-server-3.11.0.tgz" - integrity sha512-j/W6mEKeMNKuiM9oCAAjm87agPEN1O3IU4cFLT4ZOCyyq3UXN7HiIXF+q7izxJcYSar15B/JaSxcijoPCR8Tag== - dependencies: - base32.js "0.1.0" - ipv6-normalize "1.0.1" - nodemailer "6.7.3" - -smtp-tester@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/smtp-tester/-/smtp-tester-2.1.0.tgz#ed67ef933767cacb8defcbf0683f29d75335a1ca" - integrity sha512-HfOBdHkdwoBO+Qb06H8ShVEc08nnvDbtYWzdT5iQMIeInBdLKu17XOhuaC79uM24zPApRfN3JAg627TIy3y/Ww== - dependencies: - "@types/mailparser" "^3.4.0" - "@types/smtp-server" "^3.5.7" - mailparser "^3.5.0" - smtp-server "^3.11.0" - socket.io-adapter@~2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz#5de9477c9182fdc171cd8c8364b9a8894ec75d12" @@ -14320,11 +14151,6 @@ tinyspy@^3.0.0: resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== -tlds@1.236.0: - version "1.236.0" - resolved "https://registry.npmjs.org/tlds/-/tlds-1.236.0.tgz" - integrity sha512-oP2PZ3KeGlgpHgsEfrtva3/K9kzsJUNliQSbCfrJ7JMCWFoCdtG+9YMq/g2AnADQ1v5tVlbtvKJZ4KLpy/P6MA== - to-absolute-glob@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz" @@ -14587,11 +14413,6 @@ typescript@^5.2.2: resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== -uc.micro@^1.0.1: - version "1.0.6" - resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"