Skip to content
Windows only · Invite only. To get the SDK, DM @snailyt on Telegram.

Sign-in flows

Every successful sign-in raises Event::LoggedIn and starts heartbeats.

// Create an account: username, password and a license key.
eonauth::RegisterAsync(username, password, licenseKey, [](const eonauth::Result& r) { /* … */ });
// Sign in later.
eonauth::LoginAsync(username, password, [](const eonauth::Result& r) { /* … */ });
  • Usernames are 3 to 32 letters, digits, _, ., -, unique in the app (the app can require a longer minimum).
  • Passwords are 8 to 128 characters. If the app blocks leaked passwords, Register can answer PasswordLeaked.
  • One-time keys can’t create an account (LicenseTypeNotAllowed).

Customers can sign in with just a license key. The first time a key is used, the server needs a username and answers UsernameRequired until you send one. That creates a key-login account: it has no password and signs in with any of its keys.

void SignInWithKey(const std::string& key, const std::string& username /* may be empty */) {
eonauth::LoginWithKeyAsync(key, username, [=](const eonauth::Result& r) {
if (r.status == eonauth::Status::UsernameRequired) {
AskForUsername([=](std::string name) { SignInWithKey(key, name); });
} else if (r.status == eonauth::Status::UsernameTaken) {
ShowError("That username is taken. Pick another one.");
} else if (!r) {
ShowError(eonauth::UserMessage(r), eonauth::UserHint(r));
}
});
}

Later sign-ins with that key ignore the username. Login(username, password) never works for a key-login account.

If the app has free mode turned on:

eonauth::LoginFreeAsync([](const eonauth::Result& r) {
if (r.status == eonauth::Status::FreeModeDisabled) ShowKeyScreen();
});

While signed in this way:

  • IsFree() is true, Username() is empty, and there are no subscriptions.
  • Only variables and files marked Free users can be fetched.
  • Account features (per-user variables, ChangeUsername, Redeem) answer AccountRequired.

To upgrade, call LoginWithKey on the same PC. The panel counts it as a conversion. If the app turns free mode off, free sessions end at their next heartbeat.

With Config::persistSession on (the default), the session is saved for the current Windows user, encrypted with DPAPI. On the next start:

eonauth::ResumeSessionAsync([](const eonauth::Result& r) {
if (!r) ShowLoginUi(); // nothing saved, or the server no longer accepts it
});

A resumed session is always checked with the server before it is used. The saved file is deleted on sign-out and on any definitive refusal, and it won’t decrypt for another Windows user, another PC or another app.

Offering Keep me signed in? Do what the GUI demo does: on exit, call Shutdown(!keepSignedIn). Shutdown(true) signs out and deletes the saved session; Shutdown() leaves it resumable.

// Signed in: add a key (extends a tier they have, or adds a new one).
eonauth::RedeemAsync(licenseKey, [](const eonauth::Result& r) { /* SubscriptionsChanged follows */ });
// Expired account that can't sign in: renew with its credentials.
eonauth::RedeemWithCredentialsAsync(username, password, licenseKey, [](const eonauth::Result& r) { /* … */ });
eonauth::LogoutAsync(); // ends the server session, raises LoggedOut

Shutdown(true) also signs out. Shutdown() alone leaves the session resumable.

// Paste-friendly: " “abcd–efgh–ijkl” " becomes "ABCD-EFGH-IJKL".
const std::string key = eonauth::NormalizeLicenseKey(eonauth::ToUtf8(typed));
keyField.SetText(eonauth::ToWide(key)); // show what will actually be sent
if (const std::string problem = eonauth::CheckLicenseKey(key); !problem.empty()) {
ShowStatus(problem); // "That license key is too short." Nothing was sent
return;
}

CheckUsername, CheckPassword and CheckVariableName work the same way. The SDK runs the same checks itself before sending (bad input fails with InvalidRequest without touching the network); calling them yourself only lets the user find out sooner.

By default, an account is locked to the PC it first signed in from. Another PC gets HwidMismatch. The user asks you (or your support bot) for a HWID reset. Show them eonauth::Hwid() as a support ID so you can find their PC in the panel.

Even with the lock turned off, each session stays bound to the PC that opened it, so a copied session doesn’t work elsewhere.