feat: remove PREFIX logic in db (#171)

This commit is contained in:
Dream Hunter
2024-04-28 13:20:09 +08:00
committed by GitHub
parent c73c86e86c
commit 4fd7f776f6
5 changed files with 78 additions and 93 deletions
+4
View File
@@ -0,0 +1,4 @@
update
address
set
name = 'tmp' || name;
+9 -17
View File
@@ -15,20 +15,17 @@ api.get('/admin/address', async (c) => {
} }
if (query) { if (query) {
const { results } = await c.env.DB.prepare( 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(); ).bind(`%${query}%`, limit, offset).all();
let count = 0; let count = 0;
if (offset == 0) { if (offset == 0) {
const { count: addressCount } = await c.env.DB.prepare( 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(); ).bind(`%${query}%`).first();
count = addressCount; count = addressCount;
} }
return c.json({ return c.json({
results: results.map((r) => { results: results,
r.name = c.env.PREFIX + r.name;
return r;
}),
count: count count: count
}) })
} }
@@ -43,10 +40,7 @@ api.get('/admin/address', async (c) => {
count = addressCount; count = addressCount;
} }
return c.json({ return c.json({
results: results.map((r) => { results: results,
r.name = c.env.PREFIX + r.name;
return r;
}),
count: count count: count
}) })
}) })
@@ -61,7 +55,7 @@ api.delete('/admin/delete_address/:id', async (c) => {
} }
const { success: mailSuccess } = await c.env.DB.prepare( const { success: mailSuccess } = await c.env.DB.prepare(
`DELETE FROM mails WHERE address IN `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(); ).bind(id).run();
if (!mailSuccess) { if (!mailSuccess) {
return c.text("Failed to delete mails", 500) 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( const name = await c.env.DB.prepare(
`SELECT name FROM address WHERE id = ? ` `SELECT name FROM address WHERE id = ? `
).bind(id).first("name"); ).bind(id).first("name");
// compute address
const emailAddress = c.env.PREFIX + name
const jwt = await Jwt.sign({ const jwt = await Jwt.sign({
address: emailAddress, address: name,
address_id: id address_id: id
}, c.env.JWT_SECRET) }, c.env.JWT_SECRET)
return c.json({ return c.json({
@@ -125,7 +117,7 @@ api.get('/admin/mails_unknow', async (c) => {
} }
const { results } = await c.env.DB.prepare(` const { results } = await c.env.DB.prepare(`
SELECT * FROM raw_mails 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 ? ` order by id desc limit ? offset ? `
).bind(limit, offset).all(); ).bind(limit, offset).all();
let count = 0; let count = 0;
@@ -133,7 +125,7 @@ api.get('/admin/mails_unknow', async (c) => {
const { count: mailCount } = await c.env.DB.prepare(` const { count: mailCount } = await c.env.DB.prepare(`
SELECT count(*) as count FROM raw_mails SELECT count(*) as count FROM raw_mails
where address NOT IN where address NOT IN
(select concat('${c.env.PREFIX}', name) from address)` (select name from address)`
).first(); ).first();
count = mailCount; count = mailCount;
} }
@@ -232,7 +224,7 @@ api.post('/admin/cleanup', async (c) => {
case "mails_unknow": case "mails_unknow":
await c.env.DB.prepare(` await c.env.DB.prepare(`
DELETE FROM raw_mails WHERE address NOT IN 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(); ).run();
break; break;
case "address": case "address":
+2 -3
View File
@@ -37,15 +37,14 @@ api.get('/admin/v1/mails_unknow', async (c) => {
} }
const { results } = await c.env.DB.prepare(` const { results } = await c.env.DB.prepare(`
SELECT id, source, subject, message FROM mails 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 ? ` order by id desc limit ? offset ? `
).bind(limit, offset).all(); ).bind(limit, offset).all();
let count = 0; let count = 0;
if (offset == 0) { if (offset == 0) {
const { count: mailCount } = await c.env.DB.prepare(` const { count: mailCount } = await c.env.DB.prepare(`
SELECT count(*) as count FROM mails SELECT count(*) as count FROM mails
where address NOT IN where address NOT IN (select name from address)`
(select concat('${c.env.PREFIX}', name) from address)`
).first(); ).first();
count = mailCount; count = mailCount;
} }
+39 -44
View File
@@ -7,54 +7,49 @@ async function email(message, env, ctx) {
console.log(`Reject message from ${message.from} to ${message.to}`); console.log(`Reject message from ${message.from} to ${message.to}`);
return; return;
} }
if (!env.PREFIX || (message.to && message.to.startsWith(env.PREFIX))) { const rawEmail = await new Response(message.raw).text();
const rawEmail = await new Response(message.raw).text(); const message_id = message.headers.get("Message-ID");
const message_id = message.headers.get("Message-ID"); // save email
// save email const { success } = await env.DB.prepare(
const { success } = await env.DB.prepare( `INSERT INTO raw_mails (source, address, raw, message_id) VALUES (?, ?, ?, ?)`
`INSERT INTO raw_mails (source, address, raw, message_id) VALUES (?, ?, ?, ?)` ).bind(
).bind( message.from, message.to, rawEmail, message_id
message.from, message.to, rawEmail, message_id ).run();
).run(); if (!success) {
if (!success) { message.setReject(`Failed save message to ${message.to}`);
message.setReject(`Failed save message to ${message.to}`); console.log(`Failed save message from ${message.from} to ${message.to}`);
console.log(`Failed save message from ${message.from} to ${message.to}`); }
}
// auto reply email // auto reply email
if (env.ENABLE_AUTO_REPLY) { if (env.ENABLE_AUTO_REPLY) {
try { try {
const results = await env.DB.prepare( const results = await env.DB.prepare(
`SELECT * FROM auto_reply_mails where address = ? and enabled = 1` `SELECT * FROM auto_reply_mails where address = ? and enabled = 1`
).bind(message.to).first(); ).bind(message.to).first();
if (results && results.source_prefix && message.from.startsWith(results.source_prefix)) { if (results && results.source_prefix && message.from.startsWith(results.source_prefix)) {
const msg = createMimeMessage(); const msg = createMimeMessage();
msg.setHeader("In-Reply-To", message.headers.get("Message-ID")); msg.setHeader("In-Reply-To", message.headers.get("Message-ID"));
msg.setSender({ msg.setSender({
name: results.name || results.address, name: results.name || results.address,
addr: results.address addr: results.address
}); });
msg.setRecipient(message.from); msg.setRecipient(message.from);
msg.setSubject(results.subject || "Auto-reply"); msg.setSubject(results.subject || "Auto-reply");
msg.addMessage({ msg.addMessage({
contentType: 'text/plain', contentType: 'text/plain',
data: results.message || "This is an auto-reply message, please reconact later." data: results.message || "This is an auto-reply message, please reconact later."
}); });
const replyMessage = new EmailMessage( const replyMessage = new EmailMessage(
message.to, message.to,
message.from, message.from,
msg.asRaw() msg.asRaw()
); );
await message.reply(replyMessage); await message.reply(replyMessage);
}
} catch (error) {
console.log("reply email error", error);
} }
} catch (error) {
console.log("reply email error", error);
} }
} else {
message.setReject(`Unknown address ${message.to}`);
console.log(`Unknown address ${message.to}`);
} }
} }
+24 -29
View File
@@ -34,7 +34,7 @@ api.get('/api/mails', async (c) => {
}) })
api.delete('/api/mails/:id', 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) return c.text("User delete email is disabled", 403)
} }
const { address } = c.get("jwtPayload") const { address } = c.get("jwtPayload")
@@ -61,28 +61,26 @@ api.get('/api/settings', async (c) => {
return c.text("Invalid address", 400) return c.text("Invalid address", 400)
} }
} }
if (address.startsWith(c.env.PREFIX)) { // check address id
// check address id try {
try { if (!address_id) {
if (!address_id) { const db_address_id = await c.env.DB.prepare(
const db_address_id = await c.env.DB.prepare( `SELECT id FROM address where name = ?`
`SELECT id FROM address where name = ?` ).bind(address).first("id");
).bind(address.substring(c.env.PREFIX.length)).first("id"); if (!db_address_id) {
if (!db_address_id) { return c.text("Invalid address", 400)
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 = {}; let auto_reply = {};
if (c.env.ENABLE_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)]; domain = domains[Math.floor(Math.random() * domains.length)];
} }
// create address // create address
const emailAddress = c.env.PREFIX + name + "@" + domain name = c.env.PREFIX + name + "@" + domain
try { try {
const { success } = await c.env.DB.prepare( const { success } = await c.env.DB.prepare(
`INSERT INTO address(name) VALUES(?)` `INSERT INTO address(name) VALUES(?)`
).bind(name + "@" + domain).run(); ).bind(name).run();
if (!success) { if (!success) {
return c.text("Failed to create address", 500) return c.text("Failed to create address", 500)
} }
@@ -199,13 +197,13 @@ api.get('/api/new_address', async (c) => {
try { try {
address_id = await c.env.DB.prepare( address_id = await c.env.DB.prepare(
`SELECT id FROM address where name = ?` `SELECT id FROM address where name = ?`
).bind(name + "@" + domain).first("id"); ).bind(name).first("id");
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
// create jwt // create jwt
const jwt = await Jwt.sign({ const jwt = await Jwt.sign({
address: emailAddress, address: name,
address_id: address_id address_id: address_id
}, c.env.JWT_SECRET) }, c.env.JWT_SECRET)
return c.json({ return c.json({
@@ -214,14 +212,11 @@ api.get('/api/new_address', async (c) => {
}) })
api.delete('/api/delete_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) return c.text("User delete email is disabled", 403)
} }
const { address } = c.get("jwtPayload") const { address } = c.get("jwtPayload")
let name = address; let name = address;
if (address.startsWith(c.env.PREFIX)) {
name = address.substring(c.env.PREFIX.length);
}
const { success } = await c.env.DB.prepare( const { success } = await c.env.DB.prepare(
`DELETE FROM address WHERE name = ? ` `DELETE FROM address WHERE name = ? `
).bind(name).run(); ).bind(name).run();