23 Commits

Author SHA1 Message Date
2a6e624189 toggle for wifi and switch-router on openwrt page 2026-07-01 14:06:02 +00:00
d6c1feca97 fix(openwrt): fix TollGate provisioning pipeline, add reconfigure UI
Several compounding bugs were blocking end-to-end TollGate provisioning
on OpenWrt 25.x (apk-native) routers:

- install_ipk's non-ar fallback assumed a flat tarball, but some .ipks are
  a gzip tar of the three classic ipk members one level deep; it was
  dumping debian-binary/data.tar.gz/control.tar.gz straight into / instead
  of unpacking the real payload.
- Manually-extracted packages never ran their pending /etc/uci-defaults/*
  scripts (that only happens through opkg/apk's own postinst bookkeeping),
  so nothing ever created /etc/config/tollgate.
- uci_apply() never ensured the target config file existed first — `uci
  set` fails outright on a config namespace nothing has created yet, which
  is true for a package-defined one like "tollgate" (unlike wireless/
  network/dhcp, which ship by default).
- The installed-check and restart_services looked for a binary/init script
  named after the opkg package ("tollgate-module-basic-go"/"tollgate"),
  but the real on-disk names are tollgate-wrt — so status always reported
  "not installed" and service restarts silently no-op'd.
- provision_ssid used `uci add`, creating a new wifi-iface section (and
  therefore a new duplicate broadcast SSID) on every provision call instead
  of updating one in place.

Also adds a TollGateConfig.enabled field so the enable/disable state is
actually applied to the running service and the SSID's own broadcast
(stop + disable at boot, or start + enable), not just written to UCI.

On the frontend, the OpenWrt Gateway page's TollGate panel was read-only
once installed — add an edit form (price, step size, min steps, mint URL,
enabled toggle) that reuses the same idempotent provision-tollgate call.
2026-07-01 11:59:43 +00:00
edbad30501 fix(openwrt): TollGate apk-native install for OpenWrt 25.x
- WISP wizard: step-by-step flow for WiFi, DHCP, masquerade config
- WAN status: expose lan_ip, dhcp_start/limit, masq, sta_state, wifi_log
- wifi_scan: detect CCMP as WPA2 (psk2) so association succeeds
- opkg: PkgManager enum — detect apk-native mode when opkg not in repos
- tollgate: apk-native install path using manual ipk extraction
- arch detection: read DISTRIB_ARCH from /etc/openwrt_release; normalise
  bare mipsel/mips from uname -m to mipsel_24kc/mips_24kc
- install_ipk: install binutils via apk when ar not in BusyBox
- install_ipk: wget --no-check-certificate for routers without CA bundle
- install_ipk: ar fallback to tar -xzf for non-standard ipk formats
- install_ipk: 5MB overlay space check with clear user-facing error
- middleware: allow "Not enough flash/space" errors through sanitizer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:12:57 +00:00
a862877189 feat(openwrt): add WAN diagnostics to get-status and UI
get_wan_status now returns: radio0_disabled, sta_iface (from iw dev),
sta_state (operstate), assoc_ssid (actually associated SSID vs
configured), and recent wifi_log lines from logread. The WAN panel
shows a diagnostic grid when configured but not connected so the user
can see exactly what's wrong without digging into server logs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:12:57 +00:00
9a782fb551 feat(openwrt): WAN/WISP setup from the UI with WiFi network scan
New RPC methods:
- openwrt.scan-wifi: triggers iwinfo scan on the router radio,
  returns networks sorted by signal strength
- openwrt.configure-wan: creates UCI wireless.wwan (sta mode) +
  network.wwan (DHCP) + adds wwan to firewall WAN zone, then
  calls `wifi reload`

get-status now includes a `wan` object with configured/ssid/ip/
internet fields so the UI can show current uplink state.

Frontend WAN panel: scan → pick SSID (signal bars) → enter password
→ apply. Shows "Configure WAN first" hint above TollGate install
button when internet is not available.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:12:57 +00:00
f69fac627a style(openwrt): adopt glass-card design system for contrast
Replace bg-white/5 card containers with glass-card (rgba(0,0,0,0.65) +
backdrop-blur), match input styling to Login.vue, and use glass-button
variants for actions. Fixes low contrast against the background image.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:12:57 +00:00
f054766a58 feat(openwrt): add TollGate provision button and direct-download fallback
- OpenWrtGateway.vue: add "Install TollGate" button when not installed;
  tracks connected credentials for reuse in the provision call
- install.rs: fall back to wget download from GitHub releases when the
  package is not in any opkg feed (mips_24kc and other arches supported)
- openwrt.rs: provision-tollgate now falls back to saved router_config
  for credentials, matching the behaviour of get-status

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:12:57 +00:00
d71f36370d feat(openwrt): add OpenWrt gateway status view and get-status RPC
Backend: new `openwrt.get-status` RPC endpoint SSHes into the saved (or
provided) OpenWrt router and returns system info, TollGate config, and WiFi
AP interfaces via UCI.

Frontend: new OpenWrtGateway.vue view at /dashboard/server/openwrt shows
system hostname, OpenWrt version, uptime, TollGate install/enable state with
pricing and mint URL, and all AP-mode WiFi interfaces. Linked from the Local
Network section of the Server view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:12:57 +00:00
archipelago
1bce694ebb feat(ui): mobile mesh tabs, AIUI-style audio player, cloud grid + map fixes
UI (this session):
- Global audio player now scales the whole interface into the space above it
  on desktop (sidebar + main) and docks directly above the tab bar on mobile;
  it stays visible while navigating.
- Mesh mobile redesign: floating Chat / BTC / Dead Man / AI / Map tab strip
  with a single fixed, internally-scrolling pane (page no longer scrolls);
  tabs hide while a conversation is open; floating back button; collapsible
  Device panel (starts collapsed); keyboard-aware conversation sizing via
  VisualViewport so the chat sits just above the keyboard.
- Cloud file grid: uniform 4/3 card heights (folders + images match).
- Swipe left/right switches tabs on the Apps and Web5 screens.
- Map tool fills its pane (no bottom gap); fix skewed Share Location toggle
  on mobile (global min-height rule was deforming the switch).
- Trim redundant helper copy from the mesh AI tab.

Also bundles pre-existing in-progress work that was already in the tree:
mesh listener/session + wallet + container + bitcoin-status backend changes,
docker UI updates, and assorted other UI tweaks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 09:52:26 -04:00
archipelago
5af9a22b98 feat(fips): selectable TCP/UDP transport when adding a seed anchor
The add-anchor form previously hardcoded transport=udp. Expose a
TCP/UDP selector (default tcp) so public internet anchors and
local-network anchors can both be added. Includes changelog + What's
New entry for v1.7.96-alpha.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 10:12:23 -04:00
archipelago
d6f108d818 chore: snapshot release workspace 2026-06-12 03:00:15 -04:00
archipelago
1a3d726eac frontend: polish app launch and release experience 2026-06-11 00:24:40 -04:00
Dorian
1c1416cc1a release(v1.7.25-alpha): TCP transport for public FIPS mesh + modal cleanup
Re-adds the TCP transport (`0.0.0.0:8443`) to the rendered fips.yaml
alongside UDP. Upstream factory default enables both; we had
inadvertently narrowed to UDP-only when the yaml rewriter was last
touched, which left nodes unable to reach fips.v0l.io (the public
anchor only answers on TCP right now) or talk across networks that
block UDP.

Backend startup now compares the installed yaml against the current
rendered schema and restarts whichever fips unit is active when they
differ — so OTA-upgrading nodes pick up the new transport without
anyone having to click Reconnect.

Dropped the earlier plan to auto-add federated peers as seed anchors:
invites don't carry a FIPS-reachable IP:port, and once TCP reconnects
the public mesh, federated peers become npub-routable without needing
a seed entry.

Seed Anchors modal cleanup: replaced malformed header icon with a
three-arc broadcast glyph, and the close button now matches the
What's New modal (embedded in the card header, same icon + hover
style) instead of the earlier floating off-design placeholder.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 09:25:53 -04:00
Dorian
b5da6875d7 release(v1.7.23-alpha): FIPS Seed Anchors reachable via gear icon
Adds a gear button next to the FIPS Mesh card's status pill that
opens a Teleport-ed modal containing FipsSeedAnchorsCard. The card
was landed on disk in v1.7.21 but never wired into a UI entry point
per the entry-point convention, so users couldn't access the
Add/Remove/Apply controls at all. One gear click now opens them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 08:17:26 -04:00
Dorian
4b6a088e38 release(v1.7.22-alpha): honest anchor status + Reconnect works on all nodes
- fips::service::active_unit() picks whichever fips unit is running
  (archipelago-fips.service vs upstream fips.service) so
  handle_fips_restart and handle_fips_reconnect don't silently no-op
  on hosts where the archipelago-managed unit was never created.
- peer_connectivity_summary(anchor_candidates) replaces the old
  identity-cache check. anchor_connected is now true when at least
  one authenticated peer's npub matches the public anchor OR any
  entry in seed-anchors.json, which matches what the user actually
  cares about ("am I in the mesh?") rather than what the card used
  to claim ("is this one specific public anchor reachable?").
- FipsStatus::query takes data_dir now (so it can read seed-anchors)
  rather than identity_dir. All call-sites updated.
- handle_fips_reconnect re-pushes seed anchors after restart so the
  new daemon gets dialed without waiting for the 5-min apply loop.
- FipsNetworkCard label drops "(fips.v0l.io)" — misleading now that
  multiple anchors may be configured.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 07:08:26 -04:00
Dorian
f8304aed90 release(v1.7.21-alpha): operator-editable FIPS seed anchors
Adds a local seed-anchor list at <data_dir>/seed-anchors.json. Each
entry is {npub, address, transport, label}. On archipelago startup
and every 5 minutes the list is pushed into the running fips daemon
via `fipsctl connect <npub> <addr> <transport>`, so a cluster can
anchor itself independently of the global fips.v0l.io. A flaky or
unreachable public anchor no longer strands a fresh install.

New RPCs:
- fips.list-seed-anchors
- fips.add-seed-anchor (validates npub1… + host:port)
- fips.remove-seed-anchor
- fips.apply-seed-anchors (on-demand re-dial)

New standalone UI card at views/server/FipsSeedAnchorsCard.vue. Not
wired into Home.vue / Server.vue — operator places it per the
entry-point convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 06:21:37 -04:00
Dorian
be8e5ee46b release(v1.7.14-alpha): install overlay + FIPS real fix + AIUI restore
Install UX
  SystemUpdate.vue now shows a full-screen overlay after apply: the
  BitcoinFaceAscii logo, a target-version label, an indeterminate
  progress stripe (solid orange; solid green on ready), and an
  elapsed-time readout. Polls /health every 1.5s and auto-reloads
  once the backend reports the new version. 3-min stall → "Reload
  now" button. Download UI also shows a spinner + "Finishing
  download — verifying checksum…" while the fake bar sits at 95%.

FIPS reconnect — for real this time
  New fips.reconnect RPC does stop → start → wait 20s → re-poll →
  classify. Classification buckets: connected / daemon_down /
  no_seed_key / no_outbound_udp_or_anchor_down / peers_but_no_anchor,
  each with a plain-language hint surfaced verbatim by the Reconnect
  button. The real reason nodes like .198/.253 couldn't reach the
  anchor: identity::write_fips_key_from_seed was writing fips_key.pub
  as a bech32 npub TEXT file, but upstream fips expects 32 raw
  bytes. The daemon silently authenticated with garbage. Fix:
  PublicKey::to_bytes() → raw 32 bytes, and new
  fips::config::normalize_pub_file migrates legacy files by decoding
  the npub and rewriting in place. fips.reconnect also re-installs
  the config + healed keys to /etc/fips before restarting.

AIUI preservation + restore
  apply_update was wiping /opt/archipelago/web-ui/aiui because the
  Vue build doesn't include it — every OTA lost the Claude sidebar.
  The preserve block now copies aiui/ + archipelago-companion.apk
  from the old web-ui into the staging dir before the swap, and
  prefers new-tar versions if present. To restore it on the three
  nodes that already lost it (.116/.198/.253), this release bundles
  the 85 MB aiui build into the frontend tarball. Frontend component
  size is now ~155 MB.

Download / install timeouts
  Backend download client timeout 1800s → 3600s (1 h). Larger
  tarball + slow gitea raw throughput put us above the old cap.
  Frontend update.download rpc timeout 30 min → 65 min to match.
  package.install rpc timeout 15 min → 45 min — IndeedHub pulls
  6 images and was timing out mid-install.

UI nit
  "Rollback to Previous" → "Rollback Available".

App-catalog proxy already landed in v1.7.13.

Artefacts:
  archipelago                                      725e18e6…3c525e6   40462288
  archipelago-frontend-1.7.14-alpha.tar.gz         c35284be…ff2c16   162077052 (+aiui)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 16:40:25 -04:00
Dorian
3db71adb55 release(v1.7.3-alpha): sidebar version sync + FIPS reconnect + profile pic render
Sidebar version
  detect_build_version() no longer reads /opt/archipelago/build-info.txt
  first. That file was written by the ISO installer at flash time and
  never rewritten by OTA or sideload, so after any binary swap the
  sidebar kept advertising whatever the ISO shipped with. Now just
  returns env!("CARGO_PKG_VERSION") unconditionally — always matches the
  running binary.

FIPS card
  The two-column grid in FipsNetworkCard.vue placed version/npub boxes
  side-by-side on mobile but the anchor-status panel forced col-span-2,
  creating an unbalanced empty column at every desktop width. Anchor
  status moves to its own full-width row below the grid. When the
  anchor is not reached, a "Reconnect" button appears next to the
  status line; it calls fips.restart (45s timeout), waits 5s for the
  daemon to come back, then reloads fips.status. Surfaces whether the
  restart actually recovered the anchor in a status flash.

Profile picture render
  Uploaded profile pictures are stored with an onion-rooted URL so
  external Nostr clients can fetch them. The local browser isn't
  Tor-routed though, so the <img src> silently 404'd and the UI fell
  back to showing initials. Added a displayableUrl() helper on
  Web5Identities.vue that rewrites http://<onion>/blob/<cid>[?...] to
  same-origin /blob/<cid> for rendering, while the stored URL keeps
  its onion prefix so publishing to Nostr still works for external
  viewers. Pass-through for data: URLs and already-relative paths.

Identity row title
  The identity list header now renders profile.display_name (when set)
  and keeps identity.name as a muted parenthetical. Before, only the
  internal name was shown and a user who'd customised their Nostr
  display_name saw a mismatch between their own UI and what peers
  rendered.

Artefacts:
  archipelago                                      99184b95…22dc1b  40350664
  archipelago-frontend-1.7.3-alpha.tar.gz          7b933cf4…74a8bc  76987031

Changelog layman-style per the saved feedback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:44:59 -04:00
Dorian
423c2f8201 feat(web5): anchor connectivity badge on FipsNetworkCard
Consumes the new authenticated_peer_count + anchor_connected fields
from fips.status. Shows a cyan dot + "connected" when fips.v0l.io is
in the identity cache (DHT routing to unknown npubs will work), or
an orange "not reached" with a one-line explainer that federation
and messaging will fall back to Tor until the anchor reconnects.

Peer count appears on the same row so users see "3 peers" when the
fleet-pair script has been run, or "0 peers" on a fresh install
still waiting for the anchor handshake.

Block only renders when service_active — pre-onboarding the FIPS
package is masked so there's nothing meaningful to report.

Covers the UI half of task #20. Multi-anchor defaulting is still
open (need real anchor addresses beyond fips.v0l.io).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 08:42:50 -04:00
Dorian
6b42bfd503 fix(fips): fall back to upstream daemon npub on legacy/dev nodes
Nodes without a seed-derived FIPS key (legacy deploys, fresh pre-onboarding
installs) were reporting "Awaiting seed" in the dashboard even when the
upstream fips.service was running — status.npub was None unless
/data/identity/fips_key.pub existed.

- fips/service.rs: new read_upstream_npub() reads /etc/fips/fips.pub
  (bech32 text or raw 32 bytes) from the debian package.
- fips/mod.rs: FipsStatus::current() prefers the seed-derived npub,
  falls back to the upstream key. service_active is now TRUE if either
  archipelago-fips.service OR upstream fips.service is active; adds
  upstream_service_state to the status payload.
- fips/update.rs: resolve the upstream default branch from the GitHub
  repo API (jmcorgan/fips is on `master`, not `main`) instead of
  hardcoding — future repo rename just works.
- network/router.rs + api/rpc/router.rs: diagnostics gain wifi_ssid from
  `nmcli -t device` so the Network card can show the connected SSID.
- UI: Home.vue adds a FIPS row to the Local Network card; Server.vue
  mounts the new FipsNetworkCard and shows SSID + FIPS Mesh rows;
  HomeNetworkCard.vue removed (superseded by the inline rows).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 00:42:56 -04:00
Dorian
bb17e3d46a fix: add missing tracing::warn import, hide QuickActionsCard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 08:44:08 +01:00
Dorian
fdd69ce1b5 fix: auth, container resilience, ISO build, gamepad polish
- fix: login disconnect — verify session before WebSocket connect
- fix: 403 on app install — distinguish CSRF vs RBAC errors, only retry CSRF
- fix: health monitor now watches ALL containers (removed skip list for
  backend services like nbxplorer, databases, UI containers)
- fix: server.get-state added to CSRF-exempt list (read-only)
- fix: ISO build includes container-specs.sh and lib/common.sh in rootfs
  so reconcile actually works on fresh installs
- fix: gamepad nav — improved Server tab zone nav, focus styles, autofocus
- chore: move L484 web-only apps to Services tab
- chore: install store for cross-view install tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:35:02 +01:00
Dorian
69e25410b0 refactor: split Marketplace, Server, Home, AppDetails views; minor frontend quality fixes
- F29-F32: Split 4 views (Marketplace 1293→505, Server 1132→486, Home 1059→394, AppDetails 1036→386)
- F20: Add aria-current="page" to Dashboard nav links
- F21: Add 150ms search debounce in Marketplace and Apps views
- F22: Reduce backdrop-filter blur to 8px on mobile for GPU performance
- F23: Track and clear WebSocket connect check interval in all paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:01:38 +00:00