增加英文文档

This commit is contained in:
david_bai
2025-06-20 23:31:48 +08:00
parent 079827546b
commit a0034d46ff
8 changed files with 800 additions and 2 deletions
+84
View File
@@ -0,0 +1,84 @@
# PrivyDrop - A Privacy-Focused, WebRTC-Based File Sharing Tool
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
PrivyDrop(formerly SecureShare) is an open-source, peer-to-peer (P2P) file and text sharing tool built on WebRTC. It requires no server-side data relay; all data is transmitted directly between browsers, ensuring end-to-end encryption for maximum privacy and security.
We believe everyone should have control over their own data. PrivyDrop was created to fulfill this vision: a simple, fast, and private sharing solution.
[**Try it Live »**](https://www.securityshare.xyz/) | [**GitHub Repository »**](https://github.com/david-bai00/PrivyDrop)
---
![PrivyDrop Interface GIF](frontend/public/HowItWorks.gif)
## ✨ Key Features
- 🔒 **End-to-End Encryption**: Leverages P2P direct connections via WebRTC. All files and text are transferred directly between browsers without passing through any central server.
- 📂 **File & Folder Transfer**: Supports transferring multiple files and entire folders.
-**Real-time & Efficient**: Displays real-time transfer progress and automatically calculates transfer speed.
- 📝 **Rich Text Clipboard**: Supports editing and sending formatted text, not just files.
- 🔗 **Convenient Sharing**: Easily share a room and establish a connection via a link or QR code.
- 📱 **Multi-Device Support**: Responsive design supports both desktop and mobile browsers.
- 🌐 **Internationalization**: Supports multiple languages, including English and Chinese.
## 🛠️ Tech Stack
- **Frontend**: Next.js 14, React 18, TypeScript, Tailwind CSS, shadcn/ui
- **Backend**: Node.js, Express.js, TypeScript
- **Real-time Communication**: WebRTC, Socket.IO
- **Data Storage**: Redis
- **Deployment**: PM2, Nginx, Docker [WIP]
## 🚀 Quick Start (Full-Stack Local Development)
Before you begin, ensure your development environment has [Node.js](https://nodejs.org/) (v18+), [npm](https://www.npmjs.com/), and a running [Redis](https://redis.io/) instance installed.
1. **Clone the Project**
```bash
git clone https://github.com/david-bai00/PrivyDrop.git
cd PrivyDrop
```
2. **Configure and Start the Backend Service**
```bash
cd backend
npm install
# Create and configure .env.development.local according to the instructions in backend/README.md
npm run dev # Starts by default at http://localhost:3001
```
3. **Configure and Start the Frontend App** (in a new terminal window)
```bash
cd frontend
pnpm install
# Create and configure .env.development.local according to the instructions in frontend/README.md
pnpm dev # Starts by default at http://localhost:3000
```
4. **Start Sharing**
Open `http://localhost:3000` in your browser to access the application.
## 📚 Documentation
We provide detailed documentation to help you dive deeper into the project's design and deployment details:
- [**Overall Project Architecture**](./docs/ARCHITECTURE.md): Understand how all components of the PrivyDrop system work together.
- [**Frontend Architecture Deep Dive**](./docs/FRONTEND_ARCHITECTURE.md): Explore the frontend's code structure, state management, and core logic.
- [**Backend Architecture Deep Dive**](./docs/BACKEND_ARCHITECTURE.md): Dive into the backend's code structure, signaling flow, and Redis design.
- [**Deployment Guide**](./docs/DEPLOYMENT.md): Learn how to deploy the complete PrivyDrop application in a production environment.
## 🤝 Contributing
We warmly welcome contributions of all forms! Whether it's reporting a bug, suggesting a feature, submitting code or adding a star, your help is invaluable to PrivyDrop's growth. Please read our [**Contribution Guidelines**](./.github/CONTRIBUTING.md) to start your journey.
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
+2 -2
View File
@@ -1,4 +1,4 @@
# PrivyDrop(前 SecureShare) - 基于 WebRTC 的隐私安全文件分享工具
# PrivyDrop - 基于 WebRTC 的隐私安全文件分享工具
[![开源协议](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
@@ -77,7 +77,7 @@ PrivyDrop (原 SecureShare) 是一个基于 WebRTC 的开源点对点(P2P)
## 🤝 参与贡献
我们热烈欢迎任何形式的贡献!无论是报告 Bug、提出功能建议还是提交代码,都对 PrivyDrop 的成长帮助巨大。请阅读我们的 [**贡献指南**](./.github/CONTRIBUTING.md) 来开始你的贡献之旅。
我们热烈欢迎任何形式的贡献!无论是报告 Bug、提出功能建议提交代码还是加星,都对 PrivyDrop 的成长帮助巨大。请阅读我们的 [**贡献指南**](./.github/CONTRIBUTING.md) 来开始你的贡献之旅。
## 📄 开源协议
+66
View File
@@ -0,0 +1,66 @@
# PrivyDrop - Backend
This is the backend server for PrivyDrop. It is built with Node.js, Express, and Socket.IO, and is responsible for handling WebRTC connection signaling, room management, and API requests from the frontend.
## ✨ Features
- **WebRTC Signaling:** Uses Socket.IO to exchange SDP and ICE candidates.
- **Room Management:** Efficiently creates and manages temporary file-sharing rooms using Redis.
- **Lightweight API:** Provides core HTTP endpoints for frontend interaction.
- **Temporary Data Storage:** All room data in Redis has an automatic expiration time (TTL).
## 🛠️ Tech Stack
- **Runtime**: Node.js
- **Framework**: Express.js
- **Language**: TypeScript
- **Real-time Communication**: Socket.IO
- **Database**: Redis (using the ioredis client)
- **Process Management**: PM2
## 🚀 Getting Started (Local Development)
1. **Prerequisites**
- Node.js (v18.x or newer)
- A running Redis instance
2. **Navigate to Directory and Install Dependencies**
```bash
cd backend
npm install
```
3. **Configure Environment Variables**
Create a `.env.development.local` file in the `backend/` directory and populate it with the following variables:
```ini
# Server Configuration
PORT=3001
CORS_ORIGIN=http://localhost:3000 # URL of the frontend development server
# Redis Configuration
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
# REDIS_PASSWORD=your_redis_password
```
4. **Run the Development Server**
```bash
npm run dev
```
The server will start on the port specified by the `PORT` environment variable (defaults to 3001).
## 📖 API & Event Summary
This service provides a set of API endpoints and Socket.IO events to support the frontend application.
- **API Endpoints**: Primarily include room creation (`/api/get_room`), joining, and checking.
- **Socket.IO Events**: Responsible for handling clients joining rooms (`join`) and forwarding WebRTC signaling messages (`offer`, `answer`, `ice-candidate`).
## 📚 Detailed Documentation
- To understand the backend's code structure, module design, and Redis data model in depth, please read the [**Backend Architecture Deep Dive**](../docs/BACKEND_ARCHITECTURE.md).
- To learn about how the frontend and backend collaborate, refer to the [**Overall Project Architecture**](../docs/ARCHITECTURE.md).
- For instructions on deploying in a production environment, please see the [**Deployment Guide**](../docs/DEPLOYMENT.md).
+73
View File
@@ -0,0 +1,73 @@
# PrivyDrop - System Architecture Overview
This document provides a high-level overview of the PrivyDrop project's overall architecture, helping developers understand how the various technical components work together.
## 1. Core Components
The PrivyDrop system is primarily composed of the following core parts:
1. **Frontend**: A Single Page Application (SPA) built with Next.js. It's the interface users interact with, responsible for handling file selection, UI presentation, and initiating WebRTC connections.
2. **Backend**: A server built with Node.js and Express. It does not handle any file data. Its core responsibilities are:
- **Signaling Service**: Implemented with Socket.IO, it relays signaling messages (like SDP and ICE Candidates) for the "handshake" process before a WebRTC connection is established.
- **Room Management**: Handles the creation, joining, and status checking of rooms.
- **API Service**: Provides auxiliary HTTP endpoints.
3. **Redis**: An in-memory database used by the backend to store temporary data, such as room information and lists of participants, utilizing its TTL feature for automatic cleanup of expired rooms.
4. **TURN/STUN Server (Optional)**: Used to assist WebRTC with NAT traversal, ensuring a higher success rate for P2P connections in complex network environments. STUN is used to discover public IP addresses, while TURN serves as a fallback relay server. (This feature is not enabled by default in the current setup).
## 2. Data Flow and Interaction Diagram
The following diagram illustrates the main flow for users establishing a connection and transferring files:
```mermaid
graph TD
subgraph "User A's Browser"
ClientA[Frontend UI]
end
subgraph "User B's Browser"
ClientB[Frontend UI]
end
subgraph "Server Infrastructure"
Nginx[Nginx Reverse Proxy]
Backend[Backend API / Socket.IO]
Redis[Redis Cache]
TURN[TURN/STUN Server]
end
ClientA -- 1.Create/Join Room (HTTP/Socket) --> Nginx
Nginx --> Backend
Backend -- Read/Write Room Status --> Redis
ClientB -- 2.Join Same Room (HTTP/Socket) --> Nginx
Backend -- 3.Broadcast user join event --> ClientA
Backend -- 3.Broadcast user join event --> ClientB
ClientA -- 4.Send Signal (Offer/ICE) --> Backend
Backend -- 5.Forward Signal --> ClientB
ClientB -- 6.Send Signal (Answer/ICE) --> Backend
Backend -- 7.Forward Signal --> ClientA
ClientA <-.-> |8.STUN Check| TURN
ClientB <-.-> |8.STUN Check| TURN
ClientA <-..- |9.P2P Direct Data Transfer| ClientB
ClientA <-.-> |9.TURN Relayed Data Transfer| TURN
ClientB <-.-> |9.TURN Relayed Data Transfer| TURN
```
**Flow Description:**
1. **Room Creation/Joining**: User A (the sender) requests the backend to create a unique room ID via the frontend. The backend records this room in Redis.
2. **Sharing & Joining**: User A shares the room ID with User B via a link or QR code. User B uses this ID to request joining the room.
3. **Signaling Exchange**:
- Once there are two or more users in a room, they begin exchanging WebRTC signaling messages through the backend's Socket.IO service.
- This process includes exchanging network information (ICE candidates) and session descriptions (SDP offers/answers). The backend server acts merely as a "postman" for these messages, forwarding them without understanding their content.
4. **NAT Traversal**: The browsers use the network information obtained from the signals, along with STUN/TURN servers, to attempt and establish a direct P2P connection.
5. **P2P Connection Established**: Once the connection is successfully established, all file and text data are transferred directly between User A's and User B's browsers, without passing through any server. If a direct connection fails, data will be relayed through a TURN server.
## 3. Design Philosophy
- **Privacy First**: Core file data is never uploaded to the server. The server only acts as an "introducer" or "matchmaker."
- **Frontend-Backend Separation**: Responsibilities are clearly separated. The frontend handles all user interaction and the complex logic of WebRTC; the backend provides lightweight, efficient signaling and room management services.
- **Horizontal Scalability**: The backend is stateless (with state managed in Redis), which theoretically allows it to be scaled horizontally by adding more Node.js instances to handle a large volume of concurrent signaling requests.
+135
View File
@@ -0,0 +1,135 @@
# PrivyDrop - Backend Architecture Deep Dive
## 1. Overview
### 1.1 Core Responsibilities
The PrivyDrop backend is a lightweight server built on Node.js and Express.js. Its core responsibility is **not to transfer files directly** but to act as a "**Signaling Server**" and "**Room Coordinator**" for establishing WebRTC connections.
Its main functions include:
- **HTTP API Service**: Provides RESTful interfaces for creating, querying, and checking the status of rooms.
- **WebRTC Signaling**: Utilizes Socket.IO to relay signaling messages (SDP Offers/Answers, ICE Candidates) between clients in real-time to facilitate P2P connections.
- **Room Lifecycle Management**: Efficiently manages the state of rooms and participants using Redis, leveraging its TTL mechanism for automatic cleanup.
- **Basic Security**: Implements IP-based rate limiting to prevent service abuse.
### 1.2 Design Principles
- **Stateless**: The backend service itself does not hold any state related to rooms or users. All state is delegated to an external Redis service, which allows the backend application to be easily scaled horizontally.
- **Lightweight Signaling**: The server acts only as a relay for signaling messages. It does not parse or store the content of these signals, ensuring the privacy of end-to-end communication.
- **High Efficiency & Low Latency**: Employs Redis as an in-memory database for room state management and Socket.IO for real-time communication to minimize the latency of signal exchange.
- **Single Responsibility**: Each module (API, Socket handling, Redis service) has a clear and single responsibility, making it easy to understand, maintain, and test.
## 2. Project Structure
The backend source code is organized by functional modules, primarily located in the `src/` directory:
```
backend/
├── src/
│ ├── config/ # Environment variables and server configuration (CORS)
│ │ ├── env.ts
│ │ └── server.ts
│ ├── routes/ # API route definitions (Express router)
│ │ └── api.ts
│ ├── services/ # Core business logic (Room, Redis, Rate Limiting)
│ │ ├── rateLimit.ts
│ │ ├── redis.ts
│ │ └── room.ts
│ ├── socket/ # Socket.IO event handlers and signaling logic
│ │ └── handlers.ts
│ ├── types/ # TypeScript type definitions and interfaces
│ │ ├── room.ts
│ │ └── socket.ts
│ └── server.ts # Main application entry point: Express and Socket.IO setup
├── ecosystem.config.js # PM2 configuration file
├── package.json
└── tsconfig.json
```
## 3. Core Module Deep Dive
### 3.1 Application Entry Point (`src/server.ts`)
This is the application's startup file. It is responsible for:
1. Loading environment variables.
2. Initializing the Express application instance.
3. Configuring middleware such as CORS and JSON parsing.
4. Mounting the `/api` routes.
5. Creating an HTTP server and attaching the Socket.IO service to it.
6. Calling `initializeSocketHandlers` to set up all Socket.IO event listeners.
7. Starting the server and listening on the specified port.
### 3.2 API Routes (`src/routes/api.ts`)
Defines all the HTTP RESTful APIs called by the frontend.
- **`POST /api/create_room`**: Receives a `roomId` specified by the frontend, checks for its availability, and creates a new room if available.
- **`GET /api/get_room`**: Generates a unique, random room ID, creates the room, and returns it to the frontend.
- **`POST /api/check_room`**: Checks if a given `roomId` already exists.
- **`POST /api/set_track`**: Used to track traffic sources (referrers).
- **`POST /api/logs_debug`**: A simple debugging endpoint to receive logs from the frontend and print them on the backend console.
### 3.3 Socket.IO Event Handling (`src/socket/handlers.ts`)
This is the core of the signaling exchange. The `initializeSocketHandlers` function binds a series of event handlers to an incoming `socket` connection.
- **Connection & Disconnection**:
- `connection`: Logs the `socket.id` when a new client connects.
- `disconnect`: When a client disconnects, it is removed from the room it was in, and other peers in the room are notified (`peer-disconnected`).
- **Room Logic**:
- **`join`**: Handles a client's request to join a room. It verifies if the room exists, adds the client's `socket.id` to the room's set of members, and finally sends a `joinResponse` to the requester.
- **`initiator-online`**: Emitted by the room creator (initiator), often when the app comes back from being backgrounded, to notify the recipient, "I'm online, let's re-establish the connection."
- **`recipient-ready`**: Emitted by the recipient to notify the initiator in the room, "I'm ready, you can start the reconnection process," which typically signals the start of the WebRTC `offer` flow.
- **WebRTC Signaling Forwarding**:
- **`offer`**, **`answer`**, **`ice-candidate`**: These three events are pure relays. They are responsible for accurately forwarding a peer's WebRTC signaling message to the other peer in the room.
### 3.4 Service Layer (`src/services/`)
Encapsulates interactions with external dependencies (like Redis) and core business logic.
- **`redis.ts`**: Provides a singleton instance of the Redis client. All interactions with Redis should go through this module.
- **`room.ts`**: Encapsulates all room-related Redis operations, such as `createRoom`, `isRoomExist`, `bindSocketToRoom`, etc. It decouples business logic (e.g., "add user to room") from the underlying Redis commands (e.g., `SADD`, `HSET`).
- **`rateLimit.ts`**: Implements a rate limiter based on IP address and a Redis Sorted Set to restrict users from creating or joining rooms too frequently in a short period.
## 4. Redis Data Structure Deep Dive
Redis is a key component of the backend, used to store all temporary state. We cleverly use different data structures to meet business needs and set a TTL for all keys to ensure automatic data cleanup.
- **1. Room Information (`Hash`)**:
- **Key Pattern**: `room:<roomId>` (e.g., `room:ABCD12`)
- **Purpose**: Stores the metadata of a room.
- **Fields**:
- `created_at`: Timestamp of when the room was created.
- **Example**: `HSET room:ABCD12 created_at 1705123456789`
- **2. Sockets in a Room (`Set`)**:
- **Key Pattern**: `room:<roomId>:sockets` (e.g., `room:ABCD12:sockets`)
- **Purpose**: Stores all client `socketId`s within a single room. Using a Set guarantees the uniqueness of members and makes additions and removals convenient.
- **Members**: The client's `socketId`.
- **Example**: `SADD room:ABCD12:sockets "socketId_A" "socketId_B"`
- **3. Socket-to-Room Mapping (`String`)**:
- **Key Pattern**: `socket:<socketId>` (e.g., `socket:xgACY6QcQCojsOQaAAAB`)
- **Purpose**: Provides a reverse mapping from a `socketId` to its `roomId`. This is very useful when handling client disconnections, as we can quickly find the room and perform cleanup using only the `socketId`.
- **Value**: The `roomId`.
- **Example**: `SET socket:xgACY6QcQCojsOQaAAAB ABCD12`
- **4. Rate Limiting (`Sorted Set`)**:
- **Key Pattern**: `ratelimit:join:<ipAddress>` (e.g., `ratelimit:join:192.168.1.100`)
- **Purpose**: Records all request timestamps from a specific IP address within a given time window.
- **Members**: `timestamp-randomNumber` (e.g., `1678886400000-0.12345`). A random number suffix is used to ensure uniqueness for multiple requests within the same millisecond.
- **Score**: The Unix timestamp of the request (in milliseconds).
- **Logic**: Old records outside the time window are removed using `ZREMRANGEBYSCORE`, and then the number of requests within the window is counted with `ZCARD` to determine if the limit has been exceeded.
- **5. Referrer Tracking (`Hash`)**:
- **Key Pattern**: `referrers:daily:<YYYY-MM-DD>` (e.g., `referrers:daily:2023-03-15`)
- **Purpose**: Tracks the number of visits from different sources (Referrers) on a daily basis.
- **Fields**: The referrer's domain name (e.g., `google.com`, `github.com`).
- **Value**: The cumulative visit count for the day.
- **Logic**: The `HINCRBY` command is used to atomically increment the count for a specified source.
+250
View File
@@ -0,0 +1,250 @@
# PrivyDrop Deployment Guide
This guide provides comprehensive instructions for deploying the full-stack PrivyDrop application, including setting up Redis, a TURN server, the backend service, the frontend application, and configuring Nginx as a reverse proxy.
## 1. Introduction
This document will guide you through preparing your server environment, configuring dependencies, and deploying both the frontend and backend of PrivyDrop. Whether you are setting up a development/testing environment or a full production instance, this guide aims to cover all essential aspects.
## 2. Prerequisites
Before you begin, please ensure your server environment meets the following requirements:
- **Operating System:** A Linux distribution (e.g., Ubuntu 20.04 LTS or newer is recommended).
- **Node.js:** v18.x or higher.
- **npm (or yarn/pnpm):** The package manager for Node.js.
- **Root or Sudo Privileges:** Required for installing packages and configuring services.
- **Domain Name:** Required for a production deployment.
- **Optional: Base Environment & Docker Image Reference:** If you are starting from a very clean system environment or wish to see the base dependencies for a Docker build, you can refer to the `backend/docker/Dockerfile` (for Docker image creation) and `backend/docker/env_install.log` (dependency installation log) files.
## 3. Dependency Services: Installation & Configuration
### 3.1. Redis Server
Redis is used by the backend for room management, session information, and caching.
**Installation (Ubuntu Example):**
```bash
sudo apt update
sudo apt install redis-server
```
**Configuration:**
- By default, Redis listens on `127.0.0.1:6379` without a password. Ensure your backend's `.env` file includes the correct `REDIS_HOST` and `REDIS_PORT`.
- Verify that Redis is running: `sudo systemctl status redis-server`
- If it's not running, start it: `sudo systemctl start redis-server`
### 3.2. TURN/STUN Server (Coturn)
**Important: This section is optional.** By default, PrivyDrop uses public STUN servers, which are sufficient to establish connections in most network environments. You only need to set up your own TURN server if you have extremely high requirements for NAT traversal success rates.
A TURN server is crucial for WebRTC to traverse NATs and firewalls. Coturn is a popular implementation.
**Installation (Ubuntu Example):**
```bash
sudo apt update
sudo apt install coturn
```
**Configuration:**
1. **Enable the Coturn service:** Edit `/etc/default/coturn` and uncomment `TURNSERVER_ENABLED=1`.
2. **Firewall Configuration:** Open the necessary ports on your server's firewall (e.g., using `ufw`):
- TCP & UDP `3478`: For STUN and TURN.
- TCP & UDP `5349`: For TURNS (TURN over TLS/DTLS) - **Production**.
- UDP `49152-65535`: Coturn's default relay port range.
```bash
sudo ufw allow 3478
sudo ufw allow 5349
sudo ufw allow 49152:65535/udp
sudo ufw enable
```
3. **Production SSL Certificate (for TURNS):**
Obtain an SSL certificate for your TURN domain (e.g., `turn.yourdomain.com`).
```bash
# Ensure a DNS 'A' record points turn.yourdomain.com to your server's IP
sudo apt install certbot
sudo certbot certonly --standalone -d turn.yourdomain.com
```
4. **SSL Certificate Permissions:**
The Coturn process (usually runs as the `turnserver` user) needs permission to read the SSL certificate and private key.
- Check current permissions:
```bash
sudo ls -lh /etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem
sudo ls -ld /etc/letsencrypt/archive/
```
- If Coturn logs show permission errors:
Create a group (e.g., `ssl-cert`), add `turnserver` to it, and adjust permissions:
```bash
sudo groupadd -f ssl-cert
# Find the user coturn runs as, usually 'turnserver' or 'coturn'
# ps aux | grep turnserver
sudo usermod -a -G ssl-cert turnserver # Replace 'turnserver' if different
sudo chown -R root:ssl-cert /etc/letsencrypt/
sudo chmod -R 750 /etc/letsencrypt/
```
Verify the new permissions on `/etc/letsencrypt/archive/` and `/etc/letsencrypt/live/`.
5. **Configure and Start Coturn:**
- Configure `TURN_*` related environment variables in the backend's `.env` file (e.g., username, password, certificate paths).
- For a **testing environment**, you need to set:
```
TURN_EXTERNAL_IP=YourServerPublicIP # e.g., 123.123.456.567
TURN_REALM=YourServerPublicIP
TURN_USERNAME=YourTurnUsername
TURN_PASSWORD=YourTurnPassword
```
- For a **production deployment**, you need to set:
```
TURN_EXTERNAL_IP=YourServerPublicIP # e.g., 123.123.456.567
TURN_REALM=turn.yourdomain
TURN_USERNAME=YourTurnUsername
TURN_PASSWORD=YourTurnPassword
TURN_CERT_PATH=/etc/letsencrypt/live/turn.yourdomain/fullchain.pem
TURN_KEY_PATH=/etc/letsencrypt/live/turn.yourdomain/privkey.pem
```
- Use the script provided in the project to generate the configuration file and start the service:
```bash
# Located in the backend/ directory
sudo bash ./docker/TURN/configure.sh path/to/your/.env.production.local
# For a development environment, use .env.development.local
sudo systemctl status coturn
```
- Check the logs at `/var/log/turnserver.log` to confirm there are no errors.
6. **Online Testing (Optional):**
Use an online tool like the Metered TURN Server Tester (https://www.metered.ca/turn-server-testing):
- **For Development/Testing (non-TLS):**
- TURN URL: `YourServerPublicIP`
- TURN Port: `3478`
- Username: `YourTurnUsername`
- Password: `YourTurnPassword`
- **For Production (TURNS):**
- TURNS URL: `turn.yourdomain.com`
- TURNS Port: `5349`
- Username: `YourTurnUsername`
- Password: `YourTurnPassword`
A successful test should show a "Reachable" message.
## 4. Application Deployment (Production)
This section describes how to deploy PrivyDrop in a production environment using Nginx and PM2.
### 4.1. Get the Code and Install Dependencies
```bash
git clone <your-repository-url> privydrop
cd privydrop
# Install backend dependencies
cd backend && npm install && cd ..
# Install frontend dependencies
cd frontend && pnpm install && cd ..
```
### 4.2. Configure Environment Variables
- **Backend:**
- Create a `.env.production.local` file in the `backend/` directory.
- Fill in the necessary environment variables (e.g., `PORT`, `REDIS_HOST`, `REDIS_PORT`, `CORS_ORIGIN`).
- For Nginx integration, also add `NGINX_SERVER_NAME`, `NGINX_SSL_CERT`, `NGINX_SSL_KEY`, and `NGINX_FRONTEND_ROOT`.
- **Frontend:**
- Create a `.env.production.local` file in the `frontend/` directory.
- Fill in the `NEXT_PUBLIC_API_URL` variable.
### 4.3. Build the Frontend Application
```bash
cd frontend
pnpm build
```
This will generate an optimized production build in the `frontend/.next` directory.
### 4.4. Run the Application with PM2
PM2 is a powerful process manager for Node.js. We will use it to run the backend and frontend services separately.
1. **Install PM2 globally:**
```bash
sudo npm install -g pm2
```
2. **Start the Backend Service:**
The backend directory provides an `ecosystem.config.js` file for PM2.
```bash
cd backend
# Ensure .env.production.local is fully configured
pm2 start ecosystem.config.js
```
3. **Start the Frontend Service:**
```bash
cd frontend
pm2 start npm --name "privydrop-frontend" -- run start
```
The `npm start` command starts the Next.js production server, which listens on port 3000 by default.
4. **Manage Applications:**
- View status: `pm2 list`
- View logs: `pm2 logs <app_name>`
- Set up startup script: `pm2 startup` followed by `pm2 save`
### 4.5. Configure Nginx as a Reverse Proxy
In production, Nginx will act as the entry point for all traffic, handling SSL termination and routing requests to the correct frontend or backend service.
1. **Install Nginx:** It's recommended to install a newer version that supports HTTP/3.
2. **Firewall:** Ensure ports `TCP:80 (HTTP)` and `TCP/UDP:443 (HTTPS/HTTP3)` are open.
3. **Main Domain SSL Certificate:** Obtain a certificate for your main domain (e.g., `yourdomain.com`).
```bash
sudo apt install python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
```
4. **Nginx Configuration File:**
The `backend/docker/Nginx/` directory in the project provides a configuration script and template.
- Add the `NGINX_*` related variables to your backend's `.env.production.local` file, including the domain, certificate paths, and the **root directory of the frontend build artifacts**. Example:
```
NGINX_SERVER_NAME=yourdomain.com # The full domain name
NGINX_SSL_CERT=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
NGINX_SSL_KEY=/etc/letsencrypt/live/yourdomain.com/privkey.pem
NGINX_FRONTEND_ROOT=/path/to/your/frontend/.next # Path to frontend build output
```
5. **Apply Configuration:** Generate the Nginx config, create a symbolic link, and restart Nginx.
```bash
# This script uses NGINX_* variables from your .env file to generate the Nginx config
sudo bash backend/docker/Nginx/configure.sh backend/.env.production.local
```
## 5. Troubleshooting
- **Connection Issues:** Check firewall settings, Nginx proxy configurations, `CORS_ORIGIN` settings, and ensure all PM2 processes are running.
- **Nginx Errors:** Use `sudo nginx -t` to check syntax and review `/var/log/nginx/error.log`.
- **PM2 Issues:** Use `pm2 logs <app_name>` to view application logs.
- **Certificate Permissions (Production):** If Coturn or Nginx cannot read SSL certificates, carefully check file permissions and user/group settings.
## 6. Security & Maintenance
- **SSL Certificate Renewal (Production):** You can refer to the `backend/docker/Nginx/renew_ssl.sh` script to automate renewal.
- **Firewall:** Maintain strict firewall rules, only allowing necessary ports.
+144
View File
@@ -0,0 +1,144 @@
# PrivyDrop Frontend Architecture Documentation
## 1. Architecture Overview
### 1.1 Project Vision
PrivyDrop is a P2P file/text sharing tool based on WebRTC, designed to provide a secure, private, and efficient online sharing solution. The core objective of the frontend architecture is to build a high-performance, maintainable, and scalable modern web application, adhering to Next.js best practices.
### 1.2 Design Philosophy
In a recent refactor, we established a design philosophy centered on "**Separation of Concerns**" and "**Logical Cohesion**":
- **UI and Logic Separation**: Views (Components) should remain as "pure" as possible, responsible only for rendering the UI and responding to user interactions. All complex business logic, state management, and side effects should be extracted from components.
- **Hooks as the Core of Business Logic**: Custom React Hooks are first-class citizens for organizing our business logic and state. Each Hook encapsulates a distinct, cohesive functional module (e.g., WebRTC connection, room management), making the logic unit reusable, testable, and significantly simplifying the component tree.
- **Layered Architecture**: The codebase follows a clear, layered structure, ensuring that each layer has a single responsibility, reducing coupling between modules.
### 1.3 Core Tech Stack
- **Framework**: Next.js 14 (App Router)
- **Language**: TypeScript
- **UI**: React 18, Tailwind CSS, shadcn/ui (based on Radix UI)
- **State Management**: Modular state management centered on custom React Hooks
- **WebRTC Signaling**: Socket.IO Client
- **Data Fetching**: React Server Components (RSC), Fetch API
- **Internationalization**: `next/server` middleware + dynamic JSON dictionaries
- **Content**: MDX (for blog and static content pages)
### 1.4 High-Level Layered Model
The frontend architecture can be broadly divided into four layers:
```
+---------------------------------------------------+
| ① Application & Routing Layer (App Router) | app/
| (Pages, Layouts, Routing, i18n Middleware) |
+---------------------------------------------------+
| ② UI & Component Layer | components/
| (Coordinator Components, UI Panels, Common |
| Components, Base UI Elements) |
+---------------------------------------------------+
| ③ Business Logic & State Layer (Hooks) | hooks/
| (WebRTC Connection, Room Management, File |
| Transfer, Clipboard Operations, etc.) |
+---------------------------------------------------+
| ④ Core Libraries & Utilities Layer | lib/
| (Low-level WebRTC Wrappers, File Handling, |
| Utility Functions, API Client) |
+---------------------------------------------------+
```
- **① Application & Routing Layer**: Managed by the Next.js App Router, responsible for page rendering, route control, internationalization, and initial data fetching.
- **② UI & Component Layer**: Responsible for displaying the entire user interface. It consumes state and methods from the layer below (Hooks) and propagates user interaction events upward.
- **③ Business Logic & State Layer**: **This is the "brain" of the application**. It encapsulates all core functional business logic and state through a series of custom Hooks.
- **④ Core Libraries & Utilities Layer**: Provides the lowest-level, framework-agnostic, pure functions, such as low-level WebRTC wrappers and API requests.
---
## 2. Core Feature Implementation: P2P File/Text Transfer
This section details how the application's most critical P2P transfer feature is implemented through the collaboration of different architectural layers.
### 2.1 Overall Flow
1. **User Action (`components`)**: The user performs an action in `SendTabPanel` or `RetrieveTabPanel` (e.g., selecting a file, entering a room code).
2. **Logic Processing (`hooks`)**: Hooks like `useFileTransferHandler` and `useRoomManager` capture these actions, manage related state (e.g., the list of files to be sent), and invoke connection methods provided by the `useWebRTCConnection` Hook.
3. **Connection Establishment (`hooks` -> `lib`)**: `useWebRTCConnection` calls low-level functions in `lib/webrtc_*.ts` to negotiate with the peer via the Socket.IO signaling server and establish an `RTCPeerConnection`.
4. **Data Transfer (`lib`)**: Once the connection is established, `lib/fileSender.ts` and `lib/fileReceiver.ts` are responsible for chunking, serializing, and transferring the file over the `RTCDataChannel`.
5. **State Updates & Callbacks (`lib` -> `hooks` -> `components`)**: During the transfer, the `lib` layer notifies the `hooks` layer of state changes (e.g., progress updates) via callbacks. These state changes in the `hooks` layer ultimately trigger a re-render of the `components` layer's UI.
### 2.2 Module Deep Dive
- **Low-Level WebRTC Wrappers (`lib/`)**:
- `webrtc_base.ts`: Encapsulates interactions with the Socket.IO signaling server, generic management of `RTCPeerConnection` (ICE, connection state), and the creation of `RTCDataChannel`. It is the foundation for all WebRTC operations.
- `fileSender.ts` / `fileReceiver.ts`: Handle the logic for sending and receiving files/text, including metadata exchange, file chunking, progress calculation, data reassembly, and file saving.
- **WebRTC Business Logic Wrappers (`hooks/`)**:
- `useWebRTCConnection.ts`: **The connection's "central hub"**. It initializes and manages `sender` and `receiver` instances, handles the connection lifecycle, and provides a clean API (e.g., `broadcastDataToAllPeers`) and state (e.g., `peerCount`, `sendProgress`) to the upper layers.
- `useRoomManager.ts`: **The room's "state machine"**. It's responsible for the creation, validation (with debouncing), and joining logic for room IDs, and manages UI state text related to the room.
- `useFileTransferHandler.ts`: **The transfer's "data center"**. It manages the text and files to be sent or received, handles user actions like adding/removing/downloading files, and provides callbacks to `useWebRTCConnection` for processing received data.
- **UI Coordination & Display (`components/`)**:
- `ClipboardApp.tsx`: **The core application's "main coordinator"**. It contains no business logic itself. Its sole responsibility is to integrate all the core Hooks mentioned above and then distribute the state and callbacks obtained from these Hooks as props to specific UI sub-components.
- `SendTabPanel.tsx` / `RetrieveTabPanel.tsx`: Purely presentational components responsible for rendering the send and receive panels and responding to user input.
- `FileListDisplay.tsx`: Used to display the file list and transfer status.
## 3. Application Layer Detailed Architecture
### 3.1 Directory Structure & Responsibilities
- **`frontend/app/`**: Core application routes and pages.
- `[lang]/`: Implements multi-language dynamic routing.
- `layout.tsx`: Global layout, provides Providers (Theme, i18n).
- `page.tsx`: Main page entry point, renders `HomeClient`.
- `HomeClient.tsx`: (Client Component) Hosts the core `ClipboardApp` and other marketing/display components.
- `config/`: Application configuration.
- `api.ts`: Centralizes interaction with the backend API.
- `environment.ts`: Manages environment variables and runtime configurations (like ICE servers).
- **`frontend/components/`**: UI component library.
- `ClipboardApp/`: All UI sub-components broken down from `ClipboardApp`. **Implements separation of concerns**.
- `common/`: Reusable components that can be used across the project (e.g., `YouTubePlayer`).
- `ui/`: (from shadcn/ui) Base atomic components.
- `web/`: Large, page-level static components for the website (e.g., `Header`, `Footer`).
- `Editor/`: Custom rich text editor.
- **`frontend/hooks/`**: **The core of business logic and state management**. Detailed above.
- **`frontend/lib/`**: Core libraries and utility functions.
- `webrtc_*.ts`, `fileSender.ts`, `fileReceiver.ts`: WebRTC core.
- `dictionary.ts`: Internationalization dictionary loading.
- `utils.ts`, `fileUtils.ts`: General utility functions.
- **`frontend/types/`**: Global TypeScript type definitions.
- **`frontend/constants/`**: Application-wide constants, mainly for i18n configuration and message files.
### 3.2 State Management Strategy
The project uses **custom React Hooks as the core for modular state management**. We deliberately avoided introducing global state management libraries (like Redux or Zustand) for the following reasons:
- **Reduce Complexity**: For the current scale of the application, a global state would introduce unnecessary complexity.
- **Promote Cohesion**: Encapsulating related state and logic within the same Hook makes the code easier to understand and maintain.
- **Leverage React's Native Capabilities**: Passing state managed by Hooks through Context and Props is sufficient for all current needs.
### 3.3 Internationalization (i18n)
- **Route-Driven**: Language switching is implemented via the URL path (`/[lang]/`).
- **Automatic Detection**: `middleware.ts` intercepts requests and automatically redirects to the appropriate language path based on the `Accept-Language` header or a cookie.
- **Dynamic Loading**: The `getDictionary` function in `lib/dictionary.ts` asynchronously loads the corresponding `messages/*.json` file based on the `lang` parameter, enabling code splitting.
## 4. Summary and Outlook
The current frontend architecture successfully deconstructs a complex WebRTC application into a series of clean, maintainable modules through layered design and Hook-centric logic encapsulation. The boundaries between UI, business logic, and underlying libraries are clear, laying a solid foundation for future feature expansion and maintenance.
Future areas for optimization include:
- **Adding Unit/Integration Tests**: Writing test cases for core Hooks (`useWebRTCConnection`, etc.) and utility classes in `lib`.
- **Bundle Analysis**: Regularly analyzing the bundle size with `@next/bundle-analyzer` to identify optimization opportunities.
- **Component Library Enhancement**: Continuously refining and polishing the common components in `components/common`.
+46
View File
@@ -0,0 +1,46 @@
# PrivyDrop - Frontend
This is the frontend for PrivyDrop, a privacy-focused file sharing application built with Next.js and based on WebRTC.
## 🛠️ Tech Stack
- **Frontend Framework**: Next.js 14 (App Router)
- **UI Framework**: React 18 + TypeScript
- **Styling**: Tailwind CSS + shadcn/ui
- **P2P Transport**: WebRTC
- **Signaling Service Client**: Socket.IO Client
- **Internationalization**: next-intl
## 🚀 Local Development
Before you start, please ensure you have **installed and started the backend service** according to the instructions in the project's root `README.md`.
1. **Navigate to the Directory**
```bash
# Assuming you are in the project's root directory
cd frontend
```
2. **Install Dependencies**
```bash
pnpm install
```
3. **Configure Environment Variables**
Create a `.env.development.local` file in the `frontend/` directory and add the necessary environment variables for development. At a minimum, you need to specify the backend API address:
```ini
NEXT_PUBLIC_API_URL=http://localhost:3001
```
4. **Start the Development Server**
```bash
pnpm dev
```
5. Open `http://localhost:3000` in your browser to see the application.
## 📚 Detailed Documentation
- To understand the complete project architecture and how components collaborate, please see the [**Overall Project Architecture**](../docs/ARCHITECTURE.md).
- To dive deep into the frontend's code structure, Hooks design, and state management, please read the [**Frontend Architecture Deep Dive**](../docs/FRONTEND_ARCHITECTURE.md).
- For instructions on deploying in a production environment, please refer to the [**Deployment Guide**](../docs/DEPLOYMENT.md).
## 🤝 Contributing
We welcome all forms of contributions! Please read the [**Contribution Guidelines**](../.github/CONTRIBUTING.md) in the root directory to get started.