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
5.7 KiB
Document Storage
Upload and store documents directly in Ackify.
Overview
Ackify supports optional document storage, allowing users to upload files directly instead of providing external URLs. Documents are stored securely and served through authenticated API endpoints.
Storage options:
- Disabled (default) - Users provide document URLs
- Local filesystem - Documents stored on the server
- S3-compatible - AWS S3, MinIO, Wasabi, DigitalOcean Spaces, etc.
Supported File Types
| Type | Extensions | MIME Types |
|---|---|---|
.pdf |
application/pdf |
|
| Images | .png, .jpg, .jpeg, .gif, .webp |
image/* |
| Office | .doc, .docx |
application/msword, application/vnd.openxmlformats-* |
| Text | .txt |
text/plain |
| HTML | .html, .htm |
text/html |
Configuration
Local Storage
Store documents on the server filesystem using a Docker volume.
ACKIFY_STORAGE_TYPE=local
ACKIFY_STORAGE_LOCAL_PATH=/data/documents
ACKIFY_STORAGE_MAX_SIZE_MB=50
Docker Compose volume:
services:
ackify-ce:
volumes:
- ackify_storage:/data/documents
volumes:
ackify_storage:
S3-Compatible Storage
Works with any S3-compatible storage provider.
ACKIFY_STORAGE_TYPE=s3
ACKIFY_STORAGE_MAX_SIZE_MB=50
ACKIFY_STORAGE_S3_ENDPOINT=https://s3.amazonaws.com
ACKIFY_STORAGE_S3_BUCKET=ackify-documents
ACKIFY_STORAGE_S3_ACCESS_KEY=your_access_key
ACKIFY_STORAGE_S3_SECRET_KEY=your_secret_key
ACKIFY_STORAGE_S3_REGION=us-east-1
ACKIFY_STORAGE_S3_USE_SSL=true
MinIO (Self-hosted S3)
MinIO is a popular open-source S3-compatible storage solution.
ACKIFY_STORAGE_TYPE=s3
ACKIFY_STORAGE_S3_ENDPOINT=http://minio:9000
ACKIFY_STORAGE_S3_BUCKET=ackify-documents
ACKIFY_STORAGE_S3_ACCESS_KEY=minioadmin
ACKIFY_STORAGE_S3_SECRET_KEY=minioadmin
ACKIFY_STORAGE_S3_REGION=us-east-1
ACKIFY_STORAGE_S3_USE_SSL=false
Docker Compose with MinIO:
services:
minio:
image: minio/minio:latest
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio_data:/data
ports:
- "9000:9000"
- "9001:9001"
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 10s
timeout: 5s
retries: 5
volumes:
minio_data:
Usage
User Interface
When storage is enabled, an upload button appears next to the document URL input:
- Click the upload button (or drag & drop)
- Select a file from your computer
- The file name and size are displayed
- Click "Upload" to submit
Features:
- Progress bar during upload
- Automatic title from filename
- File type validation
- Size limit enforcement
API Endpoints
Upload Document
POST /api/v1/documents/upload
Content-Type: multipart/form-data
X-CSRF-Token: abc123
file: (binary)
title: Optional document title
Response:
{
"success": true,
"data": {
"doc_id": "abc123",
"title": "document.pdf",
"storage_key": "abc123/document.pdf",
"storage_provider": "local",
"file_size": 1048576,
"mime_type": "application/pdf",
"checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"checksum_algorithm": "SHA-256",
"created_at": "2025-01-07T12:00:00Z",
"is_new": true
}
}
Get Document Content
GET /api/v1/storage/{docId}/content
Returns the document file with appropriate Content-Type header.
Note: Requires authenticated session.
Security
Authentication
- All storage endpoints require authentication
- Documents are only accessible to authenticated users
- CSRF protection on upload endpoint
Checksum Verification
- SHA-256 checksum calculated automatically on upload
- Stored in document metadata
- Ensures file integrity
File Validation
- File type checked against allowed MIME types
- File size validated against
ACKIFY_STORAGE_MAX_SIZE_MB - Filename sanitized to prevent path traversal
Database Schema
Uploaded documents add fields to the documents table:
ALTER TABLE documents ADD COLUMN storage_key TEXT;
ALTER TABLE documents ADD COLUMN storage_provider TEXT;
ALTER TABLE documents ADD COLUMN file_size BIGINT;
ALTER TABLE documents ADD COLUMN mime_type TEXT;
Best Practices
Storage Selection
| Scenario | Recommended Storage |
|---|---|
| Single server deployment | Local |
| Multiple servers / scaling | S3 |
| Air-gapped environment | Local |
| Cloud-native deployment | S3 |
| Development / testing | Local or MinIO |
Backup
Local storage:
- Include
ackify_storagevolume in backup strategy - Use
docker-volume-backupor similar tools
S3 storage:
- Configure bucket versioning
- Enable cross-region replication if needed
- Use bucket lifecycle policies for retention
Performance
- Enable S3 SSL in production (
ACKIFY_STORAGE_S3_USE_SSL=true) - Use regional S3 endpoints for lower latency
- Consider CDN for frequently accessed documents
Limitations
- Maximum file size: configurable, default 50MB
- No virus scanning (implement at infrastructure level)
- No document preview generation
- No automatic compression
Troubleshooting
Upload fails with "Storage not configured"
Ensure ACKIFY_STORAGE_TYPE is set to local or s3.
S3 connection errors
- Verify endpoint URL format (include
http://orhttps://) - Check access key and secret key
- Verify bucket exists and is accessible
- Check SSL setting matches endpoint
File too large error
Increase ACKIFY_STORAGE_MAX_SIZE_MB or reduce file size.
Permission denied (local storage)
Ensure the container has write access to the storage path:
docker exec ackify-ce ls -la /data/documents