Commit Graph

105 Commits

Author SHA1 Message Date
Benjamin
cff602c812 fix(tests): update OAuth tests to use correct signature URL path
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)
2025-11-06 01:15:45 +01:00
Benjamin
7b1f69ade6 fix(email): correct signature reminder URL path
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
2025-11-06 01:09:44 +01:00
Benjamin
2dd7d8686c fix(email): correct SMTP TLS/STARTTLS configuration for Gmail
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.
2025-11-06 00:05:16 +01:00
Benjamin
d3f7aa4853 fix(install): always write auth method enabled flags to .env
- 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.
2025-11-05 23:48:12 +01:00
Benjamin
e71528a76b fix(install): correct mail template directory path
Change ACKIFY_MAIL_TEMPLATE_DIR from 'templates/emails' to 'templates'
to match actual directory structure where templates are in /app/templates.
2025-11-05 23:44:42 +01:00
Benjamin
4269b66c18 fix: add ACKIFY_ prefix to all variables in .env.example files
Update both .env.example files to use correct variable names:

Root .env.example:
- Remove obsolete APP_NAME and APP_DNS variables
- Add ACKIFY_DB_DSN example
- Add ACKIFY_ADMIN_EMAILS section
- Remove deprecated ACKIFY_TEMPLATES_DIR

install/.env.example:
- Fix all variable names to use ACKIFY_ prefix
- Update OAuth variables (PROVIDER, CLIENT_ID, etc.)
- Update Mail/SMTP variables (HOST, PORT, USERNAME, etc.)
- Update Auth variables (AUTH_OAUTH_ENABLED, AUTH_MAGICLINK_ENABLED)
- Update Admin variables (ADMIN_EMAILS)
- Update all references in comments and instructions
2025-11-05 23:41:00 +01:00
Benjamin
c13ce508c7 fix(install): add all missing env variables to 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.
2025-11-05 23:38:20 +01:00
Benjamin
4386a02a8c fix(install): generate hex password to avoid URL encoding issues
Use openssl rand -hex instead of -base64 for database password to prevent
special characters (/, +, =) from breaking the DSN URL parsing
2025-11-05 22:35:28 +01:00
Benjamin
12ef046bea fix(install): add missing env variables and fix key name
- 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
2025-11-05 22:25:43 +01:00
Benjamin
6efb1b6aba fix(install): improve domain extraction and password input
- 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
2025-11-05 22:24:39 +01:00
Benjamin
10d3406a80 fix(install): use domain instead of DNS for email addresses
Extract APP_DOMAIN from APP_DNS (removing subdomain and port) and use it
for default email addresses (noreply@domain.com, admin@domain.com) instead
of using the full DNS (noreply@subdomain.domain.com).
2025-11-05 22:16:42 +01:00
Benjamin
fa85dba6e2 fix(install): add ACKIFY_ prefix to all environment variables
Corrects all environment variable names in the installation script to match
the expected configuration format. Adds missing ACKIFY_DB_DSN variable.
2025-11-05 22:11:21 +01:00
Benjamin
2209f13006 fix(e2e): wait for page reload in rate limiting test
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.
2025-11-05 21:48:46 +01:00
Benjamin
264f3d40d5 fix(e2e): copy webapp/dist to backend embed location before build
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.
2025-11-05 21:17:04 +01:00
Benjamin
bba992102b fix: copy locales and templates for e2e-tests GitHub Actions workflow
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.
2025-11-05 21:02:26 +01:00
Benjamin
c88508897f fix: github actions tests runs 2025-11-05 20:43:13 +01:00
Benjamin
b45d332c26 fix: migrations path in e2e-tests.yml workflow 2025-11-05 17:51:55 +01:00
Benjamin
b867acb61d feat: improve install script + installation readme 2025-11-05 17:17:55 +01:00
Benjamin
32b469f04e feat: add magic link authentication
- 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)
2025-11-05 15:01:23 +01:00
Benjamin
f4b3430f06 feat(document): improve better title extraction v1.2.0 2025-10-28 00:06:18 +01:00
Benjamin
3dad2f1d51 feat(doc): update changelog 2025-10-27 23:55:17 +01:00
Benjamin
289f8cd53b fix(embed): add middleware to authorize embed create document (with hard rate limit) 2025-10-27 23:24:07 +01:00
Benjamin
9ad267a704 feat(ci): fix push only release to latest tag on dockerhub 2025-10-27 19:20:59 +01:00
Benjamin
44c8cbef04 feat(vers): add version number to front 2025-10-27 18:34:27 +01:00
Benjamin
a3fbcee448 feat(footer): update footer visibility 2025-10-27 17:36:37 +01:00
Benjamin
925d363ac3 feat(webhook): ajout de la prise en charge des webhooks signés
- 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
2025-10-27 15:11:06 +01:00
Benjamin
77018a975d feat: improve build stage 2025-10-26 22:44:30 +01:00
Benjamin
714f122cfa fix: missing database integration test 2025-10-26 21:52:32 +01:00
Benjamin
c5e41e9e93 fix: split unit and integration coverage 2025-10-26 18:47:54 +01:00
Benjamin
ee02df0287 fix: use random hex for test database names to prevent collisions
- 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.)
2025-10-26 16:21:43 +01:00
Benjamin
8ca23ce736 fix: ensure migrations directory is found in CI tests
- 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
2025-10-26 13:57:06 +01:00
Benjamin
2410653f63 fix: integrations tests concurency + missing column due a hardcoded database struct (removed) 2025-10-26 13:37:40 +01:00
Benjamin
c738763ac3 fix: integrations tests concurency 2025-10-26 11:37:41 +01:00
Benjamin
7291c1083b fix: makefile to make coverage-all on 2 stage unit and then integration 2025-10-26 02:45:53 +02:00
Benjamin
68426bc882 feat: add PKCE support to OAuth2 flow for enhanced security
- 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.
2025-10-26 02:32:10 +02:00
Benjamin
e95185f9c7 feat: migrate to Vue.js SPA with API-first architecture
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.
2025-10-26 02:32:10 +02:00
Benjamin Touchard
e22fe5d9ea Create FUNDING.yml
Add Patreon username
2025-10-15 14:05:50 +02:00
Benjamin
4ac19a7fde docs: update README(_FR).md and CHANGELOG.md v1.1.3 2025-10-08 15:28:55 +02:00
Benjamin
58382309bb fix: Add missing files 2025-10-08 15:08:18 +02:00
Benjamin
d18f401797 feat: add document metadata management system
- 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
2025-10-08 14:57:57 +02:00
Benjamin
6e12fb69ed feat: add email reminder system for pending signers
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
2025-10-08 00:57:04 +02:00
Benjamin
af3ab1f54a feat: improved UX navigation and admin dashboard
- 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
2025-10-06 23:38:23 +02:00
Benjamin
5e74921ee7 feat: admin dashboard document request signatures
- 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
2025-10-06 23:34:01 +02:00
Benjamin
54d6de8090 docs: update README with SMTP email service configuration
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
2025-10-06 14:48:03 +02:00
Benjamin
2c24c3f2f6 feat: add SMTP email service with signature reminders
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
2025-10-06 14:07:09 +02:00
Benjamin
0015af12e1 feat: add silent OAuth login with auto-authentication
- Add ACKIFY_OAUTH_AUTO_LOGIN config flag (default: false)
- Implement /api/auth/check endpoint for session validation
- Add silent login flow with prompt=none OAuth parameter
- Implement localStorage-based retry prevention (5min cooldown)
- Add comprehensive OAuth flow debugging logs
- Handle OAuth errors gracefully (login_required, interaction_required)
- Update templates with silent login JavaScript
- Add login button in header when not authenticated
- Fix /health endpoint documentation (remove /healthz alias)
- Extend tests to include autoLogin parameter
2025-10-06 13:13:17 +02:00
Benjamin
b5b6ddaaf7 set changelog for tracking 2025-10-06 13:02:13 +02:00
Benjamin
296010c0aa feat: add SSO provider logout support
When users click logout, they are now redirected to the SSO provider's
logout endpoint to ensure complete session termination. This prevents
users from remaining logged in at the provider level after logging out
of the application.

Changes:
- Add LogoutURL configuration for OAuth providers (Google, GitHub, GitLab)
- Implement GetLogoutURL method with post-logout redirect parameter
- Update HandleLogout to redirect to SSO logout when configured
- Add ACKIFY_OAUTH_LOGOUT_URL environment variable for custom providers
- Add tests for both local and SSO logout scenarios
v1.1.2
2025-10-03 15:47:19 +02:00
Benjamin
2583482198 fix: isolate blockchain chains per document
Each document now maintains its own independent blockchain chain
with its own genesis signature. GetLastSignature now filters by
doc_id to prevent cross-document chain corruption.

Changes:
- Add docID parameter to GetLastSignature interface and implementation
- Update SQL query to filter by document ID
- Add comprehensive test for multi-document blockchain isolation
- Update all test mocks and integration tests
2025-10-03 15:47:09 +02:00
Benjamin
0ce076bd3a refactor: separate template variables from locale strings
Move all template variables out of locale JSON files into separate keys.
Update templates to concatenate locale strings with dynamic values.
Replace inline conditionals with proper locale key lookups for pluralization.
v1.1.1
2025-10-02 22:34:36 +02:00