mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-07-08 17:12:26 +08:00
feat: allow user delete mail && notify when send access changed (#132)
This commit is contained in:
@@ -32,14 +32,18 @@ const { t } = useI18n({
|
|||||||
refresh: 'Refresh',
|
refresh: 'Refresh',
|
||||||
attachments: 'Show Attachments',
|
attachments: 'Show Attachments',
|
||||||
downloadMail: 'Download Mail',
|
downloadMail: 'Download Mail',
|
||||||
pleaseSelectMail: "Please select a mail to view."
|
pleaseSelectMail: "Please select a mail to view.",
|
||||||
|
delete: 'Delete',
|
||||||
|
deleteMailTip: 'Are you sure you want to delete this mail?'
|
||||||
},
|
},
|
||||||
zh: {
|
zh: {
|
||||||
autoRefresh: '自动刷新',
|
autoRefresh: '自动刷新',
|
||||||
refresh: '刷新',
|
refresh: '刷新',
|
||||||
downloadMail: '下载邮件',
|
downloadMail: '下载邮件',
|
||||||
attachments: '查看附件',
|
attachments: '查看附件',
|
||||||
pleaseSelectMail: "请选择一封邮件查看。"
|
pleaseSelectMail: "请选择一封邮件查看。",
|
||||||
|
delete: '删除',
|
||||||
|
deleteMailTip: '确定要删除这封邮件吗?'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -100,6 +104,19 @@ const mailItemClass = (row) => {
|
|||||||
return curMail.value && row.id == curMail.value.id ? (themeSwitch.value ? 'overlay overlay-dark-backgroud' : 'overlay overlay-light-backgroud') : '';
|
return curMail.value && row.id == curMail.value.id ? (themeSwitch.value ? 'overlay overlay-dark-backgroud' : 'overlay overlay-light-backgroud') : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deleteMail = async () => {
|
||||||
|
try {
|
||||||
|
await api.fetch(`/api/mails/${curMail.value.id}`, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
message.success(t("success"));
|
||||||
|
curMail.value = null;
|
||||||
|
await refresh();
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message || "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await refresh();
|
await refresh();
|
||||||
});
|
});
|
||||||
@@ -158,6 +175,12 @@ onMounted(async () => {
|
|||||||
<n-tag type="info">
|
<n-tag type="info">
|
||||||
FROM: {{ curMail.source }}
|
FROM: {{ curMail.source }}
|
||||||
</n-tag>
|
</n-tag>
|
||||||
|
<n-popconfirm @positive-click="deleteMail">
|
||||||
|
<template #trigger>
|
||||||
|
<n-button tertiary type="error" size="small">{{ t('delete') }}</n-button>
|
||||||
|
</template>
|
||||||
|
{{ t('deleteMailTip') }}
|
||||||
|
</n-popconfirm>
|
||||||
<n-button v-if="curMail.attachments && curMail.attachments.length > 0" size="small" tertiary type="info"
|
<n-button v-if="curMail.attachments && curMail.attachments.length > 0" size="small" tertiary type="info"
|
||||||
@click="getAttachments(curMail.attachments)">
|
@click="getAttachments(curMail.attachments)">
|
||||||
{{ t('attachments') }}
|
{{ t('attachments') }}
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ onMounted(async () => {
|
|||||||
<n-tag type="info">
|
<n-tag type="info">
|
||||||
ID: {{ row.id }}
|
ID: {{ row.id }}
|
||||||
</n-tag>
|
</n-tag>
|
||||||
|
<n-tag type="info">
|
||||||
|
TO: {{ row.address }}
|
||||||
|
</n-tag>
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
<div v-html="row.message"></div>
|
<div v-html="row.message"></div>
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ const updateData = async () => {
|
|||||||
await api.fetch(`/admin/address_sender`, {
|
await api.fetch(`/admin/address_sender`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
address: curRow.value.address,
|
||||||
address_id: curRow.value.id,
|
address_id: curRow.value.id,
|
||||||
balance: senderBalance.value,
|
balance: senderBalance.value,
|
||||||
enabled: senderEnabled.value ? 1 : 0
|
enabled: senderEnabled.value ? 1 : 0
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ features:
|
|||||||
- title: Use rust wasm to parse emails
|
- title: Use rust wasm to parse emails
|
||||||
details: Use rust wasm to parse emails, support various RFC standards for emails, support attachments, extremely fast
|
details: Use rust wasm to parse emails, support various RFC standards for emails, support attachments, extremely fast
|
||||||
- title: Support sending emails
|
- title: Support sending emails
|
||||||
details: Support sending txt or html emails through domain name mailboxes
|
details: Support sending txt or html emails through domain name mailboxes,Support DKIM signature
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ features:
|
|||||||
- title: 使用 rust wasm 解析邮件
|
- title: 使用 rust wasm 解析邮件
|
||||||
details: 使用 rust wasm 解析邮件,支持邮件各种RFC标准,支持附件, 速度极快
|
details: 使用 rust wasm 解析邮件,支持邮件各种RFC标准,支持附件, 速度极快
|
||||||
- title: 支持发送邮件
|
- title: 支持发送邮件
|
||||||
details: 支持通过域名邮箱发送 txt 或者 html 邮件
|
details: 支持通过域名邮箱发送 txt 或者 html 邮件,支持 DKIM 签名
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Hono } from 'hono'
|
import { Hono } from 'hono'
|
||||||
import { Jwt } from 'hono/utils/jwt'
|
import { Jwt } from 'hono/utils/jwt'
|
||||||
import { getSendbox } from './send_mail_api'
|
import { getSendbox } from './send_mail_api'
|
||||||
|
import { sendAdminInternalMail } from './utils'
|
||||||
|
|
||||||
const api = new Hono()
|
const api = new Hono()
|
||||||
|
|
||||||
@@ -164,7 +165,7 @@ api.get('/admin/address_sender', async (c) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
api.post('/admin/address_sender', async (c) => {
|
api.post('/admin/address_sender', async (c) => {
|
||||||
let { address_id, balance, enabled } = await c.req.json();
|
let { address, address_id, balance, enabled } = await c.req.json();
|
||||||
if (!address_id) {
|
if (!address_id) {
|
||||||
return c.text("Invalid address_id", 400)
|
return c.text("Invalid address_id", 400)
|
||||||
}
|
}
|
||||||
@@ -175,6 +176,10 @@ api.post('/admin/address_sender', async (c) => {
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
return c.text("Failed to update address sender", 500)
|
return c.text("Failed to update address sender", 500)
|
||||||
}
|
}
|
||||||
|
await sendAdminInternalMail(
|
||||||
|
c, address, "Account Send Access Updated",
|
||||||
|
`You send access has been ${enabled ? "enabled" : "disabled"}, balance: ${balance}`
|
||||||
|
);
|
||||||
return c.json({
|
return c.json({
|
||||||
success: success
|
success: success
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ api.get('/api/mails', async (c) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
api.delete('/api/mails/:id', async (c) => {
|
||||||
|
const { address } = c.get("jwtPayload")
|
||||||
|
const { id } = c.req.param();
|
||||||
|
const { success } = await c.env.DB.prepare(
|
||||||
|
`DELETE FROM raw_mails WHERE address = ? and id = ?`
|
||||||
|
).bind(address, id).run();
|
||||||
|
return c.json({
|
||||||
|
success: success
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
api.get('/api/settings', async (c) => {
|
api.get('/api/settings', async (c) => {
|
||||||
const { address, address_id } = c.get("jwtPayload")
|
const { address, address_id } = c.get("jwtPayload")
|
||||||
if (address_id && address_id > 0) {
|
if (address_id && address_id > 0) {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { createMimeMessage } from "mimetext";
|
||||||
|
|
||||||
export const getDomains = (c) => {
|
export const getDomains = (c) => {
|
||||||
if (!c.env.DOMAINS) {
|
if (!c.env.DOMAINS) {
|
||||||
return [];
|
return [];
|
||||||
@@ -45,3 +47,33 @@ export const getAdminPasswords = (c) => {
|
|||||||
}
|
}
|
||||||
return c.env.ADMIN_PASSWORDS;
|
return c.env.ADMIN_PASSWORDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const sendAdminInternalMail = async (c, toMail, subject, text) => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const msg = createMimeMessage();
|
||||||
|
msg.setSender({
|
||||||
|
name: "Admin",
|
||||||
|
addr: "admin@internal"
|
||||||
|
});
|
||||||
|
msg.setRecipient(toMail);
|
||||||
|
msg.setSubject(subject);
|
||||||
|
msg.addMessage({
|
||||||
|
contentType: 'text/plain',
|
||||||
|
data: text
|
||||||
|
});
|
||||||
|
const message_id = Math.random().toString(36).substring(2, 15);
|
||||||
|
const { success } = await c.env.DB.prepare(
|
||||||
|
`INSERT INTO raw_mails (source, address, raw, message_id) VALUES (?, ?, ?, ?)`
|
||||||
|
).bind(
|
||||||
|
"admin@internal", toMail, msg.asRaw(), message_id
|
||||||
|
).run();
|
||||||
|
if (!success) {
|
||||||
|
console.log(`Failed save message from admin@internal to ${toMail}`);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("sendAdminInternalMail error", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user