mercury/web/app/middleware.go

53 lines
1.1 KiB
Go

package app
import (
"context"
"net/http"
"time"
"git.sleepycat.moe/sam/mercury/internal/database"
)
type ctxKey int
const (
ctxKeyClaims ctxKey = 1
)
func (app *App) FrontendAuth(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie(database.TokenCookieName)
if err != nil || cookie.Value == "" {
next.ServeHTTP(w, r)
return
}
token, err := app.ParseToken(r.Context(), cookie.Value)
if err != nil {
app.ErrorTemplate(w, r, "Invalid token", "The provided token was not valid. Try clearing your cookies and reloading the page.")
return
}
if token.Expires.Before(time.Now()) {
http.SetCookie(w, &http.Cookie{Name: database.TokenCookieName, Value: "", Expires: time.Now()})
next.ServeHTTP(w, r)
return
}
ctx := context.WithValue(r.Context(), ctxKeyClaims, token)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
func (app *App) TokenFromContext(ctx context.Context) (database.Token, bool) {
v := ctx.Value(ctxKeyClaims)
if v == nil {
return database.Token{}, false
}
claims, ok := v.(database.Token)
return claims, ok
}