diff --git a/apps/smtp-server/package.json b/apps/smtp-server/package.json new file mode 100644 index 0000000..2afb1a8 --- /dev/null +++ b/apps/smtp-server/package.json @@ -0,0 +1,28 @@ +{ + "name": "smtp-server", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc", + "start": "node dist/server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@types/dotenv": "^8.2.0", + "@types/mailparser": "^3.4.4", + "@types/smtp-server": "^3.5.10", + "dotenv": "^16.4.5", + "mailparser": "^3.7.1", + "nodemailer": "^6.9.14", + "smtp-server": "^3.13.4" + }, + "devDependencies": { + "@types/node": "^22.1.0", + "@types/nodemailer": "^6.4.15", + "typescript": "^5.5.4" + } +} diff --git a/apps/smtp-server/src/server.ts b/apps/smtp-server/src/server.ts new file mode 100644 index 0000000..f62ae05 --- /dev/null +++ b/apps/smtp-server/src/server.ts @@ -0,0 +1,101 @@ +import { SMTPServer, SMTPServerOptions } from 'smtp-server'; +import { Readable } from 'stream'; +import dotenv from 'dotenv'; +import { simpleParser } from 'mailparser'; + +dotenv.config(); + +const AUTH_USERNAME = process.env.SMTP_AUTH_USERNAME!; +const UNSEND_BASE_URL = process.env.UNSEND_BASE_URL!; +let API_KEY = ''; + +const ports = [25, 465, 2465, 587, 2587]; // Array of ports to listen on + +const serverOptions: SMTPServerOptions = { + onData(stream: Readable, session: any, callback: (error?: Error) => void) { + console.log('Receiving email data...'); // Debug statement + simpleParser(stream, (err, parsed) => { + if (err) { + console.error('Failed to parse email data:', err.message); + return callback(err); + } + + const emailObject: any = { + to: Array.isArray(parsed.to) ? parsed.to.map(addr => addr.text).join(', ') : parsed.to?.text, + from: Array.isArray(parsed.from) ? parsed.from.map(addr => addr.text).join(', ') : parsed.from?.text, + subject: parsed.subject, + text: parsed.text, + html: parsed.html, + }; + + console.log('Parsed email data:', emailObject); // Debug statement + + sendEmailToUnsend(emailObject) + .then(() => callback()) + .catch((error) => { + console.error('Failed to send email:', error.message); + callback(error); + }); + }); + }, + onAuth(auth: any, session: any, callback: (error?: Error, user?: any) => void) { + API_KEY = auth.password; + if (auth.username === AUTH_USERNAME) { + console.log('Authenticated successfully'); // Debug statement + callback(undefined, { user: AUTH_USERNAME }); + } else { + console.error('Invalid username or password'); + callback(new Error('Invalid username or password')); + } + }, +}; + +async function sendEmailToUnsend(emailData: any) { + try { + const apiEndpoint = '/api/v1/emails'; + const url = new URL(apiEndpoint, UNSEND_BASE_URL); // Combine base URL with endpoint + console.log('Sending email to Unsend API at:', url.href); // Debug statement + + const response = await fetch(url.href, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${API_KEY}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify(emailData), + }); + + if (!response.ok) { + const errorData = await response.json(); + console.error('Unsend API error response:', errorData); + throw new Error(`Failed to send email: ${errorData.message || 'Unknown error from server'}`); + } + + const responseData = await response.json(); + console.log('Unsend API response:', responseData); + } catch (error) { + if (error instanceof Error) { + console.error('Error message:', error.message); + throw new Error(`Failed to send email: ${error.message}`); + } else { + console.error('Unexpected error:', error); + throw new Error('Failed to send email: Unexpected error occurred'); + } + } +} + +function startServers() { + ports.forEach(port => { + const server = new SMTPServer(serverOptions); + + server.listen(port, () => { + console.log(`SMTP server is listening on port ${port}`); + }); + + server.on('error', (err) => { + console.error(`Error occurred on port ${port}:`, err); + }); + }); +} + +startServers(); diff --git a/apps/smtp-server/src/usage.js b/apps/smtp-server/src/usage.js new file mode 100644 index 0000000..5e91071 --- /dev/null +++ b/apps/smtp-server/src/usage.js @@ -0,0 +1,37 @@ +const nodemailer = require('nodemailer'); + +const transporter = nodemailer.createTransport({ + host: "localhost", + port: 2587, + secure: false, + auth: { + user: "unsend", + pass: "us_38de56vwa7_cc90a91b01a402de0c15516b3554adc1", + }, + tls: { + rejectUnauthorized: false, + } + }); + + + +const mailOptions = { + to: "harsh121102@gmail.com", + from: "hello@support.harshbhat.me", + subject: "Testing SMTP", + html: "THIS IS USING SMTP,

Unsend is the best open source sending platform

check out unsend.dev", + text: "hello,\n\nUnsend is the best open source sending platform", +}; + + +transporter.sendMail(mailOptions, (error, info) => { + if (error) { + console.error('Error sending email:', error); + } else { + console.log('Email sent successfully:', info.response); + } +}); + + + + diff --git a/apps/smtp-server/tsconfig.json b/apps/smtp-server/tsconfig.json new file mode 100644 index 0000000..b4722b8 --- /dev/null +++ b/apps/smtp-server/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "module": "commonjs", /* Specify what module code is generated. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Modules */ + "rootDir": "./src", /* Specify the root folder within your source files. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + + /* Emit */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "removeComments": true, /* Disable emitting comments. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["src/**/*.ts"], /* Include all TypeScript files in the src directory. */ + "exclude": ["node_modules"] /* Exclude node_modules from compilation. */ +} diff --git a/apps/web/src/app/(dashboard)/api-keys/page.tsx b/apps/web/src/app/(dashboard)/api-keys/page.tsx index c9de74c..c9a66fd 100644 --- a/apps/web/src/app/(dashboard)/api-keys/page.tsx +++ b/apps/web/src/app/(dashboard)/api-keys/page.tsx @@ -2,15 +2,43 @@ import ApiList from "./api-list"; import AddApiKey from "./add-api-key"; +import Smtp from "./smtp"; +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@unsend/ui/src/tabs"; +import { useState } from 'react'; export default function ApiKeysPage() { + const [activeTab, setActiveTab] = useState("apiKeys"); + const disableSmtp = true; + const handleTabChange = (value: any) => { + if (value === "smtp" && disableSmtp) { + return; + } + setActiveTab(value); + }; + return (

-
-

API Keys

- -
- + + + API keys + + SMTP + + + +
+

API Keys

+ +
+ +
+ + + +
); } diff --git a/apps/web/src/app/(dashboard)/api-keys/smtp.tsx b/apps/web/src/app/(dashboard)/api-keys/smtp.tsx new file mode 100644 index 0000000..930a014 --- /dev/null +++ b/apps/web/src/app/(dashboard)/api-keys/smtp.tsx @@ -0,0 +1,54 @@ +"use client"; +import * as React from "react"; +import { Code } from "@unsend/ui/src/code"; +import { Button } from "@unsend/ui/src/button"; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@unsend/ui/src/card"; +import { TextWithCopyButton } from "@unsend/ui/src/text-with-copy"; + +export default function ExampleCard() { + const smtpDetails = { + smtp: "smtp.example.com", + port: "587", + user: "user@example.com", + password: "supersecretpassword" + }; + + return ( + + + SMTP + + Send emails using SMTP instead of the REST API. See documentation for more information. + + + +
+
+ Host: + +
+
+ Port: + +

For encrypted/TLS connections use 2465, 587 or 2587

+
+
+ User: + +
+
+ Password: + +
+
+
+
+ ); +} diff --git a/packages/ui/src/card.tsx b/packages/ui/src/card.tsx new file mode 100644 index 0000000..ba8f736 --- /dev/null +++ b/packages/ui/src/card.tsx @@ -0,0 +1,76 @@ +import * as React from "react" + +import { cn } from "../lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 61ea2ab..bb8ab58 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,6 +92,40 @@ importers: specifier: ^5 version: 5.4.2 + apps/smtp-server: + dependencies: + '@types/dotenv': + specifier: ^8.2.0 + version: 8.2.0 + '@types/mailparser': + specifier: ^3.4.4 + version: 3.4.4 + '@types/smtp-server': + specifier: ^3.5.10 + version: 3.5.10 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + mailparser: + specifier: ^3.7.1 + version: 3.7.1 + nodemailer: + specifier: ^6.9.14 + version: 6.9.14 + smtp-server: + specifier: ^3.13.4 + version: 3.13.4 + devDependencies: + '@types/node': + specifier: ^22.1.0 + version: 22.1.0 + '@types/nodemailer': + specifier: ^6.4.15 + version: 6.4.15 + typescript: + specifier: ^5.5.4 + version: 5.5.4 + apps/web: dependencies: '@auth/prisma-adapter': @@ -6360,7 +6394,7 @@ packages: /@types/cors@2.8.17: resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} dependencies: - '@types/node': 20.11.27 + '@types/node': 20.12.12 dev: true /@types/d3-array@3.2.1: @@ -6411,6 +6445,13 @@ packages: '@types/ms': 0.7.34 dev: true + /@types/dotenv@8.2.0: + resolution: {integrity: sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==} + deprecated: This is a stub types definition. dotenv provides its own type definitions, so you do not need this installed. + dependencies: + dotenv: 16.4.5 + dev: false + /@types/eslint@8.56.5: resolution: {integrity: sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==} dependencies: @@ -6461,6 +6502,13 @@ packages: resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} dev: true + /@types/mailparser@3.4.4: + resolution: {integrity: sha512-C6Znp2QVS25JqtuPyxj38Qh+QoFcLycdxsvcc6IZCGekhaMBzbdTXzwGzhGoYb3TfKu8IRCNV0sV1o3Od97cEQ==} + dependencies: + '@types/node': 20.12.12 + iconv-lite: 0.6.3 + dev: false + /@types/mdast@3.0.15: resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} dependencies: @@ -6501,8 +6549,18 @@ packages: resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} dependencies: undici-types: 5.26.5 + + /@types/node@22.1.0: + resolution: {integrity: sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==} + dependencies: + undici-types: 6.13.0 dev: true + /@types/nodemailer@6.4.15: + resolution: {integrity: sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ==} + dependencies: + '@types/node': 20.12.12 + /@types/normalize-package-data@2.4.4: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true @@ -6559,6 +6617,13 @@ packages: resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} dev: true + /@types/smtp-server@3.5.10: + resolution: {integrity: sha512-i3Jx7sJ2qF52vjaOf3HguulXlWRFf6BSfsRLsIdmytDyVGv7KkhSs+gR9BXJnJWg1Ljkh/56Fh1Xqwa6u6X7zw==} + dependencies: + '@types/node': 20.12.12 + '@types/nodemailer': 6.4.15 + dev: false + /@types/ua-parser-js@0.7.39: resolution: {integrity: sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==} dev: true @@ -7428,6 +7493,10 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base32.js@0.1.0: + resolution: {integrity: sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==} + engines: {node: '>=0.12.0'} + /balanced-match@2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} dev: false @@ -8497,7 +8566,6 @@ packages: /dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} - dev: true /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -8543,6 +8611,16 @@ packages: engines: {node: '>= 0.8'} dev: true + /encoding-japanese@2.0.0: + resolution: {integrity: sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ==} + engines: {node: '>=8.10.0'} + dev: false + + /encoding-japanese@2.1.0: + resolution: {integrity: sha512-58XySVxUgVlBikBTbQ8WdDxBDHIdXucB16LO5PBHR8t75D54wQrNo4cg+58+R1CtJfKnsVsvt9XlteRaR8xw1w==} + engines: {node: '>=8.10.0'} + dev: false + /engine.io-parser@5.2.2: resolution: {integrity: sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==} engines: {node: '>=10.0.0'} @@ -8554,7 +8632,7 @@ packages: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 - '@types/node': 20.11.27 + '@types/node': 20.12.12 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -8831,7 +8909,7 @@ packages: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.0(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) @@ -8889,7 +8967,7 @@ packages: enhanced-resolve: 5.16.0 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.3 is-core-module: 2.13.1 @@ -9023,6 +9101,41 @@ packages: ignore: 5.3.1 dev: true + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.2) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.4 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.2 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} @@ -9058,40 +9171,6 @@ packages: - supports-color dev: true - /eslint-plugin-import@2.29.1(eslint@8.57.0): - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.4 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - hasown: 2.0.2 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.2 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: true - /eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -10399,6 +10478,11 @@ packages: property-information: 6.5.0 space-separated-tokens: 2.0.2 + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: false + /highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} dev: false @@ -10500,6 +10584,13 @@ packages: safer-buffer: 2.1.2 dev: true + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -10631,6 +10722,10 @@ packages: engines: {node: '>= 0.10'} dev: true + /ipv6-normalize@1.0.1: + resolution: {integrity: sha512-Bm6H79i01DjgGTCWjUuCjJ6QDo1HB96PT/xCYuyJUP9WFbVDrLSbG4EZCvOCun2rNswZb0c3e4Jt/ws795esHA==} + dev: false + /is-absolute-url@4.0.1: resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -11230,6 +11325,40 @@ packages: type-check: 0.4.0 dev: true + /libbase64@1.2.1: + resolution: {integrity: sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==} + dev: false + + /libbase64@1.3.0: + resolution: {integrity: sha512-GgOXd0Eo6phYgh0DJtjQ2tO8dc0IVINtZJeARPeiIJqge+HdsWSuaDTe8ztQ7j/cONByDZ3zeB325AHiv5O0dg==} + dev: false + + /libmime@5.2.0: + resolution: {integrity: sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw==} + dependencies: + encoding-japanese: 2.0.0 + iconv-lite: 0.6.3 + libbase64: 1.2.1 + libqp: 2.0.1 + dev: false + + /libmime@5.3.5: + resolution: {integrity: sha512-nSlR1yRZ43L3cZCiWEw7ali3jY29Hz9CQQ96Oy+sSspYnIP5N54ucOPHqooBsXzwrX1pwn13VUE05q4WmzfaLg==} + dependencies: + encoding-japanese: 2.1.0 + iconv-lite: 0.6.3 + libbase64: 1.3.0 + libqp: 2.1.0 + dev: false + + /libqp@2.0.1: + resolution: {integrity: sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg==} + dev: false + + /libqp@2.1.0: + resolution: {integrity: sha512-O6O6/fsG5jiUVbvdgT7YX3xY3uIadR6wEZ7+vy9u7PKHAlSEB6blvC1o5pHBjgsi95Uo0aiBBdkyFecj6jtb7A==} + dev: false + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -11362,6 +11491,27 @@ packages: engines: {node: '>=12'} dev: false + /mailparser@3.7.1: + resolution: {integrity: sha512-RCnBhy5q8XtB3mXzxcAfT1huNqN93HTYYyL6XawlIKycfxM/rXPg9tXoZ7D46+SgCS1zxKzw+BayDQSvncSTTw==} + dependencies: + encoding-japanese: 2.1.0 + he: 1.2.0 + html-to-text: 9.0.5 + iconv-lite: 0.6.3 + libmime: 5.3.5 + linkify-it: 5.0.0 + mailsplit: 5.4.0 + nodemailer: 6.9.13 + punycode.js: 2.3.1 + tlds: 1.252.0 + dev: false + + /mailsplit@5.4.0: + resolution: {integrity: sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA==} + dependencies: + libbase64: 1.2.1 + libmime: 5.2.0 + libqp: 2.0.1 /magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} dependencies: @@ -12468,6 +12618,16 @@ packages: vm-browserify: 1.1.2 dev: false + /nodemailer@6.9.13: + resolution: {integrity: sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==} + engines: {node: '>=6.0.0'} + dev: false + + /nodemailer@6.9.14: + resolution: {integrity: sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==} + engines: {node: '>=6.0.0'} + dev: false + /nopt@7.2.1: resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -13604,6 +13764,7 @@ packages: engines: {node: '>=6'} dev: false + /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} dev: false @@ -13611,7 +13772,6 @@ packages: /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - dev: true /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} @@ -14562,7 +14722,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true /sax@1.3.0: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} @@ -14781,6 +14940,16 @@ packages: engines: {node: '>=12'} dev: true + /smtp-server@3.13.4: + resolution: {integrity: sha512-BbElv5UP+HgPtCZtcRW35N/GFoc4DzPkrbSMLioXsrVMmQT1mMBoO0k+egl264hxWaWczoVvadSPY2pLUINFXg==} + engines: {node: '>=12.0.0'} + dependencies: + base32.js: 0.1.0 + ipv6-normalize: 1.0.1 + nodemailer: 6.9.13 + punycode: 2.3.1 + dev: false + /socket.io-adapter@2.5.4: resolution: {integrity: sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==} dependencies: @@ -15322,6 +15491,10 @@ packages: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} dev: false + /tlds@1.252.0: + resolution: {integrity: sha512-GA16+8HXvqtfEnw/DTcwB0UU354QE1n3+wh08oFjr6Znl7ZLAeUgYzCcK+/CCrOyE0vnHR8/pu3XXG3vDijXpQ==} + hasBin: true + /tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} dependencies: @@ -15647,6 +15820,12 @@ packages: hasBin: true dev: true + /typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + /ua-parser-js@1.0.38: resolution: {integrity: sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==} dev: false @@ -15666,6 +15845,9 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + /undici-types@6.13.0: + resolution: {integrity: sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==} dev: true /undici@5.28.4: