""" Nur Falah mail relay — tiny HTTP wrapper around the existing, working falah-ibaas EmailConnector (SMTP via the local Postfix relay Ghost already uses successfully on this VPS). Exists because Supabase Edge Functions run on Supabase's cloud, not on this VPS, and can't reach localhost:25 directly — this gives them a real internet-reachable endpoint that forwards to it. Auth: a single shared-secret bearer token (X-Relay-Secret header), generated locally and never committed to the repo — set as a Supabase project secret (NF_RELAY_SECRET) and matched here via the RELAY_SECRET env var. """ import os import sys from http.server import BaseHTTPRequestHandler, HTTPServer import json sys.path.insert(0, "/opt/falah-ibaas/connectors/email") from handler import EmailConnector RELAY_SECRET = os.environ["RELAY_SECRET"] connector = EmailConnector( smtp_host=os.environ.get("SMTP_HOST", "localhost"), smtp_port=int(os.environ.get("SMTP_PORT", "25")), smtp_user=os.environ.get("SMTP_USER", ""), smtp_pass=os.environ.get("SMTP_PASS", ""), from_address=os.environ.get("SMTP_FROM", "notifications@falahos.my"), from_name="Nur Falah", ) class Handler(BaseHTTPRequestHandler): def _send(self, code, body): payload = json.dumps(body).encode() self.send_response(code) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(payload))) self.end_headers() self.wfile.write(payload) def do_GET(self): if self.path == "/health": return self._send(200, {"status": "ok", "metrics": connector.metrics()}) return self._send(404, {"error": "not_found"}) def do_POST(self): if self.path != "/send": return self._send(404, {"error": "not_found"}) if self.headers.get("X-Relay-Secret") != RELAY_SECRET: return self._send(401, {"error": "unauthorized"}) length = int(self.headers.get("Content-Length", 0)) try: data = json.loads(self.rfile.read(length)) except Exception: return self._send(400, {"error": "invalid_json"}) to = data.get("to") subject = data.get("subject") if not to or not subject: return self._send(400, {"error": "to and subject are required"}) result = connector.send_email( to=to, subject=subject, body_text=data.get("body_text"), body_html=data.get("body_html"), cc=data.get("cc"), bcc=data.get("bcc"), ) code = 200 if result.get("status") == "sent" else 502 return self._send(code, result) def log_message(self, fmt, *args): sys.stderr.write("%s - %s\n" % (self.address_string(), fmt % args)) if __name__ == "__main__": port = int(os.environ.get("PORT", "8091")) server = HTTPServer(("0.0.0.0", port), Handler) print(f"nf-mail-relay listening on :{port}") server.serve_forever()