Remove API key requirement

This commit is contained in:
NeilClack
2026-08-17 20:36:59 -05:00
parent 359ae905d7
commit 74245ee07d
16 changed files with 74 additions and 194 deletions
+13 -26
View File
@@ -4,10 +4,6 @@
#include <curl/curl.h>
#include <string>
#ifndef API_KEY
#define API_KEY ""
#endif
namespace radiantwave::api {
namespace {
@@ -31,7 +27,7 @@ size_t writeCallback(char* ptr, size_t size, size_t nmemb, void* userdata) {
}
// Shared curl setup + perform. Returns a populated HttpResponse.
HttpResponse performRequest(const std::string& url, const std::string& apiKey,
HttpResponse performRequest(const std::string& url,
bool post, const std::string& jsonBody) {
HttpResponse response;
@@ -47,12 +43,6 @@ HttpResponse performRequest(const std::string& url, const std::string& apiKey,
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response.body);
struct curl_slist* headers = nullptr;
// An explicit apiKey wins; otherwise fall back to the key baked in at
// build time via -DAPI_KEY (empty string when unset).
const std::string effectiveKey = apiKey.empty() ? API_KEY : apiKey;
if (!effectiveKey.empty()) {
headers = curl_slist_append(headers, ("Authorization: Bearer " + effectiveKey).c_str());
}
if (post) {
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
@@ -79,13 +69,12 @@ HttpResponse performRequest(const std::string& url, const std::string& apiKey,
// ─── HTTP helpers ──────────────────────────────────────────────────────
HttpResponse httpGet(const std::string& path, const std::string& apiKey) {
return performRequest(urlFor(path), apiKey, false, "");
HttpResponse httpGet(const std::string& path) {
return performRequest(urlFor(path), false, "");
}
HttpResponse httpPost(const std::string& path, const std::string& jsonBody,
const std::string& apiKey) {
return performRequest(urlFor(path), apiKey, true, jsonBody);
HttpResponse httpPost(const std::string& path, const std::string& jsonBody) {
return performRequest(urlFor(path), true, jsonBody);
}
// ─── GET /frequencies ──────────────────────────────────────────────────
@@ -112,8 +101,8 @@ bool parseFrequenciesJson(const std::string& body, std::vector<Frequency>& out)
return true;
}
bool fetchFrequencies(std::vector<Frequency>& out, const std::string& apiKey) {
HttpResponse response = httpGet(PATH_FREQUENCIES, apiKey);
bool fetchFrequencies(std::vector<Frequency>& out) {
HttpResponse response = httpGet(PATH_FREQUENCIES);
if (!response.transportOk || response.status < 200 || response.status >= 300) {
return false;
}
@@ -169,8 +158,8 @@ bool parseColorPalettesJson(const std::string& body, std::vector<ColorPalette>&
return true;
}
bool fetchColorPalettes(std::vector<ColorPalette>& out, const std::string& apiKey) {
HttpResponse response = httpGet(PATH_COLOR_PALETTES, apiKey);
bool fetchColorPalettes(std::vector<ColorPalette>& out) {
HttpResponse response = httpGet(PATH_COLOR_PALETTES);
if (!response.transportOk || response.status < 200 || response.status >= 300) {
return false;
}
@@ -196,13 +185,12 @@ bool parseLicenseJson(const std::string& body, LicenseInfo& out) {
return !out.key.empty();
}
LicenseResult validateLicense(const std::string& key, const std::string& email,
const std::string& apiKey) {
LicenseResult validateLicense(const std::string& key, const std::string& email) {
LicenseResult result;
const std::string jsonBody =
"{\"license_key\":\"" + key + "\",\"email_address\":\"" + email + "\"}";
HttpResponse response = httpPost(PATH_LICENSE, jsonBody, apiKey);
HttpResponse response = httpPost(PATH_LICENSE, jsonBody);
result.status = response.status;
if (!response.transportOk) {
@@ -233,8 +221,7 @@ bool parseCreateAccountJson(const std::string& body, AccountBody& out) {
return true;
}
AccountResult createAccount(const std::string& email, const std::string& name,
const std::string& apiKey) {
AccountResult createAccount(const std::string& email, const std::string& name) {
AccountResult result;
std::string jsonBody =
@@ -244,7 +231,7 @@ AccountResult createAccount(const std::string& email, const std::string& name,
}
jsonBody += "}";
HttpResponse response = httpPost(PATH_CREATE_ACCOUNT, jsonBody, apiKey);
HttpResponse response = httpPost(PATH_CREATE_ACCOUNT, jsonBody);
result.status = response.status;
if (!response.transportOk) {
+7 -14
View File
@@ -24,14 +24,9 @@ struct HttpResponse {
bool transportOk = false; // true when the request completed without a transport error
};
// Performs a GET/POST against `path` (relative to API_BASE_URL). When `apiKey` is
// non-empty it is sent as `Authorization: Bearer <apiKey>`. When it is empty (or
// omitted) the request falls back to the key baked in at build time via the
// `API_KEY` compile definition (see CMakeLists.txt); with neither set, no auth
// header is sent.
HttpResponse httpGet(const std::string& path, const std::string& apiKey = "");
HttpResponse httpPost(const std::string& path, const std::string& jsonBody,
const std::string& apiKey = "");
// Performs a GET/POST against `path` (relative to API_BASE_URL).
HttpResponse httpGet(const std::string& path);
HttpResponse httpPost(const std::string& path, const std::string& jsonBody);
// ─── GET /frequencies ──────────────────────────────────────────────────
@@ -45,7 +40,7 @@ struct Frequency {
bool parseFrequenciesJson(const std::string& body, std::vector<Frequency>& out);
// Fetch the solfeggio frequencies. Returns true only on HTTP 2xx + successful parse.
bool fetchFrequencies(std::vector<Frequency>& out, const std::string& apiKey = "");
bool fetchFrequencies(std::vector<Frequency>& out);
// ─── GET /color-palettes ───────────────────────────────────────────────
@@ -75,7 +70,7 @@ bool parseColorPalettesJson(const std::string& body, std::vector<ColorPalette>&
// NOTE: the portal does not expose this route yet. This is readiness code — it
// is deliberately not called anywhere in the app until the route ships, so
// palettes can be updated from the portal rather than code releases.
bool fetchColorPalettes(std::vector<ColorPalette>& out, const std::string& apiKey = "");
bool fetchColorPalettes(std::vector<ColorPalette>& out);
// ─── POST /license ─────────────────────────────────────────────────────
@@ -98,8 +93,7 @@ struct LicenseResult {
// Validate a license key / email pair against the portal. Never throws; failures
// (network, HTTP error status) are reported through the returned LicenseResult.
// A 2xx response means the license is valid and the subscription is active.
LicenseResult validateLicense(const std::string& key, const std::string& email,
const std::string& apiKey = "");
LicenseResult validateLicense(const std::string& key, const std::string& email);
// ─── POST /automations/create/account ──────────────────────────────────
@@ -122,7 +116,6 @@ struct AccountResult {
// Creates (or reuses) a user account and issues a license key. The key is emailed
// to the user and is NOT part of the response. `name` may be empty.
AccountResult createAccount(const std::string& email, const std::string& name = "",
const std::string& apiKey = "");
AccountResult createAccount(const std::string& email, const std::string& name = "");
} // namespace radiantwave::api
+1 -2
View File
@@ -17,7 +17,6 @@ long long nowEpochSeconds() {
} // namespace
Result validateStoredLicense(radiantwave::db::DatabaseManager& db,
const std::string& apiKey,
std::string* outErrorMessage) {
if (outErrorMessage) outErrorMessage->clear();
@@ -28,7 +27,7 @@ Result validateStoredLicense(radiantwave::db::DatabaseManager& db,
}
const radiantwave::api::LicenseResult result =
radiantwave::api::validateLicense(key, email, apiKey);
radiantwave::api::validateLicense(key, email);
if (result.status == 0) {
if (outErrorMessage) *outErrorMessage = "network error";
-1
View File
@@ -26,7 +26,6 @@ constexpr long long GRACE_PERIOD_SECONDS = 7LL * 24 * 60 * 60;
//
// `outErrorMessage` is an optional out-param.
Result validateStoredLicense(radiantwave::db::DatabaseManager& db,
const std::string& apiKey = "",
std::string* outErrorMessage = nullptr);
// Records the current time as the "last verified" stamp of the license. Called
+4 -6
View File
@@ -190,10 +190,9 @@ bool parseProclamationPalettesJson(const std::string& body,
return true;
}
bool syncColorPalettesFromApi(radiantwave::db::DatabaseManager& db,
const std::string& apiKey) {
bool syncColorPalettesFromApi(radiantwave::db::DatabaseManager& db) {
std::vector<api::ColorPalette> palettes;
if (!api::fetchColorPalettes(palettes, apiKey)) {
if (!api::fetchColorPalettes(palettes)) {
return false;
}
@@ -211,9 +210,8 @@ bool syncColorPalettesFromApi(radiantwave::db::DatabaseManager& db,
return db.replaceColorPalettes(records);
}
bool syncProclamationPalettesFromApi(radiantwave::db::DatabaseManager& db,
const std::string& apiKey) {
api::HttpResponse response = api::httpGet(api::PATH_PROCLAMATIONS, apiKey);
bool syncProclamationPalettesFromApi(radiantwave::db::DatabaseManager& db) {
api::HttpResponse response = api::httpGet(api::PATH_PROCLAMATIONS);
if (!response.transportOk || response.status < 200 || response.status >= 300) {
return false;
}
+2 -4
View File
@@ -37,13 +37,11 @@ bool parseProclamationPalettesJson(const std::string& body,
// NOTE: not yet wired into the app flow — the portal does not expose the route
// yet. Readiness code: palettes should be updated from the portal, not code
// releases, so callers should treat this as a future sync step.
bool syncColorPalettesFromApi(radiantwave::db::DatabaseManager& db,
const std::string& apiKey = "");
bool syncColorPalettesFromApi(radiantwave::db::DatabaseManager& db);
// Alternative to syncColorPalettesFromApi: fetch proclamations and replace the
// local palette table using the palettes embedded in each proclamation.
// NOTE: not yet wired into the app flow; see syncColorPalettesFromApi.
bool syncProclamationPalettesFromApi(radiantwave::db::DatabaseManager& db,
const std::string& apiKey = "");
bool syncProclamationPalettesFromApi(radiantwave::db::DatabaseManager& db);
} // namespace radiantwave::sync