fix: clean up related mails before deleting address in admin API (#1081)

* fix: clean up related mails before deleting address in admin API

* fix: run admin address deletion in a single D1 batch
This commit is contained in:
Maxim Lapan
2026-07-11 14:06:14 +08:00
committed by GitHub
parent 565bb839db
commit 99b332345b
3 changed files with 31 additions and 20 deletions
+29 -20
View File
@@ -70,29 +70,38 @@ const createNewAddress = async (c: Context<HonoCustomType>) => {
const deleteAddress = async (c: Context<HonoCustomType>) => {
const msgs = i18n.getMessagesbyContext(c);
const { id } = c.req.param();
const { success } = await c.env.DB.prepare(
`DELETE FROM address WHERE id = ? `
).bind(id).run();
// single batch runs as one transaction: rows keyed by address name are
// deleted first and the address row last, so the name subqueries still
// resolve and a failed statement rolls back the whole deletion
const results = await c.env.DB.batch([
c.env.DB.prepare(
`DELETE FROM raw_mails WHERE address IN`
+ ` (select name from address where id = ?) `
).bind(id),
c.env.DB.prepare(
`DELETE FROM address_sender WHERE address IN`
+ ` (select name from address where id = ?) `
).bind(id),
c.env.DB.prepare(
`DELETE FROM sendbox WHERE address IN`
+ ` (select name from address where id = ?) `
).bind(id),
c.env.DB.prepare(
`DELETE FROM auto_reply_mails WHERE address IN`
+ ` (select name from address where id = ?) `
).bind(id),
c.env.DB.prepare(
`DELETE FROM users_address WHERE address_id = ?`
).bind(id),
c.env.DB.prepare(
`DELETE FROM address WHERE id = ? `
).bind(id),
]);
const success = results.every((result) => result.success);
if (!success) {
return c.text(msgs.OperationFailedMsg, 500)
}
const { success: mailSuccess } = await c.env.DB.prepare(
`DELETE FROM raw_mails WHERE address IN`
+ ` (select name from address where id = ?) `
).bind(id).run();
if (!mailSuccess) {
return c.text(msgs.OperationFailedMsg, 500)
}
const { success: sendAccess } = await c.env.DB.prepare(
`DELETE FROM address_sender WHERE address IN`
+ ` (select name from address where id = ?) `
).bind(id).run();
const { success: usersAddressSuccess } = await c.env.DB.prepare(
`DELETE FROM users_address WHERE address_id = ?`
).bind(id).run();
return c.json({
success: success && mailSuccess && sendAccess && usersAddressSuccess
})
return c.json({ success })
};
const clearInbox = async (c: Context<HonoCustomType>) => {