Implement JWT authentication and app passkey support

- Add JWT token generation and validation
- Implement bcrypt password hashing
- Create auth service with register/login/refresh/logout
- Add app passkey generation and management
- Implement protected routes and auth middleware
- Add comprehensive tests for new functionality
This commit is contained in:
2026-04-29 11:50:09 +08:00
parent 901a769ee7
commit 3eeb9f6d26
24 changed files with 2063 additions and 36 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/dhao2001/mygo/internal/config"
"github.com/dhao2001/mygo/internal/repository"
"github.com/dhao2001/mygo/internal/service"
)
// WebApp contains application-wide runtime dependencies and metadata.
@@ -14,14 +15,16 @@ type WebApp struct {
Config *config.Config
Version string
DB *gorm.DB
UserRepo repository.UserRepository
SessionRepo repository.SessionRepository
FileRepo repository.FileRepository
DB *gorm.DB
UserRepo repository.UserRepository
SessionRepo repository.SessionRepository
FileRepo repository.FileRepository
CredentialRepo repository.CredentialRepository
AuthService *service.AuthService
}
// Bootstrap creates a fully initialized WebApp from config.
// It opens the database, runs migrations, and wires all repositories.
// It opens the database, runs migrations, and wires all repositories and services.
func Bootstrap(cfg *config.Config) (*WebApp, error) {
db, err := repository.Open(cfg.Database)
if err != nil {
@@ -32,25 +35,48 @@ func Bootstrap(cfg *config.Config) (*WebApp, error) {
return nil, fmt.Errorf("migrate database: %w", err)
}
userRepo := repository.NewUserRepository(db)
sessionRepo := repository.NewSessionRepository(db)
fileRepo := repository.NewFileRepository(db)
credentialRepo := repository.NewCredentialRepository(db)
jwtSecret := []byte(cfg.JWT.Secret)
authService := service.NewAuthService(
userRepo, sessionRepo, credentialRepo,
jwtSecret,
cfg.JWT.AccessDuration(),
cfg.JWT.RefreshDuration(),
)
return &WebApp{
Config: cfg,
Version: AppVersion,
DB: db,
UserRepo: repository.NewUserRepository(db),
SessionRepo: repository.NewSessionRepository(db),
FileRepo: repository.NewFileRepository(db),
Config: cfg,
Version: AppVersion,
DB: db,
UserRepo: userRepo,
SessionRepo: sessionRepo,
FileRepo: fileRepo,
CredentialRepo: credentialRepo,
AuthService: authService,
}, nil
}
// NewWebApp creates a WebApp with pre-built dependencies (useful for testing).
func NewWebApp(cfg *config.Config, db *gorm.DB, userRepo repository.UserRepository, sessionRepo repository.SessionRepository, fileRepo repository.FileRepository) *WebApp {
func NewWebApp(cfg *config.Config, db *gorm.DB,
userRepo repository.UserRepository,
sessionRepo repository.SessionRepository,
fileRepo repository.FileRepository,
credentialRepo repository.CredentialRepository,
authService *service.AuthService,
) *WebApp {
return &WebApp{
Config: cfg,
Version: AppVersion,
DB: db,
UserRepo: userRepo,
SessionRepo: sessionRepo,
FileRepo: fileRepo,
Config: cfg,
Version: AppVersion,
DB: db,
UserRepo: userRepo,
SessionRepo: sessionRepo,
FileRepo: fileRepo,
CredentialRepo: credentialRepo,
AuthService: authService,
}
}