From b771c1f65a56e18a7ef8ac11091e956f851561e3 Mon Sep 17 00:00:00 2001 From: eoao Date: Sat, 26 Jul 2025 23:11:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9D=83=E9=99=90=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E9=99=90=E5=88=B6=E5=92=8C=E9=93=BE=E6=8E=A5=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-en.md | 6 +- README.md | 5 +- doc/images/support.png | Bin 0 -> 6566 bytes mail-vue/package-lock.json | 7 - mail-vue/package.json | 1 - mail-vue/src/App.vue | 2 +- mail-vue/src/i18n/en.js | 17 +- mail-vue/src/i18n/zh.js | 19 +- mail-vue/src/layout/aside/index.vue | 4 +- mail-vue/src/layout/index.vue | 1 - mail-vue/src/main.js | 4 +- mail-vue/src/utils/convert.js | 23 ++- mail-vue/src/utils/day.js | 4 +- mail-vue/src/utils/file-utils.js | 13 +- mail-vue/src/views/role/index.vue | 62 ++++++- mail-vue/src/views/setting/index.vue | 3 +- mail-vue/src/views/sys-setting/index.vue | 161 ++++++++++++----- mail-vue/src/views/user/index.vue | 1 - mail-worker/dist/assets/index-C5vjKzw7.css | 1 - mail-worker/dist/assets/index-CTj27R8v.css | 1 + mail-worker/dist/assets/index-DzqHrwam.js | 193 ++++++++++++++++++++ mail-worker/dist/assets/index-mj4MUxg3.js | 199 --------------------- mail-worker/dist/index.html | 4 +- mail-worker/src/email/email.js | 37 ++-- mail-worker/src/entity/role.js | 1 + mail-worker/src/i18n/en.js | 5 + mail-worker/src/i18n/zh.js | 9 +- mail-worker/src/init/init.js | 9 +- mail-worker/src/security/security.js | 1 - mail-worker/src/service/account-service.js | 14 +- mail-worker/src/service/email-service.js | 17 +- mail-worker/src/service/login-service.js | 25 ++- mail-worker/src/service/role-service.js | 36 +++- mail-worker/src/service/setting-service.js | 45 +++-- mail-worker/src/utils/file-utils.js | 4 +- mail-worker/wrangler-dev.toml | 4 +- 36 files changed, 584 insertions(+), 354 deletions(-) create mode 100644 doc/images/support.png delete mode 100644 mail-worker/dist/assets/index-C5vjKzw7.css create mode 100644 mail-worker/dist/assets/index-CTj27R8v.css create mode 100644 mail-worker/dist/assets/index-DzqHrwam.js delete mode 100644 mail-worker/dist/assets/index-mj4MUxg3.js diff --git a/README-en.md b/README-en.md index fb05086..4511e84 100644 --- a/README-en.md +++ b/README-en.md @@ -161,9 +161,9 @@ After the update, run `https://your-project-domain/api/init/your-jwt-secret` to ## Support -**Buy me a cup of milk tea** - - + + +

**Special Sponsors** diff --git a/README.md b/README.md index 244984d..1b30c7a 100644 --- a/README.md +++ b/README.md @@ -182,9 +182,10 @@ jwt_secret = "" #登录身份令牌的密钥,随便填一串字符串 ## 赞助 -**请我喝一杯奶茶** - + + +

**特别赞助商** diff --git a/doc/images/support.png b/doc/images/support.png new file mode 100644 index 0000000000000000000000000000000000000000..c84921b0daeafbaab01a44079afba85e3c9d4151 GIT binary patch literal 6566 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 \ No newline at end of file diff --git a/mail-vue/src/i18n/en.js b/mail-vue/src/i18n/en.js index ca373b6..9fb4fd0 100644 --- a/mail-vue/src/i18n/en.js +++ b/mail-vue/src/i18n/en.js @@ -96,7 +96,6 @@ const en = { expand: 'Expand', collapse: 'Collapse', daily: 'Daily', - emailBlock: '*Intercept all incoming emails to @example.com', searchRegKeyDesc: 'Enter invite code to search', remainingUses: 'Remaining uses', exhausted: 'Exhausted', @@ -168,11 +167,11 @@ const en = { addOsDomain: 'Add domain', domainDesc: 'Domain', addTurnstileSecret: 'Add turnstile secret', - backgroundCropping: 'Background cropping', + backgroundTitle: 'Change background', tgBotDesc: 'Forward received emails to a Telegram bot', tgBotToken: 'Bot token', toBotTokenDesc: 'Multiple user chat_ids, separated by commas', - otherEmailDec: 'emails can be forwarded to external email, but must be verified via cloudflare.', + otherEmailDesc: 'emails can be forwarded to external email, but must be verified via cloudflare.', otherEmailInputDesc: 'Separate multiple email addresses with commas.', forwardingRulesDesc: 'Rule-based forwarding only forwards emails received by the specified address.', ruleEmailsInputDesc: 'Separate multiple email addresses with commas.', @@ -246,7 +245,17 @@ const en = { totalUserAccount: '{msg}', sendBanned: 'Banned', wrote: 'wrote', - support: 'Support' + support: 'Support', + supportDesc: 'Buy me tea', + featDesc: 'Feature Description', + emailInterception: 'Email Interception', + emailInterceptionDesc: '*Intercept emails by blocking entire domain using @example.com to prevent users from receiving emails from certain websites.', + availableDomains: 'Available domains', + availableDomainsDesc: 'Restrict users to email domains specified. Domains not on the approved list will be blocked from registration, adding email addresses, and sending/receiving emails. If left blank, all domains will be allowed by default.', + backgroundUrlDesc: 'Image URL', + localUpload: ' Local upload', + imageLink: 'Image URL', + backgroundWarning: 'Image file size affects website load speed.' } export default en diff --git a/mail-vue/src/i18n/zh.js b/mail-vue/src/i18n/zh.js index 2e6ffb8..c1eab35 100644 --- a/mail-vue/src/i18n/zh.js +++ b/mail-vue/src/i18n/zh.js @@ -96,7 +96,6 @@ const zh = { expand: '展开', collapse: '收起', daily: '每天', - emailBlock: '输入邮箱拦截收件, 拦截所有前缀 *@example.com', searchRegKeyDesc: '输入注册码搜索', remainingUses: '剩余次数', exhausted: '已用尽', @@ -165,14 +164,14 @@ const zh = { community: '交流', changeTitle: '修改标题', addResendTokenDesc: '输入内容添加,不填则删除', - addOsDomain: '添加访对象存储问域名', + addOsDomain: '添加访问域名', domainDesc: '域名', addTurnstileSecret: '添加 Turnstile 密钥', - backgroundCropping: '背景截图', + backgroundTitle: '设置背景', tgBotDesc: '可以将接收的邮件转发到Tg机器人', tgBotToken: '机器人 token', toBotTokenDesc: '用户 chat_id 多个用,分开', - otherEmailDec: '可以将邮件转到其他服务商邮箱,需要在cloudflare验证邮箱', + otherEmailDesc: '可以将邮件转到其他服务商邮箱,需要在cloudflare验证邮箱', otherEmailInputDesc: '多个邮箱用, 分开', forwardingRulesDesc: '规则转发只会转发设置邮箱所接收的邮件', ruleEmailsInputDesc: '多个邮箱用, 分开', @@ -246,6 +245,16 @@ const zh = { totalUserAccount: '{msg} 个', sendBanned: '已禁用', wrote: '来信', - support: '赞助' + support: '赞助', + supportDesc: '请我喝杯奶茶', + featDesc: '功能说明', + emailInterception: '邮件拦截', + emailInterceptionDesc: '拦截邮件, 要拦截整个域名输入 *@example.com, 可用于禁止用户接收某些网站的邮件', + availableDomains: '可用域名', + availableDomainsDesc: '限制用户只能使用指定的域名邮箱,不在配置名单内的域名会被禁止使用注册添加邮箱,接收发送邮件等功能,留空默认允许可用所有域名', + backgroundUrlDesc: '在线图片链接', + localUpload: '本地上传', + imageLink: '图片链接', + backgroundWarning: '图片文件大小会影响网站加载速度', } export default zh \ No newline at end of file diff --git a/mail-vue/src/layout/aside/index.vue b/mail-vue/src/layout/aside/index.vue index 8a3dbbd..57c92c8 100644 --- a/mail-vue/src/layout/aside/index.vue +++ b/mail-vue/src/layout/aside/index.vue @@ -61,8 +61,8 @@ - - {{$t('SystemSettings')}} + + {{$t('SystemSettings')}} diff --git a/mail-vue/src/layout/index.vue b/mail-vue/src/layout/index.vue index 4b6af20..8ec30b5 100644 --- a/mail-vue/src/layout/index.vue +++ b/mail-vue/src/layout/index.vue @@ -38,7 +38,6 @@ const handleResize = () => { } onMounted(() => { - uiStore.writerRef = writerRef window.addEventListener('resize', handleResize) diff --git a/mail-vue/src/main.js b/mail-vue/src/main.js index 8da163c..29bfd35 100644 --- a/mail-vue/src/main.js +++ b/mail-vue/src/main.js @@ -2,8 +2,6 @@ import {createApp} from 'vue'; import App from './App.vue'; import router from './router'; import './style.css'; -import VueCropper from 'vue-cropper'; -import 'vue-cropper/dist/index.css' import { init } from '@/init/init.js'; import { createPinia } from 'pinia'; import piniaPersistedState from 'pinia-plugin-persistedstate'; @@ -12,7 +10,7 @@ const pinia = createPinia().use(piniaPersistedState) import i18n from "@/i18n/index.js"; const app = createApp(App).use(pinia) await init() -app.use(router).use(VueCropper).use(i18n).directive('perm',perm) +app.use(router).use(i18n).directive('perm',perm) app.config.devtools = true; app.mount('#app'); diff --git a/mail-vue/src/utils/convert.js b/mail-vue/src/utils/convert.js index 2289672..26522db 100644 --- a/mail-vue/src/utils/convert.js +++ b/mail-vue/src/utils/convert.js @@ -1,5 +1,24 @@ import {useSettingStore} from "@/store/setting.js"; export function cvtR2Url(key) { - const settingStore = useSettingStore(); - return settingStore.settings.r2Domain + '/' + key + + if (!key) { + return + 'https://' + '' + } + + if (key.startsWith('https://')) { + return key + } + + const { settings } = useSettingStore(); + + let domain = settings.r2Domain + + if (!domain.startsWith('http')) { + return 'https://' + domain + '/' + key + } + + if (domain.endsWith("/")) { + domain = domain.slice(0, -1); + } + return domain + '/' + key } \ No newline at end of file diff --git a/mail-vue/src/utils/day.js b/mail-vue/src/utils/day.js index 01a57ae..f7ab2f0 100644 --- a/mail-vue/src/utils/day.js +++ b/mail-vue/src/utils/day.js @@ -40,11 +40,11 @@ export function fromNow(date) { if (diffSeconds < 60) return `Just now`; if (diffMinutes < 60) return `${diffMinutes} min ago`; if (diffHours < 2) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`; - return d.format('HH:mm'); + return d.format('hh:mm A'); } if (now.subtract(1, 'day').isSame(d, 'day')) { - return d.format('hh:mm A'); + return d.format('MMM D'); } return d.year() === now.year() diff --git a/mail-vue/src/utils/file-utils.js b/mail-vue/src/utils/file-utils.js index 8763fc1..6611efa 100644 --- a/mail-vue/src/utils/file-utils.js +++ b/mail-vue/src/utils/file-utils.js @@ -14,13 +14,18 @@ export function formatBytes(bytes) { return `${size} ${units[i]}`; } -export function fileToBase64(file) { +export function fileToBase64(file, type = false) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { - const base64 = reader.result.split(',')[1]; - resolve(base64); + if (type) { + const base64 = reader.result; + resolve(base64); + } else { + const base64 = reader.result.split(',')[1]; + resolve(base64); + } }; reader.onerror = reject; }); @@ -50,4 +55,4 @@ export function compressImage(file, config = {}) { }, }); }); -} +} \ No newline at end of file diff --git a/mail-vue/src/views/role/index.vue b/mail-vue/src/views/role/index.vue index 576f5ab..5e2608a 100644 --- a/mail-vue/src/views/role/index.vue +++ b/mail-vue/src/views/role/index.vue @@ -47,15 +47,52 @@ - + +
- + + + +
@@ -108,6 +145,7 @@ import {roleAdd, roleDelete, rolePermTree, roleRoleList, roleSet, roleSetDef} fr import loading from '@/components/loading/index.vue'; import {useRoleStore} from "@/store/role.js"; import {useUserStore} from "@/store/user.js"; +import {useSettingStore} from "@/store/setting.js"; import {isEmail} from "@/utils/verify-utils.js"; import {useI18n} from "vue-i18n"; @@ -115,6 +153,7 @@ defineOptions({ name: 'role' }) +const { domainList } = useSettingStore(); const { t, locale } = useI18n(); const userStore = useUserStore(); const roleStore = useRoleStore(); @@ -144,8 +183,11 @@ const form = reactive({ accountCount: 0, sort: 0, isDefault: 0, + availDomain: [] }) +let domainOptions = [] + const expand = ref(false) let chooseRole = {} @@ -156,6 +198,18 @@ rolePermTree().then(tree => { treeList.push(...tree) }) +domainOptions = domainList.map(domain => ({label: domain,value: domain})) + + +function availDomainChange() { + const index = form.availDomain.findIndex(domain => { + return !domainOptions.map(option => option.value).includes(domain) + }) + if (index > -1) { + form.availDomain.splice(index,1) + } +} + function banEmailAddTag(val) { const emails = Array.from(new Set( val.split(/[,,]/).map(item => item.trim()).filter(item => item) @@ -270,6 +324,7 @@ function resetForm() { form.accountCount = 0 form.banEmail = [] form.banEmailType = 0 + form.availDomain = [] tree.value.setCheckedKeys([]) } @@ -285,6 +340,7 @@ function openRoleSet(role) { form.sendCount = role.sendCount form.accountCount = role.accountCount form.banEmail = role.banEmail + form.availDomain = role.availDomain nextTick(() => { tree.value.setCheckedKeys(role.permIds) }) @@ -394,7 +450,7 @@ window.onresize = () => { .warning { position: relative; left: 5px; - top: 5px; + top: 2px; color: gray; cursor: pointer; } diff --git a/mail-vue/src/views/setting/index.vue b/mail-vue/src/views/setting/index.vue index 160a0d6..705bee3 100644 --- a/mail-vue/src/views/setting/index.vue +++ b/mail-vue/src/views/setting/index.vue @@ -73,9 +73,8 @@ import {accountSetName} from "@/request/account.js"; import {useAccountStore} from "@/store/account.js"; import {useI18n} from "vue-i18n"; import {useSettingStore} from "@/store/setting.js"; -import dayjs from "dayjs"; -const { t, locale } = useI18n() +const { t } = useI18n() const settingStore = useSettingStore() const accountStore = useAccountStore() const userStore = useUserStore(); diff --git a/mail-vue/src/views/sys-setting/index.vue b/mail-vue/src/views/sys-setting/index.vue index 017f61e..f4b14e3 100644 --- a/mail-vue/src/views/sys-setting/index.vue +++ b/mail-vue/src/views/sys-setting/index.vue @@ -101,13 +101,13 @@ fit="cover" >
- + @@ -286,10 +286,10 @@
{{$t('support')}} : - - Afdian + + {{t('supportDesc')}}
@@ -299,7 +299,7 @@
- +
{{$t('save')}} @@ -319,7 +319,7 @@ {{$t('save')}}
- +
{{$t('save')}} @@ -334,24 +334,37 @@
-
- -
+ + +
+ + {{$t('localUpload')}} + + + {{$t('imageLink')}} + {{$t('save')}}
@@ -387,7 +400,7 @@