package auth import ( "time" "gitea.local/admin/hspguard/internal/cache" "gitea.local/admin/hspguard/internal/config" imiddleware "gitea.local/admin/hspguard/internal/middleware" "gitea.local/admin/hspguard/internal/repository" "gitea.local/admin/hspguard/internal/types" "gitea.local/admin/hspguard/internal/util" "github.com/go-chi/chi/v5" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" ) type AuthHandler struct { repo *repository.Queries cache *cache.Client cfg *config.AppConfig } type SignedToken struct { Token string ExpiresAt time.Time ID uuid.UUID } func NewSignedToken(token string, expiresAt time.Time, jti uuid.UUID) *SignedToken { return &SignedToken{ Token: token, ExpiresAt: expiresAt, ID: jti, } } func (h *AuthHandler) signTokens(user *repository.User) (*SignedToken, *SignedToken, error) { accessExpiresAt := time.Now().Add(15 * time.Minute) accessJTI := uuid.New() accessClaims := types.UserClaims{ UserEmail: user.Email, IsAdmin: user.IsAdmin, RegisteredClaims: jwt.RegisteredClaims{ Issuer: h.cfg.Uri, Subject: user.ID.String(), IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(accessExpiresAt), ID: accessJTI.String(), }, } accessToken, err := util.SignJwtToken(accessClaims, h.cfg.Jwt.PrivateKey) if err != nil { return nil, nil, err } refreshExpiresAt := time.Now().Add(30 * 24 * time.Hour) refreshJTI := uuid.New() refreshClaims := types.UserClaims{ UserEmail: user.Email, IsAdmin: user.IsAdmin, RegisteredClaims: jwt.RegisteredClaims{ Issuer: h.cfg.Uri, Subject: user.ID.String(), IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(refreshExpiresAt), ID: refreshJTI.String(), }, } refreshToken, err := util.SignJwtToken(refreshClaims, h.cfg.Jwt.PrivateKey) if err != nil { return nil, nil, err } return NewSignedToken(accessToken, accessExpiresAt, accessJTI), NewSignedToken(refreshToken, refreshExpiresAt, refreshJTI), nil } func NewAuthHandler(repo *repository.Queries, cache *cache.Client, cfg *config.AppConfig) *AuthHandler { return &AuthHandler{ repo, cache, cfg, } } func (h *AuthHandler) RegisterRoutes(api chi.Router) { api.Route("/auth", func(r chi.Router) { r.Group(func(protected chi.Router) { authMiddleware := imiddleware.NewAuthMiddleware(h.cfg) protected.Use(authMiddleware.Runner) protected.Get("/profile", h.getProfile) protected.Post("/email", h.requestEmailOtp) protected.Post("/email/otp", h.confirmOtp) protected.Post("/verify", h.finishVerification) protected.Post("/signout", h.signOut) }) r.Post("/login", h.login) r.Post("/refresh", h.refreshToken) }) }