From 4fd7f776f63c9945114763a63e30bdfaa3d5e1fb Mon Sep 17 00:00:00 2001 From: Dream Hunter Date: Sun, 28 Apr 2024 13:20:09 +0800 Subject: [PATCH] feat: remove PREFIX logic in db (#171) --- db/2024-04-28-patch.sql | 4 ++ worker/src/admin_api.js | 26 +++++-------- worker/src/api_v1.js | 5 +-- worker/src/email.js | 83 +++++++++++++++++++---------------------- worker/src/router.js | 53 ++++++++++++-------------- 5 files changed, 78 insertions(+), 93 deletions(-) create mode 100644 db/2024-04-28-patch.sql diff --git a/db/2024-04-28-patch.sql b/db/2024-04-28-patch.sql new file mode 100644 index 00000000..455f5389 --- /dev/null +++ b/db/2024-04-28-patch.sql @@ -0,0 +1,4 @@ +update + address +set + name = 'tmp' || name; diff --git a/worker/src/admin_api.js b/worker/src/admin_api.js index 91fb0eca..e86b7a98 100644 --- a/worker/src/admin_api.js +++ b/worker/src/admin_api.js @@ -15,20 +15,17 @@ api.get('/admin/address', async (c) => { } if (query) { const { results } = await c.env.DB.prepare( - `SELECT * FROM address where concat('${c.env.PREFIX}', name) like ? order by id desc limit ? offset ? ` + `SELECT * FROM address where name like ? order by id desc limit ? offset ? ` ).bind(`%${query}%`, limit, offset).all(); let count = 0; if (offset == 0) { const { count: addressCount } = await c.env.DB.prepare( - `SELECT count(*) as count FROM address where concat('${c.env.PREFIX}', name) like ?` + `SELECT count(*) as count FROM address where name like ?` ).bind(`%${query}%`).first(); count = addressCount; } return c.json({ - results: results.map((r) => { - r.name = c.env.PREFIX + r.name; - return r; - }), + results: results, count: count }) } @@ -43,10 +40,7 @@ api.get('/admin/address', async (c) => { count = addressCount; } return c.json({ - results: results.map((r) => { - r.name = c.env.PREFIX + r.name; - return r; - }), + results: results, count: count }) }) @@ -61,7 +55,7 @@ api.delete('/admin/delete_address/:id', async (c) => { } const { success: mailSuccess } = await c.env.DB.prepare( `DELETE FROM mails WHERE address IN - (select concat('${c.env.PREFIX}', name) from address where id = ?) ` + (select name from address where id = ?) ` ).bind(id).run(); if (!mailSuccess) { return c.text("Failed to delete mails", 500) @@ -79,10 +73,8 @@ api.get('/admin/show_password/:id', async (c) => { const name = await c.env.DB.prepare( `SELECT name FROM address WHERE id = ? ` ).bind(id).first("name"); - // compute address - const emailAddress = c.env.PREFIX + name const jwt = await Jwt.sign({ - address: emailAddress, + address: name, address_id: id }, c.env.JWT_SECRET) return c.json({ @@ -125,7 +117,7 @@ api.get('/admin/mails_unknow', async (c) => { } const { results } = await c.env.DB.prepare(` SELECT * FROM raw_mails - where address NOT IN(select concat('${c.env.PREFIX}', name) from address) + where address NOT IN (select name from address) order by id desc limit ? offset ? ` ).bind(limit, offset).all(); let count = 0; @@ -133,7 +125,7 @@ api.get('/admin/mails_unknow', async (c) => { const { count: mailCount } = await c.env.DB.prepare(` SELECT count(*) as count FROM raw_mails where address NOT IN - (select concat('${c.env.PREFIX}', name) from address)` + (select name from address)` ).first(); count = mailCount; } @@ -232,7 +224,7 @@ api.post('/admin/cleanup', async (c) => { case "mails_unknow": await c.env.DB.prepare(` DELETE FROM raw_mails WHERE address NOT IN - (select concat('${c.env.PREFIX}', name) from address) AND created_at < datetime('now', '-${cleanDays} day')` + (select name from address) AND created_at < datetime('now', '-${cleanDays} day')` ).run(); break; case "address": diff --git a/worker/src/api_v1.js b/worker/src/api_v1.js index 3e681bc9..19b95eb4 100644 --- a/worker/src/api_v1.js +++ b/worker/src/api_v1.js @@ -37,15 +37,14 @@ api.get('/admin/v1/mails_unknow', async (c) => { } const { results } = await c.env.DB.prepare(` SELECT id, source, subject, message FROM mails - where address NOT IN(select concat('${c.env.PREFIX}', name) from address) + where address NOT IN(select name from address) order by id desc limit ? offset ? ` ).bind(limit, offset).all(); let count = 0; if (offset == 0) { const { count: mailCount } = await c.env.DB.prepare(` SELECT count(*) as count FROM mails - where address NOT IN - (select concat('${c.env.PREFIX}', name) from address)` + where address NOT IN (select name from address)` ).first(); count = mailCount; } diff --git a/worker/src/email.js b/worker/src/email.js index b07d0ac6..e83b5e63 100644 --- a/worker/src/email.js +++ b/worker/src/email.js @@ -7,54 +7,49 @@ async function email(message, env, ctx) { console.log(`Reject message from ${message.from} to ${message.to}`); return; } - if (!env.PREFIX || (message.to && message.to.startsWith(env.PREFIX))) { - const rawEmail = await new Response(message.raw).text(); - const message_id = message.headers.get("Message-ID"); - // save email - const { success } = await env.DB.prepare( - `INSERT INTO raw_mails (source, address, raw, message_id) VALUES (?, ?, ?, ?)` - ).bind( - message.from, message.to, rawEmail, message_id - ).run(); - if (!success) { - message.setReject(`Failed save message to ${message.to}`); - console.log(`Failed save message from ${message.from} to ${message.to}`); - } + const rawEmail = await new Response(message.raw).text(); + const message_id = message.headers.get("Message-ID"); + // save email + const { success } = await env.DB.prepare( + `INSERT INTO raw_mails (source, address, raw, message_id) VALUES (?, ?, ?, ?)` + ).bind( + message.from, message.to, rawEmail, message_id + ).run(); + if (!success) { + message.setReject(`Failed save message to ${message.to}`); + console.log(`Failed save message from ${message.from} to ${message.to}`); + } - // auto reply email - if (env.ENABLE_AUTO_REPLY) { - try { - const results = await env.DB.prepare( - `SELECT * FROM auto_reply_mails where address = ? and enabled = 1` - ).bind(message.to).first(); - if (results && results.source_prefix && message.from.startsWith(results.source_prefix)) { - const msg = createMimeMessage(); - msg.setHeader("In-Reply-To", message.headers.get("Message-ID")); - msg.setSender({ - name: results.name || results.address, - addr: results.address - }); - msg.setRecipient(message.from); - msg.setSubject(results.subject || "Auto-reply"); - msg.addMessage({ - contentType: 'text/plain', - data: results.message || "This is an auto-reply message, please reconact later." - }); + // auto reply email + if (env.ENABLE_AUTO_REPLY) { + try { + const results = await env.DB.prepare( + `SELECT * FROM auto_reply_mails where address = ? and enabled = 1` + ).bind(message.to).first(); + if (results && results.source_prefix && message.from.startsWith(results.source_prefix)) { + const msg = createMimeMessage(); + msg.setHeader("In-Reply-To", message.headers.get("Message-ID")); + msg.setSender({ + name: results.name || results.address, + addr: results.address + }); + msg.setRecipient(message.from); + msg.setSubject(results.subject || "Auto-reply"); + msg.addMessage({ + contentType: 'text/plain', + data: results.message || "This is an auto-reply message, please reconact later." + }); - const replyMessage = new EmailMessage( - message.to, - message.from, - msg.asRaw() - ); - await message.reply(replyMessage); - } - } catch (error) { - console.log("reply email error", error); + const replyMessage = new EmailMessage( + message.to, + message.from, + msg.asRaw() + ); + await message.reply(replyMessage); } + } catch (error) { + console.log("reply email error", error); } - } else { - message.setReject(`Unknown address ${message.to}`); - console.log(`Unknown address ${message.to}`); } } diff --git a/worker/src/router.js b/worker/src/router.js index dff20403..58036a07 100644 --- a/worker/src/router.js +++ b/worker/src/router.js @@ -34,7 +34,7 @@ api.get('/api/mails', async (c) => { }) api.delete('/api/mails/:id', async (c) => { - if (c.env.ENABLE_USER_DELETE_EMAIL) { + if (!c.env.ENABLE_USER_DELETE_EMAIL) { return c.text("User delete email is disabled", 403) } const { address } = c.get("jwtPayload") @@ -61,28 +61,26 @@ api.get('/api/settings', async (c) => { return c.text("Invalid address", 400) } } - if (address.startsWith(c.env.PREFIX)) { - // check address id - try { - if (!address_id) { - const db_address_id = await c.env.DB.prepare( - `SELECT id FROM address where name = ?` - ).bind(address.substring(c.env.PREFIX.length)).first("id"); - if (!db_address_id) { - return c.text("Invalid address", 400) - } + // check address id + try { + if (!address_id) { + const db_address_id = await c.env.DB.prepare( + `SELECT id FROM address where name = ?` + ).bind(address).first("id"); + if (!db_address_id) { + return c.text("Invalid address", 400) } - } catch (error) { - return c.text("Invalid address", 400) - } - // update address updated_at - try { - c.env.DB.prepare( - `UPDATE address SET updated_at = datetime('now') where name = ?` - ).bind(address.substring(c.env.PREFIX.length)).run(); - } catch (e) { - console.warn("Failed to update address") } + } catch (error) { + return c.text("Invalid address", 400) + } + // update address updated_at + try { + c.env.DB.prepare( + `UPDATE address SET updated_at = datetime('now') where name = ?` + ).bind(address).run(); + } catch (e) { + console.warn("Failed to update address") } let auto_reply = {}; if (c.env.ENABLE_AUTO_REPLY) { @@ -181,11 +179,11 @@ api.get('/api/new_address', async (c) => { domain = domains[Math.floor(Math.random() * domains.length)]; } // create address - const emailAddress = c.env.PREFIX + name + "@" + domain + name = c.env.PREFIX + name + "@" + domain try { const { success } = await c.env.DB.prepare( `INSERT INTO address(name) VALUES(?)` - ).bind(name + "@" + domain).run(); + ).bind(name).run(); if (!success) { return c.text("Failed to create address", 500) } @@ -199,13 +197,13 @@ api.get('/api/new_address', async (c) => { try { address_id = await c.env.DB.prepare( `SELECT id FROM address where name = ?` - ).bind(name + "@" + domain).first("id"); + ).bind(name).first("id"); } catch (error) { console.log(error); } // create jwt const jwt = await Jwt.sign({ - address: emailAddress, + address: name, address_id: address_id }, c.env.JWT_SECRET) return c.json({ @@ -214,14 +212,11 @@ api.get('/api/new_address', async (c) => { }) api.delete('/api/delete_address', async (c) => { - if (c.env.ENABLE_USER_DELETE_EMAIL) { + if (!c.env.ENABLE_USER_DELETE_EMAIL) { return c.text("User delete email is disabled", 403) } const { address } = c.get("jwtPayload") let name = address; - if (address.startsWith(c.env.PREFIX)) { - name = address.substring(c.env.PREFIX.length); - } const { success } = await c.env.DB.prepare( `DELETE FROM address WHERE name = ? ` ).bind(name).run();