#include "common/Cors.h" #include namespace visione::cors { namespace { std::vector allowedOrigins() { auto cfg = drogon::app().getCustomConfig(); std::vector origins; if (cfg.isMember("cors") && cfg["cors"].isObject()) { auto &c = cfg["cors"]; if (c.isMember("allowed_origin")) { auto &v = c["allowed_origin"]; if (v.isArray()) { for (const auto &el : v) { if (el.isString()) origins.emplace_back(el.asString()); } } else if (v.isString()) { origins.emplace_back(v.asString()); } } } if (origins.empty()) origins.emplace_back("http://localhost:5173"); return origins; } bool isAllowed(const drogon::HttpRequestPtr &request) { auto origin = request->getHeader("Origin"); if (origin.empty()) return false; auto origins = allowedOrigins(); for (const auto &o : origins) { if (o == "*" || o == origin) return true; } return false; } void addHeaders(const drogon::HttpRequestPtr &request, const drogon::HttpResponsePtr &response) { auto origin = request->getHeader("Origin"); if (origin.empty()) return; auto origins = allowedOrigins(); bool allowAll = false; bool matched = false; for (const auto &o : origins) { if (o == "*") { allowAll = true; break; } if (o == origin) { matched = true; break; } } if (!allowAll && !matched) return; if (allowAll) response->addHeader("Access-Control-Allow-Origin", "*"); else response->addHeader("Access-Control-Allow-Origin", origin); 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"); response->addHeader("Vary", "Origin"); } } // 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