Skip to content
theodorexliPublic

About

Secure PDF sharing with controlled access, analytics, and page comments

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Share

Introduction

Share is a secure file sharing platform that makes it easy to upload PDFs and share them with controlled access. Whether you need to share documents with specific people or make them publicly accessible, Share provides granular control over who can view, download, and comment on your files.

The platform transforms file sharing from a simple upload into a managed experience with analytics, email-gated access, customizable share links, and interactive commenting. Built on Cloudflare's serverless infrastructure, Share offers fast, reliable file delivery with enterprise-grade security.

Key features:

  • Secure file storage with user authentication and ownership controls
  • Flexible share links with expiration dates, email requirements, and download permissions
  • Analytics tracking for access, page views, and link clicks
  • Interactive commenting with page-specific annotations
  • Rich metadata with custom links, text blocks, and AI-powered summaries

How It Works

Share is built on a modern serverless architecture:

  • Frontend: React + TypeScript application with Clerk authentication
  • Backend: Cloudflare Worker handles all API requests and file operations
  • Database: Cloudflare D1 (SQLite) stores file metadata, share links, comments, and analytics
  • Storage: Cloudflare R2 stores the actual PDF files

When a user uploads a file, it's stored in R2 and metadata is saved to D1. Users can create multiple share links per file, each with its own settings (expiration, email requirements, download permissions). Share links use UUIDs for public access, allowing recipients to view files without authentication while maintaining security through validation checks.

The platform enforces strict access control: users can only access and modify their own files, while share links provide controlled public access with optional email gates and session management.

Features

Files

Files are stored in Cloudflare R2 with metadata in D1. Each file supports:

  • Ownership: Every file belongs to a user (via Clerk user ID)
  • Settings: Enable/disable downloads and comments per file
  • Size limit: 5MB maximum (PDF only)
  • Operations: Upload, view, update metadata, and delete (owner only)

Users & Authentication

Authentication is handled by Clerk, with JWT tokens verified on every request. Users can:

  • Sign up and sign in through Clerk
  • Access their dashboard to view all their files
  • Manage file settings and share links
  • View analytics for their shared files

All dashboard routes (/dashboard, /dashboard/files/:fileId) require authentication. File operations check ownership before allowing modifications.

Share Links

Share links enable public access to files without requiring authentication. Each file can have multiple share links with different configurations:

  • UUID-based URLs: Public links use /view/{uuid} format
  • Access controls: Enable/disable, expiration dates, download permissions
  • Email gates: Optional email requirement with 1-hour session expiry
  • Custom greetings: Personalized messages for email-gated links
  • Analytics: Track access events, page views, and link clicks

When someone accesses a share link, the Worker validates that the link is enabled, not expired, and belongs to the file. If email is required, users must enter their email before viewing, with sessions stored in localStorage and expiring after 1 hour.

File Details & Comments

Files support rich metadata through detail blocks:

  • Links: Custom links displayed in the sidebar with colors and icons
  • Text: Plain text content blocks
  • AI Summary: Auto-generated summaries (Gemini integration)
  • Images: Embedded images with alt text

Comments allow collaborative feedback:

  • Anyone with file access can view and add comments
  • Comments can be page-specific
  • File owners can resolve or delete comments
  • Comments support user and bot roles

Security

Share implements multiple layers of security:

Authentication & Authorization:

  • All authenticated requests verify Clerk JWT tokens
  • File modifications require ownership (owner_id === userId)
  • Share links are validated for enabled status, expiration, and file association

Access Control: Access is granted in this priority order:

  1. User owns the file → Access granted
  2. Valid share link (enabled, not expired, belongs to file) → Access granted
  3. Otherwise → Access denied

Security Features:

  • Input validation (file size limits, type restrictions)
  • SQL injection prevention (parameterized queries)
  • Random UUIDs for share links (not sequential)
  • Session expiry (1 hour) for email-gated links
  • Data isolation (detail blocks and share links validated to belong to files)
  • Cascading deletes (removing files deletes related data)

Session Management: Share link sessions are stored in localStorage with keys like share_session_{uuid} and share_email_{uuid}, expiring after 1 hour. Each share link maintains independent session storage. For email-gated links, the Worker also requires an email query parameter on PDF view/download (the address is not cryptographically verified).

License

MIT — see LICENSE.

Setup

Prerequisites

  • Node.js and npm
  • Cloudflare account with D1 and R2 access
  • Clerk account for authentication

Quick start (local)

cp .env.example .env
# edit .env with your Clerk publishable key and VITE_WORKER_BASE_URL=http://localhost:8787

npm install
# Configure wrangler.toml D1 IDs + [vars], then:
npx wrangler secret put CLERK_SECRET_KEY
npm run worker:dev   # terminal 1
npm run dev          # terminal 2

Cloudflare D1 Setup

  1. Create databases:

    npx wrangler d1 create share
    npx wrangler d1 create share-dev
  2. Copy the returned database_id values into wrangler.toml for production and development bindings

  3. Apply migrations:

    • Local: npx wrangler d1 migrations apply share-dev --local
    • Prod: npx wrangler d1 migrations apply share

Worker

The Worker handles all API requests and file operations. See worker/README.md.

  • Dev: npm run worker:dev (serves on http://localhost:8787 by default)
  • Deploy: npm run worker:deploy (or npm run worker:deploy:prod)
  • API base URL: Set VITE_WORKER_BASE_URL in .env (e.g. http://localhost:8787)
  • D1 binding name must remain DB (matches worker code)

Frontend

  • Dev: npm run dev
  • The app communicates with the Worker for all data operations

Environment Variables

Copy .env.example → .env for local work. Production SPA builds use .env.production (or CI variables).

Frontend (Vite):

  • VITE_CLERK_PUBLISHABLE_KEY — Clerk publishable key
  • VITE_WORKER_BASE_URL — Worker API URL

Worker secrets (wrangler secret put):

  • CLERK_SECRET_KEY
  • GEMINI_API_KEY (optional)
  • R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, CF_ACCOUNT_ID (for view-url)

Worker vars (wrangler.toml [vars]):

  • ALLOWED_ORIGINS — comma-separated CORS allowlist
  • PUBLIC_APP_URL — canonical frontend origin
  • R2_PUBLIC_BASE_URL — public R2 custom domain base

Forks should replace Clerk keys, Worker URLs, D1/R2 IDs, and the [vars] origins with their own.

Testing

npm test          # unit tests (CORS + email gate helpers)
npm run lint
npm run build

Manual Testing Checklist

  • Files: Load dashboard, create/delete a file
  • Share links: Create a share link, toggle enable/disable, expiration, download, requireEmail, customGreeting; confirm mapping resolves in /view/:uuid
  • Analytics: Open a share link, page through PDF (page views), click sidebar links (link clicks); verify state updates in UI
  • Comments: Add/resolve/delete comments on a file
  • Auth gate: For requireEmail share links, confirm email gate appears, PDF only loads after email entry, and sessions expire after 1 hour

About

Secure PDF sharing with controlled access, analytics, and page comments

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages