aboutsummaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2026-04-05 16:37:02 -0700
committerPinapelz <yukais@pinapelz.com>2026-04-05 16:39:38 -0700
commitee8e8ba44e72caa0fdd88b5b4a8cd63e07339e8d (patch)
tree42ae92ff3aa4edb8ca03fe4da216796f2e9f7178 /src/server
parentabc7f3331d43e081b8501632e584f24dcc2581ac (diff)
improve some EN locale. add frontend admin registration page via token
Signed-off-by: Pinapelz <yukais@pinapelz.com>
Diffstat (limited to 'src/server')
-rw-r--r--src/server/HttpServer.hx75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/server/HttpServer.hx b/src/server/HttpServer.hx
index 5917ee0..f0f565b 100644
--- a/src/server/HttpServer.hx
+++ b/src/server/HttpServer.hx
@@ -29,6 +29,13 @@ typedef GateRequest = {
password:String,
}
+typedef AdminRegisterRequest = {
+ name:String,
+ password:String,
+ passwordConfirmation:String,
+ token:String,
+}
+
class HttpServer {
static final mimeTypes = [
"html" => "text/html",
@@ -101,6 +108,8 @@ class HttpServer {
switch url.pathname {
case "/gate":
verifyGate(req, res);
+ case "/admin-register":
+ registerAdmin(req, res);
}
return;
}
@@ -134,6 +143,23 @@ class HttpServer {
return;
}
+ if (url.pathname == "/admin-register") {
+ if (!hasAdminToken()) {
+ res.redirect("/");
+ return;
+ }
+ Fs.readFile('$dir/admin-register.html', (err:Dynamic, data:Buffer) -> {
+ if (err != null) {
+ readFileError(err, res, '$dir/admin-register.html');
+ return;
+ }
+ data = Buffer.from(localizeHtml(data.toString(), req.headers["accept-language"]));
+ res.setHeader("content-type", getMimeType("html"));
+ res.end(data);
+ });
+ return;
+ }
+
if (url.pathname == "/proxy") {
if (!proxyUrl(req, res)) res.end('Proxy error: ${req.url}');
return;
@@ -293,6 +319,55 @@ class HttpServer {
return Sha256.encode('gate_${main.config.gatePassword}_${main.config.salt}');
}
+ function hasAdminToken():Bool {
+ final t = main.config.adminToken;
+ return t != null && t.length > 0;
+ }
+
+ function registerAdmin(req:IncomingMessage, res:ServerResponse) {
+ if (!hasAdminToken()) {
+ res.status(403).json({success: false, error: "Admin registration is disabled"});
+ return;
+ }
+
+ final bodyChunks:Array<Buffer> = [];
+ req.on("data", chunk -> bodyChunks.push(chunk));
+ req.on("end", () -> {
+ final body = Buffer.concat(bodyChunks).toString();
+ final jsonParser = new JsonParser<AdminRegisterRequest>();
+ final jsonData = jsonParser.fromJson(body);
+ if (jsonParser.errors.length > 0) {
+ res.status(400).json({success: false, error: "Invalid request"});
+ return;
+ }
+ final name = jsonData.name.trim();
+ final password = jsonData.password;
+ final passwordConfirmation = jsonData.passwordConfirmation;
+ final token = jsonData.token;
+
+ if (token != main.config.adminToken) {
+ res.status(401).json({success: false, error: "Invalid admin token"});
+ return;
+ }
+ if (main.isBadClientName(name)) {
+ res.status(400).json({success: false, error: "Invalid username"});
+ return;
+ }
+ final min = Main.MIN_PASSWORD_LENGTH;
+ final max = Main.MAX_PASSWORD_LENGTH;
+ if (password.length < min || password.length > max) {
+ res.status(400).json({success: false, error: 'Password must be $min-$max characters'});
+ return;
+ }
+ if (password != passwordConfirmation) {
+ res.status(400).json({success: false, error: "Passwords do not match"});
+ return;
+ }
+ main.addAdmin(name, password);
+ res.status(200).json({success: true});
+ });
+ }
+
function getPath(dir:String, url:URL):String {
final filePath = dir.urlDecode() + decodeURIComponent(url.pathname);
if (!FileSystem.isDirectory(filePath)) return filePath;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage