const std = @import("std");
const config = @import("../core/config.zig");
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 std.mem.concat(arena.allocator(), u8, &.{
html_before_invite_cta,
try inviteCta(arena.allocator()),
html_after_invite_cta,
});
try http_api.respond(request, .ok, body, &html_headers);
}
fn inviteCta(allocator: std.mem.Allocator) ![]const u8 {
const operator = config.operatorHandle();
if (operator.len == 0) return "";
const escaped = try escapeHtml(allocator, operator);
return std.fmt.allocPrint(
allocator,
"
Need an invite? DM @{s} , the operator of this PDS.
",
.{ escaped, escaped },
);
}
fn escapeHtml(allocator: std.mem.Allocator, text: []const u8) ![]const u8 {
var out: std.Io.Writer.Allocating = .init(allocator);
defer out.deinit();
for (text) |c| switch (c) {
'&' => try out.writer.writeAll("&"),
'<' => try out.writer.writeAll("<"),
'>' => try out.writer.writeAll(">"),
'"' => try out.writer.writeAll("""),
'\'' => try out.writer.writeAll("'"),
else => try out.writer.writeByte(c),
};
return out.toOwnedSlice();
}
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" },
};
const html_before_invite_cta =
\\
\\
\\
\\
\\
\\join zds
\\
\\
\\
\\
\\
\\
\\zds
\\join
\\Create a new account on this PDS .
\\
\\This creates a brand new account . Already have an atproto account you want to bring here? Use a migration tool such as PDS Moover instead — migration is a different flow with different identity semantics.
\\
\\
\\Already have an account here? Sign in.
\\
\\
\\
\\
;