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" }) } }) }