4ccfe7a0e6
Bundles the dashboard improvements that landed since 782e4c5 into one
commit. None of these change wire protocols or DB schema; they're all
UI + handlers on top of existing tables.
Users page (/admin/#users)
- "Last seen" column derived from MAX(tokens.last_used_at) per user
(single GROUP BY query in users_last_seen_map). Shows relative
short-form ("5m ago", "3h ago", "2d ago") with the absolute UTC
timestamp in the cell title= for hover.
- Per-row dropdown gains an inline "Edit profile" form (display name,
email, Save) so admins can edit other users' info without going
through the self-service profile.
- "Enroll TOTP" button removed from the dropdown — TOTP enrollment is
now self-service only, so admin-side enroll (which generated a secret
out-of-band with no QR/confirm) is dead UX. "Disable TOTP" stays,
shown only when the user has it enrolled, with hx-confirm.
- Per-row action popover (the ··· menu) now closes on outside click,
via a global handler in index.html that targets details.relative.
Deploy page's collapsible help section is unaffected (no `relative`).
Self-service profile page (/admin/#profile)
- New page accessible to any signed-in user (no admin gate). Sections:
* Profile info — display name, email
* Change password — requires current password + new + confirm
* Two-factor authentication — enroll/disable
- TOTP enrollment is two-step with QR confirmation. POST .../totp/start
generates a fresh secret, renders a server-side SVG QR code (new
`qrcode` crate dependency, no_std SVG renderer) plus the manual-entry
base32 secret. The secret rides in a hidden form field; nothing is
written to user_totp_secrets until the user submits a valid 6-digit
code at .../totp/confirm. Wrong code re-renders the same QR with a
"code didn't match" notice so the user can retry without re-scanning.
- TOTP removal requires the current password.
- Sidebar now has a "My profile" link at the bottom.
OIDC linkage awareness
- UserRow exposes oidc_subject (was already in schema, just not surfaced
in the struct). UserRow::is_oidc_linked() returns true for non-empty.
- Admin Users page: for OIDC-linked rows the password-set form is
replaced by a small italic note ("Linked to OIDC — password sign-in
is disabled."). Server-side, reset_password also rejects with the
same message — UI hide is cosmetic; the handler check is the actual
guarantee.
- TOTP column doubles as an auth-path indicator: OIDC-linked users get
a cyan "OIDC" badge instead of (or in preference to) the violet
"enrolled" badge.
- Self-service profile page: change-password and TOTP sections become
short notes ("Your account signs in via the identity provider …" /
"MFA is managed by your identity provider") for OIDC users.
change_password handler also short-circuits with the same message.
Login page error fragment
- The auth handler returns 401 with an HTML body for bad credentials /
disabled / not-admin / bad-TOTP, but HTMX skips the swap on 4xx by
default — so login errors silently never appeared. Form now has
hx-on::before-swap that forces shouldSwap=true and clears isError on
4xx, but only for this form (page-level htmx:responseError handler
that bounces 401s to /admin/login.html still applies elsewhere — it
wouldn't loop here since this form sets isError=false).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
86 lines
2.8 KiB
TOML
86 lines
2.8 KiB
TOML
[package]
|
|
name = "hbbs"
|
|
version = "1.1.15"
|
|
authors = ["rustdesk <info@rustdesk.com>"]
|
|
edition = "2021"
|
|
build = "build.rs"
|
|
default-run = "hbbs"
|
|
|
|
[[bin]]
|
|
name = "hbbr"
|
|
path = "src/hbbr.rs"
|
|
|
|
[[bin]]
|
|
name = "rustdesk-utils"
|
|
path = "src/utils.rs"
|
|
|
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
|
|
[dependencies]
|
|
hbb_common = { path = "libs/hbb_common" }
|
|
tokio = { version = "1", features = ["fs", "io-util"] }
|
|
totp-rs = { version = "5.4", default-features = false }
|
|
qrcode = { version = "0.14", default-features = false, features = ["svg"] }
|
|
lettre = { version = "0.10", default-features = false, features = ["smtp-transport", "tokio1-rustls-tls", "builder"] }
|
|
toml = "0.7"
|
|
serde_derive = "1.0"
|
|
serde = "1.0"
|
|
serde_json = "1.0"
|
|
lazy_static = "1.4"
|
|
clap = "2"
|
|
rust-ini = "0.18"
|
|
minreq = { version = "2.4", features = ["punycode"] }
|
|
machine-uid = "0.2"
|
|
mac_address = "1.1.5"
|
|
whoami = "1.2"
|
|
base64 = "0.13"
|
|
axum = { version = "0.5", features = ["headers"] }
|
|
sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "sqlite", "macros", "chrono", "json" ] }
|
|
deadpool = "0.8"
|
|
async-trait = "0.1"
|
|
async-speed-limit = { git = "https://github.com/open-trade/async-speed-limit" }
|
|
uuid = { version = "1.0", features = ["v4"] }
|
|
bcrypt = "0.13"
|
|
chrono = "0.4"
|
|
jsonwebtoken = "8"
|
|
headers = "0.3"
|
|
once_cell = "1.8"
|
|
sodiumoxide = "0.2"
|
|
tokio-tungstenite = "0.17"
|
|
tungstenite = "0.17"
|
|
regex = "1.4"
|
|
tower-http = { version = "0.3", features = ["fs", "trace", "cors"] }
|
|
tower = { version = "0.4", features = ["util"] }
|
|
http = "0.2"
|
|
http-body = "0.4"
|
|
flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset", "dont_minimize_extra_stacks"] }
|
|
ipnetwork = "0.20"
|
|
local-ip-address = "0.5.1"
|
|
dns-lookup = "1.0.8"
|
|
ping = "0.4.0"
|
|
flate2 = "1.0"
|
|
|
|
[target.'cfg(any(target_os = "macos", target_os = "windows"))'.dependencies]
|
|
# https://github.com/rustdesk/rustdesk-server-pro/issues/189, using native-tls for better tls support
|
|
reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "socks", "json", "native-tls", "gzip"], default-features=false }
|
|
|
|
[target.'cfg(not(any(target_os = "macos", target_os = "windows")))'.dependencies]
|
|
reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "socks", "json", "rustls-tls", "rustls-tls-native-roots", "gzip"], default-features=false }
|
|
|
|
[build-dependencies]
|
|
hbb_common = { path = "libs/hbb_common" }
|
|
|
|
[workspace]
|
|
members = ["libs/hbb_common"]
|
|
exclude = ["ui"]
|
|
|
|
#https://github.com/johnthagen/min-sized-rust
|
|
#https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles
|
|
[profile.release]
|
|
lto = true
|
|
codegen-units = 1
|
|
panic = 'abort'
|
|
strip = true
|
|
#opt-level = 'z' # only have smaller size after strip # Default is 3, better performance
|
|
#rpath = true # Not needed
|