|
@@ -4,7 +4,10 @@
|
|
|
namespace svapi {
|
|
namespace svapi {
|
|
|
|
|
|
|
|
static std::optional<KeyScope> parseScope(const nlohmann::json& body, bool admin) {
|
|
static std::optional<KeyScope> parseScope(const nlohmann::json& body, bool admin) {
|
|
|
- if (!body.contains("scope")) return std::nullopt;
|
|
|
|
|
|
|
+ // Absent OR explicit null ⇒ no scope. For PATCH, the caller only invokes this
|
|
|
|
|
+ // when "scope" is present, so a null value yields nullopt which the double-optional
|
|
|
|
|
+ // wrapper turns into "clear the scope" (outer engaged, inner nullopt).
|
|
|
|
|
+ if (!body.contains("scope") || body["scope"].is_null()) return std::nullopt;
|
|
|
if (admin) throw ApiError(ErrCode::Unprocessable, "validation", "admin keys cannot be scoped");
|
|
if (admin) throw ApiError(ErrCode::Unprocessable, "validation", "admin keys cannot be scoped");
|
|
|
const auto& sj = body["scope"];
|
|
const auto& sj = body["scope"];
|
|
|
if (!sj.is_object()) throw ApiError(ErrCode::Unprocessable, "validation", "scope must be an object");
|
|
if (!sj.is_object()) throw ApiError(ErrCode::Unprocessable, "validation", "scope must be an object");
|