Previously we would use naive revalidators which would invalidate EVERY
SINGLE action loader every 3 seconds, resulting in several fetches. It
would also bubble fetches across the layout actions into the individual
pages.
This new approach selectively has live stores of resources which then
poll for changes on the server side and then dispatches updates to the
client via a new /events/live SSE endpoint.
- Onboarding now shows which Headscale user was auto-linked
- Members (no ui_access) see a 'Pending Approval' page instead of
being silently logged out — their session stays valid
- Sign out button on the pending page so users can switch accounts
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019cce57-c9e1-7732-9709-8288127573a9
- Add 'Link Headscale user' option in user menu (admin-only, OIDC users)
- Dialog shows only unclaimed Headscale users
- New link_user action in user-actions with claim validation
- Onboarding now allows skipping the link step with clear messaging
- Users who skip are told they can ask an admin to link later
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019cce57-c9e1-7732-9709-8288127573a9
Previously REFRESH was only sent once at startup, causing version info
to stay stale. Now the agent refreshes peer data at the cache_ttl
interval (default 3 minutes).
Throwing data() in React Router v7 actions goes to ErrorBoundary instead
of returning to the component. Changed validation errors to return
directly so the login form can display them properly.
headscale 0.28 added GET /v1/preauthkey without a user param
which returns all keys including tag-only ones. this change
adds getAllPreAuthKeys() and uses it when available, falling
back to per-user fetching on older versions.
the UI now handles keys where user is null, showing them as
Tag Only in the filter dropdown.
closes#432
Amp-Thread-ID: https://ampcode.com/threads/T-019c9861-2d45-73ef-ab94-5fce62f63670
Co-authored-by: Amp <amp@ampcode.com>