refactor(security): use structured logger to prevent sensitive data exposure

Changes:
- Replace fmt.Println with logger.Logger.Warn in config loading
- Remove client_id and auth URLs from OAuth provider logs
- Remove user email, name, and sub from authentication logs
- Use structured logging for worker shutdown errors
- Fix MagicLink status logging (only log when actually enabled)
This commit is contained in:
Benjamin
2025-11-23 00:33:35 +01:00
parent 066374ca33
commit f6c75b3497
4 changed files with 18 additions and 25 deletions

View File

@@ -56,10 +56,7 @@ func NewOAuthProvider(config OAuthProviderConfig) *OAuthProvider {
},
}
logger.Logger.Info("OAuth provider configured",
"client_id", config.ClientID,
"auth_url", config.AuthURL,
"redirect_url", oauthConfig.RedirectURL)
logger.Logger.Info("OAuth provider configured successfully")
return &OAuthProvider{
oauthConfig: oauthConfig,
@@ -289,23 +286,17 @@ func (p *OAuthProvider) HandleCallback(ctx context.Context, w http.ResponseWrite
}
if !p.IsAllowedDomain(user.Email) {
logger.Logger.Warn("User domain not allowed",
"user_email", user.Email,
"allowed_domain", p.allowedDomain)
logger.Logger.Warn("User domain not allowed")
return nil, nextURL, models.ErrDomainNotAllowed
}
logger.Logger.Info("OAuth callback successful",
"user_email", user.Email,
"user_name", user.Name)
logger.Logger.Info("OAuth callback successful")
// Store refresh token if available
if token.RefreshToken != "" && p.sessionSvc.sessionRepo != nil {
if err := p.sessionSvc.StoreRefreshToken(ctx, w, r, token, user); err != nil {
// Log error but don't fail the authentication
logger.Logger.Error("Failed to store refresh token (non-fatal)",
"user_sub", user.Sub,
"error", err.Error())
logger.Logger.Error("Failed to store refresh token (non-fatal)", "error", err.Error())
}
}
@@ -379,12 +370,12 @@ func (p *OAuthProvider) parseUserInfo(resp *http.Response) (*models.User, error)
user.Name = name
logger.Logger.Debug("Extracted OAuth user identifiers",
"sub", user.Sub,
"email_present", user.Email != "",
"name_present", user.Name != "")
"has_sub", user.Sub != "",
"has_email", user.Email != "",
"has_name", user.Name != "")
if !user.IsValid() {
return nil, fmt.Errorf("invalid user data extracted: sub=%s, email=%s", user.Sub, user.Email)
return nil, fmt.Errorf("invalid user data extracted")
}
return user, nil

View File

@@ -7,6 +7,7 @@ import (
"os"
"strings"
"github.com/btouchard/ackify-ce/backend/pkg/logger"
"github.com/gorilla/securecookie"
)
@@ -240,7 +241,7 @@ func parseCookieSecret() ([]byte, error) {
raw := os.Getenv("ACKIFY_OAUTH_COOKIE_SECRET")
if raw == "" {
secret := securecookie.GenerateRandomKey(32)
fmt.Println("[WARN] ACKIFY_OAUTH_COOKIE_SECRET not set, generated volatile secret (sessions reset on restart)")
logger.Logger.Warn("OAuth cookie secret not set, sessions will reset on restart")
return secret, nil
}

View File

@@ -12,6 +12,7 @@ import (
"time"
"github.com/btouchard/ackify-ce/backend/internal/domain/models"
"github.com/btouchard/ackify-ce/backend/pkg/logger"
)
// Ed25519Signer provides cryptographic signature operations using Ed25519 elliptic curve algorithm
@@ -85,8 +86,7 @@ func loadOrGenerateKeys() (ed25519.PrivateKey, ed25519.PublicKey, error) {
return nil, nil, fmt.Errorf("failed to generate keys: %w", err)
}
// Do not print private keys. Warn about ephemeral key usage only.
fmt.Println("[WARN] Generated ephemeral Ed25519 keypair. Set ACKIFY_ED25519_PRIVATE_KEY to persist across restarts.")
logger.Logger.Warn("Ed25519 private key not set, signatures will be different on restart")
return privateKey, publicKey, nil
}

View File

@@ -120,13 +120,15 @@ func NewServer(ctx context.Context, cfg *config.Config, frontend embed.FS, versi
BaseURL: cfg.App.BaseURL,
AppName: cfg.App.Organisation,
})
logger.Logger.Info("Magic Link authentication enabled")
// Initialize Magic Link cleanup worker
var magicLinkWorker *workers.MagicLinkCleanupWorker
if cfg.Auth.MagicLinkEnabled {
logger.Logger.Info("Magic Link authentication enabled")
magicLinkWorker = workers.NewMagicLinkCleanupWorker(magicLinkService, 1*time.Hour)
go magicLinkWorker.Start(ctx)
} else {
logger.Logger.Info("Magic Link authentication disabled")
}
// Initialize reminder service with async support (needs magicLinkService)
@@ -218,22 +220,21 @@ func (s *Server) Shutdown(ctx context.Context) error {
// Stop OAuth session worker first if it exists
if s.sessionWorker != nil {
if err := s.sessionWorker.Stop(); err != nil {
fmt.Printf("Warning: failed to stop OAuth session worker: %v\n", err)
logger.Logger.Warn("Failed to stop OAuth session worker", "error", err)
}
}
// Stop email worker if it exists
if s.emailWorker != nil {
if err := s.emailWorker.Stop(); err != nil {
// Log but don't fail shutdown
fmt.Printf("Warning: failed to stop email worker: %v\n", err)
logger.Logger.Warn("Failed to stop email worker", "error", err)
}
}
// Stop webhook worker
if s.webhookWorker != nil {
if err := s.webhookWorker.Stop(); err != nil {
fmt.Printf("Warning: failed to stop webhook worker: %v\n", err)
logger.Logger.Warn("Failed to stop webhook worker", "error", err)
}
}