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
+
+ SMTP
+
+
+
+
+
+
+
+
+
+
);
}
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: