Apparently I didn't use my brain cells and rely on the /version
endpoint that Headscale has exposed since 0.26 (our lowest supported
version). Switching to that significantly simplifies the API surface.
The 'Key expiry' attribute only checked node.expiry !== null, showing a
garbled date for the '0001-01-01T00:00:00Z' zero-time that headscale
may return for tagged nodes (juanfont/headscale#3170).
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.
In Headscale 0.28+, nodes can be registered with tag-only preauth keys
which have no associated user. This change updates the Machine type to
make user optional and adds null checks throughout the codebase where
node.user is accessed.
Fixes tag node operations (rename, add tags) that previously failed
with 'Unexpected Server Error' when accessing node.user.providerId
on nodes without a user association.
Refs: #432
Adds conditional rendering for the "Change owner" menu item in machine management, hiding it for versions 0.28.0-beta.1 and above. This prevents users from attempting to change node ownership on newer versions where this functionality is not supported. The change involves passing a new `supportsNodeOwnerChange` prop through the component hierarchy and updating the menu rendering logic accordingly.
* Cookies are now encrypted JWTs (GHSA-wrqq-v7qw-r5w7)
* Authentication is stored in the SQLite database (auto-migrated)
* Session logic is much cleaner