feat: support multi domain (#18)

This commit is contained in:
Dream Hunter
2023-09-07 17:47:31 +08:00
committed by GitHub
parent c36a9036a4
commit 6fd96988ce
5 changed files with 35 additions and 18 deletions
+1 -1
View File
@@ -106,7 +106,7 @@ node_compat = true
[vars] [vars]
PREFIX = "tmp" # 要处理的邮箱名称前缀 PREFIX = "tmp" # 要处理的邮箱名称前缀
DOMAIN = "xxx.xxx" # 你的域名 DOMAINS = ["xxx.xxx1" , "xxx.xxx2"] # 你的域名
JWT_SECRET = "xxx" # 用于生成 jwt 的密钥 JWT_SECRET = "xxx" # 用于生成 jwt 的密钥
BLACK_LIST = "" # 黑名单,用于过滤发件人,逗号分隔 BLACK_LIST = "" # 黑名单,用于过滤发件人,逗号分隔
+1 -1
View File
@@ -41,7 +41,7 @@ pnpm install
# copy wrangler.toml.template to wrangler.toml # copy wrangler.toml.template to wrangler.toml
# and add your d1 config and these config # and add your d1 config and these config
# PREFIX = "tmp" - the email create will be like tmp<xxxxx>@DOMAIN # PREFIX = "tmp" - the email create will be like tmp<xxxxx>@DOMAIN
# DOMAIN = "xxx.xxx" - you domain name # DOMAINS = ["xxx.xxx1" , "xxx.xxx2"] you domain name
# JWT_SECRET = "xxx" # JWT_SECRET = "xxx"
# BLACK_LIST = "" # BLACK_LIST = ""
cp wrangler.toml.template wrangler.toml cp wrangler.toml.template wrangler.toml
+20 -9
View File
@@ -1,6 +1,6 @@
<script setup> <script setup>
import { NSpace, NAlert, NSwitch, NCard, NInput, NInputGroupLabel } from 'naive-ui' import { NSpace, NAlert, NSwitch, NCard, NInput, NInputGroupLabel } from 'naive-ui'
import { NSpin, NButton, NLayout, NInputGroup, NModal } from 'naive-ui' import { NSpin, NButton, NLayout, NInputGroup, NModal, NSelect } from 'naive-ui'
import { NList, NListItem, NThing, NTag, NNumberAnimation } from 'naive-ui' import { NList, NListItem, NThing, NTag, NNumberAnimation } from 'naive-ui'
import { watch, onMounted, ref } from "vue"; import { watch, onMounted, ref } from "vue";
import { useStorage } from '@vueuse/core' import { useStorage } from '@vueuse/core'
@@ -21,9 +21,13 @@ const timer = ref(null)
const showPassword = ref(false) const showPassword = ref(false)
const showNewEmail = ref(false) const showNewEmail = ref(false)
const emailName = ref("") const emailName = ref("")
const emailDomain = ref("")
const openSettings = ref({ const openSettings = ref({
prefix: 'test', prefix: 'test',
domain: 'test.com' domains: [{
label: 'test.com',
value: 'test.com'
}]
}) })
const { t, locale } = useI18n({ const { t, locale } = useI18n({
@@ -119,9 +123,8 @@ const newEmail = async () => {
try { try {
loading.value = true; loading.value = true;
let url = `${API_BASE}/api/new_address`; let url = `${API_BASE}/api/new_address`;
if (emailName.value) { url = `${url}?name=${emailName.value || ''}`;
url = `${url}?name=${emailName.value}`; url = `${url}&domain=${emailDomain.value || ''}`;
}
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: "GET",
headers: { headers: {
@@ -159,7 +162,16 @@ const getOpenSettings = async (jwt) => {
return; return;
} }
let res = await response.json(); let res = await response.json();
openSettings.value = res; openSettings.value = {
prefix: res["prefix"] || "",
domains: res["domains"].map((domain) => {
return {
label: domain,
value: domain
}
})
};
emailDomain.value = openSettings.value.domains[0].value;
} }
const getSettings = async (jwt) => { const getSettings = async (jwt) => {
@@ -266,9 +278,8 @@ onMounted(async () => {
{{ openSettings.prefix }} {{ openSettings.prefix }}
</n-input-group-label> </n-input-group-label>
<n-input v-model:value="emailName" /> <n-input v-model:value="emailName" />
<n-input-group-label> <n-input-group-label>@</n-input-group-label>
@{{ openSettings.domain }} <n-select v-model:value="emailDomain" :consistent-menu-width="false" :options="openSettings.domains" />
</n-input-group-label>
</n-input-group> </n-input-group>
<template #action> <template #action>
<n-button @click="showNewEmail = false"> <n-button @click="showNewEmail = false">
+12 -6
View File
@@ -21,20 +21,26 @@ api.get('/api/settings', async (c) => {
api.get('/open_api/settings', async (c) => { api.get('/open_api/settings', async (c) => {
return c.json({ return c.json({
"prefix": c.env.PREFIX, "prefix": c.env.PREFIX,
"domain": c.env.DOMAIN, "domains": c.env.DOMAINS,
}); });
}) })
api.get('/api/new_address', async (c) => { api.get('/api/new_address', async (c) => {
// insert new address let { name, domain } = await c.req.query();
let { name } = await c.req.query(); // if no name, generate random name
if (!name) { if (!name) {
name = Math.random().toString(36).substring(2, 15) name = Math.random().toString(36).substring(2, 15);
} }
// check domain, generate random domain
if (!domain || !c.env.DOMAINS.includes(domain)) {
domain = c.env.DOMAINS[Math.floor(Math.random() * c.env.DOMAINS.length)];
}
// create address
const emailAddress = c.env.PREFIX + name + "@" + domain
try { try {
const { success } = await c.env.DB.prepare( const { success } = await c.env.DB.prepare(
`INSERT INTO address (name) VALUES (?)` `INSERT INTO address (name) VALUES (?)`
).bind(name).run(); ).bind(name + "@" + domain).run();
if (!success) { if (!success) {
return c.text("Failed to create address", 500) return c.text("Failed to create address", 500)
} }
@@ -46,7 +52,7 @@ api.get('/api/new_address', async (c) => {
} }
// create jwt // create jwt
const jwt = await Jwt.sign({ const jwt = await Jwt.sign({
address: c.env.PREFIX + name + "@" + c.env.DOMAIN address: emailAddress
}, c.env.JWT_SECRET) }, c.env.JWT_SECRET)
return c.json({ return c.json({
jwt: jwt jwt: jwt
+1 -1
View File
@@ -5,7 +5,7 @@ node_compat = true
[vars] [vars]
PREFIX = "tmp" PREFIX = "tmp"
DOMAIN = "xxx.xxx" DOMAINS = ["xxx.xxx1" , "xxx.xxx2"]
JWT_SECRET = "xxx" JWT_SECRET = "xxx"
BLACK_LIST = "" BLACK_LIST = ""