TASK-SECADV-001: WebAuthn/Passkeys (F022) - WebAuthn credential model, service, handler - Registration/authentication ceremony endpoints - CRUD operations (list, rename, delete passkeys) - Routes: GET/POST/PUT/DELETE /auth/passkeys/* TASK-SECADV-002: Configurable password policy (F015) - PasswordPolicyConfig with MinLength, MaxLength, RequireUpper/Lower/Number/Special - NewPasswordValidatorWithPolicy constructor - PasswordPolicyFromEnv() reads env vars (PASSWORD_MIN_LENGTH, etc.) - All character class checks now respect policy configuration TASK-SECADV-003: Géolocalisation connexions (F025) - GeoIPResolver interface + GeoIPService implementation - Country/city columns added to login_history table - LoginHistoryService.Record() performs GeoIP lookup - GetUserHistory returns geolocation data - GET /auth/login-history endpoint TASK-SECADV-004: Password expiration (F016) - password_changed_at column on users table - CheckPasswordExpiration() method on PasswordService - All password change/reset methods now set password_changed_at - NewPasswordServiceWithPolicy() supports expiration days config Migration: 971_security_advanced_v0133.sql Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.1 KiB
Go
47 lines
1.1 KiB
Go
package services
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"veza-backend-api/internal/validators"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func TestPasswordServiceExpirationDisabled(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
ps := &PasswordService{
|
|
logger: logger,
|
|
expirationDays: 0, // disabled
|
|
}
|
|
|
|
err := ps.CheckPasswordExpiration(nil, [16]byte{})
|
|
if err != nil {
|
|
t.Errorf("expected no error when expiration disabled, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPasswordServiceExpirationNegative(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
ps := &PasswordService{
|
|
logger: logger,
|
|
expirationDays: -1, // disabled
|
|
}
|
|
|
|
err := ps.CheckPasswordExpiration(nil, [16]byte{})
|
|
if err != nil {
|
|
t.Errorf("expected no error with negative expiration days, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestNewPasswordServiceWithPolicy(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
policy := validators.DefaultPasswordPolicy()
|
|
ps := NewPasswordServiceWithPolicy(nil, logger, policy, 90)
|
|
if ps.expirationDays != 90 {
|
|
t.Errorf("expected expirationDays=90, got %d", ps.expirationDays)
|
|
}
|
|
if ps.passwordValidator == nil {
|
|
t.Error("expected non-nil passwordValidator")
|
|
}
|
|
}
|