소스 검색

fix(auth): allow X-Captcha-Token/Cache-Control in CORS; reject admin+scope via PATCH

Fszontagh 1 개월 전
부모
커밋
956c2df2bf
2개의 변경된 파일12개의 추가작업 그리고 1개의 파일을 삭제
  1. 11 0
      src/handlers/keys.cpp
  2. 1 1
      src/server.cpp

+ 11 - 0
src/handlers/keys.cpp

@@ -83,6 +83,17 @@ void registerKeyRoutes(ApiServer& s) {
             }
             scopePatch = std::optional<std::optional<KeyScope>>{ parseScope(body, effectiveAdmin) };
         }
+        // Invariant: a key cannot be both admin and scoped. parseScope already rejects
+        // sending a scope to an admin, but also catch promoting an already-scoped key to admin.
+        {
+            bool finalAdmin = false, finalScoped = false;
+            std::optional<ApiKey> cur;
+            for (const auto& k : d->keys.list()) if (k.id == id) { cur = k; break; }
+            finalAdmin  = admin.has_value()     ? *admin             : (cur && cur->admin);
+            finalScoped = scopePatch.has_value() ? scopePatch->has_value() : (cur && cur->scope.has_value());
+            if (finalAdmin && finalScoped)
+                throw ApiError(ErrCode::Unprocessable, "validation", "a key cannot be both admin and scoped");
+        }
         if (!d->keys.update(id, label, projects, admin, scopePatch))
             throw ApiError(ErrCode::NotFound, "not_found", "no such key");
         sendJson(res, 200, {{"updated", true}});

+ 1 - 1
src/server.cpp

@@ -124,7 +124,7 @@ void ApiServer::registerRoutes() {
             res.set_header("Access-Control-Allow-Origin", responseOrigin);
             if (responseOrigin != "*") res.set_header("Vary", "Origin");
         }
-        res.set_header("Access-Control-Allow-Headers", "Authorization, Content-Type");
+        res.set_header("Access-Control-Allow-Headers", "Authorization, Content-Type, X-Captcha-Token, Cache-Control");
         res.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
     });
     svr_.Options(R"(.*)", [](const httplib::Request&, httplib::Response& res) { res.status = 204; });