106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
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)
|
|
})
|
|
}
|