+
+
+
+```
+
+---
+
+## 注意事项
+
+1. **会话有效期**: 上传会话默认 15 分钟后过期,请在有效期内完成上传
+2. **文件大小限制**: 受系统配置 `uploadSize` 限制
+3. **过期类型**: 支持 `day`、`hour`、`minute`、`forever`、`count`
+4. **CORS**: 直传模式下,S3 需要配置正确的 CORS 策略
+5. **重试机制**: 建议实现上传失败重试逻辑
diff --git a/docs/en/api/index.md b/docs/en/api/index.md
index a96b6e503..2addc6459 100644
--- a/docs/en/api/index.md
+++ b/docs/en/api/index.md
@@ -15,6 +15,29 @@ Some APIs require `Authorization` header for authentication:
Authorization: Bearer
```
+### Get Token
+
+When guest upload is disabled in admin panel (`openUpload=0`), you need to login first:
+
+```bash
+curl -X POST "http://localhost:12345/admin/login" \
+ -H "Content-Type: application/json" \
+ -d '{"password": "FileCodeBox2023"}'
+```
+
+**Response Example:**
+
+```json
+{
+ "code": 200,
+ "msg": "success",
+ "detail": {
+ "token": "xxx.xxx.xxx",
+ "token_type": "Bearer"
+ }
+}
+```
+
## Share API
### Share Text
@@ -29,7 +52,22 @@ Share text content and get a share code.
|-----------|------|----------|---------|-------------|
| text | string | Yes | - | Text content to share |
| expire_value | integer | No | 1 | Expiration time value |
-| expire_style | string | No | "day" | Expiration time unit(day/hour/minute) |
+| expire_style | string | No | "day" | Expiration time unit(day/hour/minute/count/forever) |
+
+**cURL Example:**
+
+```bash
+# Guest upload (when openUpload=1)
+curl -X POST "http://localhost:12345/share/text/" \
+ -F "text=This is the text content to share" \
+ -F "expire_value=1" \
+ -F "expire_style=day"
+
+# When authentication required (openUpload=0)
+curl -X POST "http://localhost:12345/share/text/" \
+ -H "Authorization: Bearer xxx.xxx.xxx" \
+ -F "text=This is the text content to share"
+```
**Response Example:**
@@ -38,8 +76,7 @@ Share text content and get a share code.
"code": 200,
"msg": "success",
"detail": {
- "code": "abc123",
- "name": "text.txt"
+ "code": "abc123"
}
}
```
@@ -56,7 +93,32 @@ Upload and share a file, get a share code.
|-----------|------|----------|---------|-------------|
| file | file | Yes | - | File to upload |
| expire_value | integer | No | 1 | Expiration time value |
-| expire_style | string | No | "day" | Expiration time unit(day/hour/minute) |
+| expire_style | string | No | "day" | Expiration time unit(day/hour/minute/count/forever) |
+
+**cURL Example:**
+
+```bash
+# Upload file (default 1 day expiration)
+curl -X POST "http://localhost:12345/share/file/" \
+ -F "file=@/path/to/file.txt"
+
+# Upload file (7 days expiration)
+curl -X POST "http://localhost:12345/share/file/" \
+ -F "file=@/path/to/file.txt" \
+ -F "expire_value=7" \
+ -F "expire_style=day"
+
+# Upload file (10 downloads limit)
+curl -X POST "http://localhost:12345/share/file/" \
+ -F "file=@/path/to/file.txt" \
+ -F "expire_value=10" \
+ -F "expire_style=count"
+
+# When authentication required
+curl -X POST "http://localhost:12345/share/file/" \
+ -H "Authorization: Bearer xxx.xxx.xxx" \
+ -F "file=@/path/to/file.txt"
+```
**Response Example:**
@@ -75,7 +137,7 @@ Upload and share a file, get a share code.
**GET** `/share/select/`
-Get file information by share code.
+Get file information by share code (direct file download).
**Parameters:**
@@ -83,6 +145,13 @@ Get file information by share code.
|-----------|------|----------|-------------|
| code | string | Yes | File share code |
+**cURL Example:**
+
+```bash
+# Download file by extraction code
+curl -L "http://localhost:12345/share/select/?code=abc123" -o downloaded_file
+```
+
**Response Example:**
```json
diff --git a/docs/en/guide/configuration.md b/docs/en/guide/configuration.md
index e69de29bb..89f6be39c 100644
--- a/docs/en/guide/configuration.md
+++ b/docs/en/guide/configuration.md
@@ -0,0 +1,207 @@
+# Configuration Guide
+
+FileCodeBox provides rich configuration options that can be customized through the admin panel or by directly modifying the configuration. This document details all available configuration options.
+
+## Configuration Methods
+
+FileCodeBox supports two configuration methods:
+
+1. **Admin Panel Configuration** (Recommended): Access `/admin` to enter the admin panel and modify settings on the settings page
+2. **Database Configuration**: Configuration is stored in the `data/filecodebox.db` database
+
+::: tip Note
+On first startup, the system uses default configuration from `core/settings.py`. Modified configurations are saved to the database.
+:::
+
+## Basic Settings
+
+### Site Information
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `name` | string | `文件快递柜 - FileCodeBox` | Site name, displayed in page title and navigation bar |
+| `description` | string | `开箱即用的文件快传系统` | Site description, used for SEO |
+| `keywords` | string | `FileCodeBox, 文件快递柜...` | Site keywords, used for SEO |
+| `port` | int | `12345` | Service listening port |
+
+### Notification Settings
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `notify_title` | string | `系统通知` | Notification title |
+| `notify_content` | string | Welcome message | Notification content, supports HTML |
+| `page_explain` | string | Legal disclaimer | Footer explanation text |
+| `robotsText` | string | `User-agent: *\nDisallow: /` | robots.txt content |
+
+## Upload Settings
+
+### File Upload Limits
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `openUpload` | int | `1` | Enable upload functionality (1=enabled, 0=disabled) |
+| `uploadSize` | int | `10485760` | Maximum single file upload size (bytes), default 10MB |
+| `enableChunk` | int | `0` | Enable chunked upload (1=enabled, 0=disabled) |
+
+::: warning Note
+`uploadSize` is in bytes. 10MB = 10 * 1024 * 1024 = 10485760 bytes
+:::
+
+### Upload Rate Limiting
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `uploadMinute` | int | `1` | Upload limit time window (minutes) |
+| `uploadCount` | int | `10` | Maximum uploads allowed within the time window |
+
+Example: Default configuration allows up to 10 uploads per minute.
+
+
+### File Expiration Settings
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `expireStyle` | list | `["day","hour","minute","forever","count"]` | Available expiration methods |
+| `max_save_seconds` | int | `0` | Maximum file retention time (seconds), 0 means no limit |
+
+Expiration methods explained:
+- `day` - Expire by days
+- `hour` - Expire by hours
+- `minute` - Expire by minutes
+- `forever` - Never expire
+- `count` - Expire by download count
+
+## Theme Settings
+
+### Theme Selection
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `themesSelect` | string | `themes/2024` | Currently active theme |
+| `themesChoices` | list | See below | Available themes list |
+
+Default available themes:
+```json
+[
+ {
+ "name": "2023",
+ "key": "themes/2023",
+ "author": "Lan",
+ "version": "1.0"
+ },
+ {
+ "name": "2024",
+ "key": "themes/2024",
+ "author": "Lan",
+ "version": "1.0"
+ }
+]
+```
+
+### Interface Style
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `opacity` | float | `0.9` | Interface opacity (0-1) |
+| `background` | string | `""` | Custom background image URL, empty uses default background |
+
+## Admin Settings
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `admin_token` | string | `FileCodeBox2023` | Admin login password |
+| `showAdminAddr` | int | `0` | Show admin panel entry on homepage (1=show, 0=hide) |
+
+::: danger Security Warning
+Always change the default `admin_token` in production environments! Using the default password poses serious security risks.
+:::
+
+## Security Settings
+
+### Error Rate Limiting
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `errorMinute` | int | `1` | Error limit time window (minutes) |
+| `errorCount` | int | `1` | Maximum errors allowed within the time window |
+
+This setting prevents brute-force attacks on extraction codes.
+
+## Storage Settings
+
+### Storage Type
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `file_storage` | string | `local` | Storage backend type |
+| `storage_path` | string | `""` | Custom storage path |
+
+Supported storage types:
+- `local` - Local storage
+- `s3` - S3-compatible storage (AWS S3, Aliyun OSS, MinIO, etc.)
+- `onedrive` - OneDrive storage
+- `webdav` - WebDAV storage
+- `opendal` - OpenDAL storage
+
+For detailed storage configuration, see [Storage Configuration](/en/guide/storage).
+
+## Configuration Examples
+
+### Example 1: Small Personal Use
+
+Suitable for personal or small team use with relaxed limits:
+
+```python
+{
+ "name": "My File Share",
+ "uploadSize": 52428800, # 50MB
+ "uploadMinute": 5, # 5 minutes
+ "uploadCount": 20, # Max 20 uploads
+ "expireStyle": ["day", "hour", "forever"],
+ "admin_token": "your-secure-password",
+ "showAdminAddr": 1
+}
+```
+
+### Example 2: Public Service
+
+Suitable for public services requiring stricter limits:
+
+```python
+{
+ "name": "Public File Box",
+ "uploadSize": 10485760, # 10MB
+ "uploadMinute": 1, # 1 minute
+ "uploadCount": 5, # Max 5 uploads
+ "errorMinute": 5, # 5 minutes
+ "errorCount": 3, # Max 3 errors
+ "expireStyle": ["hour", "minute", "count"],
+ "max_save_seconds": 86400, # Max retention 1 day
+ "admin_token": "very-secure-password-123",
+ "showAdminAddr": 0
+}
+```
+
+### Example 3: Enterprise Internal Use
+
+Suitable for enterprise internal use with large file and chunked upload support:
+
+```python
+{
+ "name": "Enterprise File Transfer",
+ "uploadSize": 1073741824, # 1GB
+ "enableChunk": 1, # Enable chunked upload
+ "uploadMinute": 10, # 10 minutes
+ "uploadCount": 100, # Max 100 uploads
+ "expireStyle": ["day", "forever"],
+ "file_storage": "s3", # Use S3 storage
+ "admin_token": "enterprise-secure-token",
+ "showAdminAddr": 1
+}
+```
+
+## Next Steps
+
+- [Storage Configuration](/en/guide/storage) - Learn how to configure different storage backends
+- [Security Settings](/en/guide/security) - Learn how to enhance system security
+- [File Sharing](/en/guide/share) - Learn about file sharing features
diff --git a/docs/en/guide/management.md b/docs/en/guide/management.md
index e69de29bb..e22a65c1e 100644
--- a/docs/en/guide/management.md
+++ b/docs/en/guide/management.md
@@ -0,0 +1,413 @@
+# Admin Panel
+
+FileCodeBox provides a fully-featured admin panel that allows administrators to conveniently manage files, view system status, and modify configurations. This document introduces the various features and usage of the admin panel.
+
+## Accessing the Admin Panel
+
+### Login Method
+
+The admin panel is located at the `/admin` path. Access method:
+
+1. Visit `http://your-domain.com/admin` in your browser
+2. Enter the admin password (the value of the `admin_token` configuration)
+3. Click the login button
+
+::: tip Tip
+The default admin password is `FileCodeBox2023`. Be sure to change this password in production environments. See [Security Settings](/en/guide/security) for details.
+:::
+
+### Show Admin Entry
+
+By default, the admin panel entry is not shown on the homepage. You can control whether to show it via configuration:
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `showAdminAddr` | int | `0` | Show admin entry on homepage (1=show, 0=hide) |
+
+::: warning Security Recommendation
+For public services, it's recommended to keep `showAdminAddr` at `0` and access the admin panel directly via the `/admin` path to reduce the risk of malicious scanning.
+:::
+
+### Authentication Mechanism
+
+The admin panel uses JWT (JSON Web Token) for authentication:
+
+1. After successful login, the server returns a Token containing admin identity
+2. Subsequent requests carry the Token via `Authorization: Bearer ` header
+3. Token is used to verify admin identity, ensuring only authorized users can access admin functions
+
+## Dashboard
+
+After logging in, you first see the dashboard page, which displays the overall system status.
+
+### Statistics
+
+The dashboard displays the following key metrics:
+
+| Metric | Description |
+|--------|-------------|
+| **Total Files** (`totalFiles`) | Total number of files stored in the system |
+| **Storage Used** (`storageUsed`) | Total storage space occupied by all files (bytes) |
+| **System Uptime** (`sysUptime`) | Time when the system was first started |
+| **Yesterday's Uploads** (`yesterdayCount`) | Number of files uploaded yesterday |
+| **Yesterday's Upload Size** (`yesterdaySize`) | Total size of files uploaded yesterday (bytes) |
+| **Today's Uploads** (`todayCount`) | Number of files uploaded today so far |
+| **Today's Upload Size** (`todaySize`) | Total size of files uploaded today (bytes) |
+
+### Metric Notes
+
+- **Total Files**: Includes all unexpired files and text shares
+- **Storage Used**: Shows actual storage space occupied by files, excluding database and other system files
+- **Yesterday/Today Statistics**: Calculated based on file creation time, useful for understanding system usage trends
+
+::: tip Tip
+Storage usage is displayed in bytes. For example, `10485760` represents approximately 10MB.
+:::
+
+## File Management
+
+### File List
+
+The file management page displays all shared files in the system, supporting pagination and search.
+
+**List information includes:**
+- File ID
+- Extraction code (code)
+- Filename prefix (prefix)
+- File extension (suffix)
+- File size
+- Creation time
+- Expiration time
+- Remaining download count
+
+### Search Files
+
+Use the search function to quickly find specific files:
+
+1. Enter keywords in the search box
+2. System performs fuzzy matching based on filename prefix (prefix)
+3. Search results update in real-time
+
+**Search examples:**
+- Enter `report` to find all files with "report" in the filename
+- Enter `.pdf` to find all PDF files (if the filename contains this string)
+
+### Pagination
+
+The file list supports paginated display:
+
+| Parameter | Default | Description |
+|-----------|---------|-------------|
+| `page` | `1` | Current page number |
+| `size` | `10` | Items per page |
+
+
+### Delete Files
+
+Administrators can delete any file:
+
+1. Find the file to delete in the file list
+2. Click the delete button
+3. Confirm the delete operation
+
+::: danger Warning
+Delete operations are irreversible! Files will be permanently deleted from the storage backend, and database records will also be removed.
+:::
+
+**Delete process:**
+1. System first deletes the actual file from the storage backend (local/S3/OneDrive, etc.)
+2. Then deletes the file record from the database
+3. After deletion, the corresponding extraction code becomes invalid
+
+### Download Files
+
+Administrators can directly download any file:
+
+1. Find the target file in the file list
+2. Click the download button
+3. File will be downloaded via browser
+
+For text shares, the system returns text content directly instead of downloading a file.
+
+### Modify File Information
+
+Administrators can modify some information of shared files:
+
+| Modifiable Field | Description |
+|------------------|-------------|
+| `code` | Extraction code (must be unique, cannot duplicate other files) |
+| `prefix` | Filename prefix |
+| `suffix` | File extension |
+| `expired_at` | Expiration time |
+| `expired_count` | Remaining download count |
+
+**Modify extraction code:**
+```
+Original code: abc123
+New code: myfile2024
+```
+
+::: warning Note
+When modifying extraction codes, the system checks if the new code is already in use. If an identical extraction code exists, the modification will fail.
+:::
+
+## Local File Management
+
+In addition to managing shared files, the admin panel also provides local file management functionality for managing files in the `data/local` directory.
+
+### View Local Files
+
+The local file list displays all files in the `data/local` directory:
+
+| Information | Description |
+|-------------|-------------|
+| Filename | Complete filename |
+| Creation Time | File creation time |
+| File Size | File size (bytes) |
+
+### Share Local Files
+
+You can quickly share local files:
+
+1. Select the file to share in the local file list
+2. Set expiration method and value
+3. Click the share button
+4. System generates extraction code
+
+**Share parameters:**
+
+| Parameter | Description |
+|-----------|-------------|
+| `filename` | Filename to share |
+| `expire_style` | Expiration method (day/hour/minute/forever/count) |
+| `expire_value` | Expiration value (days/hours/minutes/download count) |
+
+### Delete Local Files
+
+You can delete files in the `data/local` directory:
+
+1. Find the file to delete in the local file list
+2. Click the delete button
+3. Confirm deletion
+
+::: tip Use Cases
+Local file management is useful for:
+- Sharing files after batch uploading to the server
+- Managing files uploaded to the server through other means
+- Cleaning up unnecessary local files
+:::
+
+## System Settings
+
+### View Configuration
+
+On the system settings page, you can view the current values of all configuration items. Configuration items are grouped by category:
+
+- Basic settings (site name, description, etc.)
+- Upload settings (file size limits, rate limits, etc.)
+- Storage settings (storage type, path, etc.)
+- Theme settings (theme selection, opacity, etc.)
+- Security settings (admin password, error limits, etc.)
+
+### Modify Configuration
+
+Administrators can modify most configurations through the admin panel:
+
+1. Go to the system settings page
+2. Find the configuration item to modify
+3. Enter the new value
+4. Click the save button
+
+**Modifiable configuration items:**
+
+| Category | Example Settings |
+|----------|------------------|
+| Basic Settings | `name`, `description`, `keywords`, `notify_title`, `notify_content` |
+| Upload Settings | `uploadSize`, `uploadMinute`, `uploadCount`, `openUpload`, `enableChunk` |
+| Expiration Settings | `expireStyle`, `max_save_seconds` |
+| Theme Settings | `themesSelect`, `opacity`, `background` |
+| Security Settings | `admin_token`, `showAdminAddr`, `errorMinute`, `errorCount` |
+| Storage Settings | `file_storage`, `storage_path` and storage backend-specific configurations |
+
+::: warning Note
+- `admin_token` (admin password) cannot be set to empty
+- `themesChoices` (theme list) cannot be modified through the admin panel
+- After modifying storage settings, existing files will not be automatically migrated
+:::
+
+### Configuration Effect
+
+Configuration changes take effect immediately without restarting the service. Configurations are saved in the database and persist after restart.
+
+**Configuration storage location:**
+- Database: `data/filecodebox.db`
+- Table name: `keyvalue`
+- Key name: `settings`
+
+## API Endpoints
+
+All admin panel functions are implemented through REST APIs. Here are the main endpoints:
+
+### Authentication Endpoint
+
+**Login**
+```
+POST /admin/login
+Content-Type: application/json
+
+{
+ "password": "your-admin-password"
+}
+```
+
+Response:
+```json
+{
+ "code": 200,
+ "detail": {
+ "token": "eyJhbGciOiJIUzI1NiIs...",
+ "token_type": "Bearer"
+ }
+}
+```
+
+### Dashboard Endpoint
+
+**Get Statistics**
+```
+GET /admin/dashboard
+Authorization: Bearer
+```
+
+### File Management Endpoints
+
+**Get File List**
+```
+GET /admin/file/list?page=1&size=10&keyword=
+Authorization: Bearer
+```
+
+**Delete File**
+```
+DELETE /admin/file/delete
+Authorization: Bearer
+Content-Type: application/json
+
+{
+ "id": 123
+}
+```
+
+**Download File**
+```
+GET /admin/file/download?id=123
+Authorization: Bearer
+```
+
+**Modify File Information**
+```
+PATCH /admin/file/update
+Authorization: Bearer
+Content-Type: application/json
+
+{
+ "id": 123,
+ "code": "newcode",
+ "expired_at": "2024-12-31T23:59:59"
+}
+```
+
+### Local File Endpoints
+
+**Get Local File List**
+```
+GET /admin/local/lists
+Authorization: Bearer
+```
+
+**Delete Local File**
+```
+DELETE /admin/local/delete
+Authorization: Bearer
+Content-Type: application/json
+
+{
+ "filename": "example.txt"
+}
+```
+
+**Share Local File**
+```
+POST /admin/local/share
+Authorization: Bearer
+Content-Type: application/json
+
+{
+ "filename": "example.txt",
+ "expire_style": "day",
+ "expire_value": 7
+}
+```
+
+### Configuration Endpoints
+
+**Get Configuration**
+```
+GET /admin/config/get
+Authorization: Bearer
+```
+
+**Update Configuration**
+```
+PATCH /admin/config/update
+Authorization: Bearer
+Content-Type: application/json
+
+{
+ "admin_token": "new-password",
+ "uploadSize": 52428800
+}
+```
+
+## Common Issues
+
+### Forgot Admin Password
+
+If you forgot the admin password, you can reset it through the following methods:
+
+1. Stop the FileCodeBox service
+2. Open `data/filecodebox.db` using an SQLite tool
+3. Query the record with `key='settings'` in the `keyvalue` table
+4. Modify the `admin_token` value in the JSON
+5. Restart the service
+
+```sql
+-- View current configuration
+SELECT * FROM keyvalue WHERE key = 'settings';
+
+-- Or delete configuration to restore default password
+DELETE FROM keyvalue WHERE key = 'settings';
+```
+
+### File Deletion Failed
+
+If an error occurs when deleting files, possible reasons:
+
+1. **Storage backend connection failed**: Check if storage configuration is correct
+2. **File no longer exists**: File may have been manually deleted
+3. **Insufficient permissions**: Check write permissions for storage directory
+
+### Configuration Changes Not Taking Effect
+
+If configuration changes don't take effect:
+
+1. Check if you clicked the save button
+2. Refresh the page to see if configuration was saved
+3. Check browser console for error messages
+4. Confirm configuration value format is correct (e.g., don't enter strings for numeric types)
+
+## Next Steps
+
+- [Configuration Guide](/en/guide/configuration) - Learn detailed descriptions of all configuration options
+- [Security Settings](/en/guide/security) - Learn how to enhance system security
+- [Storage Configuration](/en/guide/storage) - Configure different storage backends
diff --git a/docs/en/guide/security.md b/docs/en/guide/security.md
index e69de29bb..3c741187e 100644
--- a/docs/en/guide/security.md
+++ b/docs/en/guide/security.md
@@ -0,0 +1,325 @@
+# Security Settings
+
+FileCodeBox provides multiple layers of security mechanisms to protect your file sharing service. This document explains how to properly configure security options to ensure secure system operation.
+
+## Admin Password
+
+### Change Default Password
+
+::: danger Important Security Warning
+FileCodeBox's default admin password is `FileCodeBox2023`. **You must change this password immediately in production environments!** Using the default password allows anyone to access your admin panel.
+:::
+
+There are two ways to change the admin password:
+
+**Method 1: Via Admin Panel (Recommended)**
+
+1. Access `/admin` to enter the admin panel
+2. Log in with the current password
+3. Go to the "System Settings" page
+4. Find the `admin_token` configuration item
+5. Enter a new secure password and save
+
+**Method 2: Via Database**
+
+Configuration is stored in the `keyvalue` table of the `data/filecodebox.db` database. You can directly modify the `admin_token` value.
+
+### Password Security Recommendations
+
+- Use a strong password with at least 16 characters
+- Include uppercase and lowercase letters, numbers, and special characters
+- Avoid common words or personal information
+- Change password regularly
+
+```python
+# Recommended password format example
+"admin_token": "Xk9#mP2$vL5@nQ8&wR3"
+```
+
+### Hide Admin Entry
+
+By default, the admin panel entry is hidden. You can control whether to show the admin entry on the homepage via the `showAdminAddr` configuration:
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `showAdminAddr` | int | `0` | Show admin entry (1=show, 0=hide) |
+
+::: tip Recommendation
+For public services, it's recommended to keep `showAdminAddr` at `0` and access the admin panel directly via the `/admin` path.
+:::
+
+## IP Rate Limiting
+
+FileCodeBox has built-in IP-based rate limiting mechanisms to effectively prevent abuse and attacks.
+
+### Upload Rate Limiting
+
+Limit the number of uploads from a single IP within a specified time:
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `uploadMinute` | int | `1` | Upload limit time window (minutes) |
+| `uploadCount` | int | `10` | Maximum uploads allowed within the time window |
+
+**How it works:**
+- System records upload requests from each IP
+- When an IP's upload count reaches `uploadCount` within `uploadMinute` minutes
+- Subsequent upload requests from that IP will be rejected with HTTP 423 error
+- Counter resets after the time window expires
+
+**Configuration examples:**
+
+```python
+# Relaxed configuration: Max 20 uploads in 5 minutes
+{
+ "uploadMinute": 5,
+ "uploadCount": 20
+}
+
+# Strict configuration: Max 3 uploads in 1 minute
+{
+ "uploadMinute": 1,
+ "uploadCount": 3
+}
+```
+
+
+### Error Rate Limiting
+
+Limit the number of error attempts from a single IP to prevent brute-force attacks on extraction codes:
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `errorMinute` | int | `1` | Error limit time window (minutes) |
+| `errorCount` | int | `1` | Maximum errors allowed within the time window |
+
+**How it works:**
+- When a user enters an incorrect extraction code, the system records the error count for that IP
+- When error count reaches `errorCount`, that IP will be temporarily locked
+- Lock duration is `errorMinute` minutes
+- During lockout, all extraction requests from that IP will be rejected
+
+**Configuration example:**
+
+```python
+# Anti-brute-force configuration: Max 3 errors in 5 minutes
+{
+ "errorMinute": 5,
+ "errorCount": 3
+}
+```
+
+::: warning Note
+The default configuration `errorMinute=1, errorCount=1` is very strict, meaning you need to wait 1 minute after entering one incorrect extraction code before retrying. Adjust this configuration based on actual needs.
+:::
+
+## Upload Restrictions
+
+### File Size Limit
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `uploadSize` | int | `10485760` | Maximum single file upload size (bytes), default 10MB |
+| `openUpload` | int | `1` | Enable upload functionality (1=enabled, 0=disabled) |
+
+**Common size conversions:**
+- 10MB = 10 * 1024 * 1024 = `10485760`
+- 50MB = 50 * 1024 * 1024 = `52428800`
+- 100MB = 100 * 1024 * 1024 = `104857600`
+- 1GB = 1024 * 1024 * 1024 = `1073741824`
+
+### File Expiration Settings
+
+Through file expiration mechanisms, you can automatically clean up expired files, reducing storage usage and security risks:
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `expireStyle` | list | `["day","hour","minute","forever","count"]` | Available expiration methods |
+| `max_save_seconds` | int | `0` | Maximum file retention time (seconds), 0 means no limit |
+
+**Expiration methods explained:**
+- `day` - Expire by days
+- `hour` - Expire by hours
+- `minute` - Expire by minutes
+- `forever` - Never expire (requires alphanumeric extraction code)
+- `count` - Expire by download count
+
+**Security recommendations:**
+
+For public services, it's recommended to:
+1. Remove the `forever` option to avoid permanent file storage
+2. Set `max_save_seconds` to limit maximum retention time
+3. Prefer using `count` method for automatic deletion after download
+
+```python
+# Recommended configuration for public services
+{
+ "expireStyle": ["hour", "minute", "count"],
+ "max_save_seconds": 86400 # Max retention 1 day
+}
+```
+
+### Disable Upload Functionality
+
+In some cases, you may need to temporarily disable upload functionality:
+
+```python
+{
+ "openUpload": 0 # Disable upload functionality
+}
+```
+
+## Reverse Proxy Security Configuration
+
+In production environments, Nginx or other reverse proxy servers are typically used. Here are security configuration recommendations:
+
+### Nginx Configuration Example
+
+```nginx
+server {
+ listen 80;
+ server_name your-domain.com;
+
+ # Force HTTPS redirect
+ return 301 https://$server_name$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ server_name your-domain.com;
+
+ # SSL certificate configuration
+ ssl_certificate /path/to/cert.pem;
+ ssl_certificate_key /path/to/key.pem;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
+ ssl_prefer_server_ciphers on;
+
+ # Security headers
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+ # Limit request body size (match uploadSize configuration)
+ client_max_body_size 100M;
+
+ # Pass real IP
+ location / {
+ proxy_pass http://127.0.0.1:12345;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # Static resource caching
+ location /assets {
+ proxy_pass http://127.0.0.1:12345;
+ proxy_cache_valid 200 7d;
+ add_header Cache-Control "public, max-age=604800";
+ }
+}
+```
+
+### Key Security Configuration Notes
+
+**1. Pass Real IP**
+
+FileCodeBox's IP limiting functionality depends on obtaining the client's real IP. The system obtains IP in the following order:
+1. `X-Real-IP` request header
+2. `X-Forwarded-For` request header
+3. Direct client connection IP
+
+Ensure the reverse proxy correctly sets these headers:
+
+```nginx
+proxy_set_header X-Real-IP $remote_addr;
+proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+```
+
+**2. Request Body Size Limit**
+
+Nginx's `client_max_body_size` should match or be slightly larger than FileCodeBox's `uploadSize` configuration:
+
+```nginx
+client_max_body_size 100M; # Allow max 100MB uploads
+```
+
+**3. HTTPS Encryption**
+
+It's strongly recommended to enable HTTPS in production environments:
+- Protect uploaded file content
+- Protect admin login credentials
+- Prevent man-in-the-middle attacks
+
+### Caddy Configuration Example
+
+```nginx
+your-domain.com {
+ reverse_proxy localhost:12345
+
+ header {
+ X-Frame-Options "SAMEORIGIN"
+ X-Content-Type-Options "nosniff"
+ X-XSS-Protection "1; mode=block"
+ Strict-Transport-Security "max-age=31536000; includeSubDomains"
+ }
+}
+```
+
+## Security Checklist
+
+Before deploying FileCodeBox, confirm the following security configurations:
+
+- [ ] Changed default admin password `admin_token`
+- [ ] Hidden admin entry `showAdminAddr: 0`
+- [ ] Configured appropriate upload rate limiting
+- [ ] Configured error rate limiting to prevent brute-force attacks
+- [ ] Set reasonable file size limits
+- [ ] Configured file expiration policy
+- [ ] Enabled HTTPS encryption
+- [ ] Reverse proxy correctly passes real IP
+- [ ] Set security response headers
+
+## Recommended Security Configurations
+
+### Public Service Configuration
+
+```python
+{
+ "admin_token": "your-very-secure-password",
+ "showAdminAddr": 0,
+ "uploadSize": 10485760, # 10MB
+ "uploadMinute": 1,
+ "uploadCount": 5,
+ "errorMinute": 5,
+ "errorCount": 3,
+ "expireStyle": ["hour", "minute", "count"],
+ "max_save_seconds": 86400, # Max 1 day
+ "openUpload": 1
+}
+```
+
+### Internal Service Configuration
+
+```python
+{
+ "admin_token": "internal-secure-password",
+ "showAdminAddr": 1,
+ "uploadSize": 104857600, # 100MB
+ "uploadMinute": 5,
+ "uploadCount": 50,
+ "errorMinute": 1,
+ "errorCount": 5,
+ "expireStyle": ["day", "hour", "forever"],
+ "max_save_seconds": 0, # No limit
+ "openUpload": 1
+}
+```
+
+## Next Steps
+
+- [Configuration Guide](/en/guide/configuration) - Learn about all configuration options
+- [Storage Configuration](/en/guide/storage) - Configure secure storage backends
+- [File Sharing](/en/guide/share) - Learn about file sharing features
diff --git a/docs/en/guide/share.md b/docs/en/guide/share.md
index e69de29bb..0abb1a2f4 100644
--- a/docs/en/guide/share.md
+++ b/docs/en/guide/share.md
@@ -0,0 +1,342 @@
+# File Sharing
+
+FileCodeBox provides simple and easy-to-use file and text sharing functionality. Users can securely share and retrieve files using extraction codes.
+
+## Sharing Methods
+
+FileCodeBox supports two sharing methods:
+
+1. **Text Sharing** - Share text content directly, suitable for code snippets, configuration files, etc.
+2. **File Sharing** - Upload files for sharing, supports various file formats
+
+## Text Sharing
+
+### How to Use
+
+1. Select the "Text Share" tab on the homepage
+2. Enter or paste the content to share in the text box
+3. Select expiration method and time
+4. Click the "Share" button
+5. Get the extraction code
+
+### Text Size Limit
+
+::: warning Note
+The maximum content size for text sharing is **222KB** (227,328 bytes). If content exceeds this limit, it's recommended to use file sharing instead.
+:::
+
+Text content size is calculated using UTF-8 encoding. Chinese characters typically occupy 3 bytes.
+
+### API Endpoint
+
+**POST** `/share/text/`
+
+Request parameters:
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `text` | string | Yes | Text content to share |
+| `expire_value` | int | No | Expiration value, default 1 |
+| `expire_style` | string | No | Expiration method, default `day` |
+
+Response example:
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "123456"
+ }
+}
+```
+
+## File Sharing
+
+### How to Use
+
+1. Select the "File Share" tab on the homepage
+2. Click the upload area or drag files to the upload area
+3. Select expiration method and time
+4. Click the "Upload" button
+5. Get the extraction code
+
+### File Size Limit
+
+The default maximum single file upload size is **10MB**. Administrators can modify this limit via the `uploadSize` configuration.
+
+::: tip Tip
+If you need to upload large files, contact the administrator to enable chunked upload functionality or adjust the `uploadSize` configuration.
+:::
+
+### Supported Upload Methods
+
+- **Click Upload** - Click the upload area to select files
+- **Drag Upload** - Drag files to the upload area
+- **Paste Upload** - Paste images from clipboard (supported by some themes)
+
+### API Endpoint
+
+**POST** `/share/file/`
+
+Request parameters (multipart/form-data):
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `file` | file | Yes | File to upload |
+| `expire_value` | int | No | Expiration value, default 1 |
+| `expire_style` | string | No | Expiration method, default `day` |
+
+Response example:
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "654321",
+ "name": "example.pdf"
+ }
+}
+```
+
+
+## Expiration Settings
+
+FileCodeBox supports multiple flexible expiration methods:
+
+| Expiration Method | Parameter Value | Description |
+|-------------------|-----------------|-------------|
+| By Days | `day` | File expires after specified days |
+| By Hours | `hour` | File expires after specified hours |
+| By Minutes | `minute` | File expires after specified minutes |
+| Never Expire | `forever` | File is permanently valid |
+| By Count | `count` | File expires after specified download count |
+
+::: info Note
+- Administrators can control available expiration methods via the `expireStyle` configuration
+- Administrators can limit maximum file retention time via the `max_save_seconds` configuration
+:::
+
+### Expiration Method Examples
+
+```bash
+# File expires after 3 days
+expire_value=3, expire_style=day
+
+# File expires after 12 hours
+expire_value=12, expire_style=hour
+
+# File expires after 30 minutes
+expire_value=30, expire_style=minute
+
+# File never expires
+expire_value=1, expire_style=forever
+
+# File expires after 5 downloads
+expire_value=5, expire_style=count
+```
+
+## Retrieving Files
+
+### How to Use
+
+1. Enter the extraction code in the "Retrieve File" area on the homepage
+2. Click the "Retrieve" button
+3. System displays file information (filename, size, etc.)
+4. Click the "Download" button to download the file, or view text content directly
+
+### Extraction Code Notes
+
+- Extraction codes are typically **6-digit numbers**
+- Files that never expire use **alphanumeric** extraction codes
+- Extraction codes are case-sensitive (for alphanumeric codes)
+
+### API Endpoints
+
+**Query File Information**
+
+**POST** `/share/select/`
+
+Request parameters:
+
+```json
+{
+ "code": "123456"
+}
+```
+
+Response example (file):
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "123456",
+ "name": "example.pdf",
+ "size": 1048576,
+ "text": "https://example.com/download/..."
+ }
+}
+```
+
+Response example (text):
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "123456",
+ "name": "Text",
+ "size": 1024,
+ "text": "This is the shared text content..."
+ }
+}
+```
+
+**Direct File Download**
+
+**GET** `/share/select/?code=123456`
+
+This endpoint returns file content directly, suitable for direct browser access.
+
+## Chunked Upload (Large Files)
+
+For large file uploads, FileCodeBox supports chunked upload functionality. This feature requires administrator enablement (`enableChunk=1`).
+
+### Chunked Upload Flow
+
+```mermaid
+sequenceDiagram
+ participant C as Client
+ participant S as Server
+
+ C->>S: 1. Initialize upload (POST /chunk/upload/init/)
+ S-->>C: Return upload_id and chunk info
+
+ loop Each chunk
+ C->>S: 2. Upload chunk (POST /chunk/upload/chunk/{upload_id}/{chunk_index})
+ S-->>C: Return chunk hash
+ end
+
+ C->>S: 3. Complete upload (POST /chunk/upload/complete/{upload_id})
+ S-->>C: Return extraction code
+```
+
+### 1. Initialize Upload
+
+**POST** `/chunk/upload/init/`
+
+Request parameters:
+
+```json
+{
+ "file_name": "large_file.zip",
+ "file_size": 104857600,
+ "chunk_size": 5242880,
+ "file_hash": "sha256_hash_of_file"
+}
+```
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `file_name` | string | Yes | Filename |
+| `file_size` | int | Yes | Total file size (bytes) |
+| `chunk_size` | int | No | Chunk size, default 5MB |
+| `file_hash` | string | Yes | SHA256 hash of the file |
+
+Response example:
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "existed": false,
+ "upload_id": "abc123def456",
+ "chunk_size": 5242880,
+ "total_chunks": 20,
+ "uploaded_chunks": []
+ }
+}
+```
+
+### 2. Upload Chunk
+
+**POST** `/chunk/upload/chunk/{upload_id}/{chunk_index}`
+
+- `upload_id` - Upload session ID returned during initialization
+- `chunk_index` - Chunk index, starting from 0
+
+Request body: Chunk file data (multipart/form-data)
+
+Response example:
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "chunk_hash": "sha256_hash_of_chunk"
+ }
+}
+```
+
+### 3. Complete Upload
+
+**POST** `/chunk/upload/complete/{upload_id}`
+
+Request parameters:
+
+```json
+{
+ "expire_value": 1,
+ "expire_style": "day"
+}
+```
+
+Response example:
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "789012",
+ "name": "large_file.zip"
+ }
+}
+```
+
+### Resume Upload
+
+Chunked upload supports resume functionality. If upload is interrupted:
+
+1. Call the initialization endpoint again with the same `file_hash`
+2. Server returns `uploaded_chunks` list containing already uploaded chunk indices
+3. Client only needs to upload chunks not in the list
+
+## Error Handling
+
+### Common Error Codes
+
+| Error Code | Description | Solution |
+|------------|-------------|----------|
+| 403 | File size exceeds limit | Reduce file size or contact administrator to adjust limit |
+| 403 | Content too large | Text exceeds 222KB, use file sharing instead |
+| 403 | Upload rate limit | Wait a while before retrying |
+| 404 | File not found | Check if extraction code is correct |
+| 404 | File expired | File has expired or download count exhausted |
+
+### Rate Limiting
+
+To prevent abuse, the system has rate limits on upload and retrieval operations:
+
+- **Upload limit**: Default max 10 uploads per minute
+- **Error limit**: Default max 1 error attempt per minute
+
+::: tip Tip
+If you encounter rate limiting, wait for the limit time window to pass before retrying.
+:::
+
+## Next Steps
+
+- [Configuration Guide](/en/guide/configuration) - Learn how to configure sharing-related settings
+- [Storage Configuration](/en/guide/storage) - Learn about file storage methods
+- [Security Settings](/en/guide/security) - Learn about security-related configurations
+- [Admin Panel](/en/guide/management) - Learn how to manage shared files
diff --git a/docs/en/guide/storage.md b/docs/en/guide/storage.md
index e69de29bb..6997e439a 100644
--- a/docs/en/guide/storage.md
+++ b/docs/en/guide/storage.md
@@ -0,0 +1,395 @@
+# Storage Configuration
+
+FileCodeBox supports multiple storage backends. You can choose the appropriate storage method based on your needs. This document details the configuration methods for various storage backends.
+
+## Storage Types Overview
+
+| Storage Type | Config Value | Description |
+|--------------|--------------|-------------|
+| Local Storage | `local` | Default storage method, files saved on local server |
+| S3-Compatible Storage | `s3` | Supports AWS S3, Aliyun OSS, MinIO, etc. |
+| OneDrive | `onedrive` | Microsoft OneDrive cloud storage (work/school accounts only) |
+| WebDAV | `webdav` | Storage services supporting WebDAV protocol |
+| OpenDAL | `opendal` | Integrate more storage services via OpenDAL |
+
+## Local Storage
+
+Local storage is the default storage method. Files are saved in the server's `data/` directory.
+
+### Configuration Parameters
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `file_storage` | string | `local` | Storage type |
+| `storage_path` | string | `""` | Custom storage path (optional) |
+
+### Configuration Example
+
+```bash
+file_storage=local
+storage_path=
+```
+
+### Notes
+
+- Files are stored by default in `data/share/data/` directory
+- Subdirectories are automatically created by date: `year/month/day/fileID/`
+- In production, it's recommended to mount the `data/` directory to persistent storage
+
+## S3-Compatible Storage
+
+Supports all S3-compatible object storage services, including AWS S3, Aliyun OSS, MinIO, Tencent Cloud COS, etc.
+
+### Configuration Parameters
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `file_storage` | string | - | Set to `s3` |
+| `s3_access_key_id` | string | `""` | Access Key ID |
+| `s3_secret_access_key` | string | `""` | Secret Access Key |
+| `s3_bucket_name` | string | `""` | Bucket name |
+| `s3_endpoint_url` | string | `""` | S3 endpoint URL |
+| `s3_region_name` | string | `auto` | Region name |
+| `s3_signature_version` | string | `s3v2` | Signature version (`s3v2` or `s3v4`) |
+| `s3_hostname` | string | `""` | S3 hostname (alternative) |
+| `s3_proxy` | int | `0` | Download through server proxy (1=yes, 0=no) |
+| `aws_session_token` | string | `""` | AWS session token (optional) |
+
+
+### AWS S3 Configuration Example
+
+```bash
+file_storage=s3
+s3_access_key_id=AKIAIOSFODNN7EXAMPLE
+s3_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+s3_bucket_name=my-filecodebox-bucket
+s3_endpoint_url=https://s3.amazonaws.com
+s3_region_name=us-east-1
+s3_signature_version=s3v4
+```
+
+### Aliyun OSS Configuration Example
+
+```bash
+file_storage=s3
+s3_access_key_id=YourAccessKeyId
+s3_secret_access_key=YourSecretAccessKey
+s3_bucket_name=bucket-name
+s3_endpoint_url=https://bucket-name.oss-cn-hangzhou.aliyuncs.com
+s3_region_name=oss-cn-hangzhou
+s3_signature_version=s3v4
+```
+
+::: tip Aliyun OSS Endpoint Format
+Endpoint URL format: `https://..aliyuncs.com`
+
+Common regions:
+- Hangzhou: `oss-cn-hangzhou`
+- Shanghai: `oss-cn-shanghai`
+- Beijing: `oss-cn-beijing`
+- Shenzhen: `oss-cn-shenzhen`
+:::
+
+### MinIO Configuration Example
+
+```bash
+file_storage=s3
+s3_access_key_id=minioadmin
+s3_secret_access_key=minioadmin
+s3_bucket_name=filecodebox
+s3_endpoint_url=http://localhost:9000
+s3_region_name=us-east-1
+s3_signature_version=s3v4
+```
+
+::: warning MinIO Notes
+- `s3_endpoint_url` should be the MinIO API interface address
+- `s3_region_name` should match the `Server Location` in MinIO configuration
+- Ensure the bucket is created and has correct access permissions
+:::
+
+### Tencent Cloud COS Configuration Example
+
+```bash
+file_storage=s3
+s3_access_key_id=YourSecretId
+s3_secret_access_key=YourSecretKey
+s3_bucket_name=bucket-name-1250000000
+s3_endpoint_url=https://cos.ap-guangzhou.myqcloud.com
+s3_region_name=ap-guangzhou
+s3_signature_version=s3v4
+```
+
+### Proxy Download
+
+When `s3_proxy=1`, file downloads are proxied through the server instead of directly from S3. This is useful when:
+
+- S3 bucket doesn't allow public access
+- Need to hide the actual storage address
+- Network environment restricts direct S3 access
+
+## OneDrive Storage
+
+OneDrive storage supports saving files to Microsoft OneDrive cloud storage.
+
+::: warning Important Limitation
+OneDrive storage **only supports work or school accounts** and requires admin permissions to authorize the API. Personal accounts cannot use this feature.
+:::
+
+### Configuration Parameters
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `file_storage` | string | - | Set to `onedrive` |
+| `onedrive_domain` | string | `""` | Azure AD domain |
+| `onedrive_client_id` | string | `""` | Application (client) ID |
+| `onedrive_username` | string | `""` | Account email |
+| `onedrive_password` | string | `""` | Account password |
+| `onedrive_root_path` | string | `filebox_storage` | Storage root directory in OneDrive |
+| `onedrive_proxy` | int | `0` | Download through server proxy |
+
+### Configuration Example
+
+```bash
+file_storage=onedrive
+onedrive_domain=contoso.onmicrosoft.com
+onedrive_client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+onedrive_username=user@contoso.onmicrosoft.com
+onedrive_password=your_password
+onedrive_root_path=filebox_storage
+```
+
+### Azure App Registration Steps
+
+To use OneDrive storage, you need to register an application in the Azure portal:
+
+#### 1. Get Domain
+
+Log in to [Azure Portal](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade), hover over your account in the top right corner, and the **Domain** shown in the popup is the `onedrive_domain` value.
+
+#### 2. Register Application
+
+1. Click **+ New registration** in the top left
+2. Enter application name (e.g., FileCodeBox)
+3. **Supported account types**: Select "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts"
+4. **Redirect URI**: Select `Web`, enter `http://localhost`
+5. Click **Register**
+
+#### 3. Get Client ID
+
+After registration, find the **Application (client) ID** in the **Essentials** section on the app overview page. This is the `onedrive_client_id` value.
+
+#### 4. Configure Authentication
+
+1. Select **Authentication** in the left menu
+2. Find **Allow public client flows**, select **Yes**
+3. Click **Save**
+
+#### 5. Configure API Permissions
+
+1. Select **API permissions** in the left menu
+2. Click **+ Add a permission**
+3. Select **Microsoft Graph** → **Delegated permissions**
+4. Check the following permissions:
+ - `openid`
+ - `Files.Read`
+ - `Files.Read.All`
+ - `Files.ReadWrite`
+ - `Files.ReadWrite.All`
+ - `User.Read`
+5. Click **Add permissions**
+6. Click **Grant admin consent for xxx**
+7. After confirmation, permission status should show **Granted**
+
+### Install Dependencies
+
+Using OneDrive storage requires additional Python dependencies:
+
+```bash
+pip install msal Office365-REST-Python-Client
+```
+
+### Verify Configuration
+
+You can use the following code to test if the configuration is correct:
+
+```python
+import msal
+from office365.graph_client import GraphClient
+
+domain = 'your_domain'
+client_id = 'your_client_id'
+username = 'your_username'
+password = 'your_password'
+
+def acquire_token_pwd():
+ authority_url = f'https://login.microsoftonline.com/{domain}'
+ app = msal.PublicClientApplication(
+ authority=authority_url,
+ client_id=client_id
+ )
+ result = app.acquire_token_by_username_password(
+ username=username,
+ password=password,
+ scopes=['https://graph.microsoft.com/.default']
+ )
+ return result
+
+# Test connection
+client = GraphClient(acquire_token_pwd)
+me = client.me.get().execute_query()
+print(f"Login successful: {me.user_principal_name}")
+```
+
+
+## WebDAV Storage
+
+WebDAV storage supports saving files to any service that supports the WebDAV protocol, such as Nextcloud, ownCloud, Nutstore, etc.
+
+### Configuration Parameters
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `file_storage` | string | - | Set to `webdav` |
+| `webdav_url` | string | `""` | WebDAV server URL |
+| `webdav_username` | string | `""` | WebDAV username |
+| `webdav_password` | string | `""` | WebDAV password |
+| `webdav_root_path` | string | `filebox_storage` | Storage root directory in WebDAV |
+| `webdav_proxy` | int | `0` | Download through server proxy |
+
+### Configuration Example
+
+```bash
+file_storage=webdav
+webdav_url=https://dav.example.com/remote.php/dav/files/username/
+webdav_username=your_username
+webdav_password=your_password
+webdav_root_path=filebox_storage
+```
+
+### Nextcloud Configuration Example
+
+```bash
+file_storage=webdav
+webdav_url=https://your-nextcloud.com/remote.php/dav/files/username/
+webdav_username=your_username
+webdav_password=your_app_password
+webdav_root_path=FileCodeBox
+```
+
+::: tip Nextcloud App Password
+It's recommended to create an app password in Nextcloud instead of using your main password:
+1. Log in to Nextcloud
+2. Go to **Settings** → **Security**
+3. Create a new app password in **Devices & sessions**
+:::
+
+### Nutstore Configuration Example
+
+```bash
+file_storage=webdav
+webdav_url=https://dav.jianguoyun.com/dav/
+webdav_username=your_email@example.com
+webdav_password=your_app_password
+webdav_root_path=FileCodeBox
+```
+
+::: tip Nutstore App Password
+Nutstore requires an app password:
+1. Log in to Nutstore web version
+2. Go to **Account Info** → **Security Options**
+3. Add an app password
+:::
+
+## OpenDAL Storage
+
+OpenDAL is a unified data access layer that supports multiple storage services. Through OpenDAL, you can use Google Cloud Storage, Azure Blob Storage, and more.
+
+### Configuration Parameters
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `file_storage` | string | Set to `opendal` |
+| `opendal_scheme` | string | Storage service type (e.g., `gcs`, `azblob`) |
+| `opendal__` | string | Service-specific configuration parameters |
+
+### Install Dependencies
+
+```bash
+pip install opendal
+```
+
+### Google Cloud Storage Configuration Example
+
+```bash
+file_storage=opendal
+opendal_scheme=gcs
+opendal_gcs_root=/filecodebox
+opendal_gcs_bucket=your-bucket-name
+opendal_gcs_credential=base64_encoded_credential
+```
+
+### Azure Blob Storage Configuration Example
+
+```bash
+file_storage=opendal
+opendal_scheme=azblob
+opendal_azblob_root=/filecodebox
+opendal_azblob_container=your-container
+opendal_azblob_account_name=your_account
+opendal_azblob_account_key=your_key
+```
+
+### Supported Services
+
+OpenDAL supports numerous storage services. For the complete list, see the [OpenDAL Official Documentation](https://opendal.apache.org/docs/rust/opendal/services/index.html).
+
+Common services include:
+- `gcs` - Google Cloud Storage
+- `azblob` - Azure Blob Storage
+- `obs` - Huawei Cloud OBS
+- `oss` - Aliyun OSS (via OpenDAL)
+- `cos` - Tencent Cloud COS (via OpenDAL)
+- `hdfs` - Hadoop HDFS
+- `ftp` - FTP server
+- `sftp` - SFTP server
+
+::: warning OpenDAL Notes
+1. Services integrated via OpenDAL download through server proxy, consuming both storage service and server bandwidth
+2. Compared to native S3/OneDrive support, OpenDAL may lack some debugging information
+3. OpenDAL is written in Rust with good performance
+:::
+
+## Storage Selection Recommendations
+
+| Scenario | Recommended Storage | Reason |
+|----------|---------------------|--------|
+| Personal/Small deployment | Local storage | Simple and easy, no extra configuration needed |
+| Enterprise intranet | MinIO + S3 | Self-hosted object storage, data control |
+| Public cloud deployment | Corresponding cloud provider S3 | Fast same-region access, low cost |
+| Existing OneDrive | OneDrive | Utilize existing resources |
+| Existing WebDAV | WebDAV | Good compatibility |
+| Special storage needs | OpenDAL | Supports more storage services |
+
+## Common Issues
+
+### S3 Upload Failure
+
+1. Check if Access Key and Secret Key are correct
+2. Confirm bucket name and region configuration are correct
+3. Check bucket access permission settings
+4. Confirm signature version (`s3v2` or `s3v4`) matches service provider requirements
+
+### OneDrive Authentication Failure
+
+1. Confirm using a work/school account, not a personal account
+2. Check if Azure app has been granted admin consent
+3. Confirm API permissions are fully configured
+4. Verify username and password are correct
+
+### WebDAV Connection Failure
+
+1. Check if WebDAV URL format is correct
+2. Confirm username and password (or app password) are correct
+3. Check if server supports WebDAV protocol
+4. Confirm network connection is normal
diff --git a/docs/en/guide/upload copy.md b/docs/en/guide/upload copy.md
deleted file mode 100644
index e69de29bb..000000000
diff --git a/docs/en/guide/upload.md b/docs/en/guide/upload.md
index e69de29bb..1dd9306c6 100644
--- a/docs/en/guide/upload.md
+++ b/docs/en/guide/upload.md
@@ -0,0 +1,421 @@
+# File Upload
+
+FileCodeBox provides multiple flexible file upload methods, supporting both regular upload and chunked upload to meet different scenario requirements.
+
+## Upload Methods
+
+FileCodeBox supports the following upload methods:
+
+### Drag and Drop Upload
+
+Drag files directly to the upload area to start uploading. This is the most convenient upload method.
+
+1. Open the FileCodeBox homepage
+2. Drag files from your file manager to the upload area
+3. Release the mouse, file upload begins
+4. Get the extraction code after upload completes
+
+::: tip Tip
+Drag and drop upload supports dragging multiple files simultaneously (depending on theme support).
+:::
+
+### Click Upload
+
+Click the upload area to select files through the system file picker.
+
+1. Click the "Select File" button in the upload area
+2. Select the file to upload in the popup file picker
+3. File upload begins after confirming selection
+4. Get the extraction code after upload completes
+
+### Paste Upload
+
+Supports pasting images directly from clipboard for upload (supported by some themes).
+
+1. Copy an image to clipboard (screenshot or copy image)
+2. Use `Ctrl+V` (Windows/Linux) or `Cmd+V` (macOS) to paste in the upload area
+3. Image upload starts automatically
+4. Get the extraction code after upload completes
+
+::: warning Note
+Paste upload only supports image formats, not other file types. Specific support depends on the theme being used.
+:::
+
+## File Size Limits
+
+### Default Limits
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| `uploadSize` | 10MB | Maximum single file upload size |
+
+### Modify Upload Limits
+
+Administrators can modify upload size limits through the admin panel or configuration file:
+
+```python
+# Set maximum upload size to 100MB
+uploadSize = 104857600 # 100 * 1024 * 1024
+```
+
+::: info Note
+`uploadSize` is in bytes. Common conversions:
+- 10MB = 10485760
+- 50MB = 52428800
+- 100MB = 104857600
+- 500MB = 524288000
+- 1GB = 1073741824
+:::
+
+### Exceeding Limit Handling
+
+When an uploaded file exceeds the size limit, the system returns a 403 error:
+
+```json
+{
+ "detail": "Size exceeds limit, maximum is 10.00 MB"
+}
+```
+
+## Regular Upload API
+
+### File Upload Endpoint
+
+**POST** `/share/file/`
+
+Content-Type: `multipart/form-data`
+
+**Request parameters:**
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `file` | file | Yes | File to upload |
+| `expire_value` | int | No | Expiration value, default 1 |
+| `expire_style` | string | No | Expiration method, default `day` |
+
+**Expiration method options:**
+
+| Value | Description |
+|-------|-------------|
+| `day` | Expire by days |
+| `hour` | Expire by hours |
+| `minute` | Expire by minutes |
+| `forever` | Never expire |
+| `count` | Expire by download count |
+
+**Response example:**
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "654321",
+ "name": "example.pdf"
+ }
+}
+```
+
+**cURL example:**
+
+```bash
+# Upload file (default 1 day expiration)
+curl -X POST "http://localhost:12345/share/file/" \
+ -F "file=@/path/to/file.pdf"
+
+# Upload file with 7 days expiration
+curl -X POST "http://localhost:12345/share/file/" \
+ -F "file=@/path/to/file.pdf" \
+ -F "expire_value=7" \
+ -F "expire_style=day"
+
+# Upload file with 10 downloads limit
+curl -X POST "http://localhost:12345/share/file/" \
+ -F "file=@/path/to/file.pdf" \
+ -F "expire_value=10" \
+ -F "expire_style=count"
+
+# Share text
+curl -X POST "http://localhost:12345/share/text/" \
+ -F "text=This is the text content to share"
+
+# Download file by extraction code
+curl -L "http://localhost:12345/share/select/?code=YOUR_CODE" -o downloaded_file
+```
+
+::: tip When Authentication Required
+If guest upload is disabled in admin panel (`openUpload=0`), you need to login first:
+
+```bash
+# 1. Login to get token
+curl -X POST "http://localhost:12345/admin/login" \
+ -H "Content-Type: application/json" \
+ -d '{"password": "FileCodeBox2023"}'
+
+# Returns: {"code":200,"msg":"success","detail":{"token":"xxx.xxx.xxx","token_type":"Bearer"}}
+
+# 2. Upload file with token
+curl -X POST "http://localhost:12345/share/file/" \
+ -H "Authorization: Bearer xxx.xxx.xxx" \
+ -F "file=@/path/to/file.pdf"
+
+# 3. Share text with token
+curl -X POST "http://localhost:12345/share/text/" \
+ -H "Authorization: Bearer xxx.xxx.xxx" \
+ -F "text=This is the text content to share"
+```
+:::
+
+
+## Chunked Upload API
+
+For large files, FileCodeBox supports chunked upload functionality. Chunked upload splits large files into multiple small chunks for separate uploading, supporting resume capability.
+
+::: warning Prerequisite
+Chunked upload functionality requires administrator enablement: `enableChunk=1`
+:::
+
+### Chunked Upload Flow
+
+```
+┌─────────────┐ ┌─────────────┐ ┌─────────────┐
+│ Initialize │ ──▶ │Upload Chunks│ ──▶ │ Complete │
+│ /init/ │ │ /chunk/ │ │ /complete/ │
+└─────────────┘ └─────────────┘ └─────────────┘
+ │
+ ▼
+ ┌───────────┐
+ │ Loop │
+ │each chunk │
+ └───────────┘
+```
+
+### 1. Initialize Upload
+
+**POST** `/chunk/upload/init/`
+
+**Request parameters:**
+
+```json
+{
+ "file_name": "large_file.zip",
+ "file_size": 104857600,
+ "chunk_size": 5242880,
+ "file_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+}
+```
+
+| Parameter | Type | Required | Default | Description |
+|-----------|------|----------|---------|-------------|
+| `file_name` | string | Yes | - | Filename |
+| `file_size` | int | Yes | - | Total file size (bytes) |
+| `chunk_size` | int | No | 5MB | Chunk size (bytes) |
+| `file_hash` | string | Yes | - | SHA256 hash of the file |
+
+**Response example:**
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "existed": false,
+ "upload_id": "abc123def456789",
+ "chunk_size": 5242880,
+ "total_chunks": 20,
+ "uploaded_chunks": []
+ }
+}
+```
+
+| Field | Description |
+|-------|-------------|
+| `existed` | Whether file already exists (instant upload) |
+| `upload_id` | Upload session ID |
+| `chunk_size` | Chunk size |
+| `total_chunks` | Total number of chunks |
+| `uploaded_chunks` | List of already uploaded chunk indices |
+
+### 2. Upload Chunk
+
+**POST** `/chunk/upload/chunk/{upload_id}/{chunk_index}`
+
+**Path parameters:**
+
+| Parameter | Description |
+|-----------|-------------|
+| `upload_id` | Upload session ID returned during initialization |
+| `chunk_index` | Chunk index, starting from 0 |
+
+**Request body:**
+
+Content-Type: `multipart/form-data`
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `chunk` | file | Chunk data |
+
+**Response example:**
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "chunk_hash": "a1b2c3d4e5f6..."
+ }
+}
+```
+
+**cURL example:**
+
+```bash
+# Upload first chunk (index 0)
+curl -X POST "http://localhost:12345/chunk/upload/chunk/abc123def456789/0" \
+ -F "chunk=@/path/to/chunk_0"
+```
+
+### 3. Complete Upload
+
+**POST** `/chunk/upload/complete/{upload_id}`
+
+**Path parameters:**
+
+| Parameter | Description |
+|-----------|-------------|
+| `upload_id` | Upload session ID |
+
+**Request parameters:**
+
+```json
+{
+ "expire_value": 7,
+ "expire_style": "day"
+}
+```
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `expire_value` | int | Yes | Expiration value |
+| `expire_style` | string | Yes | Expiration method |
+
+**Response example:**
+
+```json
+{
+ "code": 200,
+ "detail": {
+ "code": "789012",
+ "name": "large_file.zip"
+ }
+}
+```
+
+### Resume Upload
+
+Chunked upload supports resume functionality. When upload is interrupted:
+
+1. Call the initialization endpoint again with the same `file_hash`
+2. Server returns `uploaded_chunks` list containing already uploaded chunk indices
+3. Client only needs to upload chunks not in the list
+4. Call the complete endpoint after all chunks are uploaded
+
+**Example flow:**
+
+```javascript
+// 1. Initialize upload
+const initResponse = await fetch('/chunk/upload/init/', {
+ method: 'POST',
+ body: JSON.stringify({
+ file_name: 'large_file.zip',
+ file_size: fileSize,
+ chunk_size: 5 * 1024 * 1024,
+ file_hash: fileHash
+ })
+});
+const { upload_id, uploaded_chunks, total_chunks } = await initResponse.json();
+
+// 2. Upload incomplete chunks
+for (let i = 0; i < total_chunks; i++) {
+ if (!uploaded_chunks.includes(i)) {
+ const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
+ await fetch(`/chunk/upload/chunk/${upload_id}/${i}`, {
+ method: 'POST',
+ body: chunk
+ });
+ }
+}
+
+// 3. Complete upload
+await fetch(`/chunk/upload/complete/${upload_id}`, {
+ method: 'POST',
+ body: JSON.stringify({
+ expire_value: 7,
+ expire_style: 'day'
+ })
+});
+```
+
+## Error Handling
+
+### Common Errors
+
+| HTTP Status | Error Message | Cause | Solution |
+|-------------|---------------|-------|----------|
+| 403 | Size exceeds limit | File exceeds `uploadSize` limit | Reduce file size or contact administrator to adjust limit |
+| 403 | Upload rate limit | Exceeded IP upload rate limit | Wait for limit time window before retrying |
+| 400 | Invalid expiration type | `expire_style` value not in allowed list | Use a valid expiration method |
+| 404 | Upload session not found | `upload_id` invalid or expired | Re-initialize upload |
+| 400 | Invalid chunk index | `chunk_index` out of range | Check if chunk index is correct |
+| 400 | Incomplete chunks | Chunk count insufficient when completing upload | Ensure all chunks are uploaded |
+
+### Rate Limiting
+
+The system has rate limits on upload operations to prevent abuse:
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| `uploadMinute` | 1 | Limit time window (minutes) |
+| `uploadCount` | 10 | Maximum uploads within time window |
+
+When rate limit is exceeded, you need to wait for the time window to pass before continuing uploads.
+
+### Error Response Format
+
+```json
+{
+ "detail": "Error message description"
+}
+```
+
+## Upload Configuration
+
+### Related Settings
+
+| Setting | Type | Default | Description |
+|---------|------|---------|-------------|
+| `openUpload` | int | 1 | Enable upload (1=enabled, 0=disabled) |
+| `uploadSize` | int | 10485760 | Maximum upload size (bytes) |
+| `enableChunk` | int | 0 | Enable chunked upload (1=enabled, 0=disabled) |
+| `uploadMinute` | int | 1 | Upload rate limit time window (minutes) |
+| `uploadCount` | int | 10 | Maximum uploads within time window |
+| `expireStyle` | list | ["day","hour","minute","forever","count"] | Allowed expiration methods |
+
+### Configuration Example
+
+```python
+# Allow 100MB file uploads, enable chunked upload
+uploadSize = 104857600
+enableChunk = 1
+
+# Relax upload rate limit: max 50 uploads per 5 minutes
+uploadMinute = 5
+uploadCount = 50
+
+# Only allow expiration by days and count
+expireStyle = ["day", "count"]
+```
+
+## Next Steps
+
+- [File Sharing](/en/guide/share) - Learn the complete sharing process
+- [Configuration Guide](/en/guide/configuration) - Learn about all configuration options
+- [Storage Configuration](/en/guide/storage) - Learn about file storage methods
+- [Security Settings](/en/guide/security) - Learn about security-related configurations
diff --git a/docs/en/showcase.md b/docs/en/showcase.md
new file mode 100644
index 000000000..01e55f86f
--- /dev/null
+++ b/docs/en/showcase.md
@@ -0,0 +1,127 @@
+# Showcase
+
+Here are some excellent sites built with FileCodeBox. If you've deployed FileCodeBox, feel free to submit a PR to add your site here!
+
+## Official Demo
+
+
+
+
+
+### 🌟 FileCodeBox Demo
+
+- **URL**: [share.lanol.cn](https://share.lanol.cn)
+- **Description**: Official demo site with the latest features
+- **Highlights**: Stable, full-featured
+
+
+
+
+
+## Community Sites
+
+::: tip Submit Your Site
+If you've built your own file sharing service using FileCodeBox, you can submit it through:
+
+1. Submit a PR on [GitHub](https://github.com/vastsa/FileCodeBox) to edit this page
+2. Open an [Issue](https://github.com/vastsa/FileCodeBox/issues) with your site info
+3. Join QQ Group 739673698 to contact the admin
+:::
+
+
+
+
+
+
+
+### QuWenJian
+
+- **URL**: [www.quwenjian.cn/fby.html](https://www.quwenjian.cn/fby.html)
+- **Description**: QuWenJian - Unlimited storage, portable and limitless
+- **Highlights**: Free file transfer station
+- **Operator**: QuWenJian
+
+
+### Anonymous File & Text Sharing with Passcode
-
+
-
Share text and files anonymously with a passcode, like picking up a package
+Share files like picking up a package — no registration required, just enter the passcode
-[](https://github.com/vastsa/FileCodeBox/stargazers)
-[](https://github.com/vastsa/FileCodeBox/network)
-[](https://github.com/vastsa/FileCodeBox/issues)
-[](https://github.com/vastsa/FileCodeBox/blob/master/LICENSE)
-[](https://qm.qq.com/q/PemPzhdEIM)
-[](https://www.python.org)
-[](https://fastapi.tiangolo.com)
-[](https://v3.vuejs.org)
+[](https://github.com/vastsa/FileCodeBox/stargazers)
+[](https://github.com/vastsa/FileCodeBox/network)
+[](https://github.com/vastsa/FileCodeBox/issues)
+[](https://github.com/vastsa/FileCodeBox/blob/master/LICENSE)
+[](https://hub.docker.com/r/lanol/filecodebox)
-[简体中文](./readme.md) | [Deployment Guide](https://github.com/vastsa/FileCodeBox/wiki/Deployment-Guide) | [FAQ](https://github.com/vastsa/FileCodeBox/wiki/FAQ)
+[](https://www.python.org)
+[](https://fastapi.tiangolo.com)
+[](https://vuejs.org)
+
+[简体中文](./README.md) | [Live Demo](https://share.lanol.cn) | [Documentation](https://github.com/vastsa/FileCodeBox/wiki/Deployment-Guide) | [FAQ](https://github.com/vastsa/FileCodeBox/wiki/FAQ)
+
+```bash
+# 🚀 Quick Deploy
+docker run -d -p 12345:12345 -v /opt/FileCodeBox:/app/data --name filecodebox lanol/filecodebox:latest
+# China Mirror (if slow): docker.cnb.cool/aixk/filecodebox
+```
-## 📝 Introduction
+---
-FileCodeBox is a lightweight file sharing tool developed with FastAPI + Vue3. It allows users to share text and files
-easily, where recipients only need a passcode to retrieve the files, just like picking up a package from a delivery
-locker.
+## Table of Contents
-## 🖼️ Preview
+- [Introduction](#-introduction)
+- [Features](#-features)
+- [Screenshots](#-screenshots)
+- [Quick Start](#-quick-start)
+- [Usage Guide](#-usage-guide)
+- [Development](#-development)
+- [FAQ](#-faq)
+- [Contributing](#-contributing)
+- [Statistics](#-statistics)
+- [Disclaimer](#-disclaimer)
-
+FileCodeBox is a lightweight file sharing tool built with **FastAPI + Vue3**. Users can anonymously share text and files, and recipients only need to enter a passcode to retrieve the content — just like picking up a package from a locker.
-### Classic Interface
+### Use Cases
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+| Scenario | Description |
+|----------|-------------|
+| 📁 **Temporary File Sharing** | Quick file sharing without registration |
+| 📝 **Code Snippet Sharing** | Share code, config files, and text content |
+| 🕶️ **Anonymous Transfer** | Privacy-protected peer-to-peer transfer |
+| 🔄 **Cross-Device Transfer** | Quickly sync files between devices |
+| 💾 **Temporary Storage** | Cloud storage with custom expiration |
+| 🌐 **Private Service** | Build your own enterprise or personal sharing service |
+
+---
-## 🎯 Use Cases
+## ✨ Features
-
-
📁 Temporary File Sharing
-Quick file sharing without registration
+
+
+### 🚀 Lightweight & Fast
+- FastAPI + SQLite3 backend
+- Vue3 + Element Plus frontend
+- One-click Docker deployment
+- Minimal resource usage
+
-
-
📝 Quick Text Sharing
-Share code snippets and text content
+
+
+### 🔒 Secure & Reliable
+- IP upload rate limiting
+- Passcode attempt limiting
+- Auto file expiration cleanup
+- Admin authentication support
+
+---
+
+## 🗓 Roadmap
+
+- [ ] 2025 New Theme
+- [ ] File Collection Feature
+
+---
+
## 📜 Disclaimer
-This project is open-source for learning purposes only. It should not be used for any illegal purposes. The author is
-not responsible for any consequences. Please retain the project address and copyright information when using it.
\ No newline at end of file
+This project is open-source for learning and communication purposes only. It should not be used for any illegal purposes. The author is not responsible for any consequences. Please retain the project address and copyright information when using it.
+
+---
+
+
+
+**If you find this project helpful, please give it a ⭐ Star!**
+
+Made with ❤️ by [vastsa](https://github.com/vastsa)
+
+