diff --git a/.env.example b/.env.example
index cd9775f..a1230c2 100644
--- a/.env.example
+++ b/.env.example
@@ -10,14 +10,18 @@ AUTH_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
+GITHUB_ID=
+GITHUB_SECRET=
+LinuxDo_CLIENT_ID=
+LinuxDo_CLIENT_SECRET=
# -----------------------------------------------------------------------------
-# Database (MySQL - Neon DB)
+# Database, example: DATABASE_URL='postgres://[user]:[password]@[hostname]:5432/[dbname]'
# -----------------------------------------------------------------------------
DATABASE_URL='postgres://[user]:[password]@[neon_hostname]/[dbname]?sslmode=require'
# -----------------------------------------------------------------------------
-# Email (Resend)
+# Email api (https://resend.com) for login and send email
# -----------------------------------------------------------------------------
RESEND_API_KEY=
@@ -27,9 +31,11 @@ RESEND_API_KEY=
CLOUDFLARE_ZONE_ID=
CLOUDFLARE_API_KEY=
CLOUDFLARE_EMAIL=
+# Cloudflare zone name, example: wr.do
+CLOUDFLARE_ZONE_NAME=
# -----------------------------------------------------------------------------
-# Free Quota
+# About to be deprecated
# -----------------------------------------------------------------------------
NEXT_PUBLIC_FREE_RECORD_QUOTA=3
NEXT_PUBLIC_FREE_URL_QUOTA=100
@@ -37,11 +43,16 @@ NEXT_PUBLIC_FREE_URL_QUOTA=100
# Open Signup
NEXT_PUBLIC_OPEN_SIGNUP=1
+# Google Analytics
NEXT_PUBLIC_GOOGLE_ID=
-SCREENSHOTONE_BASE_URL=
+# ScreenShot API
+SCREENSHOTONE_BASE_URL=https://shot.wr.do
+# GitHub api token for getting gitHub stars count
GITHUB_TOKEN=
-OPENAI_API_KEY=
-OPENAI_API_BASE=
\ No newline at end of file
+# Short domains, split by ","
+NEXT_PUBLIC_SHORT_DOMAINS=wr.do,uv.do
+
+
diff --git a/README-zh.md b/README-zh.md
index 10e5ea2..760a4e3 100644
--- a/README-zh.md
+++ b/README-zh.md
@@ -1,7 +1,7 @@
WR.DO
Discord · English | 简体中文
-
创建 DNS 记录,生成短链接
+
创建 DNS 记录,生成短链接,临时邮箱
@@ -35,10 +35,13 @@
### 要求
- [Vercel](https://vercel.com) 账户用于部署应用
-- [Cloudflare](https://dash.cloudflare.com/) 账户
-- 在 Cloudflare 托管的 **域名**
+- 至少一个在 [Cloudflare](https://dash.cloudflare.com/) 托管的 **域名**
-查看有关[开发者](https://wr.do/docs/developer/installation)的文档。
+查看[开发文档](https://wr.do/docs/developer/installation)。
+
+### Email worker
+
+查看 [email worker](https://wr.do/docs/developer/cloudflare-email-worker) 文档用于邮件接收。
## 本地开发
diff --git a/README.md b/README.md
index 924e6c5..cdffb0f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
WR.DO
Discord · English | 简体中文
-
Craft DNS Records, Make Short Links
+
Craft DNS Records, Make Short Links, Email Support.
@@ -29,18 +29,21 @@
## Quick Start
-See docs about [guide](https://wr.do/docs/quick-start) for quick start.
+See usage docs about [guide](https://wr.do/docs/quick-start) for quick start.
## Self-hosted Tutorial
### Requirements
- [Vercel](https://vercel.com) to deploy app
-- [Cloudflare](https://dash.cloudflare.com/) account
-- A **domain** name hosted on Cloudflare
+- A **domain** name hosted on [Cloudflare](https://dash.cloudflare.com/)
See more docs about [developer](https://wr.do/docs/developer/installation).
+### Email worker
+
+See more docs about [email worker](https://wr.do/docs/developer/cloudflare-email-worker).
+
## Local development
copy `.env.example` to `.env` and fill in the necessary environment variables.
diff --git a/components/ui/scroll-area.tsx b/components/ui/scroll-area.tsx
index 277caac..6be6bb6 100644
--- a/components/ui/scroll-area.tsx
+++ b/components/ui/scroll-area.tsx
@@ -14,7 +14,7 @@ const ScrollArea = React.forwardRef<
className={cn("relative overflow-hidden", className)}
{...props}
>
-
+
{children}
diff --git a/config/docs.ts b/config/docs.ts
index 5a1de01..d642eec 100644
--- a/config/docs.ts
+++ b/config/docs.ts
@@ -121,6 +121,11 @@ export const docsConfig: DocsConfig = {
href: "/docs/developer/email",
icon: "page",
},
+ {
+ title: "Email Worker",
+ href: "/docs/developer/cloudflare-email-worker",
+ icon: "page",
+ },
{
title: "Database",
href: "/docs/developer/database",
diff --git a/content/docs/developer/cloudflare-email-worker.mdx b/content/docs/developer/cloudflare-email-worker.mdx
new file mode 100644
index 0000000..421de34
--- /dev/null
+++ b/content/docs/developer/cloudflare-email-worker.mdx
@@ -0,0 +1,102 @@
+---
+title: Cloudflare Email Worker Configs
+description: How to config the cloudflare api.
+---
+
+Before you start, you must have a Cloudflare account and a domain be hosted on Cloudflare.
+
+### Introduction to Cloudflare Email Worker and R2
+
+#### Cloudflare Email Worker
+
+Cloudflare Email Worker is a feature of Cloudflare's Email Routing service combined with the Workers platform.
+It allows users to process incoming emails programmatically at Cloudflare's edge network.
+When an email is sent to a custom address configured in Email Routing,
+the associated Worker is triggered, receiving the email data (e.g., sender, recipient, headers, and body).
+Developers can write JavaScript code to define custom logic,
+such as forwarding emails to specific addresses, filtering spam,
+or integrating with external APIs.
+
+#### Cloudflare R2
+
+Cloudflare R2 (Object Storage) is a scalable, S3-compatible storage solution provided by Cloudflare.
+It allows users to store and retrieve files (e.g., email attachments) at the edge with zero egress fees.
+In the context of an Email Worker, R2 can be used to store email attachments or other data, accessible via environment bindings in the Worker script.
+
+### Overview of cf-email-forwarding-worker
+
+[oiov/cf-email-forwarding-worker](https://github.com/oiov/cf-email-forwarding-worker),
+implements an advanced email forwarding solution using Cloudflare Email Worker and R2.
+Instead of directly forwarding emails to another email address,
+it sends the email data to a third-party API endpoint for custom processing.
+Additionally, it leverages Cloudflare R2 to store email attachments, making them accessible to the third-party application.
+
+#### Key Features
+
+- **API-based Forwarding**: Emails are sent as structured data to a configurable third-party API (APP_API_URL) via HTTP POST requests.
+- **Attachment Storage**: Email attachments are uploaded to an R2 bucket and their URLs are included in the API payload.
+- **Customizable**: The third-party app can process the email data (e.g., sender, subject, body, attachments) as needed.
+#### Configuration
+
+The Worker relies on two environment variables defined in the wrangler.jsonc file:
+
+```json
+"vars": {
+ "APP_API_URL": "https://wr.do/api/v1/email-catcher"
+},
+"r2_buckets": [
+ {
+ "binding": "R2_BUCKET",
+ "bucket_name": "wremail"
+ }
+]
+```
+
+`APP_API_URL`: The URL of the third-party API endpoint that receives the email data. This allows the third-party app to handle emails in a custom way (e.g., logging, processing, or forwarding).
+
+`R2_BUCKET`: The binding name for the R2 storage bucket, accessible in the Worker code as env.R2_BUCKET. The bucket_name (`wremail`) specifies the R2 bucket where email attachments are stored. Note: R2 must be activated and configured in your Cloudflare account beforehand.
+
+#### How It Works
+
+- Email Reception: An email sent to the configured address triggers the Worker.
+- Attachment Handling: If the email contains attachments, they are extracted and uploaded to the R2 bucket (wremail). The Worker generates accessible URLs for these attachments.
+- API Forwarding: The email data (e.g., sender, recipient, subject, body, and attachment URLs) is packaged into a JSON payload and sent to the `APP_API_URL` via an HTTP POST request.
+- Third-Party Processing: The third-party app receives the payload and processes it according to its own logic.
+
+#### Example Usage
+
+- A user sends an email to example@yourdomain.com.
+- The Worker uploads any attachments to the wremail R2 bucket.
+- The Worker sends a POST request to https://wr.do/api/v1/email-catcher with the email details and attachment URLs.
+- The third-party app logs the email, stores it in a database, or forwards it elsewhere.
+#### Prerequisites
+- A Cloudflare account with Email Routing enabled.
+- An R2 bucket created and bound to the Worker (e.g., wremail).
+- A third-party API endpoint ready to receive POST requests with email data.
+
+### Deploy email worker to Cloudflare
+
+```bash
+git clone https://github.com/oiov/cf-email-forwarding-worker.git
+cd cf-email-forwarding-worker
+pnpm install
+
+wranler login
+wranler deploy
+```
+Remember to add your environment variables in `wrangler.jsonc` before deploy.
+
+### Config your domain email rule
+
+
+Via the [https://dash.cloudflare.com/account_id/zone_name/email/routing/routes](https://dash.cloudflare.com/[account_id]/[zone_name]/email/routing/routes]),
+edit `Catch-all address`, select:
+- `Action` -> `Send to a worker`
+- `Destination` -> `wrdo-email-worker`(The worker name you deploy).
+
+Then save and active it.
+
+Once you add a new domain, you need to perform the same action, the email worker can be the same.
+
+
+
diff --git a/content/docs/developer/cloudflare.mdx b/content/docs/developer/cloudflare.mdx
index 9af6573..80bceb6 100644
--- a/content/docs/developer/cloudflare.mdx
+++ b/content/docs/developer/cloudflare.mdx
@@ -11,6 +11,7 @@ In this section, you can update these variables:
CLOUDFLARE_ZONE_ID=abcdef1234567890
CLOUDFLARE_API_KEY=1234567890abcdef1234567890abcdef
CLOUDFLARE_EMAIL=user@example.com
+CLOUDFLARE_ZONE_NAME=wr.do
```
### Variable Descriptions
@@ -25,5 +26,5 @@ CLOUDFLARE_EMAIL=user@example.com
- **CLOUDFLARE_EMAIL**: This is the email address associated with your Cloudflare account. It is used for authentication alongside the API key.
-
+- **CLOUDFLARE_ZONE_NAME**: This is the name of your Cloudflare zone. It is used to specify the zone in the Cloudflare API requests.
diff --git a/content/docs/developer/installation.mdx b/content/docs/developer/installation.mdx
index bd90a88..a0993f1 100644
--- a/content/docs/developer/installation.mdx
+++ b/content/docs/developer/installation.mdx
@@ -56,11 +56,13 @@ Copy/paste the `.env.example` in the `.env` file:
| NEXT_PUBLIC_OPEN_SIGNUP | `1` | Open signup. |
| SCREENSHOTONE_BASE_URL | `https://api.example.com` | pending |
| GITHUB_TOKEN | `ghp_sscsfarwetqet` | https://github.com/settings/tokens |
+| NEXT_PUBLIC_SHORT_DOMAINS | `wr.do,uv.do` | The list of short domains. Separated by `,` |
- How to get `GOOGLE_CLIENT_ID`、`GITHUB_ID`, see [Authentification](/docs/developer/authentification).
- How to get `RESEND_API_KEY`, see [Email](/docs/developer/email).
- How to get `CLOUDFLARE_ZONE_ID`、`CLOUDFLARE_API_KEY`、`CLOUDFLARE_EMAIL`, see [Cloudflare Configs](/docs/developer/cloudflare).
- How to get `DATABASE_URL`, see [Database](/docs/developer/database).
+- How to active email worker, see [Email Worker](/docs/developer/cloudflare-email-worker).
### Configuration part
diff --git a/public/sw.js.map b/public/sw.js.map
index 0602c5e..1d8df32 100644
--- a/public/sw.js.map
+++ b/public/sw.js.map
@@ -1 +1 @@
-{"version":3,"file":"sw.js","sources":["../../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/ddd1b9320625d99d17d6e201ea930412/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"sw.js","sources":["../../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/7d0a89aab5e742e14a569aa244e668c1/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"}
\ No newline at end of file