feat: add multi-device provisioning and local remote-config UI

- add multi-device portal device management, key rotation, and sync request APIs
- add Pi settings UI for remote server URL, device name, and API key
- add local test-connection and sync-now actions
- make upload and config sync reuse dynamic shared credentials
- add Phase 25.5c migration and docs updates

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-10 18:02:09 -04:00
co-authored by Copilot
parent fbc41a5db5
commit ba682fbf3a
23 changed files with 1357 additions and 167 deletions
+39
View File
@@ -61,6 +61,45 @@
</div>
</div>
{# ── Remote server credentials ────────────────────────────────────── #}
<div class="card shadow-sm mb-3">
<div class="card-header py-2">
<p class="text-primary m-0 fw-bold small">Remote server credentials</p>
</div>
<div class="card-body py-3">
<div class="row g-3 mb-3">
<div class="col-md-4">
<label class="form-label form-label-sm" for="remote-server-url">Server URL</label>
<input class="form-control form-control-sm" id="remote-server-url" type="url" placeholder="https://your-server.example">
<div class="invalid-feedback" data-error-for="server_url"></div>
</div>
<div class="col-md-4">
<label class="form-label form-label-sm" for="remote-device-name">Device name</label>
<input class="form-control form-control-sm" id="remote-device-name" maxlength="100" placeholder="yaris-2013">
<div class="invalid-feedback" data-error-for="remote_device_name"></div>
</div>
<div class="col-md-4">
<label class="form-label form-label-sm" for="remote-api-key">API key</label>
<input class="form-control form-control-sm" id="remote-api-key" type="password" maxlength="512" autocomplete="new-password" placeholder="Paste after create/rotate">
<div class="invalid-feedback" data-error-for="api_key"></div>
<div class="form-text" id="remote-api-key-state">Leave blank to keep saved key.</div>
<div class="form-check mt-1">
<input class="form-check-input" type="checkbox" id="clear-remote-api-key">
<label class="form-check-label small" for="clear-remote-api-key">Remove saved API key</label>
</div>
</div>
</div>
<div id="remote-config-message" class="alert py-2 mb-3" role="status" hidden></div>
<div class="d-flex flex-wrap gap-2 mb-2">
<button class="btn btn-sm btn-outline-primary" id="remote-config-test" type="button">Test connection</button>
<button class="btn btn-sm btn-outline-secondary" id="remote-config-sync-now" type="button">Sync now</button>
</div>
<p class="form-text small mb-0">
These values are stored only on this Pi in <code>db/upload_creds.env</code> and are reused by both uploads and config sync.
</p>
</div>
</div>
{# ── Upload & retention ──────────────────────────────────────────── #}
<div class="card shadow-sm mb-3">
<div class="card-header py-2">