diff --git a/README.md b/README.md index 9ebaf5bc..8c23a3e4 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ - [x] 使用 Cloudflare Workers 部署后端 - [x] email 转发使用 Cloudflare Email Routing - [x] 使用 password 重新登录之前的邮箱 +- [x] 获取自定义名字的邮箱 - [ ] 免费版附件过大会造成 Exceeded CPU Limit 错误 --- diff --git a/README_EN.md b/README_EN.md index 1cbc7e61..9099293a 100644 --- a/README_EN.md +++ b/README_EN.md @@ -13,6 +13,7 @@ This is a temporary email service that uses Cloudflare Workers to create a tempo - [x] Deploy the backend with Cloudflare Workers - [x] Email forwarding using Cloudflare Email Routing - [x] Use password to login to the previous mailbox again. +- [x] Get Custom Name Email - [ ] Exceeded CPU Limit error caused by the free version of the attachment  diff --git a/frontend/.gitignore b/frontend/.gitignore index 0ae01875..e06ec0a4 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -27,4 +27,4 @@ coverage *.sln *.sw? -.env.local +.env.* diff --git a/frontend/src/App.vue b/frontend/src/App.vue index e3daae32..3bacbd11 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,7 +1,7 @@ @@ -41,7 +45,17 @@ const login = () => { Light - + + + + Logout + + + + Are you sure to logout? + + + Login -import { NSpace, NAlert, NSwitch, NCard } from 'naive-ui' -import { NSpin, NButton, NLayout, NPopconfirm, NModal } from 'naive-ui' +import { NSpace, NAlert, NSwitch, NCard, NInput, NInputGroupLabel } from 'naive-ui' +import { NSpin, NButton, NLayout, NInputGroup, NModal } from 'naive-ui' import { NList, NListItem, NThing, NTag, NNumberAnimation } from 'naive-ui' import { watch, onMounted, ref } from "vue"; import { useStorage } from '@vueuse/core' @@ -18,6 +18,12 @@ const data = ref([]) const API_BASE = import.meta.env.VITE_API_BASE || ""; const timer = ref(null) const showPassword = ref(false) +const showNewEmail = ref(false) +const emailName = ref("") +const openSettings = ref({ + prefix: 'test', + domain: 'test.com' +}) const setupAutoRefresh = async (autoRefresh) => { if (autoRefresh) { @@ -74,7 +80,11 @@ const copy = async () => { const newEmail = async () => { try { loading.value = true; - const response = await fetch(`${API_BASE}/api/new_address`, { + let url = `${API_BASE}/api/new_address`; + if (emailName.value) { + url = `${url}?name=${emailName.value}`; + } + const response = await fetch(url, { method: "GET", headers: { "Content-Type": "application/json" @@ -82,24 +92,38 @@ const newEmail = async () => { }); if (!response.ok) { - message.error( - `${response.status} ${await response.text()}` || "error", - ); throw new Error(`${response.status} ${await response.text()}` || "error"); } let res = await response.json(); jwt.value = res["jwt"]; + await refresh(); + showNewEmail.value = false; + showPassword.value = true; } catch (error) { - jwt.value = ""; message.error(error.message || "error"); console.error(error); } finally { loading.value = false; } - await refresh(); - showPassword.value = true; }; +const getOpenSettings = async (jwt) => { + const response = await fetch(`${API_BASE}/open_api/settings`, { + method: "GET", + headers: { + "Content-Type": "application/json" + }, + }); + + if (!response.ok) { + message.error(`${response.status} ${await response.text()}` || "error"); + console.error(response); + return; + } + let res = await response.json(); + openSettings.value = res; +} + const getSettings = async (jwt) => { if (typeof jwt != 'string' || jwt.trim() === '' || jwt === 'undefined') { return; @@ -126,6 +150,7 @@ const getSettings = async (jwt) => { watch(jwt, async (jwt, old) => getSettings(jwt)) onMounted(async () => { + getOpenSettings() getSettings(jwt.value) await refresh(); const token = import.meta.env.VITE_CF_WEB_ANALY_TOKEN; @@ -156,17 +181,12 @@ onMounted(async () => { Please click Get New Email button to get a new email address - + Show Password - - - - Get New Email - - - Get New Email? - + + Get New Email + Auto Refresh @@ -195,6 +215,32 @@ onMounted(async () => { + + + Get New Email + + + Please input the email you want to use. + Levaing it blank will generate a random email address. + + + + {{ openSettings.prefix }} + + + + @{{ openSettings.domain }} + + + + + Cancel + + + OK + + + Password diff --git a/worker/src/router.js b/worker/src/router.js index 9ac10d37..4c73aacb 100644 --- a/worker/src/router.js +++ b/worker/src/router.js @@ -18,14 +18,31 @@ api.get('/api/settings', async (c) => { return c.json(c.get("jwtPayload")); }) +api.get('/open_api/settings', async (c) => { + return c.json({ + "prefix": c.env.PREFIX, + "domain": c.env.DOMAIN, + }); +}) + api.get('/api/new_address', async (c) => { // insert new address - const name = Math.random().toString(36).substring(2, 15) - const { success } = await c.env.DB.prepare( - `INSERT INTO address (name) VALUES (?)` - ).bind(name).run(); - if (!success) { - return c.json({ "error": "Failed to create address" }, 500) + let { name } = await c.req.query(); + if (!name) { + name = Math.random().toString(36).substring(2, 15) + } + try { + const { success } = await c.env.DB.prepare( + `INSERT INTO address (name) VALUES (?)` + ).bind(name).run(); + if (!success) { + return c.text("Failed to create address", 500) + } + } catch (e) { + if (e.message && e.message.includes("UNIQUE")) { + return c.text("Please retry a new address", 400) + } + return c.text("Failed to create address", 500) } // create jwt const jwt = await Jwt.sign({
Please input the email you want to use.
Levaing it blank will generate a random email address.