Files
p2ns/plugin-sites/file.drop
2026-05-30 22:27:42 -04:00
..
2026-05-30 21:01:31 -04:00
2026-05-30 17:21:25 -04:00
2026-05-30 22:27:42 -04:00
2026-05-30 22:27:42 -04:00

File Drop

A P2NS plugin for temporary, peer-to-peer file sharing. Upload a file, get a link, share it. Files automatically expire after 24 hours.

Features

  • 24-Hour Expiration: Files are automatically deleted after 24 hours
  • Destroy on Download: Optional one-time download - file is deleted after first download
  • Peer-to-Peer: Files are stored in Hyperdrive and replicated across the P2NS network
  • No Size Limits: Limited only by your storage (though large files take longer to replicate)
  • Shareable Links: Each upload gets a unique link like /d/abc123def
  • Modern UI: Clean, responsive dark theme interface

How It Works

Architecture

File Drop uses two P2NS data stores:

  1. Hyperdrive (uploads): Stores the actual file data

    • Each peer has their own writable drive
    • Files are replicated to other peers on demand
  2. HyperDB (@filedrop/files): Stores file metadata

    • File ID, name, size, MIME type
    • Upload timestamp and expiration time
    • Drive key (so other peers know where to find the file)
    • Destroy-on-download flag

Upload Flow

  1. User uploads a file via the web interface
  2. File is written to the local Hyperdrive
  3. Metadata (including the drive key) is stored in HyperDB
  4. HyperDB replicates metadata to all peers
  5. User receives a shareable link

Download Flow

  1. User visits the download link
  2. Plugin looks up file metadata in HyperDB
  3. If the file is local, reads from local drive
  4. If the file is remote, opens the uploader's drive by key and fetches
  5. If "destroy on download" is enabled, file is deleted after serving

API Endpoints

POST /api/upload

Upload a file. Accepts multipart/form-data.

Form Fields:

  • file (required): The file to upload
  • destroyOnDownload (optional): Set to "true" to delete after first download

Response:

{
  "success": true,
  "id": "abc123def",
  "filename": "document.pdf",
  "size": 102400,
  "mimeType": "application/pdf",
  "expiresAt": 1702684800000,
  "destroyOnDownload": false,
  "link": "/d/abc123def"
}

GET /api/download/:id

Download a file by ID. Returns the file with appropriate Content-Type and Content-Disposition headers.

GET /api/file/:id

Get file metadata without downloading.

Response:

{
  "id": "abc123def",
  "filename": "document.pdf",
  "size": 102400,
  "mimeType": "application/pdf",
  "uploadedAt": 1702598400000,
  "expiresAt": 1702684800000,
  "expiresIn": 86400000,
  "isLocal": true
}

GET /api/files

List all active (non-expired) files.

Response:

{
  "files": [...],
  "count": 5
}

GET /d/:id

Human-friendly download page with file info and download button.

Configuration

The plugin is configured via config.json:

{
  "name": "File Drop",
  "version": "1.0.8",
  "domain": "file.drop",
  "enabled": true,
  "www": "www",
  "hyperdb": {
    "schemas": {
      "namespace": "filedrop",
      "structs": [
        {
          "name": "files",
          "fields": [
            { "name": "id", "type": "string", "required": true },
            { "name": "filename", "type": "string", "required": true },
            { "name": "size", "type": "uint", "required": true },
            { "name": "mimeType", "type": "string", "required": true },
            { "name": "driveKey", "type": "string", "required": true },
            { "name": "destroyOnDownload", "type": "bool", "required": false },
            { "name": "uploadedAt", "type": "uint", "required": true },
            { "name": "expiresAt", "type": "uint", "required": true }
          ]
        }
      ]
    },
    "collections": [
      {
        "name": "files",
        "schema": "@filedrop/files",
        "key": ["id"]
      }
    ]
  }
}

File Structure

file.drop/
├── config.json      # Plugin configuration and HyperDB schema
├── index.js         # Backend logic (upload, download, cleanup)
├── README.md        # This file
├── www/
│   ├── index.html   # Upload interface
│   └── css/
│       └── style.css
├── db/              # HyperDB data (auto-generated)
├── drives/          # Hyperdrive data (auto-generated)
└── spec/            # Generated HyperDB schema files

Usage

  1. Navigate to https://file.drop (or your configured internal domain)
  2. Drag and drop a file, or click "Choose File"
  3. Optionally check "🔥 Destroy after download" for one-time links
  4. Share the generated link
  5. Recipients can download until the file expires or is destroyed

Notes

  • Files uploaded on one peer are accessible to other peers via Hyperdrive replication
  • The uploader's peer must be online for remote peers to download (unless the file has been cached)
  • Cleanup runs hourly to remove expired files
  • The "destroy on download" feature only works when downloaded from the uploader's peer
  • This plugin is skipped on master nodes ("disable_on_master": true in config.json)

License

MIT