summaryrefslogtreecommitdiff
path: root/backend/api/src/mail.zig
blob: 2489a48111979893f4e1b1088aaf3938606bb360 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
const z = @import( "std" );
const u = @import( "util.zig" );
const smtp = @import( "smtp_client" );

const bufPrint = z.fmt.bufPrint;
const alloc = u.alloc;

pub var smtp_host = "smtppro.zoho.com";
pub var smtp_alias = "Axonbox Support";
pub var smtp_username = "support@axonbox.net";
pub var smtp_port: u16 = 465;

const Config = smtp.Config;

fn getPassword() ![]const u8 {
  return try u.readFile( "../data/mail_password.txt" );
}

fn getConfig() !Config {
  const pass = try getPassword();

  return Config {
    .host = smtp_host,
    .username = smtp_username,
    .password = pass,
    .port = smtp_port,
    .encryption = .tls,
    .allocator = alloc,
  };
}

fn formatEmail( to: []const u8, subject: []const u8, body: []const u8 ) []const u8 {
  const escaped_newl = z.mem.replaceOwned( u8, alloc, body, "\n", "\r\n" ) catch return "";
  const escaped_dots = z.mem.replaceOwned( u8, alloc, escaped_newl, "\n.", "\n.." ) catch return "";
  defer alloc.free( escaped_dots );
  alloc.free( escaped_newl );

  const fmt = "From: {s} <{s}>\r\nTo: {s}\r\nSubject: {s}\r\n\r\n{s}\r\n.\r\n";
  const slice = z.fmt.allocPrint( alloc, fmt, .{
    smtp_alias, smtp_username, to, subject, escaped_dots
  } ) catch return "";

  return slice;
}

pub fn send( to: []const u8, subject: []const u8, body: []const u8 ) !void {
  const config = getConfig() catch {
    z.debug.print( "error creating mail config", .{} );
    return;
  };
  defer alloc.free( config.password.? );

  const data = formatEmail( to, subject, body );
  defer alloc.free( data );

  smtp.send( .{ .to = &.{to}, .from = smtp_username, .data = data }, config ) catch |e| {
    z.debug.print( "error sending mail {any} {any}", .{ e, @errorReturnTrace() } );
    return e;
  };
}