From eb8f6cec059fede45e616cc9ea7e363379f23e0b Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 16 Mar 2026 14:22:51 +0100 Subject: [PATCH] new export improvements --- rowers/tests/testdata/testdata.tcx.gz | Bin 3989 -> 3989 bytes rowing-courses-spec.md | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 65720607e0b70e48ec25b1bcc4d1c9bcb030058c..bd1d17df25910e7d14606f8614a6dfb6d3b2122a 100644 GIT binary patch delta 16 XcmbO#KUJPxzMF%?f@#M__C9_9CAkD~ delta 16 XcmbO#KUJPxzMF$X{NwhG?0x(IDrW^g diff --git a/rowing-courses-spec.md b/rowing-courses-spec.md index bf7d5b1e..53348bf1 100644 --- a/rowing-courses-spec.md +++ b/rowing-courses-spec.md @@ -168,7 +168,9 @@ Even in Stage 1, users need a way to log in to like courses and have those likes 6. Worker sets the encrypted blob as an HTTP-only, Secure, SameSite=Lax cookie named `rn_session`. 7. On all subsequent authenticated requests, the Worker decrypts the cookie to recover the athlete ID and access token. No D1 lookup needed. -**D1 is not required in Stage 1.** The cookie carries all state needed for browser-based authentication. D1 is introduced in Stage 2 for the `is_organizer` flag and challenge-related state. +**Token refresh in Stage 1:** On each authenticated request the Worker decrypts the cookie and checks `expiresAt`. If the access token has expired, the Worker calls `POST https://intervals.icu/oauth/token` with the `refreshToken` from the cookie, receives a new `{accessToken, refreshToken, expiresAt}`, and rewrites the `rn_session` cookie before continuing. The refresh token is never written to D1 or KV — the cookie is the only storage. This is sufficient for Stage 1. + +**D1 is not required in Stage 1.** The cookie is entirely self-contained. D1 is introduced in Stage 2 for the `is_organizer` flag and challenge-related state. At that point the refresh token can optionally migrate to D1 (stored encrypted), which would enable server-side session revocation — currently not possible since there is no server-side session record to invalidate. **CrewNerd API key:** @@ -183,12 +185,13 @@ async function apiKeyForAthlete(athleteId: string, secret: string): Promise