mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-05-11 18:10:01 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0ccc3ded1 | ||
|
|
163d9451f7 | ||
|
|
60dda7e3fe | ||
|
|
384eb9b041 | ||
|
|
38816cbf0f | ||
|
|
d7d1ba6b64 |
39
.github/workflows/frontend_pagefunction_deploy.yaml
vendored
Normal file
39
.github/workflows/frontend_pagefunction_deploy.yaml
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
name: Deploy Frontend with page function
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v3
|
||||||
|
name: Install pnpm
|
||||||
|
id: pnpm-install
|
||||||
|
with:
|
||||||
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
|
||||||
|
- name: Deploy Frontend for ${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
cd frontend/
|
||||||
|
pnpm install --no-frozen-lockfile
|
||||||
|
pnpm build:pages
|
||||||
|
cd ../pages/
|
||||||
|
echo '${{ secrets.PAGE_TOML }}' > wrangler.toml
|
||||||
|
pnpm install --no-frozen-lockfile
|
||||||
|
pnpm run deploy
|
||||||
|
echo "Deploying prodcution for ${{ github.ref_name }}"
|
||||||
|
env:
|
||||||
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
<!-- markdownlint-disable-file MD004 MD024 MD034 MD036 -->
|
<!-- markdownlint-disable-file MD004 MD024 MD034 MD036 -->
|
||||||
# CHANGE LOG
|
# CHANGE LOG
|
||||||
|
|
||||||
|
## v0.6.1
|
||||||
|
|
||||||
|
- pages github actions && 修复清理邮件天数为 0 不生效 by @tqjason (#355)
|
||||||
|
- fix: imap proxy server 不支持 密码 by @dreamhunter2333 (#356)
|
||||||
|
- worker 新增 `ANNOUNCEMENT` 配置, 用于配置公告信息 by @dreamhunter2333 (#357)
|
||||||
|
- fix: telegram bot 新建地址默认选择第一个域名 by @dreamhunter2333 (#358)
|
||||||
|
|
||||||
## v0.6.0
|
## v0.6.0
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
@@ -313,7 +320,7 @@ The `mails` table will be discarded, and the `raw` text of the new `mail` will b
|
|||||||
```bash
|
```bash
|
||||||
git checkout v0.2.0
|
git checkout v0.2.0
|
||||||
cd worker
|
cd worker
|
||||||
wrangler d1 execute dev --file=../db/2024-04-09-patch.sql
|
wrangler d1 execute dev --file=../db/2024-04-09-patch.sql --remote
|
||||||
pnpm run deploy
|
pnpm run deploy
|
||||||
cd ../frontend
|
cd ../frontend
|
||||||
pnpm run deploy
|
pnpm run deploy
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cloudflare_temp_email",
|
"name": "cloudflare_temp_email",
|
||||||
"version": "0.6.0",
|
"version": "0.6.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ onMounted(async () => {
|
|||||||
<n-config-provider :locale="localeConfig" :theme="theme">
|
<n-config-provider :locale="localeConfig" :theme="theme">
|
||||||
<n-global-style />
|
<n-global-style />
|
||||||
<n-spin description="loading..." :show="loading">
|
<n-spin description="loading..." :show="loading">
|
||||||
<n-message-provider>
|
<n-message-provider container-style="margin-top: 20px;">
|
||||||
<n-grid x-gap="12" :cols="12">
|
<n-grid x-gap="12" :cols="12">
|
||||||
<n-gi v-if="showSideMargin" span="1"></n-gi>
|
<n-gi v-if="showSideMargin" span="1"></n-gi>
|
||||||
<n-gi :span="!showSideMargin ? 12 : 10">
|
<n-gi :span="!showSideMargin ? 12 : 10">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import axios from 'axios'
|
|||||||
const API_BASE = import.meta.env.VITE_API_BASE || "";
|
const API_BASE = import.meta.env.VITE_API_BASE || "";
|
||||||
const {
|
const {
|
||||||
loading, auth, jwt, settings, openSettings,
|
loading, auth, jwt, settings, openSettings,
|
||||||
userOpenSettings, userSettings,
|
userOpenSettings, userSettings, announcement,
|
||||||
showAuth, adminAuth, showAdminAuth, userJwt
|
showAuth, adminAuth, showAdminAuth, userJwt
|
||||||
} = useGlobalState();
|
} = useGlobalState();
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ const getOpenSettings = async (message) => {
|
|||||||
const res = await api.fetch("/open_api/settings");
|
const res = await api.fetch("/open_api/settings");
|
||||||
const domainLabels = res["domainLabels"] || [];
|
const domainLabels = res["domainLabels"] || [];
|
||||||
Object.assign(openSettings.value, {
|
Object.assign(openSettings.value, {
|
||||||
|
...res,
|
||||||
title: res["title"] || "",
|
title: res["title"] || "",
|
||||||
prefix: res["prefix"] || "",
|
prefix: res["prefix"] || "",
|
||||||
minAddressLen: res["minAddressLen"] || 1,
|
minAddressLen: res["minAddressLen"] || 1,
|
||||||
@@ -81,6 +82,14 @@ const getOpenSettings = async (message) => {
|
|||||||
if (openSettings.value.needAuth) {
|
if (openSettings.value.needAuth) {
|
||||||
showAuth.value = true;
|
showAuth.value = true;
|
||||||
}
|
}
|
||||||
|
if (openSettings.value.announcement && openSettings.value.announcement != announcement.value) {
|
||||||
|
announcement.value = openSettings.value.announcement;
|
||||||
|
message.info(announcement.value, {
|
||||||
|
showIcon: false,
|
||||||
|
duration: 0,
|
||||||
|
closable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error(error.message || "error");
|
message.error(error.message || "error");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { createGlobalState, useStorage, useDark, useToggle } from '@vueuse/core'
|
import { createGlobalState, useStorage, useDark, useToggle, useLocalStorage } from '@vueuse/core'
|
||||||
|
|
||||||
export const useGlobalState = createGlobalState(
|
export const useGlobalState = createGlobalState(
|
||||||
() => {
|
() => {
|
||||||
const isDark = useDark()
|
const isDark = useDark()
|
||||||
const toggleDark = useToggle(isDark)
|
const toggleDark = useToggle(isDark)
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const announcement = useLocalStorage('announcement', '');
|
||||||
const openSettings = ref({
|
const openSettings = ref({
|
||||||
title: '',
|
title: '',
|
||||||
|
announcement: '',
|
||||||
prefix: '',
|
prefix: '',
|
||||||
needAuth: false,
|
needAuth: false,
|
||||||
adminContact: '',
|
adminContact: '',
|
||||||
@@ -83,6 +85,7 @@ export const useGlobalState = createGlobalState(
|
|||||||
loading,
|
loading,
|
||||||
settings,
|
settings,
|
||||||
sendMailModel,
|
sendMailModel,
|
||||||
|
announcement,
|
||||||
openSettings,
|
openSettings,
|
||||||
showAuth,
|
showAuth,
|
||||||
showAddressCredential,
|
showAddressCredential,
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ const cleanupModel = ref({
|
|||||||
const { t } = useI18n({
|
const { t } = useI18n({
|
||||||
messages: {
|
messages: {
|
||||||
en: {
|
en: {
|
||||||
tip: 'Please input the cleanup days',
|
tip: 'Please input the days',
|
||||||
mailBoxLabel: 'Clean up days for mailbox',
|
mailBoxLabel: 'Cleanup the inbox before n days',
|
||||||
mailUnknowLabel: "Clean up days for unknow receiver",
|
mailUnknowLabel: "Cleanup the unknow mail before n days",
|
||||||
sendBoxLabel: "Clean up days for sendbox",
|
sendBoxLabel: "Cleanup the sendbox before n days",
|
||||||
cleanupNow: "Cleanup now",
|
cleanupNow: "Cleanup now",
|
||||||
autoCleanup: "Auto cleanup",
|
autoCleanup: "Auto cleanup",
|
||||||
cleanupSuccess: "Cleanup success",
|
cleanupSuccess: "Cleanup success",
|
||||||
@@ -33,10 +33,10 @@ const { t } = useI18n({
|
|||||||
cronTip: "Enable cron cleanup, need to configure [crons] in worker, please refer to the document",
|
cronTip: "Enable cron cleanup, need to configure [crons] in worker, please refer to the document",
|
||||||
},
|
},
|
||||||
zh: {
|
zh: {
|
||||||
tip: '请输入清理天数',
|
tip: '请输入天数',
|
||||||
mailBoxLabel: '收件箱清理天数',
|
mailBoxLabel: '清理 n 天前的收件箱',
|
||||||
mailUnknowLabel: "无收件人邮件清理天数",
|
mailUnknowLabel: "清理 n 天前的无收件人邮件",
|
||||||
sendBoxLabel: "发件箱清理天数",
|
sendBoxLabel: "清理 n 天前的发件箱",
|
||||||
autoCleanup: "自动清理",
|
autoCleanup: "自动清理",
|
||||||
cleanupSuccess: "清理成功",
|
cleanupSuccess: "清理成功",
|
||||||
cleanupNow: "立即清理",
|
cleanupNow: "立即清理",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Settings(BaseSettings):
|
|||||||
proxy_url: str = "http://localhost:8787"
|
proxy_url: str = "http://localhost:8787"
|
||||||
port: int = 8025
|
port: int = 8025
|
||||||
imap_port: int = 11143
|
imap_port: int = 11143
|
||||||
|
basic_password: str = ""
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
env_file = ".env"
|
env_file = ".env"
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class SimpleMailbox:
|
|||||||
f"{settings.proxy_url}/api/mails?limit={limit}&offset={start - 1}",
|
f"{settings.proxy_url}/api/mails?limit={limit}&offset={start - 1}",
|
||||||
headers={
|
headers={
|
||||||
"Authorization": f"Bearer {self.password}",
|
"Authorization": f"Bearer {self.password}",
|
||||||
|
"x-custom-auth": f"{settings.basic_password}",
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -147,6 +148,7 @@ class SimpleMailbox:
|
|||||||
f"{settings.proxy_url}/api/sendbox?limit={limit}&offset={start - 1}",
|
f"{settings.proxy_url}/api/sendbox?limit={limit}&offset={start - 1}",
|
||||||
headers={
|
headers={
|
||||||
"Authorization": f"Bearer {self.password}",
|
"Authorization": f"Bearer {self.password}",
|
||||||
|
"x-custom-auth": f"{settings.basic_password}",
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ git clone https://github.com/dreamhunter2333/cloudflare_temp_email.git
|
|||||||
```bash
|
```bash
|
||||||
# create a database, and copy the output to wrangler.toml in the next step
|
# create a database, and copy the output to wrangler.toml in the next step
|
||||||
wrangler d1 create dev
|
wrangler d1 create dev
|
||||||
wrangler d1 execute dev --file=db/schema.sql
|
wrangler d1 execute dev --file=db/schema.sql --remote
|
||||||
# schema update, if you have initialized the database before this date, you can execute this command to update
|
# schema update, if you have initialized the database before this date, you can execute this command to update
|
||||||
# wrangler d1 execute dev --file=db/2024-01-13-patch.sql
|
# wrangler d1 execute dev --file=db/2024-01-13-patch.sql --remote
|
||||||
# wrangler d1 execute dev --file=db/2024-04-03-patch.sql
|
# wrangler d1 execute dev --file=db/2024-04-03-patch.sql --remote
|
||||||
# create a namespace, and copy the output to wrangler.toml in the next step
|
# create a namespace, and copy the output to wrangler.toml in the next step
|
||||||
wrangler kv:namespace create DEV
|
wrangler kv:namespace create DEV
|
||||||
```
|
```
|
||||||
@@ -77,6 +77,7 @@ node_compat = true
|
|||||||
# TITLE = "Custom Title" # The title of the site
|
# TITLE = "Custom Title" # The title of the site
|
||||||
PREFIX = "tmp" # The mailbox name prefix to be processed
|
PREFIX = "tmp" # The mailbox name prefix to be processed
|
||||||
# (min, max) length of the adderss, if not set, the default is (1, 30)
|
# (min, max) length of the adderss, if not set, the default is (1, 30)
|
||||||
|
# ANNOUNCEMENT = "Custom Announcement"
|
||||||
# MIN_ADDRESS_LEN = 1
|
# MIN_ADDRESS_LEN = 1
|
||||||
# MAX_ADDRESS_LEN = 30
|
# MAX_ADDRESS_LEN = 30
|
||||||
# If you want your site to be private, uncomment below and change your password
|
# If you want your site to be private, uncomment below and change your password
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ cd worker
|
|||||||
cp wrangler.toml.template wrangler.toml
|
cp wrangler.toml.template wrangler.toml
|
||||||
# 创建 D1 并执行 schema.sql
|
# 创建 D1 并执行 schema.sql
|
||||||
wrangler d1 create dev
|
wrangler d1 create dev
|
||||||
wrangler d1 execute dev --file=../db/schema.sql
|
wrangler d1 execute dev --file=../db/schema.sql --remote
|
||||||
```
|
```
|
||||||
|
|
||||||
创建完成后,我们在 cloudflare 的控制台可以看到 D1 数据库
|
创建完成后,我们在 cloudflare 的控制台可以看到 D1 数据库
|
||||||
@@ -25,6 +25,6 @@ wrangler d1 execute dev --file=../db/schema.sql
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd worker
|
cd worker
|
||||||
wrangler d1 execute dev --file=../db/2024-01-13-patch.sql
|
wrangler d1 execute dev --file=../db/2024-01-13-patch.sql --remote
|
||||||
wrangler d1 execute dev --file=../db/2024-04-03-patch.sql
|
wrangler d1 execute dev --file=../db/2024-04-03-patch.sql --remote
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ node_compat = true
|
|||||||
# TITLE = "Custom Title" # 自定义网站标题
|
# TITLE = "Custom Title" # 自定义网站标题
|
||||||
PREFIX = "tmp" # 要处理的邮箱名称前缀,不需要后缀可配置为空字符串
|
PREFIX = "tmp" # 要处理的邮箱名称前缀,不需要后缀可配置为空字符串
|
||||||
# (min, max) adderss的长度,如果不设置,默认为(1, 30)
|
# (min, max) adderss的长度,如果不设置,默认为(1, 30)
|
||||||
|
# ANNOUNCEMENT = "Custom Announcement" # 自定义公告
|
||||||
# MIN_ADDRESS_LEN = 1
|
# MIN_ADDRESS_LEN = 1
|
||||||
# MAX_ADDRESS_LEN = 30
|
# MAX_ADDRESS_LEN = 30
|
||||||
# 如果你想要你的网站私有,取消下面的注释,并修改密码
|
# 如果你想要你的网站私有,取消下面的注释,并修改密码
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Hono } from 'hono'
|
import { Hono } from 'hono'
|
||||||
|
|
||||||
import { getDomains, getPasswords, getBooleanValue, getIntValue, getStringArray, getDefaultDomains } from './utils';
|
import { getDomains, getPasswords, getBooleanValue, getIntValue, getStringArray, getDefaultDomains, getStringValue } from './utils';
|
||||||
import { CONSTANTS } from './constants';
|
import { CONSTANTS } from './constants';
|
||||||
import { HonoCustomType } from './types';
|
import { HonoCustomType } from './types';
|
||||||
import { isS3Enabled } from './mails_api/s3_attachment';
|
import { isS3Enabled } from './mails_api/s3_attachment';
|
||||||
@@ -17,6 +17,7 @@ api.get('/open_api/settings', async (c) => {
|
|||||||
}
|
}
|
||||||
return c.json({
|
return c.json({
|
||||||
"title": c.env.TITLE,
|
"title": c.env.TITLE,
|
||||||
|
"announcement": getStringValue(c.env.ANNOUNCEMENT),
|
||||||
"prefix": c.env.PREFIX,
|
"prefix": c.env.PREFIX,
|
||||||
"minAddressLen": getIntValue(c.env.MIN_ADDRESS_LEN, 1),
|
"minAddressLen": getIntValue(c.env.MIN_ADDRESS_LEN, 1),
|
||||||
"maxAddressLen": getIntValue(c.env.MAX_ADDRESS_LEN, 30),
|
"maxAddressLen": getIntValue(c.env.MAX_ADDRESS_LEN, 30),
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ export const newAddress = async (
|
|||||||
}
|
}
|
||||||
// check domain
|
// check domain
|
||||||
const allowDomains = checkAllowDomains ? await getAllowDomains(c) : getDomains(c);
|
const allowDomains = checkAllowDomains ? await getAllowDomains(c) : getDomains(c);
|
||||||
|
// if domain is not set, use the first domain
|
||||||
|
if (!domain && allowDomains.length > 0) {
|
||||||
|
domain = allowDomains[0];
|
||||||
|
}
|
||||||
|
// check domain is valid
|
||||||
if (!domain || !allowDomains.includes(domain)) {
|
if (!domain || !allowDomains.includes(domain)) {
|
||||||
throw new Error("Invalid domain")
|
throw new Error("Invalid domain")
|
||||||
}
|
}
|
||||||
@@ -78,7 +83,7 @@ export const cleanup = async (
|
|||||||
cleanType: string | undefined | null,
|
cleanType: string | undefined | null,
|
||||||
cleanDays: number | undefined | null
|
cleanDays: number | undefined | null
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
if (!cleanType || !cleanDays || cleanDays < 0 || cleanDays > 30) {
|
if (!cleanType || typeof cleanDays !== 'number' || cleanDays < 0 || cleanDays > 30) {
|
||||||
throw new Error("Invalid cleanType or cleanDays")
|
throw new Error("Invalid cleanType or cleanDays")
|
||||||
}
|
}
|
||||||
console.log(`Cleanup ${cleanType} before ${cleanDays} days`);
|
console.log(`Cleanup ${cleanType} before ${cleanDays} days`);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export const CONSTANTS = {
|
export const CONSTANTS = {
|
||||||
VERSION: 'v0.6.0',
|
VERSION: 'v0.6.1',
|
||||||
|
|
||||||
// DB settings
|
// DB settings
|
||||||
ADDRESS_BLOCK_LIST_KEY: 'address_block_list',
|
ADDRESS_BLOCK_LIST_KEY: 'address_block_list',
|
||||||
|
|||||||
1
worker/src/types.d.ts
vendored
1
worker/src/types.d.ts
vendored
@@ -13,6 +13,7 @@ export type Bindings = {
|
|||||||
|
|
||||||
// config
|
// config
|
||||||
TITLE: string | undefined
|
TITLE: string | undefined
|
||||||
|
ANNOUNCEMENT: string | undefined | null
|
||||||
PREFIX: string | undefined
|
PREFIX: string | undefined
|
||||||
MIN_ADDRESS_LEN: string | number | undefined
|
MIN_ADDRESS_LEN: string | number | undefined
|
||||||
MAX_ADDRESS_LEN: string | number | undefined
|
MAX_ADDRESS_LEN: string | number | undefined
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ node_compat = true
|
|||||||
|
|
||||||
[vars]
|
[vars]
|
||||||
# TITLE = "Custom Title" # custom title
|
# TITLE = "Custom Title" # custom title
|
||||||
|
# ANNOUNCEMENT = "Custom Announcement"
|
||||||
PREFIX = "tmp"
|
PREFIX = "tmp"
|
||||||
# (min, max) length of the adderss, if not set, the default is (1, 30)
|
# (min, max) length of the adderss, if not set, the default is (1, 30)
|
||||||
# MIN_ADDRESS_LEN = 1
|
# MIN_ADDRESS_LEN = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user