Skip to content

Persist Snapmaker cloud login across restarts (secure token store + startup race fix)#479

Open
PGMacDesign wants to merge 2 commits into
Snapmaker:mainfrom
PGMacDesign:fix/persist-snapmaker-login
Open

Persist Snapmaker cloud login across restarts (secure token store + startup race fix)#479
PGMacDesign wants to merge 2 commits into
Snapmaker:mainfrom
PGMacDesign:fix/persist-snapmaker-login

Conversation

@PGMacDesign

@PGMacDesign PGMacDesign commented Jun 14, 2026

Copy link
Copy Markdown

Description

Snapmaker cloud login was not persisted across restarts on Linux (AppImage/Flatpak) and elsewhere — every launch forced a fresh OAuth login. This PR persists the session securely and restores it on startup, with a fix for a startup race that could otherwise leave the UI showing "logged out" despite a valid restored token.

Fixes #116
Fixes #226
Builds on the approach proposed in #266, hardened to keep the token out of plaintext on disk.

1. Persist login across restarts via the OS secret store (GUI_App.cpp/.hpp, WebSMUserLoginDialog.cpp)

  • Store only the bearer token, and only in the OS secret store via wxSecretStore (libsecret / Windows Credential Manager / macOS Keychain) — never in plaintext config.
  • If no secret service is available, the token is not persisted (falls back to the prior re-login behaviour) rather than written insecurely.
  • Guarded with wxUSE_SECRETSTORE so toolchains without it (e.g. MinGW) still compile.
  • On startup, revalidate the stored token against the accounts/current endpoint and re-fetch the profile from the server, restoring the session. The stored token is cleared on validation failure or explicit logout. No user data is written to disk.

2. Push restored login to the web UI on subscribe (SSWCP.cpp)

  • The persisted session is revalidated asynchronously at startup. That can complete before the Flutter home page subscribes to login-state updates, so the one-shot user_login_notify() push reaches an empty subscriber list and is lost — leaving the UI "logged out" despite a valid token.
  • sw_SubscribeUserLoginState now pushes the current login state immediately when the user is already logged in at subscribe time. This closes the race in both orderings (restore-before-subscribe via the immediate push here; restore-after-subscribe via the existing notify path).

Security notes

  • Only the bearer token is stored, and only in the platform secret store — nothing sensitive is written to OrcaSlicer.conf or any plaintext file.
  • No persistence when no secret service is present (graceful fallback to re-login).

Breaking changes / dependencies: none. Uses wxSecretStore (already part of wxWidgets), guarded by wxUSE_SECRETSTORE.

Screenshots/Recordings/Graphs

🎉 Can confirm Login works + Persists across app close / open 🎉

Linux (Pop! OS / Ubuntu)

bugix_linux_ubuntu_popos

Mac

bugfix_mac_screenshot

Tests

  • Log in, restart the app → session restored without re-authenticating (Linux AppImage).
  • Verify the web UI reflects the logged-in state immediately on startup (race fix).
  • Explicit logout clears the stored token.
  • Builds with and without wxUSE_SECRETSTORE.
  • Verified on Linux (Pop!_OS) and macOS (see screenshots).

Snapmaker cloud login was not persisted on Linux/AppImage (and elsewhere):
every restart forced a fresh OAuth login. Persist the session so it survives
restarts, revalidating the stored token on startup.

- Store only the bearer token, and only in the OS secret store via wxSecretStore
  (libsecret / Credential Manager / Keychain) -- never in plaintext config. If no
  secret service is available the token is not persisted (falls back to the prior
  re-login behaviour) rather than written insecurely. Guarded with
  wxUSE_SECRETSTORE so toolchains without it (e.g. MinGW) still compile.
- On startup, revalidate the token against the accounts/current endpoint and
  re-fetch the profile from the server, restoring the session; clear the stored
  token on failure or explicit logout. No user data is written to disk.

Addresses Snapmaker#116, Snapmaker#226. Builds on the approach proposed in Snapmaker#266, hardened to keep
the token out of plaintext on disk.
The persisted session is revalidated asynchronously at startup. That can
complete before the Flutter home page subscribes to login-state updates, in
which case the one-shot user_login_notify() push reaches an empty subscriber
list and is lost -- leaving the UI showing 'logged out' despite a valid,
restored token.

Make sw_SubscribeUserLoginState push the current login state immediately when
the user is already logged in at subscribe time. This closes the race in both
orderings: restore-before-subscribe is covered by the immediate push here, and
restore-after-subscribe by the existing notify() path.
@PGMacDesign

Copy link
Copy Markdown
Author

@coderabbitai review

@i-am-ez76

Copy link
Copy Markdown

Hi.
Thank you for working on this but even the latest 2.4.3 version still doens't remember the login.
Screenshot_20260615_113602

Once opened, the login just fine.
closed it and re-opened it and was prompt to login again.

The flatpak version crashed when trying to access the preference menu so i am working on the AppImage only.
Attached is the log.

2026-06-15-11-36-24.log.0.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants