File DB

File Chunking Middleware for Arkiv

Store Any File on Arkiv

A production-ready middleware with JWT authentication, Redis sessions, and secure file chunking for Arkiv. Perfect for documents, media, archives, and any file type.

🔐
JWT Authentication
Role-based access control
Redis Sessions
Scalable session storage
🚀
Production Ready
Docker deployment

Why File DB?

Built for developers who need reliable file storage on Arkiv

Universal File Support

Upload any file type up to 10MB. Documents, images, videos, archives - all automatically chunked into 16KB pieces.

Data Integrity

SHA-256 checksums ensure your files are retrieved exactly as uploaded, with full integrity verification.

Idempotent Uploads

Resume failed uploads and prevent duplicates with built-in idempotency keys and session management.

TTL Management

Set custom expiration times for your files. Default 7-day TTL for free tier, extendable with wallet mode.

Rate Limiting

Built-in quota management with 500MB storage and 50 uploads per day on the free tier.

Simple API

RESTful API with straightforward endpoints. Upload with POST, retrieve with GET, monitor with status endpoints.

Getting Started

Get up and running in minutes

1. Run with Docker

docker run -p 3000:3000 moonplkr/filesdb:latest

2. Upload a File

curl -X POST http://localhost:3000/files \
  -F "file=@document.pdf" \
  -H "Idempotency-Key: unique-key-123"

3. Retrieve Your File

curl http://localhost:3000/files/YOUR_FILE_ID \
  -o retrieved-file.pdf

JavaScript SDK

Download our lightweight JavaScript SDK for easy integration

Download SDK (2KB)
import FileDB from './filesdb-sdk.js';

const client = new FileDB('http://localhost:3000');

// Login and get token
const loginResult = await client.login('user@example.com', 'password');
console.log('Token:', loginResult.accessToken);

// Upload file with authentication
const result = await client.upload(file, {
  idempotencyKey: 'unique-key',
  ttlDays: 30
});

// Or set token manually
client.setAccessToken('your-jwt-token');
const file = await client.get('file-id-here');

console.log('File ID:', result.file_id);

// Retrieve file
const fileBlob = await client.get(result.file_id);
const fileUrl = URL.createObjectURL(fileBlob);

Response Format

{
  "file_id": "6bc95b27-1a5d-46e7-96e7-8edde7de5c70",
  "message": "Upload successful"
}

🔐 Authentication

JWT-based authentication with role-based access control

🔑 JWT Authentication

  • • Access tokens (24h expiry)
  • • Refresh tokens (7d expiry)
  • • Role-based permissions
  • • Secure token verification

👥 User Roles

User: upload, download, list, quota
Admin: all user permissions + delete, admin access

User Registration

Request

POST /auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securepassword123",
  "role": "user"
}

Response

{
  "message": "User registered successfully",
  "user": {
    "userId": "user_123...",
    "email": "user@example.com",
    "role": "user",
    "permissions": ["upload:files", "download:files", ...]
  },
  "accessToken": "eyJhbGciOiJ...",
  "refreshToken": "eyJhbGciOiJ...",
  "expiresIn": "24h",
  "tokenType": "Bearer"
}

User Login

POST /auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securepassword123"
}
{
  "message": "Login successful",
  "user": { ... },
  "accessToken": "eyJhbGciOiJ...",
  "refreshToken": "eyJhbGciOiJ...",
  "expiresIn": "24h",
  "tokenType": "Bearer"
}

Using Authentication

Include the JWT token in the Authorization header for protected endpoints:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

API Reference

Complete API documentation

POST /files

Upload a file to the service

Headers

  • Idempotency-Key (optional) - Unique key for upload session
  • BTL-Days (optional) - Time to live in days (default: 7)

Form Data

  • file - Any file type (max 10MB)

Response

HTTP 200 OK
Content-Type: application/json

{
  "file_id": "uuid-string",
  "message": "Upload successful"
}
GET /files/{file_id}

Retrieve an uploaded file by its file ID

Response

HTTP 200 OK
Content-Type: [original-mime-type]
Content-Length: file-size
Content-Disposition: inline; filename="original-name.ext"

[Binary file data]
GET /files/{file_id}/info

Get file metadata without downloading

Response

{
  "file_id": "uuid-string",
  "original_filename": "document.pdf",
  "content_type": "application/pdf",
  "file_extension": "pdf",
  "total_size": 1048576,
  "created_at": "2024-01-01T00:00:00Z"
}
GET /quota

Check current quota usage

Response

{
  "used_bytes": 1048576,
  "max_bytes": 524288000,
  "uploads_today": 3,
  "max_uploads_per_day": 50,
  "usage_percentage": "0.20"
}
GET /status/{idempotency_key}

Check upload session status

Response

{
  "file_id": "uuid-string",
  "completed": true,
  "chunks_received": 15,
  "total_chunks": 15
}

Try the Demo

Upload any file and see the chunking in action