Add new configuration option ACKIFY_ONLY_ADMIN_CAN_CREATE (default: false) to control who can create documents.
Backend changes:
- Add OnlyAdminCanCreate config field to AppConfig
- Implement authorization checks in document handlers
- Protect POST /documents and GET /documents/find-or-create endpoints
- Add unit tests for admin-only document creation (4 tests)
Frontend changes:
- Inject ACKIFY_ONLY_ADMIN_CAN_CREATE to window object
- Hide DocumentForm component for non-admin users when enabled
- Add i18n translations (en, fr, es, de, it)
- Display warning message for non-admin users
Documentation:
- Update .env.example files with new variable
- Update configuration docs (en/fr)
- Update install script to prompt for restriction option
- Update install/README.md
When enabled, only users listed in ACKIFY_ADMIN_EMAILS can create new documents. Both direct creation and find-or-create endpoints are protected.
Add authentication tokens embedded in reminder emails allowing users to
authenticate and sign documents in one click.
Changes:
- Add 'purpose' (login/reminder_auth) and 'doc_id' columns to magic_link_tokens
- Implement CreateReminderAuthToken (24h validity) and VerifyReminderAuthToken
- Create reminder auth handler and route (/api/v1/auth/reminder-link/verify)
- Update ReminderService and ReminderAsyncService to generate auth tokens
- Fix table name mismatch: magic_links → magic_link_tokens throughout
- Reorder service initialization in server.go for proper dependencies
Token validity:
- Magic Link: 15 minutes (login)
- Reminder Auth: 24 hours (document signature)
The reminder auth flow:
1. Admin sends reminder
2. User receives email with auth link
3. User clicks link → auto-authenticated if not logged in
4. User redirected to document signature page
5. If already authenticated with correct account, skip auth step
The magic link email is now sent in the same language as the frontend
at the time of the request, matching the behavior of reminder emails.
Changes:
- Modified MagicLinkService.RequestMagicLink to accept locale parameter
- Handler extracts locale using i18n.GetLangFromRequest() from HTTP headers
- Falls back to "en" if locale is empty
- Consistent with reminder email locale detection
- feat(admin): accept URLs, file paths, and IDs in document creation form
- Modified AdminDashboard to use findOrCreateDocument service
- Now matches user UI functionality for flexible document references
- feat(i18n): replace all hardcoded French texts with translation keys
- Added 50+ new translation keys across admin and user interfaces
- Updated 7 Vue components: AdminDashboard, AdminDocumentDetail,
DocumentForm, SignButton, SignatureList, SignaturesPage, EmbedPage
- Synchronized all new keys to 5 languages (fr, en, es, de, it)
- All templates now use vue-i18n with proper parameterized translations
- Zero hardcoded texts remaining in HTML templates
Change test URLs from '/sign?doc=' to '/?doc=' to match the correct
frontend route after the URL path correction in reminder emails.
Updated base64 encoded state in callback test:
- Old: L3NpZ24_ZG9jPXRlc3Q (decodes to /sign?doc=test)
- New: Lz9kb2M9dGVzdA (decodes to /?doc=test)
Change signature URL in reminder emails from '/sign?doc=' to '/?doc='
to match the correct frontend route.
Updated in:
- ReminderService.sendSingleReminder
- ReminderAsyncService.queueSingleReminder
- Email helper tests
Backend changes:
- Use 'else if' to prevent activating both TLS and STARTTLS simultaneously
- Add StartTLSPolicy = MandatoryStartTLS for proper STARTTLS enforcement
- Add comments explaining TLS modes (implicit SSL vs explicit STARTTLS)
Install script changes:
- Auto-detect TLS configuration based on port number
- Port 465 → TLS=true, STARTTLS=false (implicit SSL)
- Port 587 → TLS=false, STARTTLS=true (explicit TLS/STARTTLS)
- Non-standard ports → manual configuration with clear prompts
This fixes timeout errors when sending emails via Gmail SMTP (port 587)
which requires STARTTLS, not direct TLS connection.
- Add ACKIFY_AUTH_OAUTH_ENABLED=true when OAuth is configured
- Add ACKIFY_AUTH_OAUTH_ENABLED=false when OAuth is not configured
- Write ACKIFY_AUTH_MAGICLINK_ENABLED with true/false value explicitly
- Provides clear visibility of enabled authentication methods in .env
These variables are already passed to containers via compose files.
Complete both compose.yml and compose-traefik.yml with missing environment
variables:
OAuth variables:
- OAUTH_SCOPES, OAUTH_GITLAB_URL, OAUTH_AUTO_LOGIN
- AUTH_OAUTH_ENABLED, AUTH_MAGICLINK_ENABLED
- Add fallback defaults (:-) for all OAuth variables
Mail/SMTP variables:
- MAIL_USERNAME, MAIL_PASSWORD, MAIL_TIMEOUT
- MAIL_SUBJECT_PREFIX, MAIL_TEMPLATE_DIR, MAIL_DEFAULT_LOCALE
- Fix MAIL_TLS and MAIL_STARTTLS to use env variables instead of hardcoded false
This ensures MagicLink authentication works properly when SMTP is configured.
- Add ACKIFY_LOG_LEVEL=info to prevent Docker Compose warning
- Fix ACKIFY_ED25519_PRIVATE_KEY_B64 -> ACKIFY_ED25519_PRIVATE_KEY
to match expected variable name in backend code
- Use cut with dot counting for more robust subdomain removal
(sign.kolapsis.com -> kolapsis.com)
- Redirect password prompt newline to stderr to avoid polluting
captured variable value
The rate limiting test was failing in CI because after reloading the page
with cy.visitWithLocale('/auth'), it immediately tried to access form
elements without waiting for the page to be fully loaded.
In local environments this worked because it's faster, but in CI the timing
was different causing the test to fail with 'expected to find content:
Check your email but never did'.
Added explicit waits for #app and 'Sign in to Ackify' after each page
reload to ensure the page is fully loaded before continuing.
The Go binary embeds static files from backend/cmd/community/web/dist
via go:embed directive. The e2e-tests workflow was building the frontend
in webapp/dist but not copying it to the embed location before compiling,
resulting in an empty app (no Vue frontend loaded).
This commit adds the missing copy step, matching the Dockerfile build process.
The e2e-tests workflow was failing because the application couldn't find
the locales/en.json and templates files. These files are in backend/locales
and backend/templates, but the standalone binary expects them at the root.
This commit adds a step to copy these directories before starting the server.
- Now can activate OIDC and/or MagicLink for user authentication.
- Add page to choose authentication method (if only OIDC is enabled, auto redirecting to login screen)
- Envoi des événements vers des URLs configurées
- Signature HMAC-SHA256 via en-tête X-Signature (secret partagé)
- Retentatives avec backoff exponentiel et jitter
- Timeout réseau et gestion des erreurs/transitoires
- Idempotence par event_id et journalisation structurée
- Paramètres: WEBHOOK_URLS, WEBHOOK_SECRET, WEBHOOK_TIMEOUT_MS, WEBHOOK_MAX_RETRIES
- Replace nanosecond+pid with crypto/rand generated hex (16 chars)
- Fixes race condition where parallel tests starting at same nanosecond
would share the same database name
- Ensures true isolation even with hundreds of concurrent tests
- Resolves duplicate key constraint violations in CI (perf-doc, test-doc, etc.)
- Fix migration path lookup to check both './migrations' and './backend/migrations'
- Remove hardcoded test schema in admin handler tests
- Use database.SetupTestDB which applies all migrations automatically
- Ensures test schema matches production schema with all columns (deleted_at, doc_checksum, etc.)
- Fixes test failures in CI where admin handler tests returned empty responses
- Implement PKCE (Proof Key for Code Exchange) with S256 method
- Add crypto/pkce module with code verifier and challenge generation
- Modify OAuth flow to include code_challenge in authorization requests
- Update HandleCallback to validate code_verifier during token exchange
- Extend session lifetime from 7 to 30 days
- Add comprehensive unit tests for PKCE functions
- Maintain backward compatibility with fallback for non-PKCE sessions
- Add detailed logging for OAuth flow with PKCE tracking
PKCE enhances security by preventing authorization code interception
attacks, as recommended by OAuth 2.1 and OIDC standards.
feat: add encrypted refresh token storage with automatic cleanup
- Add oauth_sessions table for storing encrypted refresh tokens
- Implement AES-256-GCM encryption for refresh tokens using cookie secret
- Create OAuth session repository with full CRUD operations
- Add SessionWorker for automatic cleanup of expired sessions
- Configure cleanup to run every 24h for sessions older than 37 days
- Modify OAuth flow to store refresh tokens after successful authentication
- Track client IP and user agent for session security validation
- Link OAuth sessions to user sessions via session ID
- Add comprehensive encryption tests with security validations
- Integrate SessionWorker into server lifecycle with graceful shutdown
This enables persistent OAuth sessions with secure token storage,
reducing the need for frequent re-authentication from 7 to 30 days.
Major refactoring to modernize the application architecture:
Backend changes:
- Restructure API with v1 versioning and modular handlers
- Add comprehensive OpenAPI specification
- Implement RESTful endpoints for documents, signatures, admin
- Add checksum verification system for document integrity
- Add server-side runtime injection of ACKIFY_BASE_URL and meta tags
- Generate dynamic Open Graph/Twitter Card meta tags for unfurling
- Remove legacy HTML template handlers
- Isolate backend source on dedicated folder
- Improve tests suite
Frontend changes:
- Migrate from Go templates to Vue.js 3 SPA with TypeScript
- Add Tailwind CSS with shadcn/vue components
- Implement i18n support (fr, en, es, de, it)
- Add admin dashboard for document and signer management
- Add signature tracking with file checksum verification
- Add embed page with sign button linking to main app
- Implement dark mode and accessibility features
- Auto load file to compute checksum
Infrastructure:
- Update Dockerfile for SPA build process
- Simplify deployment with embedded frontend assets
- Add migration for checksum_verifications table
This enables better UX, proper link previews on social platforms,
and provides a foundation for future enhancements.
- Add documents with metadata (title, URL, checksum, description)
- Add metadata UI section in document details
- Replace JavaScript alerts/confirms with modern modal dialogs
- Make email language dynamic based on user's interface language
Enable admins to send reminder emails to expected signers who haven't signed yet.
This addresses the need to follow up with pending signers without manual tracking.
- Add reminder_logs table to track all email sends (success and failures)
- Implement ReminderService with SMTP integration
- Extend admin dashboard with reminder stats and send interface
- Support bulk send (all pending) or selective send (manual selection)
- Track reminder count and last sent date per signer
- Change terminology from "signature" to "lecture/confirmation de lecture" across all templates and emails
- Added a unified horizontal navigation menu in the header
- Redesigned the user/logout button into a single element
- Reversed priority for extracting OIDC names (name > preferred_username)
- Admin: display documents with/without expected signatures
- Admin: detailed badges “X signatures (+Y) out of Z”
- Admin: modal for adding expected signers
- Admin: display additional signatures in stats
- Simplification of expected signers table display
- Validation pattern for document creation
- Removal of redundant links in templates
- New, clearer dashboard showing the status of each document
- The administrator can create a list of expected signatures for a given document.
- The administrator can manage the list of users who must confirm that they have read the document
Add SMTP configuration section to both English and French README files:
- Optional email notifications setup with ACKIFY_MAIL_* variables
- SMTP configuration examples for development and production
- Architecture diagram updated with email/ infrastructure component
- Technology stack updated to include SMTP service
Add configurable SMTP service for sending signature reminder emails.
Features:
- Configurable via ACKIFY_MAIL_* environment variables
- Multilingual templates (en/fr) with HTML + text versions
- Template rendering with automatic variable injection
- Graceful degradation when SMTP not configured
- TLS/STARTTLS support with configurable timeout
- MailHog integration for local testing