diff options
| author | wikiapiserver | 2026-06-25 14:47:35 +0200 |
|---|---|---|
| committer | wikiapiserver | 2026-06-25 14:47:35 +0200 |
| commit | cc960860e4109b4eb50721d0b3338df4b859d559 (patch) | |
| tree | 666e75656092814461a5dc58fdc6b64c3677e390 /api/handlers.go | |
| parent | e375b6cc68f4a9b0e91b25479538dc76d1f1e620 (diff) | |
| download | wikiapiserver-cc960860e4109b4eb50721d0b3338df4b859d559.tar.gz | |
feat: token refresh with age-based logic
- RefreshTokens checks token age and chooses the right path:
- refresh_token > 90 days: re-auth via WikimediaLogin (full login)
- access_token > 24 hours: refresh via WikimediaTokenRefresh
- otherwise: return current tokens
- WikimediaTokenRefresh posts to /v1/token-refresh endpoint
- Login also uses WikimediaLogin instead of local RotateTokens
- Removed dead RotateTokens, RefreshByToken, and randomHex
- DSN includes parseTime=true for timestamp columns
Diffstat (limited to 'api/handlers.go')
| -rw-r--r-- | api/handlers.go | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/api/handlers.go b/api/handlers.go index 7918b40..f98dd6b 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -38,10 +38,6 @@ type loginReq struct { Password string `json:"password"` } -type refreshReq struct { - RefreshToken string `json:"refresh_token"` -} - // --- helper writers --- func writeJSON(w http.ResponseWriter, code int, v any) { @@ -124,6 +120,12 @@ func (h *Handler) Login(w http.ResponseWriter, r *http.Request) { } // --- Refresh: POST /refresh --- +// Accepts username and refresh_token. The refresh_token is used to +// verify identity; RefreshTokens handles the age-based logic. +type refreshReq struct { + Username string `json:"username"` + RefreshToken string `json:"refresh_token"` +} func (h *Handler) Refresh(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), defaultTimeout) @@ -135,17 +137,17 @@ func (h *Handler) Refresh(w http.ResponseWriter, r *http.Request) { return } - if req.RefreshToken == "" { - badRequest(w, "refresh_token is required") + if req.Username == "" || req.RefreshToken == "" { + badRequest(w, "username and refresh_token are required") return } - - acct, err := h.db.RefreshByToken(ctx, req.RefreshToken) + acct, err := h.db.RefreshTokens(ctx, req.Username, req.RefreshToken) if err != nil { - if err.Error() == "invalid refresh token" { + if err.Error() == "account not found" || err.Error() == "invalid refresh token" { unauthorized(w) return } + log.Printf("refresh error: %v", err) serverError(w, "could not refresh token") return } |
