Spec â UI web Skald : consultation + auth magic-link (v0.1)
Doc avant code (CLAUDE.md §2.2). Pas de TDD (dĂ©cision mainteneur). Front â exigences OPQUAST / RGAA (CLAUDE.md §5).
Décisions validées : UI Twig dans le backend Symfony, auth maison magic-link email, mono-utilisateur (liste blanche d'emails).
1. Objectif
Une interface web pour consulter et écouter les enregistrements reçus du
device, accessible aprÚs connexion sans mot de passe (lien/token envoyé
par email). Domaine : skald.phracktale.com (distinct de
api.skald.phracktale.com, qui reste l'API device).
2. PérimÚtre
Inclus
- Page login : saisie email â envoi d'un lien magique.
- VĂ©rification du lien â session authentifiĂ©e.
- Page liste : enregistrements (
Recording) triés par date, avec horodatage lisible (uploadedAt,recordedAtsi présent), durée si connue,deviceId. - Lecture audio dans la page (élément
<audio>natif), via une route de streaming protégée par la session. - Déconnexion.
Exclus (v0.1)
- Inscription publique, multi-utilisateurs, rĂŽles.
- Suppression/édition des enregistrements, recherche, pagination avancée (liste simple suffisante au début).
- Transcription/traduction (phases pipeline ultérieures).
3. Deux surfaces de sécurité distinctes (ne pas mélanger)
| Surface | Domaine | Auth |
|---|---|---|
| API ingestion device | api.skald.phracktale.com |
Bearer token statique (SKALD_API_TOKEN) |
| UI web humaine | skald.phracktale.com |
Session aprĂšs magic-link email |
Le BearerTokenSubscriber protĂšge ^/api. L'UI vit hors /api (ex. /,
/login, /recordings, /audio/{id}) et est protégée par le firewall
Symfony (session). Les deux mécanismes restent indépendants.
4. ModÚle de données
User:id,email(unique). Pas de mot de passe.LoginToken:id,user,tokenHash(hash du token, jamais en clair en base),expiresAt(courte durée, ex. 15 min),usedAt(usage unique). Le token clair n'existe que dans l'email.
Liste blanche d'emails autorisés via paramÚtre d'env SKALD_ALLOWED_EMAILS
(le tien). Un email hors liste â pas d'envoi, message neutre (pas d'oracle
d'existence de compte).
5. Flux magic-link
GET /login: formulaire email (accessible, label explicite).POST /login: si email â liste blanche â crĂ©erLoginToken(token alĂ©atoire fort, stockĂ© hachĂ©), envoyer l'email avechttps://skald.phracktale.com/login/check?token=âŠ. RĂ©ponse toujours neutre (« si cet email est autorisĂ©, un lien a Ă©tĂ© envoyĂ© »).GET /login/check?token=âŠ: token valide, non expirĂ©, non utilisĂ© â marquerusedAt, ouvrir la session, rediriger vers la liste. Sinon page d'erreur claire.- Session Symfony classique ensuite ;
GET /logout.
Token : random_bytes(32) â URL-safe ; comparaison en temps constant ;
stockage hash('sha256', token).
6. Lecture audio
GET /ou/recordings(protégé session) : liste Twig, triéeuploadedAtdesc, horodatage formaté Europe/Paris, un<audio controls preload="none">par ligne pointant/audio/{id}.GET /audio/{id}(protégé session) : renvoie le fichier depuisvar/uploads(BinaryFileResponse,Content-TypeduRecording,Accept-Rangespour le seek). 404 si absent.
7. Accessibilité (RGAA / OPQUAST)
- HTML sémantique :
main,nav,tableou liste de dĂ©finitions avec en-tĂȘtes ; titres hiĂ©rarchisĂ©s. - Lecteur
<audio>natif (contrÎles clavier natifs) ; chaque lecteur a un libellé (aria-labelincluant l'horodatage). - Formulaire login :
labellié, messages d'erreur explicites, focus géré. - Contrastes conformes, pas d'information par la couleur seule, langue
fr.
8. Domaine & déploiement (Homelab)
- Nouveau domaine
skald.phracktale.com: DNS A â82.66.11.72(Ă crĂ©er par le mainteneur) ; vhost Heimdall + certbot (mĂȘme procĂ©dure queapi.skald), proxy vers le mĂȘme conteneurhomelab_skald_app(port 18090). Un seul backend sert les deux domaines (Symfony route selon l'hĂŽte / firewall selon le path). - Email : Symfony Mailer via le relais Postfix de Heimdall
(
MAILER_DSN=smtp://192.168.1.195:25depuis Thor â relais LAN, pas de credentials OVH dans Skald). Ă confirmer : joignabilitĂ© ThorâHeimdall:25 et expĂ©diteur autorisĂ© (skald@phracktale.com). - Nouvelles variables
.env(générées/posées par bootstrap, jamais commitées) :SKALD_ALLOWED_EMAILS,MAILER_DSN,MAILER_FROM=skald@phracktale.com,APP_BASE_URL=https://skald.phracktale.com.
9. Plan d'implémentation (sans test)
- Entités
User,LoginToken+ migration. - Auth maison : controllers
/login,/login/check,/logout;security.yaml(firewall session sur le non-/api,access_control). - Mailer : service d'envoi du lien (template email texte + html sobre).
- UI Twig : liste + lecteur, route
/audio/{id}protégée. - Artefacts Homelab : vhost
skald.phracktale.com.conf, majport-routing-table.md, bootstrap (nouvelles vars + MAILER). - VĂ©rif manuelle : login email â lien â liste â lecture d'un sample.
10. Inconnues Ă lever
- DNS
skald.phracktale.com(mainteneur). - DSN SMTP réel / relais Heimdall joignable depuis Thor (à tester).
- Expéditeur
skald@phracktale.comaccepté par le relais OVH.
11. Sources
_DOCS/contexte.md§5 (stack Symfony),SECURITY.md.HOMELAB/.../secrets-management.md(relais SMTP Postfix Heimdall, OVH).- RGAA 4.1 / OPQUAST (exigences front du projet).