feat(auth): add local login, audit, API keys, and system admin UI

Gate netx Web/API/WebCRT with JWT and per-user API tokens, bootstrap an admin with forced password change, and expose users/audit/API-key management under a System section. MCP can reuse data/auth/mcp_token without extra env for local labs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
hansjone 2026-07-30 02:34:25 +00:00
parent 14f14d34bd
commit 6d4cd741ef
35 changed files with 2699 additions and 21 deletions

View file

@ -19,6 +19,7 @@ const en = {
openModule: "Open or switch to this module tab",
monitoring: "Monitoring",
operations: "Operations",
system: "System",
cards: {
umeSync: "UME Sync",
umeSyncDesc: "UME alarms, subscription & inventory",
@ -30,6 +31,12 @@ const en = {
webcrtDesc: "Interactive browser login to connected NEs (SSH/Telnet)",
topology: "Topology",
topologyDesc: "Drag NE topology maps; discover links via LLDP/CDP",
users: "Users",
usersDesc: "Admin: create, disable users and reset passwords",
audit: "Audit",
auditDesc: "View login and operation records",
apiKeys: "API Keys",
apiKeysDesc: "Issue MCP/script tokens per user with expiry",
},
},
layout: {
@ -39,6 +46,9 @@ const en = {
titleCollect: "Batch Collect",
titleWebcrt: "WebCRT",
titleTopology: "Topology",
titleUsers: "Users",
titleAudit: "Audit",
titleApiKeys: "API Keys",
navUme: "UME",
netxApi: "netx api",
oclawBridge: "oclaw WSS",
@ -47,6 +57,79 @@ const en = {
langZh: "中文",
langEn: "English",
},
auth: {
loginTitle: "Sign in to NetX",
loginHint: "Use a local account to access the ops platform",
username: "Username",
password: "Password",
login: "Sign in",
loggingIn: "Signing in…",
loginFailed: "Login failed",
logout: "Sign out",
usersTitle: "User management",
usersHint: "Only admins can create and manage local accounts.",
addUser: "Add user",
role: "Role",
roleAdmin: "Admin",
roleUser: "User",
status: "Status",
active: "Active",
disabled: "Disabled",
enable: "Enable",
disable: "Disable",
actions: "Actions",
newPassword: "New password",
resetPassword: "Reset password",
userCreated: "User created",
userUpdated: "User updated",
auditTitle: "Audit log",
auditHintAdmin: "View login and operation records for all users.",
auditHintUser: "View your own operation records.",
filterUsername: "Filter username",
filterAction: "Filter action",
colTime: "Time",
colUser: "User",
colAction: "Action",
colMethod: "Method",
colPath: "Path",
colStatus: "Status",
colIp: "IP",
apiKeysTitle: "API Key management",
apiKeysHint:
"Create long-lived tokens for MCP/scripts. The secret is shown only once. Admins can issue keys for other users.",
tokenName: "Name",
expiresIn: "Expiry",
expire7d: "7 days",
expire30d: "30 days",
expire90d: "90 days",
expire365d: "1 year",
expireNever: "Never",
tokenOwner: "Owner",
tokenOwnerSelf: "Myself ({{user}})",
createToken: "Create key",
tokenCreated: "API key created",
tokenRevoked: "Revoked",
tokenOnceHint: "Copy and store this secret now; it will not be shown again:",
copyToken: "Copy",
tokenCopied: "Copied",
tokenCopyFailed: "Copy failed",
expiresAt: "Expires",
lastUsed: "Last used",
tokenStatusActive: "Active",
tokenStatusExpired: "Expired",
tokenStatusRevoked: "Revoked",
revokeToken: "Revoke",
revokeConfirm: "Revoke this API key?",
forceChangeTitle: "Change initial password",
forceChangeHint: "Account {{user}} is still using the default password. You must change it before continuing.",
oldPassword: "Current password",
confirmPassword: "Confirm new password",
savePassword: "Save new password",
savingPassword: "Saving…",
passwordTooShort: "New password must be at least 6 characters",
passwordMismatch: "New passwords do not match",
passwordMustChange: "New password must differ from the default/old password",
},
collect: {
create: {
title: "New collection job",