53 Commits

Author SHA1 Message Date
Benjamin
bff75aafbe fix: persist options when uploading documents & dynamic config OnlyAdminCanCreate
Reader options (readMode, allowDownload, requireFullRead, verifyChecksum)
were not being saved during document upload.

SimpleAuthorizer now reads the setting dynamically from ConfigService
instead of using a static value set at startup. This allows admins to
toggle document creation permissions via the settings UI without
requiring a server restart.

Fixes #14
Fixes #15
2026-01-22 15:14:13 +01:00
Benjamin
37d023a80d fix: missing traductions & docker hub push provenance 2026-01-20 15:40:38 +01:00
Benjamin
12169ba7e0 docs: readme screenshot 2026-01-20 14:57:26 +01:00
Benjamin
122eb42f2a fix: missing translation 2026-01-20 13:20:05 +01:00
Benjamin
8a0d79ac65 fix: user document allocation
refacto: vue components extract, sign & reminder list, align tests to new components
2026-01-20 09:54:36 +01:00
Benjamin
de1d9cd5e5 doc: add missing env to .env.example 2026-01-19 00:10:12 +01:00
Benjamin
998d227898 refacto(backend): cleaning dead code 2026-01-17 01:49:41 +01:00
Benjamin
b0ef28b0ae refactor(config): replace window variables with /api/v1/config endpoint
- Add new config handler to serve public app configuration
- Create Pinia config store to load and cache configuration
- Remove window variable injection from static.go and index.html
- Update all components to use config store instead of window vars
- Remove deprecated /api/v1/auth/config endpoint (merged into /config)
- Update Cypress tests with proper type annotations
2026-01-16 01:04:53 +01:00
Benjamin
c4133c4017 test(cypress): update embed page tests for i18n changes
Update test assertions to match new terminology:
- "Sign this document" → "Confirm this document"
- "No signatures" → "No confirmations"
2026-01-15 15:45:37 +01:00
Benjamin
50fcd815ec feat(webapp): improve error handling with translated messages
- Add extractErrorDetails() to get both error code and message
- Use error codes to show appropriate translated messages in DocumentCreateForm
- Add translation keys for auth and permission errors
2026-01-15 15:45:31 +01:00
Benjamin
7689c26608 refactor(auth): load auth config from API instead of window variables
Replace static window variables (ACKIFY_OAUTH_ENABLED, ACKIFY_MAGICLINK_ENABLED)
with dynamic API call to /api/v1/auth/config. This allows auth methods to be
changed without rebuilding the frontend and supports dynamic tenant configuration.
2026-01-15 15:45:26 +01:00
Benjamin
82b695baeb Merge branch 'feat/reader'
# Conflicts:
#	install/compose.yml
#	webapp/cypress/e2e/01-signature-workflow.cy.ts
#	webapp/cypress/e2e/02-signature-uniqueness.cy.ts
#	webapp/cypress/e2e/03-admin-signers-management.cy.ts
#	webapp/cypress/e2e/04-admin-email-reminders.cy.ts
#	webapp/cypress/e2e/06-my-signatures-page.cy.ts
#	webapp/cypress/e2e/07-admin-document-deletion.cy.ts
#	webapp/cypress/e2e/08-admin-route-protection.cy.ts
#	webapp/cypress/e2e/09-complete-workflow.cy.ts
#	webapp/cypress/e2e/10-unexpected-signatures.cy.ts
#	webapp/cypress/e2e/13-embed-page.cy.ts
#	webapp/cypress/e2e/14-csv-preview.cy.ts
#	webapp/src/components/DocumentForm.vue
#	webapp/src/components/layout/AppHeader.vue
#	webapp/src/locales/de.json
#	webapp/src/locales/es.json
#	webapp/src/locales/it.json
#	webapp/src/pages/EmbedPage.vue
#	webapp/src/pages/HomePage.vue
#	webapp/src/pages/admin/AdminDashboard.vue
#	webapp/src/pages/admin/AdminDocumentDetail.vue
#	webapp/tests/components/SignButton.test.ts
2026-01-14 22:25:27 +01:00
Benjamin
fb33fd424d refactor: consolidate dependency injection and improve auth architecture
- Move service initialization (MagicLink, Email, i18n) to main.go
- Change signature lookup from user_sub to email for cross-auth consistency
- Remove OauthService wrapper, simplify auth layer
- Pass parent context to workers for graceful shutdown
- Fix IP extraction from RemoteAddr with port
- Add compact mode to SignatureList component
- Update Cypress tests with new data-testid attributes
2026-01-14 12:34:11 +01:00
Benjamin
9b28f78ce9 feat(admin): add tenant configuration UI with hot-reload support
Add admin settings page allowing runtime configuration of:
- SMTP settings with connection testing
- OIDC/OAuth2 authentication with validation
- S3 storage configuration with connectivity check

Backend includes config service with atomic hot-reload,
encrypted secrets storage, and environment seeding on startup.
2026-01-12 22:46:04 +01:00
Benjamin
a272cc7de9 feat(storage): improve MIME type detection and add ODF format support
- Add extension-based MIME type refinement for text formats (.md, .docx, .xlsx, .odt, .ods)
- Add charset=utf-8 for text-based MIME types in Content-Type header
- Support ODF formats (OpenDocument Text/Spreadsheet)
- Unify compose templates into single compose.yml.template with region markers
- Add update mode to install script to preserve existing configuration
- Extend file upload accept list in DocumentCreateForm
- Remove binary file from repository
2026-01-08 23:16:54 +01:00
Benjamin
fb9dab2f0f feat: add document storage and integrated PDF viewer
Storage:
- Add S3 and local storage providers for document uploads
- Support file upload with checksum calculation
- Fix S3 upload for non-TLS connections (MinIO)

Document viewer:
- Add PDF.js-based viewer with scroll tracking
- Implement checksum verification on document load
- Add reader options (read mode, download, require full read)
- Auto-detect read completion for signed documents

API:
- Add document upload endpoint with storage integration
- Add proxy endpoint for stored documents
- Extend document metadata with storage and reader fields
2026-01-08 20:39:34 +01:00
Benjamin
c887305b7a feat: improve e2e with data-testid for futur ui evolution 2025-12-29 21:52:13 +01:00
Benjamin
29d8012c22 feat: improvement of user name display 2025-12-29 16:00:25 +01:00
Benjamin
c2c096dd3c wip 2025-12-27 22:16:54 +01:00
Benjamin
e4521d87c7 feat(webapp): UI redesign with Technical Trust design system
- New design system (IBM Plex fonts, slate palette, dark mode)
- Complete refactor of components and pages
- Add favicon, PWA icons and new logo
- Minor fixes (null handling, translations, navigation)
2025-12-23 11:31:16 +01:00
Benjamin
44431dabf4 feat(rls): move ackify_app role creation from init script to migrate tool
BREAKING CHANGE: ACKIFY_APP_PASSWORD environment variable is now required for RLS support. The migrate tool creates the ackify_app role before running migrations, ensuring compatibility with existing deployments.

Changes:
- Add ensureAppRole() in cmd/migrate to create/update ackify_app role
- Remove docker/init-scripts/01-create-app-user.sh (no longer needed)
- Update compose.yml: add ACKIFY_APP_PASSWORD, backend connects as ackify_app
- Update migration 0016: remove conditional role creation
- Add RLS documentation (docs/en/configuration/rls.md, docs/fr/configuration/rls.md)
- Update configuration docs with RLS section and security checklist

Migration path for existing deployments:
1. Set ACKIFY_APP_PASSWORD in .env
2. Run docker compose up (migrate will create the role automatically)
2025-12-15 23:59:06 +01:00
Benjamin
eca55c6bcb refactor(go): restore go.mod (and sum) on project root
and restore missing cypress tests
2025-12-10 16:29:00 +01:00
Benjamin
796d327442 feat(tenant): add tenant support
- Add instance_metadata table with unique UUID per instance
- Add tenant_id column to all business tables (documents, signatures, expected_signers, webhooks, reminder_logs, email_queue, checksum_verifications, webhook_deliveries)
- Backfill existing data with instance tenant UUID
- Create TenantProvider interface and SingleTenantProvider implementation
- Update all repositories to filter by tenant_id
- Add immutability triggers to prevent tenant_id modification after creation

Migration 0015 includes:
- Schema changes with indexes for tenant_id columns
- SQL backfill for existing data
- Trigger functions for data integrity
2025-12-03 23:46:09 +01:00
Benjamin
6d2dd8b000 feat(e2e): fix 05-document-creation-by-url 2025-12-03 13:54:22 +01:00
Benjamin
686edc6123 feat(mail): fix mail suject alway in english, now is based on i18n 2025-12-03 12:21:44 +01:00
Benjamin
aa002f824c feat(db): improve db migrations system with force & goto command (for existing db without migration schema) 2025-12-03 11:01:23 +01:00
Benjamin
533e62fcfe feat(csv): import expected signature from CSV 2025-11-26 23:37:21 +01:00
Benjamin
d91c40edef fix(deps): revert glob and rimraf overrides to fix nyc@15 compatibility
Remove glob and rimraf from overrides to use versions compatible with nyc@15.
This accepts deprecated warnings for glob@7 and rimraf@3, but ensures
@cypress/code-coverage works correctly for E2E test coverage.

Keep inflight override to eliminate that specific warning.
2025-11-24 11:09:40 +01:00
Benjamin
253b26511a fix(ci): patch nyc@15 to handle glob@10+ and rimraf@5+
Add postinstall script that patches nyc/index.js to handle modern versions
of glob and rimraf. These packages now export objects/named exports instead
of functions, which breaks nyc@15's promisify() calls.

This fixes the 'original argument must be of type function' error.

# Conflicts:
#	webapp/scripts/patch-nyc.cjs
2025-11-24 11:02:53 +01:00
Benjamin
825705b036 fix(ci): patch nyc@15 to fix Node.js 20+ promisify compatibility
Add postinstall script that patches nyc@15 fs-promises.js to handle
promisify errors gracefully. This fixes the 'original argument must be
of type function' error when running Cypress E2E tests with coverage.
2025-11-24 10:32:10 +01:00
Benjamin
aae9ab111a fix(build): suppress vue-i18n currentInstance warning
Add Rollup onwarn handler to filter the known MISSING_EXPORT warning
where vue-i18n accesses internal Vue APIs (currentInstance).
This is a known compatibility issue that doesn't affect runtime behavior.
2025-11-24 09:44:56 +01:00
Benjamin
f842aedf11 fix(deps): eliminate deprecated npm dependencies
Use npm overrides to force modern versions:
- glob: v7.2.3 → v10.5.0
- rimraf: v3.0.2 → v5.0.10
- inflight: replaced (no longer needed with glob v10+)

This eliminates all deprecation warnings during npm install.
2025-11-24 09:41:02 +01:00
Benjamin
050351620c fix(i18n): handle literal dots in translation keys
The check-i18n script now correctly handles keys with literal dots
(e.g., 'document.created') instead of treating them as nested paths.
2025-11-24 09:33:46 +01:00
Benjamin
41e18c914f test(frontend): add comprehensive unit tests for stores, services and components
Add business logic tests to improve frontend code coverage and reliability:
- Pinia stores: auth, signatures, ui (87 tests)
- Services: checksumCalculator (19 tests)
- Components: SignButton, NotificationToast (21 tests)

Focus on critical business flows: authentication, signature management,
notification system, and file validation. All tests passing (143 total).
2025-11-24 01:04:41 +01:00
Benjamin
a46715a2f3 fix: robust coverage calculation in test suite script
Fix bash arithmetic syntax error when calculating coverage percentages
from LCOV files. The issue occurred when grep results contained whitespace
or when values were empty strings.
2025-11-24 00:23:56 +01:00
Benjamin
a1c71a023c fix: enable Istanbul code instrumentation for E2E coverage
Fix Cypress code coverage collection by properly configuring vite-plugin-istanbul
to instrument code when CYPRESS_COVERAGE=true.
2025-11-23 23:50:19 +01:00
Benjamin
a7891618c1 feat: comprehensive CI/CD refactoring with unified code coverage
Reorganize GitHub Actions workflows into reusable components and implement
complete code coverage tracking across backend, frontend, and E2E tests.

**CI/CD Improvements:**
- Split monolithic ci.yml into 6 specialized reusable workflows
- New workflows: test-backend, test-frontend, test-e2e, build-docker, security, coverage-report
- Orchestrated execution with proper dependencies and parallel jobs
- Codecov integration with multi-flag coverage (backend/frontend/e2e)

**Frontend Testing:**
- Add Vitest for unit testing with coverage-v8 provider
- Create test setup with window mocks for Ackify globals
- Add 34 unit tests for titleExtractor, referenceDetector, and http utils
- Configure Istanbul instrumentation for E2E coverage collection
- Integrate @cypress/code-coverage for E2E test coverage

**Test Infrastructure:**
- Create run-tests-suite.sh for local comprehensive test execution
- Proper Docker Compose orchestration for integration and E2E tests
- Automatic cleanup handlers with trap for test environments
- Coverage summary aggregation across all test types

**Bug Fixes:**
- Fix backend config tests after OAuth/MagicLink validation changes
- Update tests from panic expectations to error checking
- Ensure OAUTH_COOKIE_SECRET is properly configured in tests

**Configuration:**
- Add .codecov.yml for coverage reporting with flags
- Add .nycrc.json for E2E LCOV generation
- Update .gitignore for test artifacts and coverage reports
- Configure Vite for test environment and code instrumentation
2025-11-23 23:36:02 +01:00
Benjamin
5cd91654e0 feat: configurable rate limiting and comprehensive E2E test suite
Rate Limiting Configuration:
- Add ACKIFY_AUTH_MAGICLINK_RATE_LIMIT_EMAIL (default: 3/hour)
- Add ACKIFY_AUTH_MAGICLINK_RATE_LIMIT_IP (default: 10/hour)
- Add ACKIFY_AUTH_RATE_LIMIT (default: 5/min)
- Add ACKIFY_DOCUMENT_RATE_LIMIT (default: 10/min)
- Add ACKIFY_GENERAL_RATE_LIMIT (default: 100/min)

E2E Test Suite:
- 01-signature-workflow: Complete signature flow validation
- 02-signature-uniqueness: Constraint enforcement and duplicate prevention
- 03-admin-signers-management: Expected signers CRUD operations
- 04-admin-email-reminders: SMTP reminder functionality
- 05-document-creation-by-url: URL-based document initialization
- 06-my-signatures-page: User signature list and navigation
- 07-admin-document-deletion: Cascade deletion verification
- 08-admin-route-protection: Access control validation
- 09-complete-workflow: End-to-end multi-user scenario
- 10-unexpected-signatures: Handling of non-expected signers
2025-11-23 22:27:55 +01:00
Benjamin
c579e95a67 feat(frontend): enable TypeScript strict mode for better type safety
Enable strict TypeScript compilation options in the Vue 3 frontend
to catch more potential bugs at compile time and improve code quality.
2025-11-23 01:06:44 +01:00
Benjamin
93d9e2e575 feat(search): implement full-text document search across public and admin APIs
Backend:
- Add Search() method to DocumentRepository for ILIKE pattern matching on doc_id, title, url, description
- Add Count() method to accurately count total matching documents (used for pagination)
- Update admin handler to support search query parameter with proper pagination
- Implement full public documents API with search support (previously stub)
- Update test mocks to include new repository methods

Frontend:
- Replace client-side filtering with server-side search in admin dashboard
- Add debounced search input (300ms delay) to reduce API calls
- Separate loading states: initial page load vs. search/pagination (prevents input focus loss)
- Add visual feedback: spinning loader icon in search field during active search
- Enable pagination during search (previously disabled)
- Pass search parameter to API service
2025-11-23 00:21:59 +01:00
Benjamin
da1f300d2d feat(admin): improve email reminders UX and fix signer deletion
Backend changes:
- Add SMTPEnabled flag to distinguish SMTP service from MagicLink authentication
- Fix URL-encoded email decoding in DELETE /signers/{email} endpoint
- Add detailed error logging for expected signer removal operations
- Initialize ReminderAsync and MagicLink services unconditionally
- Update config tests to reflect new MagicLink requires explicit enabling

Frontend changes:
- Add ACKIFY_SMTP_ENABLED window variable for feature detection
- Hide delete button for expected signers who have already signed
- Show email reminders card only when SMTP enabled or history exists
- Display informative alert when SMTP disabled but reminder history present
- Add i18n translations for email service disabled message (5 languages)

These changes improve admin experience by preventing invalid operations
(deleting signers who signed, sending emails without SMTP) and providing
clear feedback about feature availability.
2025-11-22 00:43:35 +01:00
Benjamin
34146fb02d fix(auth): enable logout for MagicLink users
- Move /logout route outside OAuth-only block to support both OAuth
and MagicLink authentication methods.

- Also fix notification icon alignment in AuthChoicePage.

- And add press-kit inside /docs
2025-11-08 00:02:35 +01:00
Benjamin
2ec9a8b13d Fix: Increment timeouts (5s -> 15s) for CI latency 2025-11-06 19:05:27 +01:00
Benjamin
aa5fee90f6 feat(admin): add option to restrict document creation to admins only
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.
2025-11-06 16:08:03 +01:00
Benjamin
a27f051838 feat(auth): implement reminder authentication tokens
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
2025-11-06 13:43:49 +01:00
Benjamin
d28283f6ed feat(webapp): complete i18n implementation and admin document input enhancement
- 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
2025-11-06 11:02:14 +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
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
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