mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-08-30 04:26:42 +08:00
feat: add Admin random address name generation (#1127)
feat: add admin random address name
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
### Features
|
||||
|
||||
- feat: |Admin| 数据库页面新增 D1 存储容量展示,支持选择并保存 Free 或 Workers Paid 套餐,对比当前数据库大小和容量上限
|
||||
- feat: |Admin| 创建邮箱页面支持一键生成随机邮箱名称(issue #1126)
|
||||
- feat: |用户系统| 用户中心新增发送邮件、与收件箱一致的可按绑定地址过滤的发件箱,以及地址管理凭证弹框;提供使用用户 JWT 的地址设置、发信权限申请、发信及发件箱 API
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
### Features
|
||||
|
||||
- feat: |Admin| Add D1 storage capacity details to the database page, with persistent Free and Workers Paid plan selection and a comparison between the current database size and capacity limit
|
||||
- feat: |Admin| Add one-click random email-name generation to the address creation page (issue #1126)
|
||||
- feat: |User| Add mail composition, inbox-style sent-item filtering by bound address, and the shared address-credentials dialog to the user center, backed by User JWT APIs for address settings, send-access requests, sending, and sent-item management
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -402,6 +402,7 @@ export const deMessages = {
|
||||
"views.user.UserSettings.renamePasskeyNamePlaceholder": "Bitte den neuen Passkey-Namen eingeben",
|
||||
"views.user.UserSettings.passkeyNamePlaceholder": "Bitte den Passkey-Namen eingeben oder leer lassen, um einen zufälligen zu erzeugen",
|
||||
"views.admin.CreateAccount.fillInAllFields": "Bitte alle Felder ausfüllen",
|
||||
"views.admin.CreateAccount.generateName": "Zufälligen Namen erzeugen",
|
||||
"views.admin.SendBox.queryTip": "Bitte die abzufragende Adresse eingeben; leer lassen für alle",
|
||||
"views.user.UserLogin.pleaseInputCode": "Bitte den Code eingeben",
|
||||
"views.admin.UserManagement.pleaseInput": "Bitte alle erforderlichen Informationen eingeben",
|
||||
|
||||
@@ -402,6 +402,7 @@ export const esMessages = {
|
||||
"views.user.UserSettings.renamePasskeyNamePlaceholder": "Introduce el nuevo nombre de la passkey",
|
||||
"views.user.UserSettings.passkeyNamePlaceholder": "Introduce el nombre de la passkey o déjalo vacío para generarlo aleatoriamente",
|
||||
"views.admin.CreateAccount.fillInAllFields": "Rellena todos los campos",
|
||||
"views.admin.CreateAccount.generateName": "Generar nombre aleatorio",
|
||||
"views.admin.SendBox.queryTip": "Introduce la dirección a consultar; vacío para todas",
|
||||
"views.user.UserLogin.pleaseInputCode": "Introduce el código",
|
||||
"views.admin.UserManagement.pleaseInput": "Introduce la información completa",
|
||||
|
||||
@@ -402,6 +402,7 @@ export const jaMessages = {
|
||||
"views.user.UserSettings.renamePasskeyNamePlaceholder": "新しい Passkey 名を入力してください",
|
||||
"views.user.UserSettings.passkeyNamePlaceholder": "Passkey 名を入力するか、空欄でランダム生成してください",
|
||||
"views.admin.CreateAccount.fillInAllFields": "すべての項目を入力してください",
|
||||
"views.admin.CreateAccount.generateName": "ランダム名を生成",
|
||||
"views.admin.SendBox.queryTip": "検索するアドレスを入力してください。空欄で全件検索します",
|
||||
"views.user.UserLogin.pleaseInputCode": "コードを入力してください",
|
||||
"views.admin.UserManagement.pleaseInput": "必要な情報をすべて入力してください",
|
||||
|
||||
@@ -402,6 +402,7 @@ export const ptBRMessages = {
|
||||
"views.user.UserSettings.renamePasskeyNamePlaceholder": "Informe o novo nome da passkey",
|
||||
"views.user.UserSettings.passkeyNamePlaceholder": "Informe o nome da passkey ou deixe em branco para gerar um aleatório",
|
||||
"views.admin.CreateAccount.fillInAllFields": "Preencha todos os campos",
|
||||
"views.admin.CreateAccount.generateName": "Gerar nome aleatório",
|
||||
"views.admin.SendBox.queryTip": "Informe o endereço para consulta; deixe em branco para consultar todos",
|
||||
"views.user.UserLogin.pleaseInputCode": "Informe o código",
|
||||
"views.admin.UserManagement.pleaseInput": "Informe todas as informações",
|
||||
|
||||
@@ -2146,6 +2146,10 @@ export const MESSAGE_REGISTRY = {
|
||||
"en": "Please fill in all fields",
|
||||
"zh": "请填写完整信息"
|
||||
},
|
||||
"generateName": {
|
||||
"en": "Generate Fake Name",
|
||||
"zh": "生成随机名字"
|
||||
},
|
||||
"linkWithAddressCredential": {
|
||||
"en": "Open to auto login email link",
|
||||
"zh": "打开即可自动登录邮箱的链接"
|
||||
|
||||
@@ -23,6 +23,40 @@ const result = ref("")
|
||||
const addressPassword = ref("")
|
||||
const createdAddress = ref("")
|
||||
|
||||
const addressRegex = computed(() => {
|
||||
try {
|
||||
if (openSettings.value.addressRegex) {
|
||||
return new RegExp(openSettings.value.addressRegex, 'g');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
message.error(`Invalid addressRegex: ${openSettings.value.addressRegex}`);
|
||||
}
|
||||
return /[^a-z0-9]/g;
|
||||
});
|
||||
|
||||
const generateNameLoading = ref(false);
|
||||
const generateName = async () => {
|
||||
try {
|
||||
generateNameLoading.value = true;
|
||||
const { faker } = await import('https://esm.sh/@faker-js/faker');
|
||||
emailName.value = faker.internet.email()
|
||||
.split('@')[0]
|
||||
.replace(/\s+/g, '.')
|
||||
.replace(/\.{2,}/g, '.')
|
||||
.replace(addressRegex.value, '')
|
||||
.toLowerCase();
|
||||
// support maxAddressLen
|
||||
if (emailName.value.length > openSettings.value.maxAddressLen) {
|
||||
emailName.value = emailName.value.slice(0, openSettings.value.maxAddressLen);
|
||||
}
|
||||
} catch (error) {
|
||||
message.error(error.message || "error");
|
||||
} finally {
|
||||
generateNameLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const canUseRandomSubdomain = computed(() => {
|
||||
if (!emailDomain.value) {
|
||||
return false
|
||||
@@ -81,15 +115,22 @@ onMounted(async () => {
|
||||
<n-switch v-model:value="enablePrefix" :round="false" />
|
||||
</n-form-item-row>
|
||||
<n-form-item-row :label="t('address')">
|
||||
<n-input-group>
|
||||
<n-input-group-label v-if="enablePrefix && openSettings.prefix">
|
||||
{{ openSettings.prefix }}
|
||||
</n-input-group-label>
|
||||
<n-input v-model:value="emailName" />
|
||||
<n-input-group-label>@</n-input-group-label>
|
||||
<n-select v-model:value="emailDomain" :consistent-menu-width="false"
|
||||
:options="openSettings.domains" />
|
||||
</n-input-group>
|
||||
<n-spin :show="generateNameLoading" style="width: 100%;">
|
||||
<div>
|
||||
<n-button @click="generateName" style="margin-bottom: 10px;">
|
||||
{{ t('generateName') }}
|
||||
</n-button>
|
||||
<n-input-group>
|
||||
<n-input-group-label v-if="enablePrefix && openSettings.prefix">
|
||||
{{ openSettings.prefix }}
|
||||
</n-input-group-label>
|
||||
<n-input v-model:value="emailName" />
|
||||
<n-input-group-label>@</n-input-group-label>
|
||||
<n-select v-model:value="emailDomain" :consistent-menu-width="false"
|
||||
:options="openSettings.domains" />
|
||||
</n-input-group>
|
||||
</div>
|
||||
</n-spin>
|
||||
</n-form-item-row>
|
||||
<n-form-item-row v-if="canUseRandomSubdomain">
|
||||
<div style="width: 100%;">
|
||||
|
||||
Reference in New Issue
Block a user