Compare commits
5 Commits
feature/up
...
c41482a7b3
| Author | SHA1 | Date | |
|---|---|---|---|
| c41482a7b3 | |||
| 589f9595f4 | |||
| 78594c5bca | |||
| 96d559f819 | |||
| a3a7298447 |
@ -1,4 +1,4 @@
|
|||||||
ID: DOC_000001 | Version: 0.1.5 | Status: Final
|
ID: DOC_000001 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Projekt-Logbuch (Changelog)
|
# Projekt-Logbuch (Changelog)
|
||||||
@ -49,6 +49,12 @@ By: Codex (GPT-5)
|
|||||||
| 30.12.2025 | 🎨 UI | ID: TASK_000039 Login-Text reduziert, Buttons symmetrisch, Panels/Metrics harmonisiert. By: Codex (GPT-5) |
|
| 30.12.2025 | 🎨 UI | ID: TASK_000039 Login-Text reduziert, Buttons symmetrisch, Panels/Metrics harmonisiert. By: Codex (GPT-5) |
|
||||||
| 30.12.2025 | 🏗️ Planning | ID: EPIC_000010/US_000034/US_000035 Update-Service v1 Migration dokumentiert. By: Codex (GPT-5) |
|
| 30.12.2025 | 🏗️ Planning | ID: EPIC_000010/US_000034/US_000035 Update-Service v1 Migration dokumentiert. By: Codex (GPT-5) |
|
||||||
| 30.12.2025 | 🏗️ Planning | ID: TASK_000040/TASK_000041 fuer Enrollment und v1 Endpunkte angelegt. By: Codex (GPT-5) |
|
| 30.12.2025 | 🏗️ Planning | ID: TASK_000040/TASK_000041 fuer Enrollment und v1 Endpunkte angelegt. By: Codex (GPT-5) |
|
||||||
|
| 12.01.2026 | ⚙️ Code | ID: TASK_000040 Enrollment-Skript bereinigt und als scripts/enroll_local.py hinzugefuegt. By: Gemini CLI |
|
||||||
|
| 15.01.2026 | 🏗️ Planning | ID: EPIC_000011 und US_000036-US_000038 dokumentiert. By: Codex (GPT-5) |
|
||||||
|
| 15.01.2026 | 📝 Req | ID: Update-Doku und ENV-Beispiele an Code-Stand angeglichen. By: Codex (GPT-5) |
|
||||||
|
| 15.01.2026 | ⚙️ Code | ID: Makefile-Healthcheck auf Authorization: Bearer angepasst. By: Codex (GPT-5) |
|
||||||
|
| 15.01.2026 | 🏗️ Planning | ID: US_000039 und TASK_000042 fuer Doku-Audit angelegt. By: Codex (GPT-5) |
|
||||||
|
| 15.01.2026 | 📝 Req | ID: US_000039 Doku-Audit abgeschlossen (Header-Versionen konsolidiert, Update-Docs korrigiert). By: Codex (GPT-5) |
|
||||||
|
|
||||||
---
|
---
|
||||||
## Legende
|
## Legende
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -41,7 +41,7 @@ healthcheck:
|
|||||||
echo "No token set; set TOKEN=... or populate $(ENV_FILE) with SKD_AUTH_TOKEN."; \
|
echo "No token set; set TOKEN=... or populate $(ENV_FILE) with SKD_AUTH_TOKEN."; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
curl -fsS -H "X-API-Token: $(TOKEN)" "$(HEALTH_URL)" || (echo "Health check failed" && exit 1)
|
curl -fsS -H "Authorization: Bearer $(TOKEN)" "$(HEALTH_URL)" || (echo "Health check failed" && exit 1)
|
||||||
|
|
||||||
update:
|
update:
|
||||||
$(SUDO) env PROJECT_ROOT=$(INSTALL_DIR) SERVICE_NAME=$(SERVICE) SERVICE_USER=$(SERVICE_USER) BRANCH=$(BRANCH) bash -c 'cd $(INSTALL_DIR) && ./scripts/update.sh'
|
$(SUDO) env PROJECT_ROOT=$(INSTALL_DIR) SERVICE_NAME=$(SERVICE) SERVICE_USER=$(SERVICE_USER) BRANCH=$(BRANCH) bash -c 'cd $(INSTALL_DIR) && ./scripts/update.sh'
|
||||||
|
|||||||
@ -33,10 +33,12 @@ Set in `/etc/skd/env` (see `env.example`):
|
|||||||
- `SKD_DRY_RUN=true` to test without real account changes or shutdown.
|
- `SKD_DRY_RUN=true` to test without real account changes or shutdown.
|
||||||
- `SKD_SOUND_PLAYER`/`SKD_SOUND_FILE`, `SKD_NOTIFY_SEND_PATH` if defaults differ.
|
- `SKD_SOUND_PLAYER`/`SKD_SOUND_FILE`, `SKD_NOTIFY_SEND_PATH` if defaults differ.
|
||||||
- Update client:
|
- Update client:
|
||||||
- `SKD_UPDATE_URL` (default `https://update.wlkns.org`)
|
- `SKD_UPDATE_SERVICE_URL` (default `https://update.wlkns.org`)
|
||||||
- `SKD_UPDATE_TOKEN` (API token for update service)
|
- `SKD_UPDATE_PROJECT_ID` (default `safe-kiddo-control`)
|
||||||
|
- `SKD_UPDATE_ENROLL_TOKEN` (one-time enrollment token for `/update/enroll`)
|
||||||
|
- `SKD_UPDATE_TOKEN` (API token for update service; or load from `SKD_UPDATE_TOKEN_FILE`)
|
||||||
|
- `SKD_UPDATE_TOKEN_FILE` (default `/var/lib/skd/update_token`)
|
||||||
- `SKD_UPDATE_INTERVAL` (seconds; default 3600)
|
- `SKD_UPDATE_INTERVAL` (seconds; default 3600)
|
||||||
- `SKD_UPDATE_STATUS_URL` (default `https://update.wlkns.org/status`)
|
|
||||||
- `SKD_UPDATE_STATUS_FILE` (default `/var/lib/skd/update_status.json`)
|
- `SKD_UPDATE_STATUS_FILE` (default `/var/lib/skd/update_status.json`)
|
||||||
- `SKD_UPDATE_LOG_FILE` (default `/var/lib/skd/update_logs.jsonl`)
|
- `SKD_UPDATE_LOG_FILE` (default `/var/lib/skd/update_logs.jsonl`)
|
||||||
Notes:
|
Notes:
|
||||||
|
|||||||
@ -133,6 +133,20 @@
|
|||||||
<p class="text-center text-muted mt-1">Lade Update-Status...</p>
|
<p class="text-center text-muted mt-1">Lade Update-Status...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Enrollment Section -->
|
||||||
|
<div id="enrollmentSection" class="hidden" style="margin-bottom: 1rem; padding: 1rem; background: rgba(255, 255, 255, 0.05); border-radius: var(--radius-sm); border: 1px dashed var(--color-border);">
|
||||||
|
<h4 style="margin-top: 0; margin-bottom: 0.5rem;"><i data-lucide="link"></i> Gerät registrieren (Enrollment)</h4>
|
||||||
|
<p class="text-muted" style="font-size: 0.875rem; margin-bottom: 0.5rem;">
|
||||||
|
Dieses Gerät ist noch nicht beim Update-Service registriert. Bitte geben Sie einen gültigen Enrollment-Token ein.
|
||||||
|
</p>
|
||||||
|
<form id="enrollmentForm" style="display: flex; gap: 0.5rem; align-items: center;">
|
||||||
|
<input type="text" id="enrollToken" placeholder="Enrollment-Token eingeben..." required style="flex: 1;" />
|
||||||
|
<button type="submit" class="small">
|
||||||
|
<i data-lucide="check"></i> Registrieren
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<button id="checkUpdateBtn" type="button">
|
<button id="checkUpdateBtn" type="button">
|
||||||
<i data-lucide="search"></i>
|
<i data-lucide="search"></i>
|
||||||
@ -395,6 +409,8 @@
|
|||||||
// Update management
|
// Update management
|
||||||
async function refreshUpdateStatus() {
|
async function refreshUpdateStatus() {
|
||||||
const statusDiv = document.getElementById('updateStatus');
|
const statusDiv = document.getElementById('updateStatus');
|
||||||
|
// Do not clear the div if we are just refreshing to avoid flickering, maybe?
|
||||||
|
// Actually, loading spinner is fine.
|
||||||
statusDiv.innerHTML = '<div class="spinner" style="margin: 0 auto;"></div><p class="text-center text-muted mt-1">Lade Update-Status...</p>';
|
statusDiv.innerHTML = '<div class="spinner" style="margin: 0 auto;"></div><p class="text-center text-muted mt-1">Lade Update-Status...</p>';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -408,12 +424,28 @@
|
|||||||
? '<span class="badge error"><i data-lucide="x-circle"></i> Fehlgeschlagen</span>'
|
? '<span class="badge error"><i data-lucide="x-circle"></i> Fehlgeschlagen</span>'
|
||||||
: '<span class="badge neutral"><i data-lucide="minus-circle"></i> Unbekannt</span>';
|
: '<span class="badge neutral"><i data-lucide="minus-circle"></i> Unbekannt</span>';
|
||||||
|
|
||||||
|
const enrolledBadge = data.enrolled
|
||||||
|
? '<span class="badge success"><i data-lucide="link"></i> Verbunden</span>'
|
||||||
|
: '<span class="badge warning"><i data-lucide="link-2-off"></i> Nicht registriert</span>';
|
||||||
|
|
||||||
|
// Toggle Enrollment Section
|
||||||
|
const enrollSection = document.getElementById('enrollmentSection');
|
||||||
|
if (data.enrolled) {
|
||||||
|
enrollSection.classList.add('hidden');
|
||||||
|
} else {
|
||||||
|
enrollSection.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
statusDiv.innerHTML = `
|
statusDiv.innerHTML = `
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;">
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Version</div>
|
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Version</div>
|
||||||
<div style="color: var(--color-accent); font-weight: 600;">${data.current_version}</div>
|
<div style="color: var(--color-accent); font-weight: 600;">${data.current_version}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Registrierung</div>
|
||||||
|
<div>${enrolledBadge}</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Letzter Status</div>
|
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Letzter Status</div>
|
||||||
<div>${statusBadge}</div>
|
<div>${statusBadge}</div>
|
||||||
@ -637,6 +669,35 @@
|
|||||||
|
|
||||||
document.getElementById('refreshLogsBtn').addEventListener('click', refreshUpdateLogs);
|
document.getElementById('refreshLogsBtn').addEventListener('click', refreshUpdateLogs);
|
||||||
|
|
||||||
|
document.getElementById('enrollmentForm').addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const tokenInput = document.getElementById('enrollToken');
|
||||||
|
const token = tokenInput.value.trim();
|
||||||
|
const btn = e.target.querySelector('button');
|
||||||
|
|
||||||
|
if (!token) return;
|
||||||
|
|
||||||
|
const originalHTML = btn.innerHTML;
|
||||||
|
btn.innerHTML = '<div class="spinner"></div> Registriere...';
|
||||||
|
btn.disabled = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api('/update/enroll', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ enroll_token: token })
|
||||||
|
});
|
||||||
|
showToast('Gerät erfolgreich registriert!', 'success');
|
||||||
|
tokenInput.value = '';
|
||||||
|
await refreshUpdateStatus();
|
||||||
|
} catch (err) {
|
||||||
|
showToast('Registrierung fehlgeschlagen: ' + err.message, 'error');
|
||||||
|
} finally {
|
||||||
|
btn.innerHTML = originalHTML;
|
||||||
|
btn.disabled = false;
|
||||||
|
lucide.createIcons();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
checkSession();
|
checkSession();
|
||||||
checkOidcStatus();
|
checkOidcStatus();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
ID: DOC_000006 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000006 | Version: 0.2.1 | Status: Draft
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Admin Token Operations
|
# Admin Token Operations
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
openapi: 3.0.3
|
openapi: 3.0.3
|
||||||
info:
|
info:
|
||||||
title: Update Webservice API
|
title: Update Webservice API
|
||||||
version: 0.1.0
|
version: 0.2.1
|
||||||
servers:
|
servers:
|
||||||
- url: https://update.wlkns.org
|
- url: https://update.wlkns.org
|
||||||
- url: https://staging.update.wlkns.org
|
- url: https://staging.update.wlkns.org
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: DOC_000008 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000008 | Version: 0.2.1 | Status: Draft
|
||||||
|
|
||||||
# Client Quickstart
|
# Client Quickstart
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: DOC_000003 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000003 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# OIDC End-to-End Validation (Kiddo)
|
# OIDC End-to-End Validation (Kiddo)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
ID: DOC_000005 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000005 | Version: 0.2.1 | Status: Draft
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Third-Party API Guide
|
# Third-Party API Guide
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ Common error codes:
|
|||||||
`payload_too_large`, `status_invalid`
|
`payload_too_large`, `status_invalid`
|
||||||
|
|
||||||
## Rate Limits
|
## Rate Limits
|
||||||
Limits are tiered by scope. See `docs/architecture/ARCHITECTURE.md` for current values.
|
Limits are tiered by scope. See `docs/architecture/openapi/paths/limits.yaml` for current values.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
Fetch manifest:
|
Fetch manifest:
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: DOC_000006 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000006 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Update API (Kiddo Backend)
|
# Update API (Kiddo Backend)
|
||||||
@ -8,6 +8,16 @@ Definiert interne API-Endpunkte fuer Update-Status, Check, Apply, Rollback und L
|
|||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
|
### POST /update/enroll
|
||||||
|
Body (optional):
|
||||||
|
```json
|
||||||
|
{ "enroll_token": "<one-time-token>" }
|
||||||
|
```
|
||||||
|
Antwort:
|
||||||
|
```json
|
||||||
|
{ "enrolled": true, "message": "Enrollment successful" }
|
||||||
|
```
|
||||||
|
|
||||||
### GET /update/status
|
### GET /update/status
|
||||||
Antwort:
|
Antwort:
|
||||||
```json
|
```json
|
||||||
@ -15,7 +25,8 @@ Antwort:
|
|||||||
"current_version": "0.1.2",
|
"current_version": "0.1.2",
|
||||||
"last_status": "success|failed|unknown",
|
"last_status": "success|failed|unknown",
|
||||||
"last_error": "<optional>",
|
"last_error": "<optional>",
|
||||||
"last_timestamp": "2025-12-28T12:34:56Z"
|
"last_timestamp": "2025-12-28T12:34:56Z",
|
||||||
|
"enrolled": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -51,10 +62,18 @@ Antwort:
|
|||||||
Antwort:
|
Antwort:
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{"timestamp":"2025-12-28T12:34:56Z","status":"success","message":"updated to 0.1.2"}
|
{
|
||||||
|
"timestamp": "2025-12-28T12:34:56Z",
|
||||||
|
"status": "success",
|
||||||
|
"message": "updated to 0.1.2",
|
||||||
|
"version": "0.1.2",
|
||||||
|
"device_id": "kiddo-001",
|
||||||
|
"error": null
|
||||||
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- Alle Endpunkte erfordern Auth (Session/Bearer).
|
- Alle Endpunkte erfordern Auth (Session-Cookie oder `Authorization: Bearer <token>`).
|
||||||
- Apply/Rollback starten async; UI pollt /update/status.
|
- Apply/Rollback starten async; UI pollt /update/status.
|
||||||
|
- `/update/enroll` speichert das Update-Token lokal (siehe `SKD_UPDATE_TOKEN_FILE`).
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: DOC_000004 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000004 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Client Update Flow (Kiddo)
|
# Client Update Flow (Kiddo)
|
||||||
@ -18,7 +18,8 @@ Beispiel:
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Flow (High Level)
|
## Flow (High Level)
|
||||||
1. Manifest abrufen (auth optional via Bearer Token).
|
0. Falls kein Token vorhanden ist: Enrollment durchfuehren (Pre-Shared Token -> Langzeit-Token).
|
||||||
|
1. Manifest abrufen (auth via Bearer Token).
|
||||||
2. `artifact_url` herunterladen.
|
2. `artifact_url` herunterladen.
|
||||||
3. SHA256 pruefen (Signatur optional).
|
3. SHA256 pruefen (Signatur optional).
|
||||||
4. In Staging-Verzeichnis entpacken.
|
4. In Staging-Verzeichnis entpacken.
|
||||||
@ -37,13 +38,14 @@ Beispiel:
|
|||||||
|
|
||||||
## Security Notes
|
## Security Notes
|
||||||
- Artefakte muessen checksum-verifiziert sein.
|
- Artefakte muessen checksum-verifiziert sein.
|
||||||
- Token-Handling ueber `SKD_UPDATE_TOKEN`.
|
- Token-Handling ueber `SKD_UPDATE_TOKEN` oder `SKD_UPDATE_TOKEN_FILE`.
|
||||||
|
- Enrollment nutzt einen Pre-Shared Token und speichert das Langzeit-Token lokal.
|
||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
- Update-Service ist extern (update.wlkns.org).
|
- Update-Service ist extern (update.wlkns.org).
|
||||||
- Service muss als root stoppen/starten koennen.
|
- Service muss als root stoppen/starten koennen.
|
||||||
|
|
||||||
## Status Reporting
|
## Status Reporting
|
||||||
- Status wird per HTTP POST an `https://update.wlkns.org/status` gemeldet.
|
- Status wird per HTTP POST an `${SKD_UPDATE_SERVICE_URL}/v1/projects/${SKD_UPDATE_PROJECT_ID}/status` gemeldet.
|
||||||
- Schema siehe `docs/update-status.md`.
|
- Schema siehe `docs/update-status.md`.
|
||||||
- Lokaler Status/Logs liegen unter `/var/lib/skd` (konfigurierbar via ENV).
|
- Lokaler Status/Logs liegen unter `/var/lib/skd` (konfigurierbar via ENV).
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: DOC_000005 | Version: 0.1.0 | Status: Draft
|
ID: DOC_000005 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Update Status Reporting
|
# Update Status Reporting
|
||||||
@ -9,17 +9,21 @@ Definiert das Status-Schema fuer Update-Resultate und den Uebertragungsweg.
|
|||||||
## Status Schema (JSON)
|
## Status Schema (JSON)
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"device_id": "<hostname>",
|
"project_id": "safe-kiddo-control",
|
||||||
"version": "0.1.2",
|
"client_id": "<hostname>",
|
||||||
"status": "success|failed",
|
"version": "0.2.1",
|
||||||
"error": "<optional message>",
|
"status": "success|failed|in_progress",
|
||||||
"timestamp": "2025-12-28T12:34:56Z"
|
"timestamp": "2025-12-28T12:34:56Z",
|
||||||
|
"duration_ms": 1234,
|
||||||
|
"error_code": "<optional>",
|
||||||
|
"reason": "<optional>"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Transport
|
## Transport
|
||||||
- HTTP POST an `https://update.wlkns.org/status`
|
- HTTP POST an `${SKD_UPDATE_SERVICE_URL}/v1/projects/${SKD_UPDATE_PROJECT_ID}/status`
|
||||||
- Auth: Bearer Token (`SKD_UPDATE_TOKEN`)
|
- Auth: Bearer Token (`SKD_UPDATE_TOKEN` oder `SKD_UPDATE_TOKEN_FILE`)
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- Statusmeldungen sind best-effort; Fehler beim Senden blockieren kein Update.
|
- Statusmeldungen sind best-effort; Fehler beim Senden blockieren kein Update.
|
||||||
|
- Reporting wird nur gesendet, wenn ein Update-Token vorhanden ist.
|
||||||
|
|||||||
@ -22,10 +22,12 @@ SKD_DEFAULT_COUNTDOWN=60
|
|||||||
SKD_DEFAULT_SOUND=false
|
SKD_DEFAULT_SOUND=false
|
||||||
SKD_NOTIFY_TIMEOUT=5
|
SKD_NOTIFY_TIMEOUT=5
|
||||||
# Update client configuration
|
# Update client configuration
|
||||||
SKD_UPDATE_URL=https://update.wlkns.org
|
SKD_UPDATE_SERVICE_URL=https://update.wlkns.org
|
||||||
|
SKD_UPDATE_PROJECT_ID=safe-kiddo-control
|
||||||
|
SKD_UPDATE_ENROLL_TOKEN=
|
||||||
SKD_UPDATE_TOKEN=
|
SKD_UPDATE_TOKEN=
|
||||||
|
SKD_UPDATE_TOKEN_FILE=/var/lib/skd/update_token
|
||||||
SKD_UPDATE_INTERVAL=3600
|
SKD_UPDATE_INTERVAL=3600
|
||||||
SKD_UPDATE_STATUS_URL=https://update.wlkns.org/status
|
|
||||||
SKD_UPDATE_STATUS_FILE=/var/lib/skd/update_status.json
|
SKD_UPDATE_STATUS_FILE=/var/lib/skd/update_status.json
|
||||||
SKD_UPDATE_LOG_FILE=/var/lib/skd/update_logs.jsonl
|
SKD_UPDATE_LOG_FILE=/var/lib/skd/update_logs.jsonl
|
||||||
# Set to true to test without performing real system changes
|
# Set to true to test without performing real system changes
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: AGENTS_000001 | Version: 0.1.0 | Status: Draft
|
ID: AGENTS_000001 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Repository Guidelines
|
# Repository Guidelines
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: STATUS_000001 | Version: 0.1.0 | Status: Final
|
ID: STATUS_000001 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Projekt-Status
|
# Projekt-Status
|
||||||
@ -10,14 +10,15 @@ Sicheres, remote steuerbares System zum Sperren/Entsperren lokaler Nutzerkonten.
|
|||||||
✅ Stabilization
|
✅ Stabilization
|
||||||
|
|
||||||
## Aktueller Fokus
|
## Aktueller Fokus
|
||||||
1. Client-Update-Mechanik planen (EPIC_000008).
|
1. OIDC-Validierung abschliessen (EPIC_000003 / US_000025).
|
||||||
2. Dokumentierter Ist-Zustand der Module.
|
2. Client-Update-Mechanik pflegen (EPIC_000008).
|
||||||
3. Pflege der Anforderungen bei neuen Features.
|
3. Anforderungen bei neuen Features sauber dokumentieren.
|
||||||
|
|
||||||
## Projekt-Tagebuch (Kurz, optional)
|
## Projekt-Tagebuch (Kurz, optional)
|
||||||
| Datum | Typ | Beschreibung |
|
| Datum | Typ | Beschreibung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 28.12.2025 | 🏗️ Planning | Anforderungen als Epics und Stories dokumentiert. |
|
| 28.12.2025 | 🏗️ Planning | Anforderungen als Epics und Stories dokumentiert. |
|
||||||
|
| 15.01.2026 | 📝 Req | Doku und ENV-Beispiele an Code-Stand angepasst. |
|
||||||
|
|
||||||
## Epic-Backlog (Uebersicht)
|
## Epic-Backlog (Uebersicht)
|
||||||
### EPIC_000001: Legacy CLI Account Control (sk.sh)
|
### EPIC_000001: Legacy CLI Account Control (sk.sh)
|
||||||
@ -114,6 +115,13 @@ Sicheres, remote steuerbares System zum Sperren/Entsperren lokaler Nutzerkonten.
|
|||||||
- [x] US_000035: v1 Update-Endpoints und Status-Schema
|
- [x] US_000035: v1 Update-Endpoints und Status-Schema
|
||||||
- [x] TASK_000041: v1 Endpunkte im Update-Client umstellen
|
- [x] TASK_000041: v1 Endpunkte im Update-Client umstellen
|
||||||
|
|
||||||
|
### EPIC_000011: Documentation and Configuration Alignment
|
||||||
|
- [x] US_000036: Doku-Versionen auf VERSION synchronisieren
|
||||||
|
- [x] US_000037: Update-API-Doku mit /update/enroll abgleichen
|
||||||
|
- [x] US_000038: ENV-Beispiele und Healthcheck-Auth angleichen
|
||||||
|
- [x] US_000039: Doku-Audit fuer verbleibende Abweichungen
|
||||||
|
- [x] TASK_000042: Doku-Audit verbleibender Dateien
|
||||||
|
|
||||||
## Offene Risiken / Abhaengigkeiten
|
## Offene Risiken / Abhaengigkeiten
|
||||||
- Betrieb erfordert Root/sudo und lokale System-Tools (notify-send, sound player, uvicorn).
|
- Betrieb erfordert Root/sudo und lokale System-Tools (notify-send, sound player, uvicorn).
|
||||||
- OIDC-Validierung blockiert bis IdP bereit und Service laeuft.
|
- OIDC-Validierung blockiert bis IdP bereit und Service laeuft.
|
||||||
@ -122,4 +130,4 @@ Sicheres, remote steuerbares System zum Sperren/Entsperren lokaler Nutzerkonten.
|
|||||||
## Naechste Schritte
|
## Naechste Schritte
|
||||||
- Anforderungen beim naechsten Feature-Start erweitern.
|
- Anforderungen beim naechsten Feature-Start erweitern.
|
||||||
- OIDC-Validierung abschliessen und US_000025 auf Done setzen.
|
- OIDC-Validierung abschliessen und US_000025 auf Done setzen.
|
||||||
- PR vorbereiten: feature/oidc-validation (Summary, Risiko, Testschritte).
|
- Doku-Audit fuer weitere Abweichungen priorisieren (wenn Zeitfenster frei).
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: PROJECT_STATUS_TEMPLATE | Version: 0.1.0 | Status: Draft
|
ID: PROJECT_STATUS_TEMPLATE | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# 📊 Projekt-Status (Template)
|
# 📊 Projekt-Status (Template)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: SOP_000001 | Version: 0.1.0 | Status: Draft
|
ID: SOP_000001 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Onboarding: Arbeitsweise im Sound Architect Projekt
|
# Onboarding: Arbeitsweise im Sound Architect Projekt
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: SETUP_000005 | Version: 0.1.0 | Status: Draft
|
ID: SETUP_000005 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# 🧬 SETUP_GUIDE: Phase 0 - Project Genesis
|
# 🧬 SETUP_GUIDE: Phase 0 - Project Genesis
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: PROMPT_000008 | Version: 0.1.0 | Status: Draft
|
ID: PROMPT_000008 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Requirements Engineer Prompt
|
# Requirements Engineer Prompt
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000001 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000001 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000001: Legacy CLI Account Control (sk.sh)
|
# EPIC_000001: Legacy CLI Account Control (sk.sh)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000002 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000002 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000002: Backend API Service
|
# EPIC_000002: Backend API Service
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000003 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000003 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000003: Authentication & Sessions
|
# EPIC_000003: Authentication & Sessions
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000004 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000004 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000004: Web UI
|
# EPIC_000004: Web UI
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000005 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000005 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000005: Automation Scripts
|
# EPIC_000005: Automation Scripts
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000006 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000006 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000006: Systemd & Deployment Artifacts
|
# EPIC_000006: Systemd & Deployment Artifacts
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000007 | Version: 0.1.0 | Status: Final
|
ID: EPIC_000007 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000007: Documentation & Runbook
|
# EPIC_000007: Documentation & Runbook
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000008 | Version: 0.1.0 | Status: Draft
|
ID: EPIC_000008 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000008: Client-Side Update Mechanism
|
# EPIC_000008: Client-Side Update Mechanism
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000009 | Version: 0.1.0 | Status: Draft
|
ID: EPIC_000009 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000009: Update Webservice (External Team)
|
# EPIC_000009: Update Webservice (External Team)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: EPIC_000010 | Version: 0.1.5 | Status: Done
|
ID: EPIC_000010 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# EPIC_000010: Update-Service v1 Migration (Major Release)
|
# EPIC_000010: Update-Service v1 Migration (Major Release)
|
||||||
|
|||||||
43
project-management/requirements/epics/EPIC_000011.md
Normal file
43
project-management/requirements/epics/EPIC_000011.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
ID: EPIC_000011 | Version: 0.2.1 | Status: Done
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
|
# EPIC_000011: Documentation and Configuration Alignment
|
||||||
|
|
||||||
|
## Beschreibung
|
||||||
|
Konsolidierung der Dokumentation, Beispiel-Konfigurationen und Ops-Hinweise mit dem
|
||||||
|
aktuellen Code-Stand, inklusive Version-Synchronisierung mit der zentralen VERSION.
|
||||||
|
|
||||||
|
## Ziel / Business Value
|
||||||
|
Reduziert Integrationsfehler, sorgt fuer konsistente Bedienung und verringert Support-Aufwand.
|
||||||
|
|
||||||
|
## Mission Statement
|
||||||
|
Stelle sicher, dass Dokumente, Beispiele und Automationshinweise den realen API- und
|
||||||
|
Konfigurationsstand widerspiegeln.
|
||||||
|
|
||||||
|
## Business Value & Metriken
|
||||||
|
- Weniger Fehlkonfigurationen durch korrekte ENV-Keys und Auth-Header.
|
||||||
|
- Erfolgsmetrik: 0 bekannte Abweichungen zwischen Code und Doku in den Update/Health-Flows.
|
||||||
|
|
||||||
|
## In-Scope (Kiddo Team)
|
||||||
|
- Doku-Versionen auf VERSION ziehen.
|
||||||
|
- Update-API Doku inkl. /update/enroll und Response-Feldern aktualisieren.
|
||||||
|
- ENV-Beispiele und Makefile-Healthcheck auf aktuelle Auth-Mechanik angleichen.
|
||||||
|
|
||||||
|
## Out-of-Scope
|
||||||
|
- Funktionale Aenderungen am Auth-Flow im Backend.
|
||||||
|
- Erweiterte Validierung durch Integrationstests.
|
||||||
|
|
||||||
|
## High-Level Akzeptanzkriterien
|
||||||
|
- Doku-Header nutzen die aktuelle VERSION.
|
||||||
|
- Update-API-Doku listet alle implementierten Update-Endpunkte.
|
||||||
|
- ENV-Beispiele nutzen die im Code verwendeten Update-Variablen.
|
||||||
|
- Healthcheck-Beispiel nutzt Authorization: Bearer.
|
||||||
|
|
||||||
|
## Technische Constraints & Risiken
|
||||||
|
- Dokumentation darf keine falschen Defaults oder veraltete Endpunkte nennen.
|
||||||
|
- Audit kann weitere Abweichungen aufdecken und Folgetickets noetig machen.
|
||||||
|
|
||||||
|
## Zugeordnete User Stories
|
||||||
|
- US_000036: Doku-Versionen auf VERSION synchronisieren
|
||||||
|
- US_000037: Update-API-Doku mit /update/enroll und Response-Feldern abgleichen
|
||||||
|
- US_000038: ENV-Beispiele und Makefile-Healthcheck an Auth/Update-Config angleichen
|
||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000001 | Version: 0.1.0 | Status: Final
|
ID: US_000001 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000001: Nutzerkonto per CLI deaktivieren
|
# US_000001: Nutzerkonto per CLI deaktivieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000002 | Version: 0.1.0 | Status: Final
|
ID: US_000002 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000002: Nutzerkonto per CLI aktivieren
|
# US_000002: Nutzerkonto per CLI aktivieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000003 | Version: 0.1.0 | Status: Final
|
ID: US_000003 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000003: Health-Status abfragen
|
# US_000003: Health-Status abfragen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000004 | Version: 0.1.0 | Status: Final
|
ID: US_000004 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000004: Verfuegbare Nutzer auflisten
|
# US_000004: Verfuegbare Nutzer auflisten
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000005 | Version: 0.1.0 | Status: Final
|
ID: US_000005 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000005: Nutzer per API deaktivieren
|
# US_000005: Nutzer per API deaktivieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000006 | Version: 0.1.0 | Status: Final
|
ID: US_000006 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000006: Nutzer per API aktivieren
|
# US_000006: Nutzer per API aktivieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000007 | Version: 0.1.0 | Status: Final
|
ID: US_000007 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000007: PAM-Login mit Token
|
# US_000007: PAM-Login mit Token
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000008 | Version: 0.1.0 | Status: Final
|
ID: US_000008 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000008: OIDC-Login Flow
|
# US_000008: OIDC-Login Flow
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000009 | Version: 0.1.0 | Status: Final
|
ID: US_000009 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000009: Autorisierung und /me-Identitaet
|
# US_000009: Autorisierung und /me-Identitaet
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000010 | Version: 0.1.0 | Status: Final
|
ID: US_000010 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000010: Index-Seite ausliefern
|
# US_000010: Index-Seite ausliefern
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000011 | Version: 0.1.0 | Status: Final
|
ID: US_000011 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000011: Virtualenv und Abhaengigkeiten erstellen
|
# US_000011: Virtualenv und Abhaengigkeiten erstellen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000012 | Version: 0.1.0 | Status: Final
|
ID: US_000012 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000012: Service lokal starten
|
# US_000012: Service lokal starten
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000013 | Version: 0.1.0 | Status: Final
|
ID: US_000013 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000013: Service installieren
|
# US_000013: Service installieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000014 | Version: 0.1.0 | Status: Final
|
ID: US_000014 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000014: Service aktualisieren
|
# US_000014: Service aktualisieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000015 | Version: 0.1.0 | Status: Final
|
ID: US_000015 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000015: Remote-Deployment durchfuehren
|
# US_000015: Remote-Deployment durchfuehren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000016 | Version: 0.1.0 | Status: Final
|
ID: US_000016 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000016: OIDC-Client registrieren
|
# US_000016: OIDC-Client registrieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000017 | Version: 0.1.0 | Status: Final
|
ID: US_000017 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000017: Systemd-Unit im Repo
|
# US_000017: Systemd-Unit im Repo
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000018 | Version: 0.1.0 | Status: Final
|
ID: US_000018 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000018: Konfigurations-Templates verfuegbar
|
# US_000018: Konfigurations-Templates verfuegbar
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000019 | Version: 0.1.0 | Status: Final
|
ID: US_000019 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000019: Deployment-Archiv vorhanden
|
# US_000019: Deployment-Archiv vorhanden
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000020 | Version: 0.1.0 | Status: Final
|
ID: US_000020 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000020: Makefile-Automation bereitstellen
|
# US_000020: Makefile-Automation bereitstellen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000021 | Version: 0.1.0 | Status: Final
|
ID: US_000021 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000021: Konfiguration per ENV steuern
|
# US_000021: Konfiguration per ENV steuern
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000022 | Version: 0.1.0 | Status: Final
|
ID: US_000022 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000022: Web-UI Aktionen ausfuehren
|
# US_000022: Web-UI Aktionen ausfuehren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000023 | Version: 0.1.0 | Status: Final
|
ID: US_000023 | Version: 0.2.1 | Status: Final
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000023: Runbook und Security-Hinweise dokumentieren
|
# US_000023: Runbook und Security-Hinweise dokumentieren
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000024 | Version: 0.1.0 | Status: Done
|
ID: US_000024 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000024: Watchtower Theme fuer Web-UI
|
# US_000024: Watchtower Theme fuer Web-UI
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000025 | Version: 0.1.0 | Status: Draft
|
ID: US_000025 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000025: OIDC End-to-End Validierung und Runbook
|
# US_000025: OIDC End-to-End Validierung und Runbook
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000026 | Version: 0.1.0 | Status: Done
|
ID: US_000026 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000026: Client bezieht Updates (Pull)
|
# US_000026: Client bezieht Updates (Pull)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000027 | Version: 0.1.0 | Status: Done
|
ID: US_000027 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000027: Client verifiziert und wendet Updates an
|
# US_000027: Client verifiziert und wendet Updates an
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000028 | Version: 0.1.0 | Status: Done
|
ID: US_000028 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000028: Client meldet Update-Status
|
# US_000028: Client meldet Update-Status
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000029 | Version: 0.1.0 | Status: Done
|
ID: US_000029 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000029: Update-Status im Web-UI anzeigen
|
# US_000029: Update-Status im Web-UI anzeigen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000030 | Version: 0.1.0 | Status: Done
|
ID: US_000030 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000030: Update-Check im Web-UI ausloesen
|
# US_000030: Update-Check im Web-UI ausloesen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000031 | Version: 0.1.0 | Status: Done
|
ID: US_000031 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000031: Update im Web-UI anstossen
|
# US_000031: Update im Web-UI anstossen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000032 | Version: 0.1.0 | Status: Done
|
ID: US_000032 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000032: Update-Logs im Web-UI anzeigen
|
# US_000032: Update-Logs im Web-UI anzeigen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000033 | Version: 0.1.0 | Status: Done
|
ID: US_000033 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000033: Rollback im Web-UI anstossen
|
# US_000033: Rollback im Web-UI anstossen
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000034 | Version: 0.1.5 | Status: Done
|
ID: US_000034 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000034: Enrollment fuer Langzeit-Token
|
# US_000034: Enrollment fuer Langzeit-Token
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: US_000035 | Version: 0.1.5 | Status: Done
|
ID: US_000035 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# US_000035: v1 Update-Endpoints und Status-Schema
|
# US_000035: v1 Update-Endpoints und Status-Schema
|
||||||
|
|||||||
13
project-management/requirements/stories/US_000036.md
Normal file
13
project-management/requirements/stories/US_000036.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
ID: US_000036 | Version: 0.2.1 | Status: Done
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
|
# US_000036: Doku-Versionen auf VERSION synchronisieren
|
||||||
|
|
||||||
|
Als Maintainer moechte ich, dass Doku-Header und Spezifikationen die zentrale VERSION
|
||||||
|
verwenden, damit Releases konsistent dokumentiert sind.
|
||||||
|
|
||||||
|
## Akzeptanzkriterien
|
||||||
|
- Given die VERSION ist 0.2.1
|
||||||
|
- When Doku-Header oder OpenAPI-Info Versionen angegeben sind
|
||||||
|
- Then entsprechen sie 0.2.1
|
||||||
|
- And es gibt keine widerspruechlichen 0.1.0-Header in den betroffenen Doku-Dateien
|
||||||
14
project-management/requirements/stories/US_000037.md
Normal file
14
project-management/requirements/stories/US_000037.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
ID: US_000037 | Version: 0.2.1 | Status: Done
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
|
# US_000037: Update-API-Doku mit /update/enroll abgleichen
|
||||||
|
|
||||||
|
Als Betreiber moechte ich eine korrekte Update-API-Dokumentation, damit Clients die
|
||||||
|
Update-Endpunkte inkl. Enrollment korrekt nutzen.
|
||||||
|
|
||||||
|
## Akzeptanzkriterien
|
||||||
|
- Given die Backend-API implementiert /update/enroll
|
||||||
|
- When die Update-API-Doku gelesen wird
|
||||||
|
- Then /update/enroll ist beschrieben (Request und Response)
|
||||||
|
- And /update/status enthaelt das Feld enrolled
|
||||||
|
- And /update/logs beschreibt die aktuellen Felder (timestamp, status, message, version, device_id, error)
|
||||||
14
project-management/requirements/stories/US_000038.md
Normal file
14
project-management/requirements/stories/US_000038.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
ID: US_000038 | Version: 0.2.1 | Status: Done
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
|
# US_000038: ENV-Beispiele und Healthcheck-Auth angleichen
|
||||||
|
|
||||||
|
Als Operator moechte ich, dass ENV-Beispiele und Healthcheck-Header mit dem aktuellen
|
||||||
|
Auth- und Update-Config-Stand uebereinstimmen, damit Deployments nicht scheitern.
|
||||||
|
|
||||||
|
## Akzeptanzkriterien
|
||||||
|
- Given das Backend akzeptiert Authorization: Bearer Tokens
|
||||||
|
- When der Healthcheck aus dem Makefile ausgefuehrt wird
|
||||||
|
- Then wird der Header Authorization: Bearer verwendet
|
||||||
|
- And env.example/README listen SKD_UPDATE_SERVICE_URL und SKD_UPDATE_PROJECT_ID
|
||||||
|
- And nicht verwendete Update-Variablen werden nicht als Pflicht-Keys aufgefuehrt
|
||||||
14
project-management/requirements/stories/US_000039.md
Normal file
14
project-management/requirements/stories/US_000039.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
ID: US_000039 | Version: 0.2.1 | Status: Done
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
|
# US_000039: Doku-Audit fuer verbleibende Abweichungen
|
||||||
|
|
||||||
|
Als Maintainer moechte ich eine systematische Pruefung der verbleibenden Doku-Dateien,
|
||||||
|
damit keine Versions- oder Inhaltsabweichungen zwischen Code und Dokumentation bestehen.
|
||||||
|
|
||||||
|
## Akzeptanzkriterien
|
||||||
|
- Given die zentrale VERSION ist bekannt
|
||||||
|
- When alle Doku-Dateien geprueft werden
|
||||||
|
- Then sind Header-Versionen konsistent mit VERSION
|
||||||
|
- And API-/ENV-Beschreibungen entsprechen dem aktuellen Code-Stand
|
||||||
|
- And Abweichungen sind dokumentiert oder korrigiert
|
||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000025 | Version: 0.1.0 | Status: Blocked
|
ID: TASK_000025 | Version: 0.2.1 | Status: Blocked
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000025: OIDC E2E validation
|
# TASK_000025: OIDC E2E validation
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000026 | Version: 0.1.0 | Status: Blocked
|
ID: TASK_000026 | Version: 0.2.1 | Status: Blocked
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000026: OIDC runbook update
|
# TASK_000026: OIDC runbook update
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000027 | Version: 0.1.0 | Status: Done
|
ID: TASK_000027 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000027: Update endpoint config
|
# TASK_000027: Update endpoint config
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000028 | Version: 0.1.0 | Status: Done
|
ID: TASK_000028 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000028: Verify and apply update
|
# TASK_000028: Verify and apply update
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000029 | Version: 0.1.0 | Status: Done
|
ID: TASK_000029 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000029: Report update status
|
# TASK_000029: Report update status
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000030 | Version: 0.1.0 | Status: Done
|
ID: TASK_000030 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000030: UI update status view
|
# TASK_000030: UI update status view
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000031 | Version: 0.1.0 | Status: Done
|
ID: TASK_000031 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000031: UI update check trigger
|
# TASK_000031: UI update check trigger
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000032 | Version: 0.1.0 | Status: Done
|
ID: TASK_000032 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000032: UI update apply action
|
# TASK_000032: UI update apply action
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000033 | Version: 0.1.0 | Status: Done
|
ID: TASK_000033 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000033: UI update logs view
|
# TASK_000033: UI update logs view
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000034 | Version: 0.1.0 | Status: Done
|
ID: TASK_000034 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000034: UI rollback action
|
# TASK_000034: UI rollback action
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000035 | Version: 0.1.1 | Status: Done
|
ID: TASK_000035 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000035: Login-Landing und Header-Version
|
# TASK_000035: Login-Landing und Header-Version
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000036 | Version: 0.1.2 | Status: Done
|
ID: TASK_000036 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000036: Login-Landing und Dashboard-Redirect
|
# TASK_000036: Login-Landing und Dashboard-Redirect
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000037 | Version: 0.1.3 | Status: Done
|
ID: TASK_000037 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000037: OIDC-Button neben Anmelden
|
# TASK_000037: OIDC-Button neben Anmelden
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000038 | Version: 0.1.4 | Status: Done
|
ID: TASK_000038 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000038: Logo und Favicon einbinden
|
# TASK_000038: Logo und Favicon einbinden
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000039 | Version: 0.1.5 | Status: Done
|
ID: TASK_000039 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000039: Login-Text und Panel-Layout
|
# TASK_000039: Login-Text und Panel-Layout
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
ID: TASK_000040 | Version: 0.1.5 | Status: Done
|
ID: TASK_000040 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000040: Enrollment-Flow implementieren
|
# TASK_000040: Enrollment-Flow implementieren
|
||||||
|
|
||||||
## Outcome
|
## Outcome
|
||||||
Der Update-Client kann einmalig per Enrollment einen Langzeit-Token beziehen und lokal speichern.
|
Der Update-Client kann einmalig per Enrollment einen Langzeit-Token beziehen und lokal speichern.
|
||||||
|
Dazu stehen zwei Skripte zur Verfuegung:
|
||||||
|
- `scripts/enroll_local.py`: Enrollment ueber die lokale API (empfohlen).
|
||||||
|
- `scripts/manual_enroll.py`: Direktes Enrollment beim Update-Service (Bypass).
|
||||||
|
|
||||||
## Story-Bezug
|
## Story-Bezug
|
||||||
US_000034
|
US_000034
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: TASK_000041 | Version: 0.1.5 | Status: Done
|
ID: TASK_000041 | Version: 0.2.1 | Status: Done
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# TASK_000041: v1 Endpunkte im Update-Client umstellen
|
# TASK_000041: v1 Endpunkte im Update-Client umstellen
|
||||||
|
|||||||
20
project-management/requirements/tasks/TASK_000042.md
Normal file
20
project-management/requirements/tasks/TASK_000042.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
ID: TASK_000042 | Version: 0.2.1 | Status: Done
|
||||||
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
|
# TASK_000042: Doku-Audit verbleibender Dateien
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
Alle relevanten Doku-Dateien sind geprueft und konsistent mit VERSION und Code-Stand.
|
||||||
|
|
||||||
|
## Story-Bezug
|
||||||
|
US_000039
|
||||||
|
|
||||||
|
## Beschreibung
|
||||||
|
- Liste verbleibender Doku-Dateien mit Header-Versionen pruefen.
|
||||||
|
- Abgleich mit Code fuer API- und ENV-Beschreibungen.
|
||||||
|
- Abweichungen korrigieren oder als Follow-up dokumentieren.
|
||||||
|
|
||||||
|
## Definition of Done (DoD)
|
||||||
|
- Keine verbleibenden Doku-Header mit falscher Version.
|
||||||
|
- Doku nennt nur genutzte ENV-Keys und korrekte Endpunkte.
|
||||||
|
- Ergebnis im CHANGELOG dokumentiert.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
ID: PROMPT_000006 | Version: 0.1.0 | Status: Draft
|
ID: PROMPT_000006 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Restructure Prompt: Forensic Architect (Compliance Mode)
|
# Restructure Prompt: Forensic Architect (Compliance Mode)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: PROMPT_000009 | Version: 0.1.0 | Status: Draft
|
ID: PROMPT_000009 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# Story Refactoring Prompt
|
# Story Refactoring Prompt
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ID: PROMPT_000007 | Version: 0.1.0 | Status: Draft
|
ID: PROMPT_000007 | Version: 0.2.1 | Status: Draft
|
||||||
By: Codex (GPT-5)
|
By: Codex (GPT-5)
|
||||||
|
|
||||||
# The Stack-Master & System Architect
|
# The Stack-Master & System Architect
|
||||||
|
|||||||
51
scripts/enroll_local.py
Executable file
51
scripts/enroll_local.py
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
def enroll():
|
||||||
|
parser = argparse.ArgumentParser(description="Enroll this device via the local Kiddo API")
|
||||||
|
parser.add_argument("--url", default=os.getenv("API_URL", "http://localhost:8000"), help="Local API URL")
|
||||||
|
parser.add_argument("--token", help="Enrollment Token (from update service)")
|
||||||
|
parser.add_argument("--auth", help="Local Admin Auth Token (skd_session cookie value)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Use default token if not provided (keeping the one from the prototype for now as a fallback)
|
||||||
|
enroll_token = args.token or "739772f5-4803-4635-a2c2-454799c37534"
|
||||||
|
|
||||||
|
print(f"[*] Enrolling via local API at {args.url}")
|
||||||
|
print(f"[*] Enrollment Token: {enroll_token[:8]}...")
|
||||||
|
|
||||||
|
headers = {}
|
||||||
|
auth_token = args.auth or os.getenv("SKD_API_TOKEN")
|
||||||
|
if auth_token:
|
||||||
|
headers["Cookie"] = f"skd_session={auth_token}"
|
||||||
|
print("[*] Using provided authentication token")
|
||||||
|
else:
|
||||||
|
print("[!] No authentication token provided. Request might fail if API is protected.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = httpx.post(
|
||||||
|
f"{args.url}/update/enroll",
|
||||||
|
json={"enroll_token": enroll_token},
|
||||||
|
headers=headers,
|
||||||
|
timeout=15.0
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("[+] Success: Enrollment successful!")
|
||||||
|
print(f"[+] Response: {response.json()}")
|
||||||
|
elif response.status_code == 401:
|
||||||
|
print("[!] Error: Unauthorized. Please provide a valid admin auth token via --auth or SKD_API_TOKEN env.")
|
||||||
|
else:
|
||||||
|
print(f"[!] Error {response.status_code}: {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Exception: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
enroll()
|
||||||
68
scripts/manual_enroll.py
Executable file
68
scripts/manual_enroll.py
Executable file
@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Add project root to sys.path to allow imports
|
||||||
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
sys.path.insert(0, str(PROJECT_ROOT))
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
from backend.settings import get_settings
|
||||||
|
from backend.update import _ensure_parent
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Manual Enrollment Client")
|
||||||
|
parser.add_argument("--url", default="https://update.wlkns.org", help="Update Service URL")
|
||||||
|
parser.add_argument("--token", required=True, help="Enrollment Token")
|
||||||
|
parser.add_argument("--project", default="safe-kiddo-control", help="Project ID")
|
||||||
|
parser.add_argument("--insecure", action="store_true", help="Disable SSL verification")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
settings = get_settings()
|
||||||
|
|
||||||
|
print(f"[*] Enrolling client {os.uname().nodename}...")
|
||||||
|
print(f"[*] Service URL: {args.url}")
|
||||||
|
print(f"[*] Project ID: {args.project}")
|
||||||
|
|
||||||
|
enroll_url = f"{args.url}/v1/enroll"
|
||||||
|
payload = {
|
||||||
|
"project_id": args.project,
|
||||||
|
"client_id": os.uname().nodename,
|
||||||
|
"software_id": "safe-kiddo",
|
||||||
|
"enroll_token": args.token,
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with httpx.Client(verify=not args.insecure, timeout=10.0) as client:
|
||||||
|
response = client.post(enroll_url, json=payload)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"[!] Error {response.status_code}: {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
token = data.get("token")
|
||||||
|
if not token:
|
||||||
|
print("[!] Error: No token received in response")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
token_path = Path(settings.update_token_file)
|
||||||
|
_ensure_parent(token_path)
|
||||||
|
token_path.write_text(token, encoding="utf-8")
|
||||||
|
|
||||||
|
# Make sure only root/service user can read it
|
||||||
|
os.chmod(token_path, 0o600)
|
||||||
|
|
||||||
|
print(f"[+] Success! Token saved to {token_path}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Exception: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user