feat: remove apiV1 and tables && update admin/statistics (#337)

This commit is contained in:
Dream Hunter
2024-07-08 12:33:43 +08:00
committed by GitHub
parent dcfc1b3721
commit 80a8848ed8
11 changed files with 148 additions and 234 deletions

View File

@@ -1,6 +1,11 @@
<!-- markdownlint-disable-file MD004 MD024 MD034 MD036 -->
# CHANGE LOG
## main branch
- 移除 `apiV1` 相关代码和相关的数据库表
- 更新 `admin/statistics` api, 添加用户统计信息
## v0.5.4
- 点击 logo 5 次进入 admin 页面

View File

@@ -1,13 +1,3 @@
CREATE TABLE IF NOT EXISTS mails (
id INTEGER PRIMARY KEY,
message_id TEXT,
source TEXT,
address TEXT,
subject TEXT,
message TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_mails_address ON mails(address);
CREATE TABLE IF NOT EXISTS raw_mails (
@@ -43,15 +33,6 @@ CREATE TABLE IF NOT EXISTS auto_reply_mails (
CREATE INDEX IF NOT EXISTS idx_auto_reply_mails_address ON auto_reply_mails(address);
CREATE TABLE IF NOT EXISTS attachments (
id INTEGER PRIMARY KEY,
source TEXT,
address TEXT,
message_id TEXT,
data TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS address_sender (
id INTEGER PRIMARY KEY,
address TEXT UNIQUE,

View File

@@ -1,6 +1,6 @@
{
"name": "cloudflare_temp_email",
"version": "0.5.4",
"version": "0.5.5",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1191,68 +1191,68 @@ packages:
'@surma/rollup-plugin-off-main-thread@2.2.3':
resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==}
'@swc/core-darwin-arm64@1.6.12':
resolution: {integrity: sha512-aVDdQ5BNn6pFedCZIE/756rGo+6P7ue1sYtTseBlGe94yfj6jr0I7nAffBnXAA9cbQ46aMtmKvVfv023HmUwNg==}
'@swc/core-darwin-arm64@1.6.13':
resolution: {integrity: sha512-SOF4buAis72K22BGJ3N8y88mLNfxLNprTuJUpzikyMGrvkuBFNcxYtMhmomO0XHsgLDzOJ+hWzcgjRNzjMsUcQ==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
'@swc/core-darwin-x64@1.6.12':
resolution: {integrity: sha512-ud+wlkWdQKawtpdjWNP2+ZLiwZU2xkKuC3L8uhlLy6MGNmRl6OGIpD/ASEDfOy3O77UhrjYRuOiOxsgBmXwuow==}
'@swc/core-darwin-x64@1.6.13':
resolution: {integrity: sha512-AW8akFSC+tmPE6YQQvK9S2A1B8pjnXEINg+gGgw0KRUUXunvu1/OEOeC5L2Co1wAwhD7bhnaefi06Qi9AiwOag==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
'@swc/core-linux-arm-gnueabihf@1.6.12':
resolution: {integrity: sha512-I5370gbWGsyrlgQQ0bB3j2TALUTr/AZpOXFbwhB45HsUwpV+W1ZpuB0L5d6uzlX+UvMtoNXtUYiDCcdFWw2UXA==}
'@swc/core-linux-arm-gnueabihf@1.6.13':
resolution: {integrity: sha512-f4gxxvDXVUm2HLYXRd311mSrmbpQF2MZ4Ja6XCQz1hWAxXdhRl1gpnZ+LH/xIfGSwQChrtLLVrkxdYUCVuIjFg==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
'@swc/core-linux-arm64-gnu@1.6.12':
resolution: {integrity: sha512-5SzAKf+rzsTwU/OCbEF+v7sUO5DVHbM5v2nYhZf8Otq4Lqphr9X65CIlmyakv77s7vIN4IrX+e8FOffSVF+OpQ==}
'@swc/core-linux-arm64-gnu@1.6.13':
resolution: {integrity: sha512-Nf/eoW2CbG8s+9JoLtjl9FByBXyQ5cjdBsA4efO7Zw4p+YSuXDgc8HRPC+E2+ns0praDpKNZtLvDtmF2lL+2Gg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-arm64-musl@1.6.12':
resolution: {integrity: sha512-Hsy04ZPUSs6oti2ZqCoMa+3r9wBU/rhEyYYoTiqWKtdH2zxqXyph8ZfEdJfAop5STX6w318iqMiAh0p7TBM3ew==}
'@swc/core-linux-arm64-musl@1.6.13':
resolution: {integrity: sha512-2OysYSYtdw79prJYuKIiux/Gj0iaGEbpS2QZWCIY4X9sGoETJ5iMg+lY+YCrIxdkkNYd7OhIbXdYFyGs/w5LDg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-x64-gnu@1.6.12':
resolution: {integrity: sha512-86PsFFQsTXdJWXM/VjNLNE2s0JFB05Pi6DwSOa2/5g7HIHk1QuD8TCusB4zcky4F3MX78QDRHKLpxIEnOV6Tnw==}
'@swc/core-linux-x64-gnu@1.6.13':
resolution: {integrity: sha512-PkR4CZYJNk5hcd2+tMWBpnisnmYsUzazI1O5X7VkIGFcGePTqJ/bWlfUIVVExWxvAI33PQFzLbzmN5scyIUyGQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-linux-x64-musl@1.6.12':
resolution: {integrity: sha512-qqylxwMWRVYh0XiozJLajX25yqCABkaySGS1eNXIDQsc7uV8Z7qq5OB07Ilpm6FxIkyRnrjUfGG9WO4UfBWiXQ==}
'@swc/core-linux-x64-musl@1.6.13':
resolution: {integrity: sha512-OdsY7wryTxCKwGQcwW9jwWg3cxaHBkTTHi91+5nm7hFPpmZMz1HivJrWAMwVE7iXFw+M4l6ugB/wCvpYrUAAjA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-win32-arm64-msvc@1.6.12':
resolution: {integrity: sha512-nl6/7kOKSx5R4j25yANfKJntJpFy41bAIhEcI3bpm8Xay2BDp6YrDQtpaYT/MeBFzg6EUWg/YYQLcOhZsSvmaw==}
'@swc/core-win32-arm64-msvc@1.6.13':
resolution: {integrity: sha512-ap6uNmYjwk9M/+bFEuWRNl3hq4VqgQ/Lk+ID/F5WGqczNr0L7vEf+pOsRAn0F6EV+o/nyb3ePt8rLhE/wjHpPg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
'@swc/core-win32-ia32-msvc@1.6.12':
resolution: {integrity: sha512-GfWyYotHr3u6QvmGxagcIOiheK/fxP/+CTJ+SdtkADBHGLfgs/Bc9ePqzTY033sdjTVzPCOujV/JRVizmOnavA==}
'@swc/core-win32-ia32-msvc@1.6.13':
resolution: {integrity: sha512-IJ8KH4yIUHTnS/U1jwQmtbfQals7zWPG0a9hbEfIr4zI0yKzjd83lmtS09lm2Q24QBWOCFGEEbuZxR4tIlvfzA==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
'@swc/core-win32-x64-msvc@1.6.12':
resolution: {integrity: sha512-W00XNkFQnGf+2JXTPjxg3qhgYfblETXqeQBN1nAg2OXoMuvyU+xs+Qp9CryO+mOGt613GlZ/etmOvkC2xX1l7Q==}
'@swc/core-win32-x64-msvc@1.6.13':
resolution: {integrity: sha512-f6/sx6LMuEnbuxtiSL/EkR0Y6qUHFw1XVrh6rwzKXptTipUdOY+nXpKoh+1UsBm/r7H0/5DtOdrn3q5ZHbFZjQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@swc/core@1.6.12':
resolution: {integrity: sha512-XWS4fQrmZUsMUOzKWZHoSO5sBNUlLpbi++WpCtGyoXC279IKBnWL90YS7SxjYudiKuGDBWrS7Ph25yN63vTZYg==}
'@swc/core@1.6.13':
resolution: {integrity: sha512-eailUYex6fkfaQTev4Oa3mwn0/e3mQU4H8y1WPuImYQESOQDtVrowwUGDSc19evpBbHpKtwM+hw8nLlhIsF+Tw==}
engines: {node: '>=10'}
peerDependencies:
'@swc/helpers': '*'
@@ -1969,8 +1969,8 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
highlight.js@11.9.0:
resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==}
highlight.js@11.10.0:
resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==}
engines: {node: '>=12.0.0'}
hookable@5.5.3:
@@ -4082,51 +4082,51 @@ snapshots:
magic-string: 0.25.9
string.prototype.matchall: 4.0.11
'@swc/core-darwin-arm64@1.6.12':
'@swc/core-darwin-arm64@1.6.13':
optional: true
'@swc/core-darwin-x64@1.6.12':
'@swc/core-darwin-x64@1.6.13':
optional: true
'@swc/core-linux-arm-gnueabihf@1.6.12':
'@swc/core-linux-arm-gnueabihf@1.6.13':
optional: true
'@swc/core-linux-arm64-gnu@1.6.12':
'@swc/core-linux-arm64-gnu@1.6.13':
optional: true
'@swc/core-linux-arm64-musl@1.6.12':
'@swc/core-linux-arm64-musl@1.6.13':
optional: true
'@swc/core-linux-x64-gnu@1.6.12':
'@swc/core-linux-x64-gnu@1.6.13':
optional: true
'@swc/core-linux-x64-musl@1.6.12':
'@swc/core-linux-x64-musl@1.6.13':
optional: true
'@swc/core-win32-arm64-msvc@1.6.12':
'@swc/core-win32-arm64-msvc@1.6.13':
optional: true
'@swc/core-win32-ia32-msvc@1.6.12':
'@swc/core-win32-ia32-msvc@1.6.13':
optional: true
'@swc/core-win32-x64-msvc@1.6.12':
'@swc/core-win32-x64-msvc@1.6.13':
optional: true
'@swc/core@1.6.12':
'@swc/core@1.6.13':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.9
optionalDependencies:
'@swc/core-darwin-arm64': 1.6.12
'@swc/core-darwin-x64': 1.6.12
'@swc/core-linux-arm-gnueabihf': 1.6.12
'@swc/core-linux-arm64-gnu': 1.6.12
'@swc/core-linux-arm64-musl': 1.6.12
'@swc/core-linux-x64-gnu': 1.6.12
'@swc/core-linux-x64-musl': 1.6.12
'@swc/core-win32-arm64-msvc': 1.6.12
'@swc/core-win32-ia32-msvc': 1.6.12
'@swc/core-win32-x64-msvc': 1.6.12
'@swc/core-darwin-arm64': 1.6.13
'@swc/core-darwin-x64': 1.6.13
'@swc/core-linux-arm-gnueabihf': 1.6.13
'@swc/core-linux-arm64-gnu': 1.6.13
'@swc/core-linux-arm64-musl': 1.6.13
'@swc/core-linux-x64-gnu': 1.6.13
'@swc/core-linux-x64-musl': 1.6.13
'@swc/core-win32-arm64-msvc': 1.6.13
'@swc/core-win32-ia32-msvc': 1.6.13
'@swc/core-win32-x64-msvc': 1.6.13
'@swc/counter@0.1.3': {}
@@ -5011,7 +5011,7 @@ snapshots:
dependencies:
function-bind: 1.1.2
highlight.js@11.9.0: {}
highlight.js@11.10.0: {}
hookable@5.5.3: {}
@@ -5292,7 +5292,7 @@ snapshots:
date-fns: 2.30.0
date-fns-tz: 2.0.1(date-fns@2.30.0)
evtd: 0.2.4
highlight.js: 11.9.0
highlight.js: 11.10.0
lodash: 4.17.21
lodash-es: 4.17.21
seemly: 0.3.8
@@ -5868,7 +5868,7 @@ snapshots:
vite-plugin-top-level-await@1.4.1(rollup@2.79.1)(vite@5.3.3(@types/node@20.14.10)(terser@5.31.1)):
dependencies:
'@rollup/plugin-virtual': 3.0.2(rollup@2.79.1)
'@swc/core': 1.6.12
'@swc/core': 1.6.13
uuid: 9.0.1
vite: 5.3.3(@types/node@20.14.10)(terser@5.31.1)
transitivePeerDependencies:

View File

@@ -1,5 +1,5 @@
<script setup>
import { ref, watch, defineModel, onMounted } from "vue";
import { ref, watch, onMounted } from "vue";
import { useI18n } from 'vue-i18n'
import { useGlobalState } from '../store'
const { openSettings, isDark } = useGlobalState()

View File

@@ -13,14 +13,18 @@ const message = useMessage()
const { t } = useI18n({
messages: {
en: {
userCount: 'Account Count',
activeUser: '7 days Active Mail Account',
userCount: 'User Count',
addressCount: 'Address Count',
activeAddressCount7days: '7 days Active Address Count',
activeAddressCount30days: '30 days Active Address Count',
mailCount: 'Mail Count',
sendMailCount: 'Send Mail Count'
},
zh: {
userCount: '地址总数',
activeUser: '周活跃邮箱地址',
userCount: '用户总数',
addressCount: '邮箱地址总数',
activeAddressCount7days: '7天活跃邮箱地址总数',
activeAddressCount30days: '30天活跃邮箱地址总数',
mailCount: '邮件总数',
sendMailCount: '发送邮件总数'
}
@@ -28,21 +32,27 @@ const { t } = useI18n({
});
const statistics = ref({
addressCount: 0,
userCount: 0,
mailCount: 0,
activeUserCount7days: 0,
activeAddressCount7days: 0,
activeAddressCount30days: 0,
sendMailCount: 0,
})
const fetchStatistics = async () => {
try {
const {
userCount, activeUserCount7days, mailCount, sendMailCount
userCount, mailCount, sendMailCount,
addressCount, activeAddressCount7days,
activeAddressCount30days,
} = await api.fetch(`/admin/statistics`);
statistics.value.mailCount = mailCount || 0;
statistics.value.userCount = userCount || 0;
statistics.value.activeUserCount7days = activeUserCount7days || 0;
statistics.value.sendMailCount = sendMailCount || 0;
statistics.value.userCount = userCount || 0;
statistics.value.addressCount = addressCount || 0;
statistics.value.activeAddressCount7days = activeAddressCount7days || 0;
statistics.value.activeAddressCount30days = activeAddressCount30days || 0;
} catch (error) {
console.log(error)
message.error(error.message || "error");
@@ -58,36 +68,63 @@ onMounted(async () => {
</script>
<template>
<n-card :bordered="false" embedded>
<n-row>
<n-col :span="6">
<n-statistic :label="t('userCount')" :value="statistics.userCount">
<template #prefix>
<n-icon :component="User" />
</template>
</n-statistic>
</n-col>
<n-col :span="6">
<n-statistic :label="t('activeUser')" :value="statistics.activeUserCount7days">
<template #prefix>
<n-icon :component="UserCheck" />
</template>
</n-statistic>
</n-col>
<n-col :span="6">
<n-statistic :label="t('mailCount')" :value="statistics.mailCount">
<template #prefix>
<n-icon :component="MailBulk" />
</template>
</n-statistic>
</n-col>
<n-col :span="6">
<n-statistic :label="t('sendMailCount')" :value="statistics.sendMailCount">
<template #prefix>
<n-icon :component="SendOutlined" />
</template>
</n-statistic>
</n-col>
</n-row>
</n-card>
<div>
<n-card :bordered="false" embedded>
<n-row>
<n-col :span="8">
<n-statistic :label="t('addressCount')" :value="statistics.addressCount">
<template #prefix>
<n-icon :component="User" />
</template>
</n-statistic>
</n-col>
<n-col :span="8">
<n-statistic :label="t('activeAddressCount7days')" :value="statistics.activeAddressCount7days">
<template #prefix>
<n-icon :component="UserCheck" />
</template>
</n-statistic>
</n-col>
<n-col :span="8">
<n-statistic :label="t('activeAddressCount30days')" :value="statistics.activeAddressCount30days">
<template #prefix>
<n-icon :component="UserCheck" />
</template>
</n-statistic>
</n-col>
</n-row>
</n-card>
<n-card :bordered="false" embedded>
<n-row>
<n-col :span="8">
<n-statistic :label="t('userCount')" :value="statistics.userCount">
<template #prefix>
<n-icon :component="User" />
</template>
</n-statistic>
</n-col>
<n-col :span="8">
<n-statistic :label="t('mailCount')" :value="statistics.mailCount">
<template #prefix>
<n-icon :component="MailBulk" />
</template>
</n-statistic>
</n-col>
<n-col :span="8">
<n-statistic :label="t('sendMailCount')" :value="statistics.sendMailCount">
<template #prefix>
<n-icon :component="SendOutlined" />
</template>
</n-statistic>
</n-col>
</n-row>
</n-card>
</div>
</template>
<style scoped>
.n-card {
margin-bottom: 20px;
}
</style>

8
worker/pnpm-lock.yaml generated
View File

@@ -1241,8 +1241,8 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
lru-cache@10.3.1:
resolution: {integrity: sha512-9/8QXrtbGeMB6LxwQd4x1tIMnsmUxMvIH/qWGsccz6bt9Uln3S+sgAaqfQNhbGA8ufzs2fHuP/yqapGgP9Hh2g==}
lru-cache@10.4.0:
resolution: {integrity: sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==}
engines: {node: '>=18'}
magic-string@0.25.9:
@@ -3331,7 +3331,7 @@ snapshots:
dependencies:
js-tokens: 4.0.0
lru-cache@10.3.1: {}
lru-cache@10.4.0: {}
magic-string@0.25.9:
dependencies:
@@ -3460,7 +3460,7 @@ snapshots:
path-scurry@1.11.1:
dependencies:
lru-cache: 10.3.1
lru-cache: 10.4.0
minipass: 7.1.2
path-to-regexp@6.2.2: {}

View File

@@ -219,16 +219,24 @@ api.get('/admin/statistics', async (c) => {
const { count: addressCount } = await c.env.DB.prepare(
`SELECT count(*) as count FROM address`
).first<{ count: number }>() || {};
const { count: activeUserCount7days } = await c.env.DB.prepare(
const { count: activeAddressCount7days } = await c.env.DB.prepare(
`SELECT count(*) as count FROM address where updated_at > datetime('now', '-7 day')`
).first<{ count: number }>() || {};
const { count: activeAddressCount30days } = await c.env.DB.prepare(
`SELECT count(*) as count FROM address where updated_at > datetime('now', '-30 day')`
).first<{ count: number }>() || {};
const { count: sendMailCount } = await c.env.DB.prepare(
`SELECT count(*) as count FROM sendbox`
).first<{ count: number }>() || {};
const { count: userCount } = await c.env.DB.prepare(
`SELECT count(*) as count FROM users`
).first<{ count: number }>() || {};
return c.json({
mailCount: mailCount,
userCount: addressCount,
activeUserCount7days: activeUserCount7days,
addressCount: addressCount,
activeAddressCount7days: activeAddressCount7days,
activeAddressCount30days: activeAddressCount30days,
userCount: userCount,
sendMailCount: sendMailCount
})
});

View File

@@ -1,5 +1,5 @@
export const CONSTANTS = {
VERSION: 'v0.5.4',
VERSION: 'v0.5.5',
// DB settings
ADDRESS_BLOCK_LIST_KEY: 'address_block_list',

View File

@@ -1,113 +0,0 @@
import { Hono } from 'hono'
// api v1 is deprecated
const api = new Hono()
api.get('/admin/v1/mails', async (c) => {
const { address, limit, offset } = c.req.query();
if (!limit || limit < 0 || limit > 100) {
return c.text("Invalid limit", 400)
}
if (!offset || offset < 0) {
return c.text("Invalid offset", 400)
}
const { results } = await c.env.DB.prepare(
`SELECT id, source, subject, message FROM mails where address = ? order by id desc limit ? offset ? `
).bind(address, 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 = ? `
).bind(address).first();
count = mailCount;
}
return c.json({
results: results,
count: count
})
});
api.get('/admin/v1/mails_unknow', async (c) => {
const { limit, offset } = c.req.query();
if (!limit || limit < 0 || limit > 100) {
return c.text("Invalid limit", 400)
}
if (!offset || offset < 0) {
return c.text("Invalid offset", 400)
}
const { results } = await c.env.DB.prepare(`
SELECT id, source, subject, message FROM mails
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 name from address)`
).first();
count = mailCount;
}
return c.json({
results: results,
count: count
})
});
api.get('/api/v1/mails', async (c) => {
const { address } = c.get("jwtPayload")
if (!address) {
return c.json({ "error": "No address" }, 400)
}
const { limit, offset } = c.req.query();
if (!limit || limit < 0 || limit > 100) {
return c.text("Invalid limit", 400)
}
if (!offset || offset < 0) {
return c.text("Invalid offset", 400)
}
const { results } = await c.env.DB.prepare(
`SELECT id, source, subject, message, message_id, created_at FROM mails where address = ? order by id desc limit ? offset ?`
).bind(address, 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 = ?`
).bind(address).first();
count = mailCount;
}
// add attachments
let attachmentResults = [];
const message_ids = results.map((r) => r.message_id).filter((r) => r);
if (message_ids && message_ids.length > 0) {
const { results: innerAttachmentResults } = await c.env.DB.prepare(
`SELECT id, message_id FROM attachments where message_id in (${message_ids.map((id) => `'${id}'`).join(",")})`
).all();
attachmentResults = innerAttachmentResults || [];
}
results.forEach((r) => {
const attachment_id = attachmentResults.filter((ar) => ar.message_id == r.message_id).map((ar) => ar.id);
if (attachment_id && attachment_id.length > 0) {
r.attachment_id = attachment_id[0];
}
delete r.message_id;
})
return c.json({
results: results,
count: count
})
})
// attachments
api.get("/api/v1/attachment/:attachment_id", async (c) => {
const { attachment_id } = c.req.param();
const { data } = await c.env.DB.prepare(
`SELECT data FROM attachments where id = ? `
).bind(attachment_id).first();
if (!data) {
return c.text("Not found", 404)
}
return c.json(JSON.parse(data))
})
export { api }

View File

@@ -3,9 +3,6 @@ import { cors } from 'hono/cors';
import { jwt } from 'hono/jwt'
import { Jwt } from 'hono/utils/jwt'
// @ts-ignore
import { api as apiV1 } from './deprecated';
import { api as commonApi } from './commom_api';
import { api as mailsApi } from './mails_api'
import { api as userApi } from './user_api';
@@ -121,7 +118,6 @@ app.route('/', commonApi)
app.route('/', mailsApi)
app.route('/', userApi)
app.route('/', adminApi)
app.route('/', apiV1)
app.route('/', apiSendMail)
app.route('/', telegramApi)