From e1c65903a30c1058ce8d5a0d219b11f0bf4140e7 Mon Sep 17 00:00:00 2001 From: gabdevele Date: Tue, 2 Jun 2026 19:39:15 +0200 Subject: [PATCH] Add local CORS --- CMakeLists.txt | 1 + README.md | 1 + common/Cors.cc | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ common/Cors.h | 7 ++++++ main.cc | 2 ++ 5 files changed, 72 insertions(+) create mode 100644 common/Cors.cc create mode 100644 common/Cors.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 039545d..53d8c13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ set(APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/controllers/AuthController.cc ${CMAKE_CURRENT_SOURCE_DIR}/controllers/ReportController.cc ${CMAKE_CURRENT_SOURCE_DIR}/common/Auth.cc + ${CMAKE_CURRENT_SOURCE_DIR}/common/Cors.cc ${CMAKE_CURRENT_SOURCE_DIR}/common/Crypto.cc ${CMAKE_CURRENT_SOURCE_DIR}/common/Email.cc ${CMAKE_CURRENT_SOURCE_DIR}/common/GeoJson.cc diff --git a/README.md b/README.md index b1bff42..d61a8b3 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ cmake --build build The API listens on `http://localhost:5555`. MailHog listens on `http://localhost:8025`. +Local CORS allows `http://localhost:5173` by default for the Vue frontend. Local seeded admin: diff --git a/common/Cors.cc b/common/Cors.cc new file mode 100644 index 0000000..6d1fc33 --- /dev/null +++ b/common/Cors.cc @@ -0,0 +1,61 @@ +#include "common/Cors.h" + +#include + +namespace visione::cors +{ +namespace +{ +std::string allowedOrigin() +{ + return drogon::app() + .getCustomConfig()["cors"] + .get("allowed_origin", "http://localhost:5173") + .asString(); +} + +bool isAllowed(const drogon::HttpRequestPtr &request) +{ + return request->getHeader("Origin") == allowedOrigin(); +} + +void addHeaders(const drogon::HttpRequestPtr &request, + const drogon::HttpResponsePtr &response) +{ + if (!isAllowed(request)) + { + return; + } + + response->addHeader("Access-Control-Allow-Origin", allowedOrigin()); + response->addHeader("Access-Control-Allow-Credentials", "true"); + response->addHeader("Access-Control-Allow-Methods", + "GET,POST,PATCH,DELETE,OPTIONS"); + response->addHeader("Access-Control-Allow-Headers", + "Authorization,Content-Type"); +} +} // namespace + +void configure() +{ + drogon::app().registerSyncAdvice( + [](const drogon::HttpRequestPtr &request) -> drogon::HttpResponsePtr { + if (request->method() != drogon::Options) + { + return nullptr; + } + + auto response = drogon::HttpResponse::newHttpResponse(); + response->setStatusCode(drogon::k204NoContent); + addHeaders(request, response); + return response; + }); + + drogon::app().registerPostHandlingAdvice( + [](const drogon::HttpRequestPtr &request, + const drogon::HttpResponsePtr &response) { + addHeaders(request, response); + }); +} +} // namespace visione::cors + diff --git a/common/Cors.h b/common/Cors.h new file mode 100644 index 0000000..389e735 --- /dev/null +++ b/common/Cors.h @@ -0,0 +1,7 @@ +#pragma once + +namespace visione::cors +{ +void configure(); +} + diff --git a/main.cc b/main.cc index c68a423..93cac37 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,6 @@ #include +#include "common/Cors.h" #include "plugins/RequestLogger.h" #include "repositories/MigrationRunner.h" @@ -16,6 +17,7 @@ int main(int argc, char *argv[]) drogon::app().loadConfigFile(configPath); drogon::app().addPlugin("RequestLogger", {}, requestLoggerConfig); + visione::cors::configure(); const auto migrationsPath = drogon::app() .getCustomConfig()