Files
radiantwave/src/network/license_service.cpp
T
2026-08-17 20:36:59 -05:00

65 lines
2.0 KiB
C++

#include "network/license_service.h"
#include "db/db_keys.h"
#include "network/api_client.h"
#include <chrono>
#include <cstdlib>
namespace radiantwave::license {
namespace {
long long nowEpochSeconds() {
const auto now = std::chrono::system_clock::now();
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
}
} // namespace
Result validateStoredLicense(radiantwave::db::DatabaseManager& db,
std::string* outErrorMessage) {
if (outErrorMessage) outErrorMessage->clear();
const std::string email = db.getKV(radiantwave::db::KV_EMAIL_ADDRESS);
const std::string key = db.getKV(radiantwave::db::KV_LICENSE_KEY);
if (email.empty() || key.empty()) {
return Result::NotConfigured;
}
const radiantwave::api::LicenseResult result =
radiantwave::api::validateLicense(key, email);
if (result.status == 0) {
if (outErrorMessage) *outErrorMessage = "network error";
return Result::NetworkError;
}
if (!result.ok()) {
if (outErrorMessage) *outErrorMessage = result.error_message;
return Result::Invalid;
}
// A successful validation is the "subscribed" flag: the license is valid
// and the subscription is active. Only the "last verified" stamp is stored
// (it drives the offline grace window).
markLicenseVerified(db);
return Result::Ok;
}
void markLicenseVerified(radiantwave::db::DatabaseManager& db) {
db.setKV(radiantwave::db::KV_LICENSE_LAST_VERIFIED,
std::to_string(nowEpochSeconds()));
}
bool isLicenseWithinGracePeriod(const radiantwave::db::DatabaseManager& db) {
const std::string raw = db.getKV(radiantwave::db::KV_LICENSE_LAST_VERIFIED);
if (raw.empty()) return false;
char* end = nullptr;
const long long stamp = std::strtoll(raw.c_str(), &end, 10);
if (!end || *end != '\0' || stamp <= 0) return false;
return nowEpochSeconds() - stamp < GRACE_PERIOD_SECONDS;
}
} // namespace radiantwave::license