修复注册码权限无效bug
This commit is contained in:
@@ -93,7 +93,7 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="item.status === 7"
|
<el-tooltip v-if="item.status === 7"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:content="$t('NoRecipient')"
|
:content="$t('noRecipient')"
|
||||||
>
|
>
|
||||||
<Icon icon="ic:round-mark-email-read" style="color:#FBBD08" width="20"
|
<Icon icon="ic:round-mark-email-read" style="color:#FBBD08" width="20"
|
||||||
height="20"/>
|
height="20"/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import {ref, onMounted, onBeforeUnmount, watch, nextTick, shallowRef, defineEmits} from 'vue';
|
import {ref, onMounted, onBeforeUnmount, watch, nextTick, shallowRef, defineEmits} from 'vue';
|
||||||
import loading from "@/components/loading/index.vue";
|
import loading from "@/components/loading/index.vue";
|
||||||
import {compressImage} from "@/utils/file-utils.js";
|
import {compressImage} from "@/utils/file-utils.js";
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
defineExpose({
|
defineExpose({
|
||||||
clearEditor,
|
clearEditor,
|
||||||
focus,
|
focus,
|
||||||
@@ -27,6 +28,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const { locale } = useI18n()
|
||||||
const emit = defineEmits(['change']);
|
const emit = defineEmits(['change']);
|
||||||
const editor = shallowRef(null);
|
const editor = shallowRef(null);
|
||||||
const isInitialized = ref(false);
|
const isInitialized = ref(false);
|
||||||
@@ -81,7 +83,7 @@ function initEditor() {
|
|||||||
},
|
},
|
||||||
font_size_formats: '8px 10px 12px 14px 16px 18px 24px 36px',
|
font_size_formats: '8px 10px 12px 14px 16px 18px 24px 36px',
|
||||||
emoticons_search: false,
|
emoticons_search: false,
|
||||||
language: 'zh_CN',
|
language: locale.value === 'zh' ? 'zh_CN' : 'en',
|
||||||
language_url: '/tinymce/langs/zh_CN.js',
|
language_url: '/tinymce/langs/zh_CN.js',
|
||||||
menubar: false,
|
menubar: false,
|
||||||
license_key: 'gpl',
|
license_key: 'gpl',
|
||||||
|
|||||||
@@ -67,9 +67,8 @@ const en = {
|
|||||||
loginDevice: 'Login device',
|
loginDevice: 'Login device',
|
||||||
loginSystem: 'Login system',
|
loginSystem: 'Login system',
|
||||||
browserLogin: 'Browser Login',
|
browserLogin: 'Browser Login',
|
||||||
noPerm: 'Unauthorized',
|
unauthorized: 'Unauthorized',
|
||||||
noLimit: 'Unlimited',
|
unlimited: 'Unlimited',
|
||||||
blocked: 'Blocked',
|
|
||||||
sendCount: 'Send email : ',
|
sendCount: 'Send email : ',
|
||||||
accountCount: 'Add account : ',
|
accountCount: 'Add account : ',
|
||||||
action: 'Action',
|
action: 'Action',
|
||||||
@@ -173,7 +172,7 @@ const en = {
|
|||||||
tgBotDesc: 'Forward received emails to a Telegram bot',
|
tgBotDesc: 'Forward received emails to a Telegram bot',
|
||||||
tgBotToken: 'Bot token',
|
tgBotToken: 'Bot token',
|
||||||
toBotTokenDesc: 'Multiple user chat_ids, separated by commas',
|
toBotTokenDesc: 'Multiple user chat_ids, separated by commas',
|
||||||
otherEmailDec: 'emails can be forwarded to other providers, but must be verified via cloudflare',
|
otherEmailDec: 'emails can be forwarded to external email, but must be verified via cloudflare.',
|
||||||
otherEmailInputDesc: 'Separate multiple email addresses with commas.',
|
otherEmailInputDesc: 'Separate multiple email addresses with commas.',
|
||||||
forwardingRulesDesc: 'Rule-based forwarding only forwards emails received by the specified address.',
|
forwardingRulesDesc: 'Rule-based forwarding only forwards emails received by the specified address.',
|
||||||
ruleEmailsInputDesc: 'Separate multiple email addresses with commas.',
|
ruleEmailsInputDesc: 'Separate multiple email addresses with commas.',
|
||||||
@@ -225,7 +224,7 @@ const en = {
|
|||||||
allRestore: 'Includes deleted data',
|
allRestore: 'Includes deleted data',
|
||||||
restoreSuccessMsg: 'Restore successful',
|
restoreSuccessMsg: 'Restore successful',
|
||||||
banRestore: 'Confirm banning {msg}?',
|
banRestore: 'Confirm banning {msg}?',
|
||||||
signOut: 'Sign out',
|
logOut: 'Sign out',
|
||||||
clearContentConfirm: 'Are you sure to clear all content?',
|
clearContentConfirm: 'Are you sure to clear all content?',
|
||||||
attLimitMsg: 'Attachment size limit: 28MB',
|
attLimitMsg: 'Attachment size limit: 28MB',
|
||||||
emptyRecipientMsg: 'Recipient email cannot be empty',
|
emptyRecipientMsg: 'Recipient email cannot be empty',
|
||||||
@@ -240,9 +239,9 @@ const en = {
|
|||||||
sendingErrorMsg: 'Sending in progress',
|
sendingErrorMsg: 'Sending in progress',
|
||||||
networkErrorMsg: 'Network error. Check your internet',
|
networkErrorMsg: 'Network error. Check your internet',
|
||||||
timeoutErrorMsg: 'Timeout. Try again later',
|
timeoutErrorMsg: 'Timeout. Try again later',
|
||||||
serverBusyErrorMsg: 'Server busy. Please try again later.',
|
serverBusyErrorMsg: 'Server busy. Please try again later',
|
||||||
reqFailErrorMsg: 'Request failed. Try again later.',
|
reqFailErrorMsg: 'Request failed. Try again later',
|
||||||
mailDetails: 'Message',
|
message: 'Message',
|
||||||
language: 'Language',
|
language: 'Language',
|
||||||
totalUserAccount: '{msg}',
|
totalUserAccount: '{msg}',
|
||||||
sendBanned: 'Banned',
|
sendBanned: 'Banned',
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const zh = {
|
|||||||
totalSent: '发送数量',
|
totalSent: '发送数量',
|
||||||
totalMailboxes: '邮箱数量',
|
totalMailboxes: '邮箱数量',
|
||||||
totalUsers: '用户数量',
|
totalUsers: '用户数量',
|
||||||
deleted: '已删除',
|
deleted: '删除',
|
||||||
active: '正常',
|
active: '正常',
|
||||||
emailSource: '邮件来源',
|
emailSource: '邮件来源',
|
||||||
userGrowth: '用户增长',
|
userGrowth: '用户增长',
|
||||||
@@ -67,9 +67,8 @@ const zh = {
|
|||||||
loginDevice: '登录设备',
|
loginDevice: '登录设备',
|
||||||
loginSystem: '登录系统',
|
loginSystem: '登录系统',
|
||||||
browserLogin: '登录浏览器',
|
browserLogin: '登录浏览器',
|
||||||
noPerm: '无权限',
|
unauthorized: '无权限',
|
||||||
noLimit: '无限制',
|
unlimited: '无限制',
|
||||||
blocked: '被禁用',
|
|
||||||
sendCount: '邮件发送 :',
|
sendCount: '邮件发送 :',
|
||||||
accountCount: '邮箱添加 :',
|
accountCount: '邮箱添加 :',
|
||||||
action: '操作',
|
action: '操作',
|
||||||
@@ -225,7 +224,7 @@ const zh = {
|
|||||||
allRestore: '包括已删除的数据',
|
allRestore: '包括已删除的数据',
|
||||||
restoreSuccessMsg: '恢复成功',
|
restoreSuccessMsg: '恢复成功',
|
||||||
banRestore: '确认禁用 {msg} 吗?',
|
banRestore: '确认禁用 {msg} 吗?',
|
||||||
signOut: '退出',
|
logOut: '退出',
|
||||||
clearContentConfirm: '确定要清空所有内容吗?',
|
clearContentConfirm: '确定要清空所有内容吗?',
|
||||||
attLimitMsg: '附件大小限制28mb',
|
attLimitMsg: '附件大小限制28mb',
|
||||||
emptyRecipientMsg: '收件人邮箱地址不能为空',
|
emptyRecipientMsg: '收件人邮箱地址不能为空',
|
||||||
@@ -242,10 +241,10 @@ const zh = {
|
|||||||
timeoutErrorMsg: '请求超时,请稍后重试',
|
timeoutErrorMsg: '请求超时,请稍后重试',
|
||||||
serverBusyErrorMsg: '服务器繁忙,请稍后重试',
|
serverBusyErrorMsg: '服务器繁忙,请稍后重试',
|
||||||
reqFailErrorMsg: '请求失败,请稍后再试',
|
reqFailErrorMsg: '请求失败,请稍后再试',
|
||||||
mailDetails: '邮件详情',
|
message: '邮件详情',
|
||||||
language: '网站语言',
|
language: '网站语言',
|
||||||
totalUserAccount: '{msg} 个',
|
totalUserAccount: '{msg} 个',
|
||||||
sendBan: '已禁用',
|
sendBanned: '已禁用',
|
||||||
wrote: '来信'
|
wrote: '来信'
|
||||||
}
|
}
|
||||||
export default zh
|
export default zh
|
||||||
@@ -16,8 +16,6 @@ export async function init() {
|
|||||||
|
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
console.log(settingStore.lang)
|
|
||||||
|
|
||||||
if (!settingStore.lang) {
|
if (!settingStore.lang) {
|
||||||
settingStore.lang = navigator.language.split('-')[0]
|
settingStore.lang = navigator.language.split('-')[0]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<Icon icon="fluent:settings-48-regular" width="20" height="20" />
|
<Icon icon="fluent:settings-48-regular" width="20" height="20" />
|
||||||
<span class="menu-name" style="margin-left: 21px">{{$t('settings')}}</span>
|
<span class="menu-name" style="margin-left: 21px">{{$t('settings')}}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<div class="manage-title" v-perm="['user:query','role:query','setting:query','analysis:query']">
|
<div class="manage-title" v-perm="['user:query','role:query','setting:query','analysis:query','reg-key:query']">
|
||||||
<div>{{$t('manage')}}</div>
|
<div>{{$t('manage')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<el-menu-item @click="router.push({name: 'analysis'})" index="analysis" v-perm="'analysis:query'"
|
<el-menu-item @click="router.push({name: 'analysis'})" index="analysis" v-perm="'analysis:query'"
|
||||||
|
|||||||
@@ -48,13 +48,13 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-tag v-if="settingStore.settings.manyEmail || settingStore.settings.addEmail" >{{$t('disabled')}}</el-tag>
|
<el-tag v-if="settingStore.settings.manyEmail || settingStore.settings.addEmail" >{{$t('disabled')}}</el-tag>
|
||||||
<span v-else-if="accountCount && hasPerm('account:add')" style="margin-right: 5px">{{ $t('totalUserAccount',{msg: accountCount}) }}</span>
|
<span v-else-if="accountCount && hasPerm('account:add')" style="margin-right: 5px">{{ $t('totalUserAccount',{msg: accountCount}) }}</span>
|
||||||
<el-tag v-else-if="!accountCount && hasPerm('account:add')" >{{$t('noLimit')}}</el-tag>
|
<el-tag v-else-if="!accountCount && hasPerm('account:add')" >{{$t('unlimited')}}</el-tag>
|
||||||
<el-tag v-else-if="!hasPerm('account:add')" >{{$t('blocked')}}</el-tag>
|
<el-tag v-else-if="!hasPerm('account:add')" >{{$t('unauthorized')}}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="logout">
|
<div class="logout">
|
||||||
<el-button type="primary" :loading="logoutLoading" @click="clickLogout">{{$t('signOut')}}</el-button>
|
<el-button type="primary" :loading="logoutLoading" @click="clickLogout">{{$t('logOut')}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -94,20 +94,21 @@ const sendType = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!hasPerm('email:send')) {
|
if (!hasPerm('email:send')) {
|
||||||
return t('noPerm')
|
return t('unauthorized')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userStore.user.role.sendType === 'ban') {
|
||||||
|
return t('sendBanned')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userStore.user.role.sendCount) {
|
if (!userStore.user.role.sendCount) {
|
||||||
return t('noLimit')
|
return t('unlimited')
|
||||||
}
|
|
||||||
|
|
||||||
if (userStore.user.role.sendCount < 0) {
|
|
||||||
return t('blocked')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userStore.user.role.sendType === 'day') {
|
if (userStore.user.role.sendType === 'day') {
|
||||||
return t('daily')
|
return t('daily')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userStore.user.role.sendType === 'count') {
|
if (userStore.user.role.sendType === 'count') {
|
||||||
return t('total')
|
return t('total')
|
||||||
}
|
}
|
||||||
@@ -115,15 +116,20 @@ const sendType = computed(() => {
|
|||||||
|
|
||||||
const sendCount = computed(() => {
|
const sendCount = computed(() => {
|
||||||
|
|
||||||
|
|
||||||
if (!hasPerm('email:send')) {
|
if (!hasPerm('email:send')) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userStore.user.role.sendType === 'ban') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
if (!userStore.user.role.sendCount) {
|
if (!userStore.user.role.sendCount) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userStore.user.role.sendCount < 0) {
|
if (settingStore.settings.send === 1) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasPerm(permKey) {
|
export function hasPerm(permKey) {
|
||||||
const {permKeys} = useUserStore().user;
|
const {permKeys} = useUserStore().user;
|
||||||
return permKeys.includes('*') || permKeys.includes(permKey);
|
return permKeys.includes('*') || permKeys.includes(permKey);
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,28 @@ export function permsToRouter(permKeys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const routers = {
|
const routers = {
|
||||||
|
'email:send': [
|
||||||
|
{
|
||||||
|
path: '/sent',
|
||||||
|
name: 'send',
|
||||||
|
component: () => import('@/views/send/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'sent',
|
||||||
|
name: 'send',
|
||||||
|
menu: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/drafts',
|
||||||
|
name: 'draft',
|
||||||
|
component: () => import('@/views/draft/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'drafts',
|
||||||
|
name: 'draft',
|
||||||
|
menu: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
'user:query': [{
|
'user:query': [{
|
||||||
path: '/all-users',
|
path: '/all-users',
|
||||||
name: 'user',
|
name: 'user',
|
||||||
@@ -58,7 +80,7 @@ const routers = {
|
|||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
'setting:query': [{
|
'setting:query': [{
|
||||||
path: '/sys-setting',
|
path: '/system-setting',
|
||||||
name: 'sys-setting',
|
name: 'sys-setting',
|
||||||
component: () => import('@/views/sys-setting/index.vue'),
|
component: () => import('@/views/sys-setting/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
@@ -19,31 +19,11 @@ const routes = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sent',
|
path: '/message',
|
||||||
name: 'send',
|
|
||||||
component: () => import('@/views/send/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: 'sent',
|
|
||||||
name: 'send',
|
|
||||||
menu: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/drafts',
|
|
||||||
name: 'draft',
|
|
||||||
component: () => import('@/views/draft/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: 'drafts',
|
|
||||||
name: 'draft',
|
|
||||||
menu: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/content',
|
|
||||||
name: 'content',
|
name: 'content',
|
||||||
component: () => import('@/views/content/index.vue'),
|
component: () => import('@/views/content/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'mailDetails',
|
title: 'message',
|
||||||
name: 'content',
|
name: 'content',
|
||||||
menu: false
|
menu: false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<Icon class="icon" @click="changeStar" v-if="email.isStar" icon="fluent-color:star-16" width="21" height="20"/>
|
<Icon class="icon" @click="changeStar" v-if="email.isStar" icon="fluent-color:star-16" width="21" height="20"/>
|
||||||
<Icon class="icon" @click="changeStar" v-else icon="solar:star-line-duotone" width="19" height="19"/>
|
<Icon class="icon" @click="changeStar" v-else icon="solar:star-line-duotone" width="19" height="19"/>
|
||||||
</span>
|
</span>
|
||||||
<Icon class="icon" v-if="emailStore.contentData.showReply" @click="openReply" icon="carbon:reply" width="20" height="20" />
|
<Icon class="icon" v-if="emailStore.contentData.showReply" v-perm="'email:send'" @click="openReply" icon="carbon:reply" width="20" height="20" />
|
||||||
</div>
|
</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<el-scrollbar class="scrollbar">
|
<el-scrollbar class="scrollbar">
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function jumpContent(email) {
|
|||||||
emailStore.contentData.delType = 'logic'
|
emailStore.contentData.delType = 'logic'
|
||||||
emailStore.contentData.showStar = true
|
emailStore.contentData.showStar = true
|
||||||
emailStore.contentData.showReply = true
|
emailStore.contentData.showReply = true
|
||||||
router.push('/content')
|
router.push('/message')
|
||||||
}
|
}
|
||||||
|
|
||||||
const existIds = new Set();
|
const existIds = new Set();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
>
|
>
|
||||||
<el-table-column width="10" />
|
<el-table-column width="10" />
|
||||||
<el-table-column :label="$t('roleName')" prop="name" :min-width="roleWidth">
|
<el-table-column :label="$t('role')" prop="name" :min-width="roleWidth">
|
||||||
<template #default="props">
|
<template #default="props">
|
||||||
<div class="role-name">
|
<div class="role-name">
|
||||||
<span >{{props.row.name}}</span>
|
<span >{{props.row.name}}</span>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<span>{{node.label}}</span>
|
<span>{{node.label}}</span>
|
||||||
<span class="send-num" v-if="data.permKey === 'email:send'" @click.stop>
|
<span class="send-num" v-if="data.permKey === 'email:send'" @click.stop>
|
||||||
<el-input-number v-model="form.sendCount" controls-position="right" :max="99999" size="small" :placeholder="$t('total')" >
|
<el-input-number v-model="form.sendCount" controls-position="right" :min="0" :max="99999" size="small" :placeholder="$t('total')" >
|
||||||
</el-input-number>
|
</el-input-number>
|
||||||
<el-select v-model="form.sendType" placeholder="Select" size="small" style="width: 65px;margin-left: 5px;">
|
<el-select v-model="form.sendType" placeholder="Select" size="small" style="width: 65px;margin-left: 5px;">
|
||||||
<el-option :label="$t('total')" value="count" />
|
<el-option :label="$t('total')" value="count" />
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function jumpContent(email) {
|
|||||||
emailStore.contentData.delType = 'logic'
|
emailStore.contentData.delType = 'logic'
|
||||||
emailStore.contentData.showStar = true
|
emailStore.contentData.showStar = true
|
||||||
emailStore.contentData.showReply = true
|
emailStore.contentData.showReply = true
|
||||||
router.push('/content')
|
router.push('/message')
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStar(email) {
|
function addStar(email) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function jumpContent(email) {
|
|||||||
emailStore.contentData.delType = 'logic'
|
emailStore.contentData.delType = 'logic'
|
||||||
emailStore.contentData.showStar = true
|
emailStore.contentData.showStar = true
|
||||||
emailStore.contentData.showReply = true
|
emailStore.contentData.showReply = true
|
||||||
router.push('/content')
|
router.push('/message')
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelStar(email) {
|
function cancelStar(email) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
>
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
<el-select v-model="params.status" placeholder="Select" class="status-select">
|
<el-select v-model="params.status" placeholder="Select" class="status-select" :style="`width: ${locale === 'en' ? 95 : 80 }px`">
|
||||||
<el-option :key="-1" :label="$t('all')" :value="-1"/>
|
<el-option :key="-1" :label="$t('all')" :value="-1"/>
|
||||||
<el-option :key="0" :label="$t('active')" :value="0"/>
|
<el-option :key="0" :label="$t('active')" :value="0"/>
|
||||||
<el-option :key="1" :label="$t('banned')" :value="1"/>
|
<el-option :key="1" :label="$t('banned')" :value="1"/>
|
||||||
@@ -507,11 +507,11 @@ function formatSendType(user) {
|
|||||||
function formatSendCount(user) {
|
function formatSendCount(user) {
|
||||||
|
|
||||||
if (!user.sendAction.hasPerm) {
|
if (!user.sendAction.hasPerm) {
|
||||||
return t('noPerm')
|
return t('unauthorized')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.sendAction.sendCount) {
|
if (!user.sendAction.sendCount) {
|
||||||
return t('noLimit');
|
return t('unlimited');
|
||||||
}
|
}
|
||||||
|
|
||||||
let count = user.sendCount + '/' + user.sendAction.sendCount
|
let count = user.sendCount + '/' + user.sendAction.sendCount
|
||||||
@@ -898,8 +898,6 @@ function adjustWidth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status-select {
|
.status-select {
|
||||||
width: 95px;
|
|
||||||
|
|
||||||
:deep(.el-select__wrapper) {
|
:deep(.el-select__wrapper) {
|
||||||
min-height: 28px;
|
min-height: 28px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ export async function email(message, env, ctx) {
|
|||||||
if (banEmailType === roleConst.banEmailType.ALL) return
|
if (banEmailType === roleConst.banEmailType.ALL) return
|
||||||
|
|
||||||
if (banEmailType === roleConst.banEmailType.CONTENT) {
|
if (banEmailType === roleConst.banEmailType.CONTENT) {
|
||||||
email.html = 'removed'
|
email.html = 'messageRemoved'
|
||||||
email.text = 'removed'
|
email.text = 'messageRemoved'
|
||||||
email.attachments = []
|
email.attachments = []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,8 +80,8 @@ export async function email(message, env, ctx) {
|
|||||||
if (banEmailType === roleConst.banEmailType.ALL) return
|
if (banEmailType === roleConst.banEmailType.ALL) return
|
||||||
|
|
||||||
if (banEmailType === roleConst.banEmailType.CONTENT) {
|
if (banEmailType === roleConst.banEmailType.CONTENT) {
|
||||||
email.html = 'removed'
|
email.html = 'messageRemoved'
|
||||||
email.text = 'removed'
|
email.text = 'messageRemoved'
|
||||||
email.attachments = []
|
email.attachments = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
const en = {
|
const en = {
|
||||||
IncorrectPwd: 'Incorrect password',
|
IncorrectPwd: 'Incorrect password',
|
||||||
addAccountDisabled: 'Add email account function is disabled',
|
addAccountDisabled: 'Add account feature is disabled',
|
||||||
regDisabled: 'Sign up is disabled',
|
regDisabled: 'Sign up is disabled',
|
||||||
emptyEmail: 'Email cannot be empty',
|
emptyEmail: 'Email cannot be empty',
|
||||||
notEmail: 'Invalid email',
|
notEmail: 'Invalid email',
|
||||||
notExistDomain: 'Email domain does not exist',
|
notExistDomain: 'Email domain does not exist',
|
||||||
isDelAccount: 'This Email has been deleted',
|
isDelAccount: 'This Email has been deleted',
|
||||||
isRegAccount: 'This Email is already signed up',
|
isRegAccount: 'This Email is already signed up',
|
||||||
accountLimit: 'Email account limit reached',
|
accountLimit: 'Account limit reached',
|
||||||
delMyAccount: 'Cannot delete your own email account',
|
delMyAccount: 'Cannot delete your own account',
|
||||||
noUserAccount: 'This email does not belong to the current user',
|
noUserAccount: 'This email does not belong to the current user',
|
||||||
usernameLengthLimit: 'Username length exceeds the limit',
|
usernameLengthLimit: 'Username length exceeds the limit',
|
||||||
noOsDomainSendPic: 'Cannot send body images: R2 domain not configured',
|
noOsDomainSendPic: 'Cannot send body images: R2 domain not configured',
|
||||||
noOsSendPic: 'Cannot send body images: R2 object storage not configured',
|
noOsSendPic: 'Cannot send body images: R2 object storage not configured',
|
||||||
noOsDomainSendAtt: 'Cannot send attachments: R2 domain not configured',
|
noOsDomainSendAtt: 'Cannot send attachments: R2 domain not configured',
|
||||||
noOsSendAtt: 'Cannot send attachments: R2 object storage not configured',
|
noOsSendAtt: 'Cannot send attachments: R2 object storage not configured',
|
||||||
disabledSend: 'Email sending is disabled',
|
disabledSend: 'Email sending feature is disabled',
|
||||||
noSeparateSend: 'Attachments are not supported in separate sending',
|
noSeparateSend: 'Attachments are not supported in separate sending',
|
||||||
userNoSendTotal: 'User has no remaining sends',
|
|
||||||
daySendLimit: 'Daily send limit reached',
|
daySendLimit: 'Daily send limit reached',
|
||||||
totalSendLimit: 'Total send limit reached',
|
totalSendLimit: 'Total send limit reached',
|
||||||
daySendLack: 'Not enough remaining sends today',
|
daySendLack: 'Not enough remaining sends today',
|
||||||
@@ -53,6 +52,7 @@ const en = {
|
|||||||
botVerifyFail: 'Bot verification failed, please try again',
|
botVerifyFail: 'Bot verification failed, please try again',
|
||||||
authExpired: 'Authentication expired, please log in again',
|
authExpired: 'Authentication expired, please log in again',
|
||||||
unauthorized: 'Unauthorized',
|
unauthorized: 'Unauthorized',
|
||||||
|
bannedSend: 'You are banned from sending emails',
|
||||||
perms: {
|
perms: {
|
||||||
"邮件": "Email",
|
"邮件": "Email",
|
||||||
"邮件发送": "Send email",
|
"邮件发送": "Send email",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import en from './en.js'
|
|||||||
import app from '../hono/hono';
|
import app from '../hono/hono';
|
||||||
|
|
||||||
app.use('*', async (c, next) => {
|
app.use('*', async (c, next) => {
|
||||||
const lang = c.req.header('accept-language').split('-')[0]
|
const lang = c.req.header('accept-language')?.split('-')[0]
|
||||||
i18next.init({
|
i18next.init({
|
||||||
lng: lang,
|
lng: lang,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ const zh = {
|
|||||||
noOsSendAtt: 'r2对象存储未配置不能发送附件',
|
noOsSendAtt: 'r2对象存储未配置不能发送附件',
|
||||||
disabledSend: '邮件发送功能已停用',
|
disabledSend: '邮件发送功能已停用',
|
||||||
noSeparateSend: '分别发送暂时不支持附件',
|
noSeparateSend: '分别发送暂时不支持附件',
|
||||||
userNoSendTotal: '用户无发送次数',
|
|
||||||
daySendLimit: '发送次数已到达每日限制',
|
daySendLimit: '发送次数已到达每日限制',
|
||||||
totalSendLimit: '发送次数已到达限制',
|
totalSendLimit: '发送次数已到达限制',
|
||||||
daySendLack: '当日剩余发送次数不足',
|
daySendLack: '当日剩余发送次数不足',
|
||||||
@@ -53,6 +52,7 @@ const zh = {
|
|||||||
botVerifyFail: '人机验证失败,请重试',
|
botVerifyFail: '人机验证失败,请重试',
|
||||||
authExpired: '身份认证失效,请重新登录',
|
authExpired: '身份认证失效,请重新登录',
|
||||||
unauthorized: '权限不足',
|
unauthorized: '权限不足',
|
||||||
|
bannedSend: '你已被禁止发送邮件',
|
||||||
perms: {
|
perms: {
|
||||||
"邮件": "邮件",
|
"邮件": "邮件",
|
||||||
"邮件发送": "邮件发送",
|
"邮件发送": "邮件发送",
|
||||||
@@ -65,7 +65,7 @@ const zh = {
|
|||||||
"用户注销": "用户注销",
|
"用户注销": "用户注销",
|
||||||
"分析页": "分析页",
|
"分析页": "分析页",
|
||||||
"数据查看": "数据查看",
|
"数据查看": "数据查看",
|
||||||
"用户信息": "用户信息",
|
"用户信息": "用户列表",
|
||||||
"用户查看": "用户查看",
|
"用户查看": "用户查看",
|
||||||
"用户添加": "用户添加",
|
"用户添加": "用户添加",
|
||||||
"密码修改": "密码修改",
|
"密码修改": "密码修改",
|
||||||
|
|||||||
@@ -237,8 +237,8 @@ const init = {
|
|||||||
(25, '用户添加', 'user:add', 6, 2, 1),
|
(25, '用户添加', 'user:add', 6, 2, 1),
|
||||||
(26, '发件重置', 'user:reset-send', 6, 2, 6),
|
(26, '发件重置', 'user:reset-send', 6, 2, 6),
|
||||||
(27, '邮件列表', '', 0, 1, 4),
|
(27, '邮件列表', '', 0, 1, 4),
|
||||||
(28, '邮件查看', 'sys-email:query', 27, 2, 0),
|
(28, '邮件查看', 'all-email:query', 27, 2, 0),
|
||||||
(29, '邮件删除', 'sys-email:delete', 27, 2, 0),
|
(29, '邮件删除', 'all-email:delete', 27, 2, 0),
|
||||||
(30, '身份添加', 'role:add', 13, 2, -1)
|
(30, '身份添加', 'role:add', 13, 2, -1)
|
||||||
`).run();
|
`).run();
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ const init = {
|
|||||||
INSERT INTO setting (
|
INSERT INTO setting (
|
||||||
register, receive, add_email, many_email, title, auto_refresh_time, register_verify, add_email_verify
|
register, receive, add_email, many_email, title, auto_refresh_time, register_verify, add_email_verify
|
||||||
)
|
)
|
||||||
SELECT 0, 0, 0, 1, 'Cloud 邮箱', 0, 1, 1
|
SELECT 0, 0, 0, 1, 'Cloud Mail', 0, 1, 1
|
||||||
WHERE NOT EXISTS (SELECT 1 FROM setting)
|
WHERE NOT EXISTS (SELECT 1 FROM setting)
|
||||||
`).run();
|
`).run();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ const premKey = {
|
|||||||
'setting:set': ['/setting/set', '/setting/setBackground'],
|
'setting:set': ['/setting/set', '/setting/setBackground'],
|
||||||
'setting:clean': ['/setting/physicsDeleteAll'],
|
'setting:clean': ['/setting/physicsDeleteAll'],
|
||||||
'analysis:query': ['/analysis/echarts'],
|
'analysis:query': ['/analysis/echarts'],
|
||||||
'role-key:add': ['/regKey/add'],
|
'reg-key:add': ['/regKey/add'],
|
||||||
'role-key:query': ['/regKey/list','/regKey/history'],
|
'reg-key:query': ['/regKey/list','/regKey/history'],
|
||||||
'role-key:delete': ['/regKey/delete','/regKey/clearNotUse'],
|
'reg-key:delete': ['/regKey/delete','/regKey/clearNotUse'],
|
||||||
};
|
};
|
||||||
|
|
||||||
app.use('*', async (c, next) => {
|
app.use('*', async (c, next) => {
|
||||||
@@ -126,6 +126,7 @@ app.use('*', async (c, next) => {
|
|||||||
const userPaths = permKeyToPaths(permKeys);
|
const userPaths = permKeyToPaths(permKeys);
|
||||||
|
|
||||||
const userPermIndex = userPaths.findIndex(item => {
|
const userPermIndex = userPaths.findIndex(item => {
|
||||||
|
console.log(item)
|
||||||
return path.startsWith(item);
|
return path.startsWith(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,31 @@ const emailService = {
|
|||||||
|
|
||||||
let { attDataList, html } = await attService.toImageUrlHtml(c, content, r2Domain);
|
let { attDataList, html } = await attService.toImageUrlHtml(c, content, r2Domain);
|
||||||
|
|
||||||
|
if (send === settingConst.send.CLOSE) {
|
||||||
|
throw new BizError(t('disabledSend'), 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userRow = await userService.selectById(c, userId);
|
||||||
|
const roleRow = await roleService.selectById(c, userRow.type);
|
||||||
|
|
||||||
|
if (roleRow.sendType === 'ban') {
|
||||||
|
throw new BizError(t('bannedSend'), 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.env.admin !== userRow.email && roleRow.sendCount) {
|
||||||
|
|
||||||
|
if (userRow.sendCount >= roleRow.sendCount) {
|
||||||
|
if (roleRow.sendType === 'day') throw new BizError(t('daySendLimit'), 403);
|
||||||
|
if (roleRow.sendType === 'count') throw new BizError(t('totalSendLimit'), 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userRow.sendCount + receiveEmail.length > roleRow.sendCount) {
|
||||||
|
if (roleRow.sendType === 'day') throw new BizError(t('daySendLack'), 403);
|
||||||
|
if (roleRow.sendType === 'count') throw new BizError(t('totalSendLack'), 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (attDataList.length > 0 && !r2Domain) {
|
if (attDataList.length > 0 && !r2Domain) {
|
||||||
throw new BizError(t('noOsDomainSendPic'));
|
throw new BizError(t('noOsDomainSendPic'));
|
||||||
}
|
}
|
||||||
@@ -150,37 +175,11 @@ const emailService = {
|
|||||||
throw new BizError(t('noOsSendAtt'));
|
throw new BizError(t('noOsSendAtt'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send === settingConst.send.CLOSE) {
|
|
||||||
throw new BizError(t('disabledSend'), 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachments.length > 0 && manyType === 'divide') {
|
if (attachments.length > 0 && manyType === 'divide') {
|
||||||
throw new BizError(t('noSeparateSend'));
|
throw new BizError(t('noSeparateSend'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const userRow = await userService.selectById(c, userId);
|
|
||||||
const roleRow = await roleService.selectById(c, userRow.type);
|
|
||||||
|
|
||||||
if (c.env.admin !== userRow.email && roleRow.sendCount) {
|
|
||||||
|
|
||||||
if (roleRow.sendCount < 0) {
|
|
||||||
throw new BizError(t('userNoSendTotal'), 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userRow.sendCount >= roleRow.sendCount) {
|
|
||||||
if (roleRow.sendType === 'day') throw new BizError(t('daySendLimit'), 403);
|
|
||||||
if (roleRow.sendType === 'count') throw new BizError(t('totalSendLimit'), 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userRow.sendCount + receiveEmail.length > roleRow.sendCount) {
|
|
||||||
if (roleRow.sendType === 'day') throw new BizError(t('daySendLack'), 403);
|
|
||||||
if (roleRow.sendType === 'count') throw new BizError(t('totalSendLack'), 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const accountRow = await accountService.selectById(c, accountId);
|
const accountRow = await accountService.selectById(c, accountId);
|
||||||
|
|
||||||
if (!accountRow) {
|
if (!accountRow) {
|
||||||
@@ -272,8 +271,7 @@ const emailService = {
|
|||||||
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
throw new BizError(error.error);
|
||||||
throw new BizError(error.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html = this.imgReplace(html, null, r2Domain);
|
html = this.imgReplace(html, null, r2Domain);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const resendService = {
|
|||||||
async webhooks(c, body) {
|
async webhooks(c, body) {
|
||||||
|
|
||||||
const params = {}
|
const params = {}
|
||||||
|
console.error(body)
|
||||||
if (body.type === 'email.delivered') {
|
if (body.type === 'email.delivered') {
|
||||||
params.status = emailConst.status.DELIVERED
|
params.status = emailConst.status.DELIVERED
|
||||||
params.resendEmailId = body.data.email_id
|
params.resendEmailId = body.data.email_id
|
||||||
|
|||||||
Reference in New Issue
Block a user