Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
be07ab2fa3
commit
c71f7dbd87
@@ -0,0 +1,104 @@
|
||||
// Send an email via the firm's configured SMTP server.
|
||||
// Uses denomailer (SMTP client for Deno).
|
||||
import { SMTPClient } from "https://deno.land/x/denomailer@1.6.0/mod.ts";
|
||||
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.49.4";
|
||||
|
||||
const corsHeaders = {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers":
|
||||
"authorization, x-client-info, apikey, content-type",
|
||||
};
|
||||
|
||||
interface SendBody {
|
||||
to: string | string[];
|
||||
subject: string;
|
||||
html?: string;
|
||||
text?: string;
|
||||
cc?: string | string[];
|
||||
bcc?: string | string[];
|
||||
replyTo?: string;
|
||||
test?: boolean;
|
||||
}
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
if (req.method === "OPTIONS") return new Response(null, { headers: corsHeaders });
|
||||
|
||||
try {
|
||||
const authHeader = req.headers.get("Authorization");
|
||||
if (!authHeader) {
|
||||
return json({ error: "Missing authorization" }, 401);
|
||||
}
|
||||
|
||||
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
|
||||
const anonKey = Deno.env.get("SUPABASE_ANON_KEY")!;
|
||||
const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
|
||||
|
||||
// Verify caller is authenticated
|
||||
const userClient = createClient(supabaseUrl, anonKey, {
|
||||
global: { headers: { Authorization: authHeader } },
|
||||
});
|
||||
const { data: userData, error: userErr } = await userClient.auth.getUser();
|
||||
if (userErr || !userData.user) return json({ error: "Unauthorized" }, 401);
|
||||
|
||||
const admin = createClient(supabaseUrl, serviceKey);
|
||||
|
||||
// Load latest enabled SMTP settings
|
||||
const { data: settings, error: setErr } = await admin
|
||||
.from("smtp_settings")
|
||||
.select("*")
|
||||
.eq("enabled", true)
|
||||
.order("updated_at", { ascending: false })
|
||||
.limit(1)
|
||||
.maybeSingle();
|
||||
|
||||
if (setErr) return json({ error: setErr.message }, 500);
|
||||
if (!settings) return json({ error: "No SMTP settings configured" }, 400);
|
||||
|
||||
const password = Deno.env.get("SMTP_PASSWORD") ?? "";
|
||||
if (!password) return json({ error: "SMTP_PASSWORD secret not set" }, 400);
|
||||
|
||||
const body = (await req.json()) as SendBody;
|
||||
if (!body.to || !body.subject) {
|
||||
return json({ error: "to and subject are required" }, 400);
|
||||
}
|
||||
|
||||
const client = new SMTPClient({
|
||||
connection: {
|
||||
hostname: settings.host,
|
||||
port: settings.port,
|
||||
tls: !!settings.secure,
|
||||
auth: settings.username
|
||||
? { username: settings.username, password }
|
||||
: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const fromAddr = settings.from_name
|
||||
? `${settings.from_name} <${settings.from_email}>`
|
||||
: settings.from_email;
|
||||
|
||||
await client.send({
|
||||
from: fromAddr,
|
||||
to: body.to,
|
||||
cc: body.cc,
|
||||
bcc: body.bcc,
|
||||
replyTo: body.replyTo ?? settings.reply_to ?? undefined,
|
||||
subject: body.subject,
|
||||
content: body.text ?? "auto",
|
||||
html: body.html,
|
||||
});
|
||||
await client.close();
|
||||
|
||||
return json({ ok: true });
|
||||
} catch (e) {
|
||||
console.error("send-smtp-email error", e);
|
||||
return json({ error: e instanceof Error ? e.message : String(e) }, 500);
|
||||
}
|
||||
});
|
||||
|
||||
function json(data: unknown, status = 200) {
|
||||
return new Response(JSON.stringify(data), {
|
||||
status,
|
||||
headers: { ...corsHeaders, "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user