Authentication System
Authentication System Documentation
Overview
Conformo implements a comprehensive JWT-based authentication system with the following features:
- User Registration with email verification
- Secure Login with account lockout protection
- Token-based Authentication (JWT access + refresh tokens)
- Password Reset via email
- Italian Localization for all messages and forms
- Business Context fields for Italian SMEs
- Rate Limiting on all sensitive endpoints
- Audit Logging for security monitoring
Architecture
Backend Components
Database Schema
users- User accounts with Italian business infouser_sessions- Refresh token managementuser_tokens- Email verification and password reset tokensauth_logs- Comprehensive audit trail
Services
passwordService.ts- Password hashing and validationtokenService.ts- JWT token generation and managementemailService.ts- SendGrid integration for transactional emailsauthLogger.ts- Security event logging
API Endpoints
| Endpoint | Method | Description | Rate Limit |
|---|---|---|---|
/api/auth/register |
POST | Create new user account | 5/hour per IP |
/api/auth/login |
POST | Authenticate user | 5/15min per email |
/api/auth/logout |
POST | Revoke session | Authenticated |
/api/auth/token/refresh |
POST | Rotate tokens | None |
/api/auth/verify-email |
POST | Verify email address | 3/hour |
/api/auth/forgot-password |
POST | Request password reset | 3/hour per email |
/api/auth/reset-password |
POST | Complete password reset | None |
/api/auth/profile |
GET | Get user profile | Authenticated |
Frontend Components
Auth Components
RegisterForm.tsx- Multi-step registration with Italian business fieldsLoginForm.tsx- Login with remember me and lockout displayForgotPasswordForm.tsx- Password reset requestResetPasswordForm.tsx- Password reset completionPasswordStrengthMeter.tsx- Real-time password validationAuthLayout.tsx- Auth page wrapper with logoEmailVerificationPage.tsx- Email verification handlerResetPasswordPage.tsx- Password reset handler
State Management
AuthContext.tsx- Global authentication stateauthApi.ts- API client for auth endpoints
Security Features
Password Requirements
- Minimum 8 characters (12+ recommended)
- At least 1 uppercase letter
- At least 1 lowercase letter
- At least 1 number
- At least 1 special character (!@#$%^&*)
- Cannot contain email or company name
- Dictionary check for common passwords
Account Lockout
- 5 failed login attempts trigger 30-minute lockout
- Lockout countdown displayed to user
- Remaining attempts shown after failed login
- Automatic unlock after lockout period
Token Management
- Access tokens: 15-minute expiry
- Refresh tokens: 24 hours (default) or 7 days (Remember Me)
- Server-side token storage for revocation
- Automatic rotation on refresh
Rate Limiting
- Registration: 5 attempts per IP per hour
- Login: 5 attempts per email per 15 minutes
- Password reset: 3 attempts per email per hour
- Email verification: 3 attempts per hour
Italian Business Context
Required Fields
- Company Name (Nome Azienda)
- Business Type (Tipo di Azienda)
- S.r.l., S.p.A., S.n.c., S.a.s., Ditta Individuale, Altro
- Employee Count (Numero Dipendenti)
- 1-10, 11-50, 51-250, 250+
- Province (Provincia)
- All 107 Italian provinces supported
- VAT Number (Partita IVA) - Optional
Localization
All UI text, error messages, and emails are in Italian:
- Form labels and placeholders
- Validation error messages
- Success/error notifications
- Email templates (verification, password reset)
Usage Examples
Frontend Usage
Using the Auth Context
import { useAuth } from './hooks/auth/AuthContext';
function MyComponent() {
const { user, isAuthenticated, login, logout } = useAuth();
const handleLogin = async () => {
try {
await login('user@example.com', 'password', true);
// Redirect to dashboard
} catch (error) {
// Handle error
}
};
return (
<div>
{isAuthenticated ? (
<div>
<p>Welcome, {user?.firstName}!</p>
<button onClick={() => logout()}>Logout</button>
</div>
) : (
<button onClick={handleLogin}>Login</button>
)}
</div>
);
}
Navigation
The app supports these routes:
/auth/login- Login page/auth/register- Registration page/auth/forgot-password- Forgot password page/auth/verify-email?token=xxx- Email verification/auth/reset-password?token=xxx- Password reset
Backend Usage
Creating a Protected Route
import { authenticateToken, AuthRequest } from './utils/authMiddleware';
app.get('/api/protected', authenticateToken, (req: AuthRequest, res) => {
// Access user info from req.user
const userId = req.user?.userId;
res.json({ message: 'Protected data', userId });
});
Logging Authentication Events
import { logAuthEvent, AuthEvent } from './services/auth/authLogger';
await logAuthEvent({
eventType: AuthEvent.LOGIN_SUCCESS,
success: true,
userId: user.id,
emailAttempted: email,
ipAddress: req.ip,
userAgent: req.get('user-agent'),
});
Email Templates
Verification Email (Italian)
- Subject: “Conferma il tuo account Conformo”
- Contains verification link with 24-hour expiry
- Branded with Conformo colors
Password Reset Email (Italian)
- Subject: “Reset password Conformo”
- Contains reset link with 1-hour expiry
- Security notice about unsolicited requests
Testing
Manual Testing Checklist
Registration Flow:
- Register with valid data
- Verify email received
- Click verification link
- Attempt duplicate registration
- Test password strength validation
- Test all Italian business fields
Login Flow:
- Login with verified account
- Login with unverified account
- Test “Remember Me” functionality
- Test account lockout (5 failed attempts)
- Verify lockout countdown
- Test logout
Password Reset Flow:
- Request password reset
- Verify email received
- Complete password reset
- Test token expiry (after 1 hour)
- Login with new password
Session Management:
- Access protected routes with valid token
- Test token expiry (after 15 minutes)
- Test token refresh
- Test logout from all devices
API Testing with cURL
See backend/db/README.md for complete API testing examples.
Troubleshooting
Common Issues
Email verification not working
- Check SENDGRID_API_KEY in .env
- Verify FROM_EMAIL is configured
- Check SendGrid sender verification
- In development, check console logs for token
Database connection errors
- Verify DATABASE_URL in .env
- Ensure PostgreSQL is running
- Run database schema script
- Check database user permissions
Token validation fails
- Verify JWT_SECRET matches on server
- Check token hasn’t expired
- Ensure token is sent in Authorization header
- Format:
Authorization: Bearer <token>
Rate limiting too strict
- Adjust limits in
utils/rateLimiter.ts - Clear browser cache/cookies
- Wait for rate limit window to expire
Security Best Practices
- Never commit .env files with real credentials
- Use strong JWT secrets (at least 32 characters, random)
- Rotate JWT secrets regularly in production
- Enable HTTPS in production
- Monitor auth_logs for suspicious activity
- Set up alerts for repeated failed logins
- Regularly review user_sessions for anomalies
- Keep dependencies updated for security patches
Future Enhancements
- Two-factor authentication (2FA)
- Social login (Google, Microsoft)
- OAuth2 support for third-party integrations
- Advanced password policies (expiry, history)
- Biometric authentication
- Session management UI for users
- IP whitelisting/blacklisting
- CAPTCHA for repeated failures