feat: cleanup support address and inactive address (#671)

This commit is contained in:
Dream Hunter
2025-06-18 17:31:15 +08:00
committed by GitHub
parent c694b07380
commit 9ac9cd46b0
6 changed files with 115 additions and 29 deletions

View File

@@ -17,13 +17,11 @@ export default {
return c.json({ success: true })
},
getCleanup: async (c: Context<HonoCustomType>) => {
const value = await getJsonSetting(c, CONSTANTS.AUTO_CLEANUP_KEY);
const cleanupSetting = new CleanupSettings(value);
const cleanupSetting = await getJsonSetting<CleanupSettings>(c, CONSTANTS.AUTO_CLEANUP_KEY);
return c.json(cleanupSetting)
},
saveCleanup: async (c: Context<HonoCustomType>) => {
const value = await c.req.json();
const cleanupSetting = new CleanupSettings(value);
const cleanupSetting = await c.req.json<CleanupSettings>();
await saveSetting(c, CONSTANTS.AUTO_CLEANUP_KEY, JSON.stringify(cleanupSetting));
return c.json({ success: true })
}

View File

@@ -155,6 +155,18 @@ export const cleanup = async (
}
console.log(`Cleanup ${cleanType} before ${cleanDays} days`);
switch (cleanType) {
case "inactiveAddress":
await batchDeleteAddressWithData(
c,
`updated_at < datetime('now', '-${cleanDays} day')`
)
break;
case "addressCreated":
await batchDeleteAddressWithData(
c,
`created_at < datetime('now', '-${cleanDays} day')`
)
break;
case "mails":
await c.env.DB.prepare(`
DELETE FROM raw_mails WHERE created_at < datetime('now', '-${cleanDays} day')`
@@ -177,6 +189,37 @@ export const cleanup = async (
return true;
}
const batchDeleteAddressWithData = async (
c: Context<HonoCustomType>,
addressQueryCondition: string,
): Promise<boolean> => {
await c.env.DB.prepare(
`DELETE FROM raw_mails WHERE address IN ( ` +
`SELECT name FROM address WHERE ${addressQueryCondition})`
).run();
await c.env.DB.prepare(
`DELETE FROM sendbox WHERE address IN ( ` +
`SELECT name FROM address WHERE ${addressQueryCondition})`
).run();
await c.env.DB.prepare(
`DELETE FROM auto_reply_mails WHERE address IN ( ` +
`SELECT name FROM address WHERE ${addressQueryCondition})`
).run();
await c.env.DB.prepare(
`DELETE FROM address_sender WHERE address IN ( ` +
`SELECT name FROM address WHERE ${addressQueryCondition})`
).run();
await c.env.DB.prepare(
`DELETE FROM users_address WHERE address_id IN ( ` +
`SELECT id FROM address WHERE ${addressQueryCondition})`
).run();
// delete address
await c.env.DB.prepare(`
DELETE FROM address WHERE ${addressQueryCondition}`
).run();
return true;
}
/**
* TODO: need senbox delete?
*/
@@ -214,13 +257,19 @@ export const deleteAddressWithData = async (
const { success: sendAccess } = await c.env.DB.prepare(
`DELETE FROM address_sender WHERE address = ? `
).bind(address).run();
const { success: sendboxSuccess } = await c.env.DB.prepare(
`DELETE FROM sendbox WHERE address = ? `
).bind(address).run();
const { success: addressSuccess } = await c.env.DB.prepare(
`DELETE FROM users_address WHERE address_id = ? `
).bind(address_id).run();
const { success: autoReplySuccess } = await c.env.DB.prepare(
`DELETE FROM auto_reply_mails WHERE address = ? `
).bind(address).run();
const { success } = await c.env.DB.prepare(
`DELETE FROM address WHERE name = ? `
).bind(address).run();
if (!success || !mailSuccess || !addressSuccess || !sendAccess) {
if (!success || !mailSuccess || !sendboxSuccess || !addressSuccess || !sendAccess || !autoReplySuccess) {
throw new Error("Failed to delete address")
}
return true;

View File

@@ -32,7 +32,7 @@ export type WebhookMail = {
parsedHtml: string;
}
export class CleanupSettings {
export type CleanupSettings = {
enableMailsAutoCleanup: boolean | undefined;
cleanMailsDays: number;
@@ -40,23 +40,12 @@ export class CleanupSettings {
cleanUnknowMailsDays: number;
enableSendBoxAutoCleanup: boolean | undefined;
cleanSendBoxDays: number;
constructor(data: CleanupSettings | undefined | null) {
const {
enableMailsAutoCleanup, cleanMailsDays,
enableUnknowMailsAutoCleanup, cleanUnknowMailsDays,
enableSendBoxAutoCleanup, cleanSendBoxDays
} = data || {};
this.enableMailsAutoCleanup = enableMailsAutoCleanup;
this.cleanMailsDays = cleanMailsDays || 0;
this.enableUnknowMailsAutoCleanup = enableUnknowMailsAutoCleanup;
this.cleanUnknowMailsDays = cleanUnknowMailsDays || 0;
this.enableSendBoxAutoCleanup = enableSendBoxAutoCleanup;
this.cleanSendBoxDays = cleanSendBoxDays || 0;
}
enableAddressAutoCleanup: boolean | undefined;
cleanAddressDays: number;
enableInactiveAddressAutoCleanup: boolean | undefined;
cleanInactiveAddressDays: number;
}
export class GeoData {
ip: string;

View File

@@ -6,11 +6,14 @@ import { CleanupSettings } from './models';
export async function scheduled(event: ScheduledEvent, env: Bindings, ctx: any) {
console.log("Scheduled event: ", event);
const value = await getJsonSetting(
const autoCleanupSetting = await getJsonSetting<CleanupSettings>(
{ env: env, } as Context<HonoCustomType>,
CONSTANTS.AUTO_CLEANUP_KEY
);
const autoCleanupSetting = new CleanupSettings(value);
if (!autoCleanupSetting) {
console.log("No auto cleanup settings found, skipping cleanup.");
return;
}
console.log("autoCleanupSetting:", JSON.stringify(autoCleanupSetting));
if (autoCleanupSetting.enableMailsAutoCleanup) {
await cleanup(
@@ -33,4 +36,18 @@ export async function scheduled(event: ScheduledEvent, env: Bindings, ctx: any)
autoCleanupSetting.cleanSendBoxDays
);
}
if (autoCleanupSetting.enableInactiveAddressAutoCleanup) {
await cleanup(
{ env: env, } as Context<HonoCustomType>,
"inactiveAddress",
autoCleanupSetting.cleanInactiveAddressDays
);
}
if (autoCleanupSetting.enableAddressAutoCleanup) {
await cleanup(
{ env: env, } as Context<HonoCustomType>,
"addressCreated",
autoCleanupSetting.cleanAddressDays
);
}
}