feat(auth): add device session tracking with configurable limits

Track authenticated sessions per device (parsing user-agent for desktop
vs mobile via mileusna/useragent), enforce configurable concurrent device
limits (Auth.DeviceLimits), and surface device status and "remove other
devices" management in the account dialog. Adds device/session context to
the auth module stores and exposes limits through the API.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-11 01:01:54 +08:00
parent 875fff825c
commit 58f11302fe
32 changed files with 1783 additions and 253 deletions
+18 -5
View File
@@ -19,16 +19,27 @@
"username": "Username",
"email": "Email",
"deviceManagement": "Device Management",
"removeAllDevices": "Remove All Devices",
"removeAllDevicesDescription": "A Moteva account is for personal use only. To prevent abuse and keep the platform stable, tasks can run in up to 2 desktop web sessions and 1 mobile web session at the same time. For team or multi-person use, please purchase Team Plan.",
"removeAllDevices": "Remove Other Devices",
"removeAllDevicesDescription": "A Moteva account is for personal use only. To prevent abuse and keep the platform stable, tasks can run in up to {desktop} desktop web sessions and {mobile} mobile web sessions at the same time. For team or multi-person use, please purchase Team Plan.",
"deviceLimitsLoading": "Loading the current device policy.",
"deviceLimitsUnavailable": "The current device policy is temporarily unavailable.",
"onlineStatus": "Online",
"deviceInfo": "Device Info",
"deviceStatus": "Device status",
"currentDevice": "Current Device",
"system": "System",
"currentLoginAccount": "Current account: {name}",
"accountDeviceDesktop": "Desktop",
"accountDeviceMobile": "Mobile",
"accountDeviceUnknownSystem": "Unknown system",
"accountDeviceUnknownBrowser": "Unknown browser",
"deviceOnline": "Online",
"deviceOffline": "Offline",
"deviceLastSeen": "Last active {time}",
"deviceListLoading": "Loading devices",
"deviceListLoadFailed": "Could not load devices",
"noActiveDevices": "No active devices",
"retry": "Retry",
"avatarImageRequired": "Please choose an image file.",
"avatarTooLarge": "Avatar image must be under 2 MB.",
"avatarUpdateFailed": "Failed to update avatar. Please choose the image again.",
@@ -37,9 +48,11 @@
"usernameUpdated": "Username updated.",
"usernameUpdateFailed": "Failed to update username. Please try again later.",
"currentDeviceNotice": "This is the device you are using now.",
"devicesRemoved": "{count} device(s) removed.",
"removeAllDevicesConfirmTitle": "Remove all devices?",
"removeAllDevicesConfirmText": "After confirmation, your current session will be removed and you will need to log in again.",
"devicesRemoved": "{count} other device(s) removed.",
"devicesRemoving": "Removing",
"devicesRemoveFailed": "Could not remove the other devices. Please try again.",
"removeAllDevicesConfirmTitle": "Remove other devices?",
"removeAllDevicesConfirmText": "This will sign out {count} other device(s). Your current device will stay signed in.",
"guides": "Guides",
"contactUs": "Contact us",
"logout": "Log out",