Backend and frontend now run in background so Gin debug output
is preserved. View logs with:
tail -f /tmp/imc-backend.log
tail -f /tmp/imc-frontend.log
- Add .air.toml configuration for Go hot-reloading
- Add 'dev' target to run both frontend and backend together
- Update dev-backend to use air instead of go run
- Install air with: go install github.com/air-verse/air@latest
Authentication now works only via hashed passwords in imc_users table.
Users must be created through the password reset flow or directly in the database.
- Add .env.example with all configuration options documented
- Remove ADMIN_PASSWORD from .env files
- Set password via environment variable or --reset-admin-password flag
- Migrate all pages to daisyUI components
- Add data-theme="light" to app.html for proper theme
- Fix config to load .env from multiple locations
- Update avatar to use avatar-placeholder pattern
- Use @tailwindcss/vite plugin instead of PostCSS
1. Password reset tokens: use crypto/rand instead of math/rand
2. IP spoofing: only trust X-Forwarded-For from configured trusted proxies
3. Cleanup: purge failed login attempts older than 24 hours
4. JWT secret: validate minimum 32 character length on startup
Updated .env.example with TRUSTED_PROXIES setting
- Add lib/auth.ts with decodeJWT() and isTokenValid()
- Layout decodes JWT directly - no extra request
- Domains page also uses JWT for admin check
- Removed redundant user.domains from domains list page
- Add mail.GetQuota() using doveadm quota get
- Fix UserWithQuota response struct
- Fix frontend NaN display with Unknown fallback
- Update field names to camelCase (usedQuota)
- Remove dots from character class (handled separately)
- Check username doesn't start/end with dot
- Check for no consecutive dots (..)
- Valid chars: a-zA-Z0-9!#$%&'*+-/=?^_`{|}~-
- Prefill domain part in forms (e.g. input + @domain.com)
- Use native <dialog> element for modals
- Show error messages instead of alert()
- Cleaner input group styling
- Validate domain name format: letters, numbers, dots, hyphens only
- Must have at least one dot (TLD required)
- Cannot start/end with dot or hyphen
- Label length 1-63 characters
- Return ValidationError with descriptive message
- Added gin-gonic v1.10.0 dependency
- Refactored router.go: clean route groups with middleware chains
- Refactored all handlers to use gin.Context instead of http.ResponseWriter/*http.Request
- Simplified response helpers (JSON, Error, Success, Created, NoContent)
- Clean auth middleware using Gin's c.Set() for context
- Cleaner route definitions with path parameters (e.g., /domains/:name/users/:id)
- Admin routes moved to /api/admin group with RequireAdmin middleware