mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-05 15:38:34 +08:00
feat: 账号设置页面增加 邮件转发规则 和 禁止接收未知地址邮件 配置 (#710)
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
## main(v1.0.4)
|
## main(v1.0.4)
|
||||||
|
|
||||||
- feat: |UI| 优化极简模式主页, 增加全部邮件页面功能(删除/下载/附件/...), 可在 `外观` 中切换
|
- feat: |UI| 优化极简模式主页, 增加全部邮件页面功能(删除/下载/附件/...), 可在 `外观` 中切换
|
||||||
|
- feat: admin 账号设置页面增加 `邮件转发规则` 配置
|
||||||
|
- feat: admin 账号设置页面增加 `禁止接收未知地址邮件` 配置
|
||||||
|
|
||||||
## v1.0.3
|
## v1.0.3
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref, h } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { NButton, NPopconfirm, NInput, NSelect } from 'naive-ui'
|
||||||
|
|
||||||
import { useGlobalState } from '../../store'
|
import { useGlobalState } from '../../store'
|
||||||
import { api } from '../../api'
|
import { api } from '../../api'
|
||||||
|
|
||||||
const { loading } = useGlobalState()
|
const { loading, openSettings } = useGlobalState()
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
const { t } = useI18n({
|
const { t } = useI18n({
|
||||||
@@ -20,6 +21,20 @@ const { t } = useI18n({
|
|||||||
noLimitSendAddressList: 'No Balance Limit Send Address List',
|
noLimitSendAddressList: 'No Balance Limit Send Address List',
|
||||||
verified_address_list: 'Verified Address List(Can send email by cf internal api)',
|
verified_address_list: 'Verified Address List(Can send email by cf internal api)',
|
||||||
fromBlockList: 'Block Keywords for receive email',
|
fromBlockList: 'Block Keywords for receive email',
|
||||||
|
block_receive_unknow_address_email: 'Block receive unknow address email',
|
||||||
|
email_forwarding_config: 'Email Forwarding Configuration',
|
||||||
|
domain_list: 'Domain List',
|
||||||
|
forward_address: 'Forward Address',
|
||||||
|
actions: 'Actions',
|
||||||
|
select_domain: 'Select Domain',
|
||||||
|
forward_placeholder: 'forward@example.com',
|
||||||
|
delete_rule: 'Delete',
|
||||||
|
delete_rule_confirm: 'Are you sure you want to delete this rule?',
|
||||||
|
delete_success: 'Delete Success',
|
||||||
|
forwarding_rule_warning: 'Each rule will run, if domains is empty, all emails will be forwarded, forward address needs to be a verified address',
|
||||||
|
add: 'Add',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
config: 'Config',
|
||||||
},
|
},
|
||||||
zh: {
|
zh: {
|
||||||
tip: '您可以手动输入以下多选输入框, 回车增加',
|
tip: '您可以手动输入以下多选输入框, 回车增加',
|
||||||
@@ -31,6 +46,20 @@ const { t } = useI18n({
|
|||||||
noLimitSendAddressList: '无余额限制发送地址列表',
|
noLimitSendAddressList: '无余额限制发送地址列表',
|
||||||
verified_address_list: '已验证地址列表(可通过 cf 内部 api 发送邮件)',
|
verified_address_list: '已验证地址列表(可通过 cf 内部 api 发送邮件)',
|
||||||
fromBlockList: '接收邮件地址屏蔽关键词',
|
fromBlockList: '接收邮件地址屏蔽关键词',
|
||||||
|
block_receive_unknow_address_email: '禁止接收未知地址邮件',
|
||||||
|
email_forwarding_config: '邮件转发配置',
|
||||||
|
domain_list: '域名列表',
|
||||||
|
forward_address: '转发地址',
|
||||||
|
actions: '操作',
|
||||||
|
select_domain: '选择域名',
|
||||||
|
forward_placeholder: 'forward@example.com',
|
||||||
|
delete_rule: '删除',
|
||||||
|
delete_rule_confirm: '确定要删除这条规则吗?',
|
||||||
|
delete_success: '删除成功',
|
||||||
|
forwarding_rule_warning: '每条规则都会运行,如果 domains 为空,则转发所有邮件,转发地址需要为已验证的地址',
|
||||||
|
add: '添加',
|
||||||
|
cancel: '取消',
|
||||||
|
config: '配置',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -40,6 +69,90 @@ const sendAddressBlockList = ref([])
|
|||||||
const noLimitSendAddressList = ref([])
|
const noLimitSendAddressList = ref([])
|
||||||
const verifiedAddressList = ref([])
|
const verifiedAddressList = ref([])
|
||||||
const fromBlockList = ref([])
|
const fromBlockList = ref([])
|
||||||
|
const emailRuleSettings = ref({
|
||||||
|
blockReceiveUnknowAddressEmail: false,
|
||||||
|
emailForwardingList: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const showEmailForwardingModal = ref(false)
|
||||||
|
const emailForwardingList = ref([])
|
||||||
|
|
||||||
|
|
||||||
|
const emailForwardingColumns = [
|
||||||
|
{
|
||||||
|
title: t('domain_list'),
|
||||||
|
key: 'domains',
|
||||||
|
render: (row, index) => {
|
||||||
|
return h(NSelect, {
|
||||||
|
value: Array.isArray(row.domains) ? row.domains : [],
|
||||||
|
onUpdateValue: (val) => {
|
||||||
|
emailForwardingList.value[index].domains = val
|
||||||
|
},
|
||||||
|
options: openSettings.value?.domains || [],
|
||||||
|
multiple: true,
|
||||||
|
filterable: true,
|
||||||
|
tag: true,
|
||||||
|
placeholder: t('select_domain')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('forward_address'),
|
||||||
|
key: 'forward',
|
||||||
|
render: (row, index) => {
|
||||||
|
return h(NInput, {
|
||||||
|
value: row.forward,
|
||||||
|
onUpdateValue: (val) => {
|
||||||
|
emailForwardingList.value[index].forward = val
|
||||||
|
},
|
||||||
|
placeholder: 'forward@example.com'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('actions'),
|
||||||
|
key: 'actions',
|
||||||
|
render: (row, index) => {
|
||||||
|
return h('div', { style: 'display: flex; gap: 8px;' }, [
|
||||||
|
h(NPopconfirm, {
|
||||||
|
onPositiveClick: () => {
|
||||||
|
emailForwardingList.value = emailForwardingList.value.filter((_, i) => i !== index)
|
||||||
|
message.success(t('delete_success'))
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
default: () => t('delete_rule_confirm'),
|
||||||
|
trigger: () => h(NButton, {
|
||||||
|
size: 'small',
|
||||||
|
type: 'error'
|
||||||
|
}, { default: () => t('delete_rule') })
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const openEmailForwardingModal = () => {
|
||||||
|
// 从 emailRuleSettings 转换出列表数据
|
||||||
|
emailForwardingList.value = emailRuleSettings.value.emailForwardingList ?
|
||||||
|
[...emailRuleSettings.value.emailForwardingList] : []
|
||||||
|
showEmailForwardingModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const addNewEmailForwardingItem = () => {
|
||||||
|
emailForwardingList.value = [
|
||||||
|
...emailForwardingList.value,
|
||||||
|
{
|
||||||
|
domains: [],
|
||||||
|
forward: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveEmailForwardingConfig = () => {
|
||||||
|
emailRuleSettings.value.emailForwardingList = [...emailForwardingList.value]
|
||||||
|
showEmailForwardingModal.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -49,6 +162,10 @@ const fetchData = async () => {
|
|||||||
verifiedAddressList.value = res.verifiedAddressList || []
|
verifiedAddressList.value = res.verifiedAddressList || []
|
||||||
fromBlockList.value = res.fromBlockList || []
|
fromBlockList.value = res.fromBlockList || []
|
||||||
noLimitSendAddressList.value = res.noLimitSendAddressList || []
|
noLimitSendAddressList.value = res.noLimitSendAddressList || []
|
||||||
|
emailRuleSettings.value = res.emailRuleSettings || {
|
||||||
|
blockReceiveUnknowAddressEmail: false,
|
||||||
|
emailForwardingList: []
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error(error.message || "error");
|
message.error(error.message || "error");
|
||||||
}
|
}
|
||||||
@@ -64,6 +181,7 @@ const save = async () => {
|
|||||||
verifiedAddressList: verifiedAddressList.value || [],
|
verifiedAddressList: verifiedAddressList.value || [],
|
||||||
fromBlockList: fromBlockList.value || [],
|
fromBlockList: fromBlockList.value || [],
|
||||||
noLimitSendAddressList: noLimitSendAddressList.value || [],
|
noLimitSendAddressList: noLimitSendAddressList.value || [],
|
||||||
|
emailRuleSettings: emailRuleSettings.value,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
message.success(t('successTip'))
|
message.success(t('successTip'))
|
||||||
@@ -81,9 +199,14 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<n-card :bordered="false" embedded style="max-width: 600px;">
|
<n-card :bordered="false" embedded style="max-width: 600px;">
|
||||||
<n-alert :show-icon="false" type="warning" style="margin-bottom: 10px;">
|
<n-alert :show-icon="false" :bordered="false" type="warning" style="margin-bottom: 10px;">
|
||||||
{{ t("tip") }}
|
<span>{{ t("tip") }}</span>
|
||||||
</n-alert>
|
</n-alert>
|
||||||
|
<n-flex justify="end">
|
||||||
|
<n-button @click="save" type="primary" :loading="loading">
|
||||||
|
{{ t('save') }}
|
||||||
|
</n-button>
|
||||||
|
</n-flex>
|
||||||
<n-form-item-row :label="t('address_block_list')">
|
<n-form-item-row :label="t('address_block_list')">
|
||||||
<n-select v-model:value="addressBlockList" filterable multiple tag
|
<n-select v-model:value="addressBlockList" filterable multiple tag
|
||||||
:placeholder="t('address_block_list_placeholder')" />
|
:placeholder="t('address_block_list_placeholder')" />
|
||||||
@@ -103,11 +226,31 @@ onMounted(async () => {
|
|||||||
<n-form-item-row :label="t('fromBlockList')">
|
<n-form-item-row :label="t('fromBlockList')">
|
||||||
<n-select v-model:value="fromBlockList" filterable multiple tag :placeholder="t('fromBlockList')" />
|
<n-select v-model:value="fromBlockList" filterable multiple tag :placeholder="t('fromBlockList')" />
|
||||||
</n-form-item-row>
|
</n-form-item-row>
|
||||||
<n-button @click="save" type="primary" block :loading="loading">
|
<n-form-item-row :label="t('block_receive_unknow_address_email')">
|
||||||
{{ t('save') }}
|
<n-checkbox v-model:checked="emailRuleSettings.blockReceiveUnknowAddressEmail" />
|
||||||
</n-button>
|
</n-form-item-row>
|
||||||
|
<n-form-item-row :label="t('email_forwarding_config')">
|
||||||
|
<n-button @click="openEmailForwardingModal">{{ t('config') }}</n-button>
|
||||||
|
</n-form-item-row>
|
||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 邮件转发配置弹窗 -->
|
||||||
|
<n-modal v-model:show="showEmailForwardingModal" preset="card" :title="t('email_forwarding_config')"
|
||||||
|
style="max-width: 800px;">
|
||||||
|
<n-space vertical>
|
||||||
|
<n-alert :show-icon="false" :bordered="false" type="warning">
|
||||||
|
<span>{{ t('forwarding_rule_warning') }}</span>
|
||||||
|
</n-alert>
|
||||||
|
<n-space justify="end">
|
||||||
|
<n-button @click="addNewEmailForwardingItem">{{ t('add') }}</n-button>
|
||||||
|
</n-space>
|
||||||
|
<n-data-table :columns="emailForwardingColumns" :data="emailForwardingList" :bordered="false" striped />
|
||||||
|
<n-space justify="end">
|
||||||
|
<n-button @click="saveEmailForwardingConfig" type="primary">{{ t('save') }}</n-button>
|
||||||
|
</n-space>
|
||||||
|
</n-space>
|
||||||
|
</n-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import worker_config from './worker_config'
|
|||||||
import admin_mail_api from './admin_mail_api'
|
import admin_mail_api from './admin_mail_api'
|
||||||
import { sendMailbyAdmin } from './send_mail'
|
import { sendMailbyAdmin } from './send_mail'
|
||||||
import db_api from './db_api'
|
import db_api from './db_api'
|
||||||
|
import { EmailRuleSettings } from '../models'
|
||||||
|
|
||||||
export const api = new Hono<HonoCustomType>()
|
export const api = new Hono<HonoCustomType>()
|
||||||
|
|
||||||
@@ -217,13 +218,15 @@ api.get('/admin/account_settings', async (c) => {
|
|||||||
const sendBlockList = await getJsonSetting(c, CONSTANTS.SEND_BLOCK_LIST_KEY);
|
const sendBlockList = await getJsonSetting(c, CONSTANTS.SEND_BLOCK_LIST_KEY);
|
||||||
const verifiedAddressList = await getJsonSetting(c, CONSTANTS.VERIFIED_ADDRESS_LIST_KEY);
|
const verifiedAddressList = await getJsonSetting(c, CONSTANTS.VERIFIED_ADDRESS_LIST_KEY);
|
||||||
const fromBlockList = c.env.KV ? await c.env.KV.get<string[]>(CONSTANTS.EMAIL_KV_BLACK_LIST, 'json') : [];
|
const fromBlockList = c.env.KV ? await c.env.KV.get<string[]>(CONSTANTS.EMAIL_KV_BLACK_LIST, 'json') : [];
|
||||||
|
const emailRuleSettings = await getJsonSetting<EmailRuleSettings>(c, CONSTANTS.EMAIL_RULE_SETTINGS_KEY);
|
||||||
const noLimitSendAddressList = await getJsonSetting(c, CONSTANTS.NO_LIMIT_SEND_ADDRESS_LIST_KEY);
|
const noLimitSendAddressList = await getJsonSetting(c, CONSTANTS.NO_LIMIT_SEND_ADDRESS_LIST_KEY);
|
||||||
return c.json({
|
return c.json({
|
||||||
blockList: blockList || [],
|
blockList: blockList || [],
|
||||||
sendBlockList: sendBlockList || [],
|
sendBlockList: sendBlockList || [],
|
||||||
verifiedAddressList: verifiedAddressList || [],
|
verifiedAddressList: verifiedAddressList || [],
|
||||||
fromBlockList: fromBlockList || [],
|
fromBlockList: fromBlockList || [],
|
||||||
noLimitSendAddressList: noLimitSendAddressList || []
|
noLimitSendAddressList: noLimitSendAddressList || [],
|
||||||
|
emailRuleSettings: emailRuleSettings || {}
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -235,7 +238,7 @@ api.post('/admin/account_settings', async (c) => {
|
|||||||
/** @type {{ blockList: Array<string>, sendBlockList: Array<string> }} */
|
/** @type {{ blockList: Array<string>, sendBlockList: Array<string> }} */
|
||||||
const {
|
const {
|
||||||
blockList, sendBlockList, noLimitSendAddressList,
|
blockList, sendBlockList, noLimitSendAddressList,
|
||||||
verifiedAddressList, fromBlockList
|
verifiedAddressList, fromBlockList, emailRuleSettings
|
||||||
} = await c.req.json();
|
} = await c.req.json();
|
||||||
if (!blockList || !sendBlockList || !verifiedAddressList) {
|
if (!blockList || !sendBlockList || !verifiedAddressList) {
|
||||||
return c.text("Invalid blockList or sendBlockList", 400)
|
return c.text("Invalid blockList or sendBlockList", 400)
|
||||||
@@ -265,6 +268,10 @@ api.post('/admin/account_settings', async (c) => {
|
|||||||
c, CONSTANTS.NO_LIMIT_SEND_ADDRESS_LIST_KEY,
|
c, CONSTANTS.NO_LIMIT_SEND_ADDRESS_LIST_KEY,
|
||||||
JSON.stringify(noLimitSendAddressList || [])
|
JSON.stringify(noLimitSendAddressList || [])
|
||||||
)
|
)
|
||||||
|
await saveSetting(
|
||||||
|
c, CONSTANTS.EMAIL_RULE_SETTINGS_KEY,
|
||||||
|
JSON.stringify(emailRuleSettings || {})
|
||||||
|
)
|
||||||
return c.json({
|
return c.json({
|
||||||
success: true
|
success: true
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const CONSTANTS = {
|
|||||||
OAUTH2_SETTINGS_KEY: 'oauth2_settings',
|
OAUTH2_SETTINGS_KEY: 'oauth2_settings',
|
||||||
VERIFIED_ADDRESS_LIST_KEY: 'verified_address_list',
|
VERIFIED_ADDRESS_LIST_KEY: 'verified_address_list',
|
||||||
NO_LIMIT_SEND_ADDRESS_LIST_KEY: 'no_limit_send_address_list',
|
NO_LIMIT_SEND_ADDRESS_LIST_KEY: 'no_limit_send_address_list',
|
||||||
|
EMAIL_RULE_SETTINGS_KEY: 'email_rule_settings',
|
||||||
|
|
||||||
// KV
|
// KV
|
||||||
TG_KV_PREFIX: "temp-mail-telegram",
|
TG_KV_PREFIX: "temp-mail-telegram",
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { Context } from "hono";
|
import { Context } from "hono";
|
||||||
|
|
||||||
import { getEnvStringList, getJsonObjectValue } from "../utils";
|
import { getEnvStringList, getJsonObjectValue, getJsonSetting } from "../utils";
|
||||||
import { sendMailToTelegram } from "../telegram_api";
|
import { sendMailToTelegram } from "../telegram_api";
|
||||||
import { auto_reply } from "./auto_reply";
|
import { auto_reply } from "./auto_reply";
|
||||||
import { isBlocked } from "./black_list";
|
import { isBlocked } from "./black_list";
|
||||||
import { triggerWebhook, triggerAnotherWorker, commonParseMail } from "../common";
|
import { triggerWebhook, triggerAnotherWorker, commonParseMail } from "../common";
|
||||||
import { check_if_junk_mail } from "./check_junk";
|
import { check_if_junk_mail } from "./check_junk";
|
||||||
import { remove_attachment_if_need } from "./check_attachment";
|
import { remove_attachment_if_need } from "./check_attachment";
|
||||||
|
import { EmailRuleSettings } from "../models";
|
||||||
|
import { CONSTANTS } from "../constants";
|
||||||
|
|
||||||
|
|
||||||
async function email(message: ForwardableEmailMessage, env: Bindings, ctx: ExecutionContext) {
|
async function email(message: ForwardableEmailMessage, env: Bindings, ctx: ExecutionContext) {
|
||||||
@@ -32,6 +34,25 @@ async function email(message: ForwardableEmailMessage, env: Bindings, ctx: Execu
|
|||||||
console.error("check junk mail error", error);
|
console.error("check junk mail error", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if unknown address mail
|
||||||
|
try {
|
||||||
|
const emailRuleSettings = await getJsonSetting<EmailRuleSettings>(
|
||||||
|
{ env: env } as Context<HonoCustomType>, CONSTANTS.EMAIL_RULE_SETTINGS_KEY
|
||||||
|
);
|
||||||
|
if (emailRuleSettings?.blockReceiveUnknowAddressEmail) {
|
||||||
|
const db_address_id = await env.DB.prepare(
|
||||||
|
`SELECT id FROM address where name = ? `
|
||||||
|
).bind(message.to).first("id");
|
||||||
|
if (!db_address_id) {
|
||||||
|
message.setReject("Unknown address");
|
||||||
|
console.log(`Unknown address mail from ${message.from} to ${message.to}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("check unknown address mail error", error);
|
||||||
|
}
|
||||||
|
|
||||||
// remove attachment if configured or size > 2MB
|
// remove attachment if configured or size > 2MB
|
||||||
try {
|
try {
|
||||||
await remove_attachment_if_need(env, parsedEmailContext, message.from, message.to, message.rawSize);
|
await remove_attachment_if_need(env, parsedEmailContext, message.from, message.to, message.rawSize);
|
||||||
@@ -70,11 +91,19 @@ async function email(message: ForwardableEmailMessage, env: Bindings, ctx: Execu
|
|||||||
try {
|
try {
|
||||||
// 遍历 FORWARD_ADDRESS_LIST
|
// 遍历 FORWARD_ADDRESS_LIST
|
||||||
const subdomainForwardAddressList = getJsonObjectValue<SubdomainForwardAddressList[]>(env.SUBDOMAIN_FORWARD_ADDRESS_LIST) || [];
|
const subdomainForwardAddressList = getJsonObjectValue<SubdomainForwardAddressList[]>(env.SUBDOMAIN_FORWARD_ADDRESS_LIST) || [];
|
||||||
for (const subdomainForwardAddress of subdomainForwardAddressList) {
|
const emailRuleSettings = await getJsonSetting<EmailRuleSettings>(
|
||||||
|
{ env: env } as Context<HonoCustomType>, CONSTANTS.EMAIL_RULE_SETTINGS_KEY
|
||||||
|
);
|
||||||
|
// 合并两个配置, env 里的配置优先级更高
|
||||||
|
const allSubdomainForwardAddressList = [
|
||||||
|
...(subdomainForwardAddressList || []),
|
||||||
|
...(emailRuleSettings?.emailForwardingList || []),
|
||||||
|
];
|
||||||
|
for (const subdomainForwardAddress of allSubdomainForwardAddressList) {
|
||||||
// 检查邮件是否匹配 domains
|
// 检查邮件是否匹配 domains
|
||||||
if (subdomainForwardAddress.domains && subdomainForwardAddress.domains.length > 0) {
|
if (subdomainForwardAddress.domains && subdomainForwardAddress.domains.length > 0) {
|
||||||
for (const domain of subdomainForwardAddress.domains) {
|
for (const domain of subdomainForwardAddress.domains) {
|
||||||
if (message.to.endsWith(domain)) {
|
if (message.to.endsWith(domain) && subdomainForwardAddress.forward) {
|
||||||
// 转发邮件
|
// 转发邮件
|
||||||
await message.forward(subdomainForwardAddress.forward);
|
await message.forward(subdomainForwardAddress.forward);
|
||||||
// 支持多邮箱转发收件,不进行截止
|
// 支持多邮箱转发收件,不进行截止
|
||||||
|
|||||||
@@ -145,3 +145,8 @@ export type UserOauth2Settings = {
|
|||||||
enableMailAllowList?: boolean | undefined;
|
enableMailAllowList?: boolean | undefined;
|
||||||
mailAllowList?: string[] | undefined;
|
mailAllowList?: string[] | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type EmailRuleSettings = {
|
||||||
|
blockReceiveUnknowAddressEmail: boolean;
|
||||||
|
emailForwardingList: SubdomainForwardAddressList[]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user