Closes the v0.4.x chapter — NFS works end to end. Five additions: ## Wake-on-LAN (Hosts → Bound hosts) - New core::wol module: parse any MAC form, build the 102-byte magic packet, broadcast it. No special capability needed (ephemeral source port; SO_BROADCAST). Sends to the limited broadcast (255.255.255.255) AND the server's own subnet broadcast (computed from advertised IP + detected mask) so it reaches the right VLAN. - POST /api/hosts/:mac/wol — only fires for *bound* MACs (404 otherwise) so it's not an open packet sprayer. - Bound-hosts table grows a "Wake" button with inline Waking…/Sent ✓ state. ## Webhook notifications (Advanced tab) - core::notify: NotifyConfig + NotifyStore (notify.json), one provider at a time — Slack / Discord / Teams (incoming-webhook JSON) or SMTP. SMTP password is persisted but redacted on GET behind a __keep__ sentinel the UI round-trips so the secret never leaves the box. - http-api::notify: delivery — reqwest POST for chat (provider-shaped bodies), lettre for SMTP (rustls, STARTTLS/implicit TLS, no plaintext). 10s timeout; every send is best-effort. - GET/PUT /api/notify, POST /api/notify/test. - Fired fire-and-forget on the canonical "machine is imaging" boot event and on WoL — never blocks the boot path. ## UI: Advanced tab - New nav item. Holds the webhook config card and the API reference block (relocated from the bottom of Settings). ## UI: login/setup logo (FleetDM treatment) - /api/me now returns has_custom_logo + logo_rev (public bootstrap). The login, setup, and connection-error cards render the uploaded logo full-width with the "OpenPXE" wordmark dropped — matching the sidebar. ## About: update check + licenses - "Check for updates" button → GET /api/updates/check queries the Gitea releases API (derived from CARGO_PKG_REPOSITORY) and compares to the running version. Strictly on-demand — no background polling, keeps the air-gapped promise. - License card documents the MIT OR Apache-2.0 dual license with links, plus a note on bundled components (iPXE GPLv2/UBDL, samba, wimtools). Deps: lettre (SMTP, rustls) + reqwest gains the json feature. Both rustls so the static musl binary stays OpenSSL-free. Tests: 179 passing (+notify round-trip/redaction, webhook validation, WoL-unbound-404, WoL packet loopback, version-compare). clippy clean. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
53 lines
1.6 KiB
TOML
53 lines
1.6 KiB
TOML
[package]
|
|
name = "openpxe-http-api"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
authors.workspace = true
|
|
description = "HTTP server: ISO uploads, iPXE script generation, ISO streaming"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[dependencies]
|
|
openpxe-core.workspace = true
|
|
openpxe-iso-store.workspace = true
|
|
openpxe-ipxe-assets.workspace = true
|
|
openpxe-webui.workspace = true
|
|
tokio.workspace = true
|
|
tokio-util.workspace = true
|
|
tokio-stream.workspace = true
|
|
time.workspace = true
|
|
axum.workspace = true
|
|
tower.workspace = true
|
|
tower-http.workspace = true
|
|
hyper.workspace = true
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
tracing.workspace = true
|
|
thiserror.workspace = true
|
|
anyhow.workspace = true
|
|
bytes.workspace = true
|
|
futures.workspace = true
|
|
mime.workspace = true
|
|
mime_guess.workspace = true
|
|
uuid.workspace = true
|
|
# v0.4.5 Forms auth: lock-free session store and cookie helpers.
|
|
parking_lot.workspace = true
|
|
# v0.5.0: outbound HTTP for chat webhooks (Slack/Teams/Discord) and the
|
|
# About-tab "check for updates" call to the Gitea releases API; SMTP for
|
|
# email notifications. Both use rustls so the static musl binary stays
|
|
# OpenSSL-free.
|
|
reqwest.workspace = true
|
|
lettre.workspace = true
|
|
|
|
[dev-dependencies]
|
|
tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread", "time"] }
|
|
tower = { workspace = true }
|
|
tempfile = "3.12"
|
|
serde_json = { workspace = true }
|
|
time = { workspace = true }
|
|
# v0.4.61: integration tests need to generate real PNG bytes for the
|
|
# `/branding/pxe-logo` compositor; hand-rolled CRCs are too fragile.
|
|
image = { version = "0.25", default-features = false, features = ["png"] }
|