#pragma once #include "db/database_manager.h" #include namespace radiantwave::license { enum class Result { Ok, // license valid; subscription active NotConfigured, // email and/or license key missing from the DB Invalid, // API rejected the pair (bad key, wrong user, inactive, ...) NetworkError, // the request never completed }; // How long a previously-validated license stays valid without a successful // re-validation (7 days). Network failures within this window after the last // successful check do not invalidate the license; the user has the whole // window to reconnect so the "last verified" stamp can be refreshed. constexpr long long GRACE_PERIOD_SECONDS = 7LL * 24 * 60 * 60; // Validates the stored license key against the stored email address via the // portal API. A successful validation is the device's "subscribed" flag — no // separate subscription state is tracked. On failure nothing is written, so a // previous good value survives a transient outage. Returns NotConfigured // without touching the network when either value is missing. Never throws. // // `outErrorMessage` is an optional out-param. Result validateStoredLicense(radiantwave::db::DatabaseManager& db, std::string* outErrorMessage = nullptr); // Records the current time as the "last verified" stamp of the license. Called // after every successful server validation so the offline grace window starts // (or is extended) from the most recent confirmation. void markLicenseVerified(radiantwave::db::DatabaseManager& db); // True when a prior successful validation happened within // GRACE_PERIOD_SECONDS of now. Returns false when no stamp is stored or the // stamp is corrupted or older than the grace window. bool isLicenseWithinGracePeriod(const radiantwave::db::DatabaseManager& db); } // namespace radiantwave::license