Files
triggerssmith/api/auth/refresh.go
2026-01-03 15:43:12 +02:00

57 lines
1.8 KiB
Go

package api_auth
import (
"encoding/json"
"errors"
"net/http"
"git.oblat.lv/alex/triggerssmith/internal/auth"
"git.oblat.lv/alex/triggerssmith/internal/server"
)
type refreshResponse struct {
Access string `json:"accessToken"`
}
// @Summary Refresh tokens
// @Description Requires valid HttpOnly refresh_token cookie
// @Tags auth
// @Produce json
// @Security RefreshCookieAuth
// @Success 200 {object} refreshResponse
// @Failure 401 {object} server.ProblemDetails
// @Failure 500 {object} server.ProblemDetails
// @Router /api/auth/refresh [post]
func (h *authHandler) handleRefresh(w http.ResponseWriter, r *http.Request) {
refreshCookie, err := r.Cookie("refresh_token")
if err != nil && errors.Is(err, http.ErrNoCookie) {
server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/refresh-token-not-found", "Refresh token is missing", "Refresh token is missing", r)
return
}
refreshStr := refreshCookie.Value
if refreshStr == "" {
server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/refresh-token-not-found", "Refresh token is missing", "Refresh token is missing", r)
return
}
tokens, err := h.a.RefreshTokens(refreshStr)
if err != nil {
if errors.Is(err, auth.ErrInvalidToken) {
server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/refresh-token-invalid", "Refresh token is invalid", "Refresh token is invalid", r)
} else {
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error: taking cookies anyway", r)
}
return
}
http.SetCookie(w, &http.Cookie{
Name: "refresh_token",
Value: tokens.Refresh,
MaxAge: 3600,
Path: "/api/auth/refresh",
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
})
var resp refreshResponse
resp.Access = tokens.Access
_ = json.NewEncoder(w).Encode(resp)
}