Files
FEDEO/src/routes/emailAsUser.ts

222 lines
7.1 KiB
TypeScript

import nodemailer from "nodemailer"
import { FastifyInstance } from "fastify";
import {sendMailAsUser} from "../utils/emailengine";
import {encrypt, decrypt} from "../utils/crypt"
import {secrets} from "../utils/secrets";
export default async function emailAsUserRoutes(server: FastifyInstance) {
// Create E-Mail Account
server.post("/email/accounts/:id?", async (req, reply) => {
if (!req.user?.tenant_id) {
return reply.code(400).send({ error: "No tenant selected" });
}
const body = req.body as {
email: string
password: string
smtp_host: string
smtp_port: number
smtp_ssl: boolean
imap_host: string
imap_port: number
imap_ssl: boolean
};
if(req.params.id) {
//SAVE Existing
let saveData = {
email_encrypted: body.email ? encrypt(body.email) : undefined,
password_encrypted: body.password ? encrypt(body.password) : undefined,
smtp_host_encrypted: body.smtp_host ? encrypt(body.smtp_host) : undefined,
smtp_port: body.smtp_port,
smtp_ssl: body.smtp_ssl,
imap_host_encrypted: body.imap_host ? encrypt(body.imap_host) : undefined,
imap_port: body.imap_port,
imap_ssl: body.imap_ssl,
}
const { data, error } = await server.supabase
.from("user_credentials")
.update(saveData)
.eq("id", req.params.id)
.select("*")
.single();
if (error) {
return reply.code(400).send({ error: error.message });
} else {
return reply.send({success: true})
}
} else {
//Create New
let createData = {
user_id: req.user.user_id,
email_encrypted: encrypt(body.email),
password_encrypted: encrypt(body.password),
tenant_id: req.user.tenant_id,
smtp_host_encrypted: encrypt(body.smtp_host),
smtp_port: body.smtp_port,
smtp_ssl: body.smtp_ssl,
type: "mail",
imap_host_encrypted: encrypt(body.imap_host),
imap_port: body.imap_port,
imap_ssl: body.imap_ssl,
}
const { data, error } = await server.supabase
.from("user_credentials")
.insert(createData)
.select("*")
.single();
if (error) {
return reply.code(400).send({ error: error.message });
} else {
return reply.send({success: true})
}
}
});
server.get("/email/accounts/:id?", async (req, reply) => {
if (!req.user?.tenant_id) {
return reply.code(400).send({ error: "No tenant selected" });
}
const { id } = req.params as { id: string };
if(id) {
let returnData = {}
// @ts-ignore
const { data, error } = await server.supabase
.from("user_credentials")
.select("id, email_encrypted, smtp_host_encrypted, smtp_port, smtp_ssl, imap_host_encrypted, imap_port, imap_ssl, user_id, tenant_id")
.eq("id", id)
.eq("tenant_id", req.user.tenant_id)
.eq("type", "mail")
.single();
if (error || !data) {
return reply.code(404).send({ error: "Not found" });
} else {
Object.keys(data).forEach((key) => {
if(key.includes("encrypted")){
returnData[key.substring(0,key.length-10)] = decrypt(data[key])
} else {
returnData[key] = data[key]
}
})
}
return returnData;
} else {
const { data, error } = await server.supabase
.from("user_credentials")
.select("id, email_encrypted, user_id, tenant_id")
.eq("tenant_id", req.user.tenant_id)
.eq("type", "mail")
let accounts = []
data.forEach(item => {
let temp = {}
Object.keys(item).forEach((key) => {
if(key.includes("encrypted")){
temp[key.substring(0,key.length-10)] = decrypt(item[key])
} else {
temp[key] = item[key]
}
})
accounts.push(temp)
})
return accounts
}
});
server.post("/email/send", async (req, reply) => {
const body = req.body as {
to: string
cc?: string
bcc?: string
subject?: string
text?: string
html?: string
attachments?: any,
account: string
}
try {
let accountData = {} as {
email: string
password: string
smtp_host: string
smtp_port: number
smtp_ssl: boolean
}
// @ts-ignore
const { data, error } = await server.supabase
.from("user_credentials")
.select("id, email_encrypted,password_encrypted, smtp_host_encrypted, smtp_port, smtp_ssl, user_id, tenant_id")
.eq("id", body.account)
.eq("tenant_id", req.user.tenant_id)
.eq("type", "mail")
.single();
if (error || !data) {
return reply.code(404).send({ error: "Not found" });
} else {
Object.keys(data).forEach((key) => {
if(key.includes("encrypted")){
accountData[key.substring(0,key.length-10)] = decrypt(data[key])
} else {
accountData[key] = data[key]
}
})
}
const transporter = nodemailer.createTransport({
host: accountData.smtp_host,
port: accountData.smtp_port,
secure: accountData.smtp_ssl,
auth: {
user: accountData.email,
pass: accountData.password,
},
})
const info = await transporter.sendMail({
from: accountData.email,
to: body.to,
cc: body.cc ? body.cc : undefined,
bcc: body.bcc ? body.bcc : undefined,
subject: body.subject,
html: body.html ? body.html : undefined,
text: body.text,
attachments: body.attachments ? body.attachments : undefined,
})
if(info.response.includes("OK")){
reply.send({success: true})
}{
reply.status(500)
}
} catch (err) {
reply.code(500).send({ error: "Failed to send E-Mail as User" })
}
})
}