From c3bc6a48a0587ffdafd23ddba634e82e3764de87 Mon Sep 17 00:00:00 2001 From: Henrik Jess Nielsen Date: Sat, 23 May 2026 01:06:45 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20guard=20against=20duplicate=20callback?= =?UTF-8?q?=20=E2=80=94=20skip=20token=20exchange=20if=20already=20stored?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/routes/demo.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/routes/demo.py b/src/routes/demo.py index 1f999ff..786bc4e 100644 --- a/src/routes/demo.py +++ b/src/routes/demo.py @@ -402,6 +402,11 @@ async def tink_callback(request: Request, code: Optional[str] = None, print(f"[CALLBACK] Tink returned error: {error}") return RedirectResponse(f"/demo/step/3?error={error}") if code: + # Guard: if we already have a user_token for this session, the code was + # already exchanged (duplicate callback from Traefik during rolling deploy). + if _load_token(sess, "user_token"): + print(f"[CALLBACK] Already have user_token — skipping duplicate exchange") + return RedirectResponse("/demo/step/3?cb_success=1", status_code=303) try: s = get_settings() print(f"[CALLBACK] Exchanging code, redirect_uri={s.tink_redirect_uri!r}")