From 1d8a273ffbe178d9e12b035cd38a6554723f489e Mon Sep 17 00:00:00 2001
From: Jacquin Antoine
Date: Mon, 20 Jul 2026 00:05:34 +0200
Subject: [PATCH] =?UTF-8?q?Ajoute=20la=20r=C3=A9g=C3=A9n=C3=A8se=20du=20to?=
=?UTF-8?q?ken=20de=20pr=C3=A9sence=20Tasker=20et=20=C3=A9largit=20le=20ba?=
=?UTF-8?q?ndeau=20de=20test=20ntfy?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Le bouton "Régénérer le token" de la carte Tasker crée un nouveau token
secret et invalide immédiatement les anciennes URLs, au cas où elles
auraient fuité. La fonction regenerate_presence_token préserve les
autres réglages notif (topic, serveur, jeton d'accès, plage). Au passage
le message de retour du bouton de test ntfy occupe désormais toute la
largeur de la carte au lieu d'être limité à 420px.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
---
app/main.py | 28 +++++++++++++++++++++
app/models.py | 9 +++++++
app/templates/settings.html | 35 ++++++++++++++++++++------
app/tests/test_logs.py | 49 +++++++++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+), 8 deletions(-)
diff --git a/app/main.py b/app/main.py
index 8bc386d..46617db 100644
--- a/app/main.py
+++ b/app/main.py
@@ -17,6 +17,7 @@ from models import (
load_config, load_week_pointages, save_week_pointages, load_conges,
toggle_conge, list_all_weeks,
load_notif_config, save_notif_config, find_user_by_token, save_presence,
+ regenerate_presence_token,
load_auth, save_auth, find_user_by_reset_token,
load_plages, save_plages, heures_jour_min,
append_log, load_logs,
@@ -630,6 +631,33 @@ def settings_test_ntfy(request: Request):
)
+@app.post("/settings/regenerate-presence-token", response_class=HTMLResponse)
+def settings_regenerate_presence_token(request: Request):
+ user_id = _get_user(request)
+ if not user_id:
+ return RedirectResponse("/login", status_code=302)
+
+ new_token = regenerate_presence_token(user_id)
+ logger.warning("token de présence régénéré pour %r", user_id)
+
+ base_url = str(request.base_url).rstrip("/")
+ arrivee_url = f"{base_url}/presence/{new_token}/arrivee"
+ depart_url = f"{base_url}/presence/{new_token}/depart"
+ return HTMLResponse(
+ f''
+ f'
'
+ f'Arrivée '
+ f'{arrivee_url}'
+ f'
'
+ f'
'
+ f'Départ '
+ f'{depart_url}'
+ f'
'
+ f'
Token régénéré. Mets à jour les URLs dans Tasker.
'
+ f'
'
+ )
+
+
@app.post("/settings/plages", response_class=HTMLResponse)
def settings_plages_save(
request: Request,
diff --git a/app/models.py b/app/models.py
index a6d6012..dd9286c 100644
--- a/app/models.py
+++ b/app/models.py
@@ -201,6 +201,15 @@ def find_user_by_token(token: str) -> str | None:
return None
+def regenerate_presence_token(user_id: str) -> str:
+ """Génère un nouveau token de présence (invalide les URLs Tasker précédentes)."""
+ cfg = load_notif_config(user_id)
+ cfg["token"] = secrets.token_hex(16)
+ _ensure_user_dirs(user_id)
+ _notif_file(user_id).write_text(json.dumps(cfg, indent=2, ensure_ascii=False))
+ return cfg["token"]
+
+
def _presence_file(user_id: str) -> Path:
return _user_root(user_id) / "presence.json"
diff --git a/app/templates/settings.html b/app/templates/settings.html
index 6ed47e0..d9839ed 100644
--- a/app/templates/settings.html
+++ b/app/templates/settings.html
@@ -134,17 +134,29 @@
5 minutes, dans la plage horaire réglée ci-dessus (jours ouvrés). Étapes détaillées sur la page
Aide .
-
- Arrivée
- {{ arrivee_url }}
-
-
-
Départ
-
{{ depart_url }}
+
+
+ Arrivée
+ {{ arrivee_url }}
+
+
+ Départ
+ {{ depart_url }}
+
Ces URLs sont secrètes (elles contiennent ton token) — ne les partage pas.
+ En cas de compromission, régénère le token : les anciennes URLs cesseront de fonctionner
+ et tu devras mettre à jour Tasker avec les nouvelles.
+
Régénérer le token