This commit is contained in:
2026-04-20 13:42:41 +03:00
parent fd3cbb019f
commit ec0671c5e8
16 changed files with 465 additions and 117 deletions

View File

@@ -78,30 +78,54 @@ public class MainVerticle extends AbstractVerticle {
startPromise.fail(err);
});
Router router = initRouter();
startHttp(router, startPromise);
createRouterAndStartHttp(startPromise);
})
.onFailure(startPromise::fail);
}
private Router initRouter() {
private void createRouterAndStartHttp(Promise<Void> startPromise) {
settingsService.get("session_timeout_minutes")
.compose(timeoutStr -> {
long timeoutMinutes = 60; // default
if (timeoutStr != null && !timeoutStr.isEmpty()) {
try {
timeoutMinutes = Long.parseLong(timeoutStr);
} catch (NumberFormatException ignored) {}
}
long timeoutMs = timeoutMinutes * 60 * 1000;
// Настройка сессий (используем LocalSessionStore для простоты)
SessionStore sessionStore = LocalSessionStore.create(vertx);
SessionHandler sessionHandler = SessionHandler.create(sessionStore)
.setSessionCookieName("admin.session")
.setCookieHttpOnlyFlag(true)
.setCookieSecureFlag(false)
.setSessionTimeout(3600000);
SessionStore sessionStore = LocalSessionStore.create(vertx);
SessionHandler sessionHandler = SessionHandler.create(sessionStore)
.setSessionCookieName("admin.session")
.setCookieHttpOnlyFlag(true)
.setCookieSecureFlag(false)
.setSessionTimeout(timeoutMs);
Router router = initRouter(sessionHandler);
startHttp(router, startPromise);
return Future.succeededFuture();
})
.onFailure(err -> {
log.error("Failed to get session timeout", err);
startPromise.fail(err);
});
}
private Router initRouter(SessionHandler sessionHandler) {
// Роутер
Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.route().handler(sessionHandler);
SecurityHandlers securityHandlers = new SecurityHandlers(settingsService);
// Обработчики безопасности (порядок важен)
router.route().handler(securityHandlers.hostValidator());
router.route().handler(securityHandlers.proxyHeadersHandler());
router.route().handler(securityHandlers.cspHeader());
// CORS для разработки
router.route().handler(ctx -> {
ctx.response()
@@ -149,7 +173,12 @@ public class MainVerticle extends AbstractVerticle {
router.post("/api/logout").handler(authHandler::handleLogout);
router.post("/api/register").handler(rc -> {
router.post("/api/register").handler(rc -> settingsService.get("enable_registration").onComplete(regCheck -> {
if (regCheck.succeeded() && "false".equals(regCheck.result())) {
rc.response().setStatusCode(403).end(new JsonObject().put("error", "Registration is disabled").encode());
return;
}
// существующий код регистрации
JsonObject body = rc.body().asJsonObject();
String login = body.getString("login");
String email = body.getString("email");
@@ -162,7 +191,7 @@ public class MainVerticle extends AbstractVerticle {
userService.createUser(login, email, password, ip)
.onSuccess(v -> rc.response().setStatusCode(201).end(new JsonObject().put("success", true).encode()))
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
}));
router.route("/api/admin/*").handler(authHandler::requireAuth);
@@ -226,7 +255,7 @@ public class MainVerticle extends AbstractVerticle {
router.put("/api/admin/users/:id/activate").handler(rc -> {
int id = Integer.parseInt(rc.pathParam("id"));
boolean active = Boolean.parseBoolean(rc.queryParam("active").get(0));
boolean active = Boolean.parseBoolean(rc.queryParam("active").getFirst());
Integer currentUserId = rc.session().get("userId");
if (currentUserId != null && currentUserId == id) {
@@ -280,11 +309,12 @@ public class MainVerticle extends AbstractVerticle {
String login = body.getString("login");
String password = body.getString("password");
String host = body.getString("host");
boolean https = body.getBoolean("https", false);
if (name == null || login == null || password == null || host == null) {
rc.response().setStatusCode(400).end("Missing fields");
return;
}
restaurantService.createRestaurant(name, login, password, host)
restaurantService.createRestaurant(name, login, password, host, https)
.onSuccess(v -> rc.response().setStatusCode(201).end())
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
@@ -296,11 +326,12 @@ public class MainVerticle extends AbstractVerticle {
String login = body.getString("login");
String password = body.getString("password");
String host = body.getString("host");
boolean https = body.getBoolean("https", false);
if (name == null || login == null || host == null) {
rc.response().setStatusCode(400).end("Missing required fields");
return;
}
restaurantService.updateRestaurant(id, name, login, password, host)
restaurantService.updateRestaurant(id, name, login, password, host, https)
.onSuccess(v -> rc.response().end())
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
@@ -314,9 +345,9 @@ public class MainVerticle extends AbstractVerticle {
// Получение всех настроек
router.get("/api/settings").handler(rc -> {
settingsService.getAll()
settingsService.getPublicSettings()
.onSuccess(settings -> rc.response().putHeader("Content-Type", "application/json").end(settings.encode()))
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
.onFailure(err -> rc.response().setStatusCode(500).end());
});
// Получить метаданные всех настроек (для построения формы)