mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-06-06 08:00:57 +08:00
feature: support init db in admin portal (#658)
This commit is contained in:
@@ -11,19 +11,20 @@
|
||||
"build": "wrangler deploy --dry-run --outdir dist --minify"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250506.0",
|
||||
"@cloudflare/workers-types": "^4.20250520.0",
|
||||
"@eslint/js": "9.18.0",
|
||||
"@simplewebauthn/types": "10.0.0",
|
||||
"@types/node": "^22.15.19",
|
||||
"eslint": "9.18.0",
|
||||
"globals": "^15.15.0",
|
||||
"typescript-eslint": "^8.32.0",
|
||||
"wrangler": "^4.14.2"
|
||||
"typescript-eslint": "^8.32.1",
|
||||
"wrangler": "^4.15.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.803.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.803.0",
|
||||
"@aws-sdk/client-s3": "^3.812.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.812.0",
|
||||
"@simplewebauthn/server": "10.0.1",
|
||||
"hono": "^4.7.8",
|
||||
"hono": "^4.7.10",
|
||||
"jsonpath-plus": "^10.3.0",
|
||||
"mimetext": "^3.0.27",
|
||||
"postal-mime": "^2.4.3",
|
||||
|
||||
1608
worker/pnpm-lock.yaml
generated
1608
worker/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
156
worker/src/admin_api/db_api.ts
Normal file
156
worker/src/admin_api/db_api.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { Context } from "hono";
|
||||
import { CONSTANTS } from "../constants";
|
||||
import utils from "../utils";
|
||||
|
||||
const DB_INIT_QUERIES = `
|
||||
CREATE TABLE IF NOT EXISTS raw_mails (
|
||||
id INTEGER PRIMARY KEY,
|
||||
message_id TEXT,
|
||||
source TEXT,
|
||||
address TEXT,
|
||||
raw TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_raw_mails_address ON raw_mails(address);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS address (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_address_name ON address(name);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auto_reply_mails (
|
||||
id INTEGER PRIMARY KEY,
|
||||
source_prefix TEXT,
|
||||
name TEXT,
|
||||
address TEXT UNIQUE,
|
||||
subject TEXT,
|
||||
message TEXT,
|
||||
enabled INTEGER DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_auto_reply_mails_address ON auto_reply_mails(address);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS address_sender (
|
||||
id INTEGER PRIMARY KEY,
|
||||
address TEXT UNIQUE,
|
||||
balance INTEGER DEFAULT 0,
|
||||
enabled INTEGER DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_address_sender_address ON address_sender(address);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sendbox (
|
||||
id INTEGER PRIMARY KEY,
|
||||
address TEXT,
|
||||
raw TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_sendbox_address ON sendbox(address);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_email TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
user_info TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_user_email ON users(user_email);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users_address (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INTEGER,
|
||||
address_id INTEGER UNIQUE,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_address_user_id ON users_address(user_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_address_address_id ON users_address(address_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INTEGER UNIQUE NOT NULL,
|
||||
role_text TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_passkeys (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
passkey_name TEXT NOT NULL,
|
||||
passkey_id TEXT NOT NULL,
|
||||
passkey TEXT NOT NULL,
|
||||
counter INTEGER DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_passkeys_user_id ON user_passkeys(user_id);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_user_passkeys_user_id_passkey_id ON user_passkeys(user_id, passkey_id);
|
||||
`
|
||||
|
||||
export default {
|
||||
initialize: async (c: Context<HonoCustomType>) => {
|
||||
// remove all \r and \n characters from the query string
|
||||
// split by ; and join with a ;\n
|
||||
const query = DB_INIT_QUERIES.replace(/[\r\n]/g, "")
|
||||
.split(";")
|
||||
.map((query) => query.trim())
|
||||
.join(";\n");
|
||||
await c.env.DB.exec(query);
|
||||
|
||||
const version = await utils.getSetting(c, CONSTANTS.DB_VERSION_KEY);
|
||||
if (version) {
|
||||
return c.json({ message: "Database already initialized" });
|
||||
}
|
||||
await utils.saveSetting(c, CONSTANTS.DB_VERSION_KEY, CONSTANTS.DB_VERSION);
|
||||
return c.json({ message: "Database initialized" });
|
||||
},
|
||||
migrate: async (c: Context<HonoCustomType>) => {
|
||||
const version = await utils.getSetting(c, CONSTANTS.DB_VERSION_KEY);
|
||||
if (version != CONSTANTS.DB_VERSION) {
|
||||
// TODO: Perform migration logic here
|
||||
|
||||
// Update the version in the settings table
|
||||
await utils.saveSetting(c, CONSTANTS.DB_VERSION_KEY, CONSTANTS.DB_VERSION);
|
||||
return c.json({
|
||||
success: true,
|
||||
message: "Database migrated"
|
||||
});
|
||||
}
|
||||
return c.json({
|
||||
success: true,
|
||||
message: "Database does not need migration"
|
||||
});
|
||||
},
|
||||
getVersion: async (c: Context<HonoCustomType>) => {
|
||||
const version = await utils.getSetting(c, CONSTANTS.DB_VERSION_KEY);
|
||||
return c.json({
|
||||
need_initialization: !version,
|
||||
need_migration: version && version != CONSTANTS.DB_VERSION,
|
||||
current_db_version: version,
|
||||
code_db_version: CONSTANTS.DB_VERSION
|
||||
});
|
||||
},
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import oauth2_settings from './oauth2_settings'
|
||||
import worker_config from './worker_config'
|
||||
import admin_mail_api from './admin_mail_api'
|
||||
import { sendMailbyAdmin } from './send_mail'
|
||||
import db_api from './db_api'
|
||||
|
||||
export const api = new Hono<HonoCustomType>()
|
||||
|
||||
@@ -304,3 +305,8 @@ api.get("/admin/worker/configs", worker_config.getConfig);
|
||||
|
||||
// send mail by admin
|
||||
api.post("/admin/send_mail", sendMailbyAdmin);
|
||||
|
||||
// db api
|
||||
api.get('admin/db_version', db_api.getVersion);
|
||||
api.post('admin/db_initialize', db_api.initialize);
|
||||
api.post('admin/db_migration', db_api.migrate);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
export const CONSTANTS = {
|
||||
VERSION: 'v' + '0.10.0',
|
||||
|
||||
// DB Version
|
||||
DB_VERSION_KEY: 'db_version',
|
||||
DB_VERSION: "v0.0.1",
|
||||
|
||||
// DB settings
|
||||
ADDRESS_BLOCK_LIST_KEY: 'address_block_list',
|
||||
SEND_BLOCK_LIST_KEY: 'send_block_list',
|
||||
|
||||
@@ -101,7 +101,10 @@ export function newTelegramBot(c: Context<HonoCustomType>, token: string): Teleg
|
||||
const res = await tgUserNewAddress(c, userId.toString(), address);
|
||||
return await ctx.reply(`创建地址成功:\n`
|
||||
+ `地址: ${res.address}\n`
|
||||
+ `凭证: ${res.jwt}\n`
|
||||
+ `凭证: \`${res.jwt}\`\n`,
|
||||
{
|
||||
parse_mode: "Markdown"
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
return await ctx.reply(`创建地址失败: ${(e as Error).message}`);
|
||||
|
||||
Reference in New Issue
Block a user