package su.xserver.iikocon.handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import su.xserver.iikocon.service.UserService; public class SetupHandler { private final UserService userService; public SetupHandler(UserService userService) { this.userService = userService; } public void checkStatus(RoutingContext ctx) { userService.countUsers().onComplete(ar -> { if (ar.succeeded()) { ctx.response() .putHeader("Content-Type", "application/json") .end(new JsonObject() .put("needsSetup", ar.result() == 0) .put("userCount", ar.result()) .encode()); } else { ctx.response().setStatusCode(500).end(ar.cause().getMessage()); } }); } public void handleSetup(RoutingContext ctx) { userService.countUsers().onComplete(ar -> { if (ar.succeeded() && ar.result() == 0) { JsonObject body = ctx.body().asJsonObject(); if (body == null) { ctx.response().setStatusCode(400).end("Invalid JSON body"); return; } String login = body.getString("login"); String password = body.getString("password"); String email = body.getString("email"); if (email == null || email.isBlank()) { email = login + "@admin.local"; // значение по умолчанию } if (login == null || password == null || login.length() < 3 || password.length() < 6) { ctx.response().setStatusCode(400) .end(new JsonObject() .put("error", "Invalid login or password (min 3/6 chars)") .encode()); return; } String clientIp = ctx.get("realClientIp"); if (clientIp == null) { clientIp = ctx.request().remoteAddress().host(); } userService.createUser(login, email, password, clientIp, true, "admin").onComplete(cr -> { if (cr.succeeded()) { ctx.response().setStatusCode(201) .end(new JsonObject().put("success", true).encode()); } else { ctx.response().setStatusCode(500) .end(new JsonObject() .put("error", "Failed to create admin: " + cr.cause().getMessage()) .encode()); } }); } else { ctx.response().setStatusCode(403) .end(new JsonObject() .put("error", "Setup already completed") .encode()); } }); } }