const std = @import("std"); const aegis256 = std.crypto.aead.aegis.Aegis256; pub const Config = @This(); signup_code: []const u8, port: u16, db_file_path: [:0]const u8, max_body_size: usize, urls: AppUrls, pbkdf2Rounds: u32, salt_length: usize, session_length: usize, ad: []const u8, npub: [aegis256.nonce_length]u8, tag: [aegis256.tag_length]u8, pub const AppUrls = struct { origin: []const u8, home: []const u8, login: []const u8, }; pub fn deinit(c: *Config, all: std.mem.Allocator) void { all.free(c.db_file_path); all.free(c.urls.origin); all.free(c.urls.home); all.free(c.urls.login); } pub fn cloneTag(c: *Config) [aegis256.tag_length]u8 { var clone = [_]u8{0} ** aegis256.tag_length; var j: usize = 0; for (c.tag) |byt| { clone[j] = byt; j += 1; } return clone; } pub fn get(init: std.process.Init) !Config { var signup_code: []const u8 = ""; const signup_code_env = init.environ_map.get("PAD_SIGNUP_CODE"); if (signup_code_env) |val| { signup_code = val; } var ad: []const u8 = ""; const ad_env = init.environ_map.get("PAD_AD"); if (ad_env) |val| { ad = val; } var port: u16 = 8000; const port_env = init.environ_map.get("PAD_PORT"); if (port_env) |val| { port = try std.fmt.parseInt(u16, val, 10); } var pbkdf2Rounds: u32 = 1000; const rounds_env = init.environ_map.get("PAD_PBKDF2_ROUNDS"); if (rounds_env) |val| { pbkdf2Rounds = try std.fmt.parseInt(u32, val, 10); } var saltLength: usize = 40; const salt_length_env = init.environ_map.get("PAD_SALT_LENGTH"); if (salt_length_env) |val| { saltLength = try std.fmt.parseInt(usize, val, 10); } var sessionLength: usize = 1234567890; const session_length_env = init.environ_map.get("PAD_SESSION_LENGTH"); if (session_length_env) |val| { sessionLength = try std.fmt.parseInt(usize, val, 10); } var db_file_path: [:0]const u8 = try std.fmt.allocPrintSentinel(init.gpa, "{s}", .{"/m/pad.db"}, 0); const db_file_path_env = init.environ_map.get("PAD_DB"); if (db_file_path_env) |val| { db_file_path = try std.fmt.allocPrintSentinel(init.gpa, "{s}", .{val}, 0); } var max_body_size: usize = 1_048_576 * 10; const max_body_size_env = init.environ_map.get("PAD_MAX_BODY_SIZE"); if (max_body_size_env) |val| { max_body_size = try std.fmt.parseInt(usize, val, 10); } const pad_listen_domain_m = init.environ_map.get("PAD_LISTEN_DOMAIN"); const originAlloc = try std.fmt.allocPrint(init.gpa, "http://localhost:{d}", .{port}); const origin: []const u8 = if (pad_listen_domain_m) |domain| domain else originAlloc; const home_url = try std.fmt.allocPrint(init.gpa, "{s}/a", .{origin}); const login_url = try std.fmt.allocPrint(init.gpa, "{s}/login", .{origin}); var npub = [_]u8{0} ** aegis256.nonce_length; const npub_env = init.environ_map.get("PAD_NPUB"); if (npub_env) |val| { if (val.len != aegis256.nonce_length) { std.log.err("bad nonce length: {d}", .{val.len}); std.process.exit(1); } var j: usize = 0; for (val) |byt| { npub[j] = byt; j += 1; } } var tag = [_]u8{0} ** aegis256.tag_length; const tag_env = init.environ_map.get("PAD_TAG"); if (tag_env) |val| { if (val.len != aegis256.tag_length) { std.log.err("bad tag length: {d}", .{val.len}); std.process.exit(1); } var j: usize = 0; for (val) |byt| { tag[j] = byt; j += 1; } } return Config{ .signup_code = signup_code, .pbkdf2Rounds = pbkdf2Rounds, .salt_length = saltLength, .session_length = sessionLength, .npub = npub, .ad = ad, .tag = tag, .port = port, .db_file_path = db_file_path, .max_body_size = max_body_size, .urls = Config.AppUrls{ .origin = origin, .home = home_url, .login = login_url, }, }; }