added email listener

This commit is contained in:
Omer Sabic 2024-03-12 21:25:30 +01:00
commit 2f221d9998
16 changed files with 5170 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
node_modules
.env

17
drizzle.config.js Normal file
View File

@ -0,0 +1,17 @@
import { config } from 'dotenv';
config();
/**
* @type {import('drizzle-kit').Config}
*/
export default {
schema: './src/lib/db/schema.js',
out: './drizzle',
driver: 'pg', // 'pg' | 'mysql2' | 'better-sqlite' | 'libsql' | 'turso'
dbCredentials: {
host: process.env.DB_HOST || "",
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME || "vocalcast"
}
}

View File

@ -0,0 +1,32 @@
-- Current sql file was generated after introspecting the database
-- If you want to run this migration please uncomment this code before executing migrations
/*
CREATE TABLE IF NOT EXISTS "sessions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"date_created" date DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "users" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text NOT NULL,
"email" text NOT NULL,
"hashed_password" text NOT NULL,
"date_created" date DEFAULT now() NOT NULL,
CONSTRAINT "users_email_unique" UNIQUE("email")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "pods" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid,
"script" text NOT NULL,
"date_created" date DEFAULT now() NOT NULL
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "pods" ADD CONSTRAINT "pods_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
*/

View File

@ -0,0 +1,55 @@
CREATE TABLE IF NOT EXISTS "groups" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid,
"email" text NOT NULL,
"name" text NOT NULL,
CONSTRAINT "groups_email_unique" UNIQUE("email")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "letters" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"sender" text NOT NULL,
"content" text NOT NULL,
"group_id" uuid NOT NULL,
"date_created" date DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "sources" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"group_id" uuid NOT NULL,
"name" text NOT NULL,
"is_confirmed" boolean DEFAULT false NOT NULL
);
--> statement-breakpoint
ALTER TABLE "pods" DROP CONSTRAINT "pods_user_id_users_id_fk";
--> statement-breakpoint
ALTER TABLE "pods" ADD COLUMN "group_id" uuid;--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "pods" ADD CONSTRAINT "pods_group_id_groups_id_fk" FOREIGN KEY ("group_id") REFERENCES "groups"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "pods" ADD CONSTRAINT "pods_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "groups" ADD CONSTRAINT "groups_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "letters" ADD CONSTRAINT "letters_group_id_groups_id_fk" FOREIGN KEY ("group_id") REFERENCES "groups"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "sources" ADD CONSTRAINT "sources_group_id_groups_id_fk" FOREIGN KEY ("group_id") REFERENCES "groups"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View File

@ -0,0 +1,2 @@
ALTER TABLE "letters" ADD COLUMN "sender_email" text NOT NULL;--> statement-breakpoint
ALTER TABLE "letters" ADD COLUMN "subject" text NOT NULL;

View File

@ -0,0 +1,146 @@
{
"id": "00000000-0000-0000-0000-000000000000",
"prevId": "",
"version": "5",
"dialect": "pg",
"tables": {
"sessions": {
"name": "sessions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"hashed_password": {
"name": "hashed_password",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"users_email_unique": {
"columns": [
"email"
],
"nullsNotDistinct": false,
"name": "users_email_unique"
}
}
},
"pods": {
"name": "pods",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"script": {
"name": "script",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"pods_user_id_users_id_fk": {
"name": "pods_user_id_users_id_fk",
"tableFrom": "pods",
"tableTo": "users",
"schemaTo": "public",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"schemas": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}

View File

@ -0,0 +1,327 @@
{
"id": "a7d58718-96f7-4d35-94ac-8f5c944d1bde",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "5",
"dialect": "pg",
"tables": {
"groups": {
"name": "groups",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"groups_user_id_users_id_fk": {
"name": "groups_user_id_users_id_fk",
"tableFrom": "groups",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"groups_email_unique": {
"name": "groups_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
}
},
"letters": {
"name": "letters",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"sender": {
"name": "sender",
"type": "text",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"group_id": {
"name": "group_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"letters_group_id_groups_id_fk": {
"name": "letters_group_id_groups_id_fk",
"tableFrom": "letters",
"tableTo": "groups",
"columnsFrom": [
"group_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"pods": {
"name": "pods",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"group_id": {
"name": "group_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"script": {
"name": "script",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"pods_user_id_users_id_fk": {
"name": "pods_user_id_users_id_fk",
"tableFrom": "pods",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"pods_group_id_groups_id_fk": {
"name": "pods_group_id_groups_id_fk",
"tableFrom": "pods",
"tableTo": "groups",
"columnsFrom": [
"group_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"sessions": {
"name": "sessions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"sources": {
"name": "sources",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"group_id": {
"name": "group_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"is_confirmed": {
"name": "is_confirmed",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
}
},
"indexes": {},
"foreignKeys": {
"sources_group_id_groups_id_fk": {
"name": "sources_group_id_groups_id_fk",
"tableFrom": "sources",
"tableTo": "groups",
"columnsFrom": [
"group_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"hashed_password": {
"name": "hashed_password",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
}
}
},
"enums": {},
"schemas": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@ -0,0 +1,339 @@
{
"id": "92db5e31-d2bf-443c-b4cd-c473e7e859d1",
"prevId": "a7d58718-96f7-4d35-94ac-8f5c944d1bde",
"version": "5",
"dialect": "pg",
"tables": {
"groups": {
"name": "groups",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"groups_user_id_users_id_fk": {
"name": "groups_user_id_users_id_fk",
"tableFrom": "groups",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"groups_email_unique": {
"name": "groups_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
}
},
"letters": {
"name": "letters",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"sender": {
"name": "sender",
"type": "text",
"primaryKey": false,
"notNull": true
},
"sender_email": {
"name": "sender_email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"subject": {
"name": "subject",
"type": "text",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"group_id": {
"name": "group_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"letters_group_id_groups_id_fk": {
"name": "letters_group_id_groups_id_fk",
"tableFrom": "letters",
"tableTo": "groups",
"columnsFrom": [
"group_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"pods": {
"name": "pods",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"group_id": {
"name": "group_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"script": {
"name": "script",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"pods_user_id_users_id_fk": {
"name": "pods_user_id_users_id_fk",
"tableFrom": "pods",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"pods_group_id_groups_id_fk": {
"name": "pods_group_id_groups_id_fk",
"tableFrom": "pods",
"tableTo": "groups",
"columnsFrom": [
"group_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"sessions": {
"name": "sessions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"sources": {
"name": "sources",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"group_id": {
"name": "group_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"is_confirmed": {
"name": "is_confirmed",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
}
},
"indexes": {},
"foreignKeys": {
"sources_group_id_groups_id_fk": {
"name": "sources_group_id_groups_id_fk",
"tableFrom": "sources",
"tableTo": "groups",
"columnsFrom": [
"group_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"hashed_password": {
"name": "hashed_password",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date_created": {
"name": "date_created",
"type": "date",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
}
}
},
"enums": {},
"schemas": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@ -0,0 +1,27 @@
{
"version": "5",
"dialect": "pg",
"entries": [
{
"idx": 0,
"version": "5",
"when": 1710271296222,
"tag": "0000_clever_amazoness",
"breakpoints": true
},
{
"idx": 1,
"version": "5",
"when": 1710272815969,
"tag": "0001_right_ghost_rider",
"breakpoints": true
},
{
"idx": 2,
"version": "5",
"when": 1710274221383,
"tag": "0002_sweet_mikhail_rasputin",
"breakpoints": true
}
]
}

3988
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

22
package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "worker",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^16.4.5",
"drizzle-orm": "^0.30.1",
"mailin": "^3.0.4",
"postgres": "^3.4.3"
},
"devDependencies": {
"drizzle-kit": "^0.20.14"
}
}

0
src/index.js Normal file
View File

14
src/lib/db/index.js Normal file
View File

@ -0,0 +1,14 @@
import { config } from 'dotenv';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
config();
const client = postgres({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});
export const db = drizzle(client);
export * from './schema';

47
src/lib/db/schema.js Normal file
View File

@ -0,0 +1,47 @@
import { pgTable, uuid, date, text, boolean } from "drizzle-orm/pg-core"
export const sessionsTable = pgTable("sessions", {
id: uuid("id").defaultRandom().primaryKey().notNull(),
userId: uuid("user_id").notNull(),
dateCreated: date("date_created").defaultNow().notNull(),
});
export const usersTable = pgTable("users", {
id: uuid("id").defaultRandom().primaryKey().notNull(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
hashedPassword: text("hashed_password").notNull(),
dateCreated: date("date_created").defaultNow().notNull(),
});
export const podsTable = pgTable("pods", {
id: uuid("id").defaultRandom().primaryKey().notNull(),
userId: uuid("user_id").references(() => usersTable.id),
groupId: uuid("group_id").references(() => groupsTable.id),
script: text("script").notNull(),
dateCreated: date("date_created").defaultNow().notNull(),
});
export const groupsTable = pgTable("groups", {
id: uuid("id").defaultRandom().primaryKey().notNull(),
userId: uuid("user_id").references(() => usersTable.id),
email: text("email").notNull().unique(),
name: text("name").notNull()
});
export const lettersTable = pgTable("letters", {
id: uuid("id").defaultRandom().primaryKey().notNull(),
sender: text("sender").notNull(),
sender_email: text("sender_email").notNull(),
subject: text("subject").notNull(),
content: text("content").notNull(),
groupId: uuid("group_id").references(() => groupsTable.id).notNull(),
date_created: date("date_created").defaultNow().notNull()
});
export const sourcesTable = pgTable("sources", {
id: uuid("id").defaultRandom().primaryKey().notNull(),
groupId: uuid("group_id").references(() => groupsTable.id).notNull(),
name: text("name").notNull(),
is_confirmed: boolean('is_confirmed').default(false).notNull()
});

View File

@ -0,0 +1,89 @@
{
id: 'd5a3b51c-2f27-447c-bea8-3e6987ef8320',
remoteAddress: '143.244.187.129',
remotePort: 40944,
clientHostname: 'mail.sendtestemail.com',
openingCommand: 'EHLO',
hostNameAppearsAs: 'mail.sendtestemail.com',
xClient: Map {},
xForward: Map {},
transmissionType: 'ESMTPS',
tlsOptions: {
name: 'TLS_AES_256_GCM_SHA384',
standardName: 'TLS_AES_256_GCM_SHA384',
version: 'TLSv1.3'
},
envelope: {
mailFrom: { address: 'support@sendtestemail.com', args: false },
rcptTo: [ [Object] ]
},
transaction: 1,
mailPath: '.tmp/d5a3b51c-2f27-447c-bea8-3e6987ef8320'
}
info: d5a3b51c-2f27-447c-bea8-3e6987ef8320 Processing message from support@sendtestemail.com
{
html: '<html>\n' +
'Congratulations!<br><br>\n' +
'If you are reading this your email address is working.<br><br>\n' +
`This is not spam or a solicitation. This email was sent to your email address because you, or someone else, requested a test email to be sent to this address. We work hard to ensure a balance between testing, transparency, and privacy. If you did not request this email test, it's likely that someone accidentally mistyped their email address as yours. You can request your email address be blocked here: <a href="https://sendtestemail.com/block">https://sendtestemail.com/block</a><br><br>\n` +
'The IP address of the requester of this test email is: 176.199.252.222\n' +
'</html>\n',
headers: {
received: 'by mail.sendtestemail.com (Postfix, from userid 48) id 309563000110; Tue, 12 Mar 2024 14:56:04 -0500 (CDT)',
'dkim-filter': 'OpenDKIM Filter v2.11.0 mail.sendtestemail.com 309563000110',
'dkim-signature': 'v=1; a=rsa-sha256; c=relaxed/relaxed; d=sendtestemail.com; s=20220914; t=1710273364; bh=Edox2JOjLuv4wijW8n+8xddAWUBejD1Mu8QeagUyMEc=; h=To:Subject:From:Date:From; b=d1/3O0x0yjVkLL6JXswgxB+piWswUPoms6ZKQJi18W2d7PZxvW9bNfWbFRzaXpvVe HY3VlBrtrEuzKOPJyi557IclqO16zinIY3tA6h3amNkzc9RidVvCCr4I83i1nwTaOM 7HxBH+fF7b1/iFhdUSB69XAbvKWV8QlNKRfOA4HcSDcW6gHX+Pt797yStl5JPh1vUF sZN03ZJ+Fm9Jp0rFXTgDEVOdSZH4znXVRwcvxRTsyin46Uy7fhc5nGBhLvcNWaN059 g4DMwIXC2SbhhKeWfg8B8U/APWzumsxy+2t9ZC/CbC2Banzw9FqrQizkXQUngHORxL FEd4FCANCk+KQ==',
to: 'johnnyboy@smtp.omersabic.com',
subject: 'SendTestEmail.com - Testing Email ID: b7a8086fa7bf286237e4e6ec1d7bf230',
from: 'SendTestEmail <noreply@sendtestemail.com>',
'mime-version': '1.0',
'content-type': 'text/html; charset=utf8',
'message-id': '<20240312195604.309563000110@mail.sendtestemail.com>',
date: 'Tue, 12 Mar 2024 14:56:04 -0500 (CDT)'
},
subject: 'SendTestEmail.com - Testing Email ID: b7a8086fa7bf286237e4e6ec1d7bf230',
messageId: '20240312195604.309563000110@mail.sendtestemail.com',
priority: 'normal',
from: [ { address: 'noreply@sendtestemail.com', name: 'SendTestEmail' } ],
to: [ { address: 'johnnyboy@smtp.omersabic.com', name: '' } ],
date: 2024-03-12T19:56:04.000Z,
receivedDate: 2024-03-12T19:56:04.000Z,
text: 'Congratulations!\n' +
'\n' +
'If you are reading this your email address is working.\n' +
'\n' +
'This is not spam or a solicitation. This email was sent to your email address\n' +
'because you, or someone else, requested a test email to be sent to this address.\n' +
'We work hard to ensure a balance between testing, transparency, and privacy. If\n' +
"you did not request this email test, it's likely that someone accidentally\n" +
'mistyped their email address as yours. You can request your email address be\n' +
'blocked here: https://sendtestemail.com/block [https://sendtestemail.com/block]\n' +
'\n' +
'The IP address of the requester of this test email is: 176.199.252.222',
dkim: 'failed',
spf: 'failed',
spamScore: 0,
language: 'english',
cc: [],
attachments: [],
connection: {
id: 'd5a3b51c-2f27-447c-bea8-3e6987ef8320',
remoteAddress: '143.244.187.129',
remotePort: 40944,
clientHostname: 'mail.sendtestemail.com',
openingCommand: 'EHLO',
hostNameAppearsAs: 'mail.sendtestemail.com',
xClient: Map {},
xForward: Map {},
transmissionType: 'ESMTPS',
tlsOptions: {
name: 'TLS_AES_256_GCM_SHA384',
standardName: 'TLS_AES_256_GCM_SHA384',
version: 'TLSv1.3'
},
envelope: { mailFrom: [Object], rcptTo: [Array] },
transaction: 1,
mailPath: '.tmp/d5a3b51c-2f27-447c-bea8-3e6987ef8320'
},
envelopeFrom: { address: 'support@sendtestemail.com', args: false },
envelopeTo: [ { address: 'johnnyboy@smtp.omersabic.com', args: false } ]
}

View File

@ -0,0 +1,62 @@
import * as mailin from 'mailin';
import { db, groupsTable, lettersTable } from '../lib/db';
import { eq } from 'drizzle-orm';
/* Start the Mailin server. The available options are:
* options = {
* port: 25,
* webhook: 'http://mydomain.com/mailin/incoming,
* disableWebhook: false,
* logFile: '/some/local/path',
* logLevel: 'warn', // One of silly, info, debug, warn, error
* smtpOptions: { // Set of options directly passed to simplesmtp.createServer(smtpOptions)
* SMTPBanner: 'Hi from a custom Mailin instance',
* // By default, the DNS validation of the sender and recipient domains is disabled so.
* // You can enable it as follows:
* disableDNSValidation: false
* }
* };
* Here disable the webhook posting so that you can do what you want with the
* parsed message. */
mailin.start({
port: 25,
disableWebhook: true // Disable the webhook posting.
});
/* Access simplesmtp server instance. */
mailin.on('authorizeUser', function(connection, username, password, done) {
if (username == "johnsmith" && password == "mysecret") {
done(null, true);
} else {
done(new Error("Unauthorized!"), false);
}
});
/* Event emitted when a connection with the Mailin smtp server is initiated. */
mailin.on('startMessage', function (connection) {
/* connection = {
from: 'sender@somedomain.com',
to: 'someaddress@yourdomain.com',
id: 't84h5ugf',
authentication: { username: null, authenticated: false, status: 'NORMAL' }
}
}; */
console.log(connection);
});
/* Event emitted after a message was received and parsed. */
mailin.on('message', async function (connection, data, content) {
const group = await db.select().from(groupsTable).where(eq(groupsTable.email, data.headers.to));
if(group.length === 0) {
return;
}
await db.insert(lettersTable).values({
sender: data.from[0].name,
sender_email: data.envelopeFrom.address,
subject: data.subject,
content: data.text,
groupId: group[0].id
});
});