Skip to content

fix(settings): harden RomM sign-in and consolidate the connection/SteamGridDB UX#1565

Merged
danielcopper merged 6 commits into
mainfrom
feature/1564-login-hardening
Jul 23, 2026
Merged

fix(settings): harden RomM sign-in and consolidate the connection/SteamGridDB UX#1565
danielcopper merged 6 commits into
mainfrom
feature/1564-login-hardening

Conversation

@danielcopper

@danielcopper danielcopper commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Hardens the RomM sign-in flow and consolidates the connection / SteamGridDB settings UX after on-device testing.

Sign-in (RomM):

  • Every mode's fields are required — username and password, the API token, or all eight pairing-code boxes. The Sign-in button stays disabled until they're filled; an empty form can only be cancelled, which leaves the existing sign-in untouched.
  • Enter / R2 is placed logically: in the username field it advances to the password field, and it confirms only from a completing field once every required field is filled — never submitting an incomplete form. A single-field modal no longer closes on an empty Enter/R2.
  • A failed sign-in keeps the dialog open and shows the error inline, closing only on success — so the message sits where you typed, and a failed re-sign-in no longer silently leaves the previous token presenting as a fresh success.
  • A rejected token is reported plainly ("RomM rejected this token…") instead of a generic "Server error", and a wrong username/password no longer wrongly claims the account can't create API tokens — RomM returns an indistinguishable 403 for both, so the message names both causes.

SteamGridDB key: validated inline in its own modal — the entered key is tested against SteamGridDB before it is saved; a rejected key keeps the modal open with the reason, and only a valid key is persisted.

Fewer redundant buttons: removed the settings-page Test Connection and Verify Key buttons — the QAM Connection row already probes on open, and both modals now validate inline.

Clearer QAM status: the Connection row surfaces the specific reason on failure (Not signed in / Sign-in rejected / Server unreachable / No server URL) instead of a bare "Not connected".

All settings text inputs (RomM URL, SteamGridDB key, default save slot) now require a non-empty value.

Needs on-device verification in Game Mode — the on-screen-keyboard Enter/R2 dispatch and gamepad focus traversal can't be exercised by the unit tests.

Closes #1564

…surface errors in the modal

The RomM sign-in modal now gates the Sign in button until the selected
mode's required fields are complete, runs the sign-in to completion inside
the modal, and only closes on success — a failed sign-in stays open and
shows the returned message inline instead of at the bottom of the page.

- ConnectModal switches from ConfirmModal to ModalRoot with a custom
  Sign in / Cancel footer so closing is controlled. Submit is async: it
  awaits the parent handler, closes on success, and on failure (or a thrown
  error) sets an inline error and stays open. A stale error clears when any
  field is edited or the mode is switched.
- Enter on the username field advances focus to the password field rather
  than submitting; Enter on the password/token field submits only when the
  mode's fields are complete; the pairing boxes submit on Enter only once
  all eight are filled, routed through the async submit.
- SettingsPage's connect handlers return their result to the modal and only
  touch the bottom status line on success; the invalid-URL and error paths
  return a failure for the modal to display.
…ic server error

RomM 5.0 answers the token-carrying /api/heartbeat version probe with a
500 (a malformed token) or a 403 (a token-shaped but invalid/revoked
one) rather than a clean 401, so a bad pasted token surfaced as the
misleading generic "Server error (500)" message. On a probe failure in
establish_user_token, restore the auth state and run a reachability
re-probe: when the server is reachable, the pasted token is at fault, so
return a token-rejected auth failure; otherwise keep the real server
error.
@danielcopper danielcopper added bug Something isn't working area:ui Frontend UI, game detail page labels Jul 22, 2026
…osing on empty Enter, and clarify the credentials error

TextInputModal now gates OK on a non-empty (trimmed) value via bOKDisabled
and only runs the confirm/close on Enter when the value is non-empty, so an
empty or whitespace-only field can no longer be confirmed with R2/Enter on
the Deck.

The ConnectModal token field is wrapped in a Focusable (the structure proven
not to close the modal on an incomplete field) and all three keydown handlers
consume Enter with preventDefault/stopPropagation before deciding to submit,
advance, or no-op, so R2/OSK-Enter on the empty token field no longer closes
the modal.

The credentials 403 message now names both possible causes — wrong
username/password and an account without token-creation permission — because
RomM returns 403 indistinguishably for both.
…ndant test buttons

Sign-in already validates inline in the modal and the QAM connection row
probes the server on open, so the two manual "test" buttons in Connection
Settings were redundant.

- Remove the "Test Connection" button from ConnectionSection (the QAM row
  probes automatically; the test_connection callable stays for that probe).
- Remove the SteamGridDB "Verify Key" button and the section's status line.
- Enter the SteamGridDB key through a dedicated SgdbApiKeyModal that verifies
  the key against SteamGridDB before saving it — an invalid key is rejected
  inline and the modal stays open, so no unchecked key is ever persisted.
- Surface the specific reason on a failed QAM connection probe (Sign-in
  rejected / Server unreachable / No server URL / Not signed in) instead of a
  bare "Not connected".
@danielcopper
danielcopper force-pushed the feature/1564-login-hardening branch from ce9bff8 to 3d1a044 Compare July 22, 2026 21:17
@danielcopper danielcopper changed the title fix(settings): harden the RomM sign-in flow — required fields, R2/Enter placement, error messaging fix(settings): harden RomM sign-in and consolidate the connection/SteamGridDB UX Jul 22, 2026
@danielcopper
danielcopper enabled auto-merge (squash) July 22, 2026 21:27
@danielcopper
danielcopper disabled auto-merge July 22, 2026 21:39
…st the sign-in gate

Pull the ModalRoot -> body -> title -> error line -> footer scaffolding shared
by ConnectModal and SgdbApiKeyModal into a single ValidatingModalShell, which
now owns the modal-body, title, error, and footer style constants that were
duplicated in both modals. Each modal renders its own field content as the
shell's children and passes its title, error, error test id, submit label,
submit-disabled gate, and submit handler.

Replace ConnectModal's nested-ternary canSubmit with a plain if/else helper,
keeping the untrimmed-password semantics.
@sonarqubecloud

Copy link
Copy Markdown

@danielcopper
danielcopper merged commit 283134d into main Jul 23, 2026
18 checks passed
@danielcopper
danielcopper deleted the feature/1564-login-hardening branch July 23, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ui Frontend UI, game detail page bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(settings): harden the RomM sign-in flow — required fields, R2/Enter placement, error messaging

1 participant