const std = @import("std"); const http_api = @import("../http/api.zig"); const http = std.http; pub fn page(request: *http_api.Request) !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const body = try @import("web/icons.zig").decorate(arena.allocator(), html); try http_api.respond(request, .ok, body, &html_headers); } pub fn redirectToSecurity(request: *http_api.Request) !void { try redirect(request, "/account/manage"); } pub fn redirectToSpaces(request: *http_api.Request) !void { try redirect(request, "/account/spaces"); } fn redirect(request: *http_api.Request, location: []const u8) !void { const headers = [_]http.Header{ .{ .name = "location", .value = location }, .{ .name = "access-control-allow-origin", .value = "*" }, .{ .name = "connection", .value = "close" }, }; try http_api.respondNowClose(request, .see_other, "", &headers); } const html_headers = [_]http.Header{ .{ .name = "content-type", .value = "text/html; charset=utf-8" }, .{ .name = "cache-control", .value = "no-store" }, .{ .name = "access-control-allow-origin", .value = "*" }, .{ .name = "access-control-allow-private-network", .value = "true" }, .{ .name = "connection", .value = "close" }, }; // Presentation stays in a replaceable static asset, outside account/protocol logic. const template = @embedFile("web/account.html"); const appearance_offset = blk: { @setEvalBranchQuota(100_000); break :blk std.mem.indexOf(u8, template, "").?; }; const html = template[0..appearance_offset] ++ "" ++ template[appearance_offset..];