Production hardening: security, resilience, observability, and compliance

Password complexity: custom validator requiring uppercase, lowercase, digit (min 8 chars)
Token expiry: 90-day token lifetime with refresh endpoint (60-90 day renewal window)
Health check: /api/health/ now pings Postgres + Redis, returns 503 on failure
Audit logging: async audit_log table for auth events (login, register, delete, etc.)
Circuit breaker: APNs/FCM push sends wrapped with 5-failure threshold, 30s recovery
FK indexes: 27 missing foreign key indexes across all tables (migration 017)
CSP header: default-src 'none'; frame-ancestors 'none'
Gzip compression: level 5 with media endpoint skipper
Prometheus metrics: /metrics endpoint using existing monitoring service
External timeouts: 15s push, 30s SMTP, context timeouts on all external calls

Migrations: 016 (token created_at), 017 (FK indexes), 018 (audit_log)
Tests: circuit breaker (15), audit service (8), token refresh (7), health (4),
       middleware expiry (5), validator (new)
This commit is contained in:
Trey T
2026-03-26 14:05:28 -05:00
parent 4abc57535e
commit b679f28e55
30 changed files with 2077 additions and 47 deletions

View File

@@ -11,7 +11,7 @@ type LoginRequest struct {
type RegisterRequest struct {
Username string `json:"username" validate:"required,min=3,max=150"`
Email string `json:"email" validate:"required,email,max=254"`
Password string `json:"password" validate:"required,min=8"`
Password string `json:"password" validate:"required,min=8,password_complexity"`
FirstName string `json:"first_name" validate:"max=150"`
LastName string `json:"last_name" validate:"max=150"`
}
@@ -35,7 +35,7 @@ type VerifyResetCodeRequest struct {
// ResetPasswordRequest represents the reset password request body
type ResetPasswordRequest struct {
ResetToken string `json:"reset_token" validate:"required"`
NewPassword string `json:"new_password" validate:"required,min=8"`
NewPassword string `json:"new_password" validate:"required,min=8,password_complexity"`
}
// UpdateProfileRequest represents the profile update request body

View File

@@ -79,6 +79,12 @@ type ResetPasswordResponse struct {
Message string `json:"message"`
}
// RefreshTokenResponse represents the token refresh response
type RefreshTokenResponse struct {
Token string `json:"token"`
Message string `json:"message"`
}
// MessageResponse represents a simple message response
type MessageResponse struct {
Message string `json:"message"`