mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-05 07:27:27 +08:00
fix: support admin auth for Telegram MiniApp mail viewing (#875)
* fix: support admin auth for Telegram MiniApp mail viewing (#852) Admin users configured in miniAppUrl can now view emails via the MiniApp without needing Telegram initData auth. The getMail endpoint reads the x-admin-auth header (already sent by the frontend) to bypass Telegram auth and address permission checks for admin users. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: extract isAdmin() as shared utility function Reuse the x-admin-auth header check logic across worker.ts and miniapp.ts via a common isAdmin() helper in utils.ts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: rename isAdmin to checkIsAdmin for consistency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR review comments - Remove unused getAdminPasswords import from worker.ts - Return 404 when admin queries a non-existent mail Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
635e0f4456
commit
8341cae28f
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
- fix: |Telegram| 修复 admin 用户通过 Telegram MiniApp 查看邮件时报 `Auth date expired` 的问题,支持 admin 密码认证查看邮件
|
||||||
- fix: |Admin API| 修复 `/admin/account_settings` 在未配置 KV 且 `fromBlockList` 为空时触发 `Cannot read properties of undefined (reading 'put')` 的问题
|
- fix: |Admin API| 修复 `/admin/account_settings` 在未配置 KV 且 `fromBlockList` 为空时触发 `Cannot read properties of undefined (reading 'put')` 的问题
|
||||||
- fix: |数据库| 修复 `DB_INIT_QUERIES` 缺少 `idx_raw_mails_message_id` 索引导致 `UPDATE raw_mails ... WHERE message_id = ?` 全表扫描的问题,同步 `schema.sql` 与初始化代码,新增 v0.0.6 迁移逻辑
|
- fix: |数据库| 修复 `DB_INIT_QUERIES` 缺少 `idx_raw_mails_message_id` 索引导致 `UPDATE raw_mails ... WHERE message_id = ?` 全表扫描的问题,同步 `schema.sql` 与初始化代码,新增 v0.0.6 迁移逻辑
|
||||||
- fix: |文档| 修复 User Mail API 文档中错误使用 `x-admin-auth` 的问题,改为正确的 `x-user-token`
|
- fix: |文档| 修复 User Mail API 文档中错误使用 `x-admin-auth` 的问题,改为正确的 `x-user-token`
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
- fix: |Telegram| Fix admin users unable to view emails via Telegram MiniApp due to `Auth date expired` error, support admin password auth for viewing emails
|
||||||
- fix: |Admin API| Fix `/admin/account_settings` throwing `Cannot read properties of undefined (reading 'put')` when KV is not configured and `fromBlockList` is empty
|
- fix: |Admin API| Fix `/admin/account_settings` throwing `Cannot read properties of undefined (reading 'put')` when KV is not configured and `fromBlockList` is empty
|
||||||
- fix: |Database| Fix missing `idx_raw_mails_message_id` index in `DB_INIT_QUERIES` causing full table scan on `UPDATE raw_mails ... WHERE message_id = ?`, sync `schema.sql` with init code, add v0.0.6 migration
|
- fix: |Database| Fix missing `idx_raw_mails_message_id` index in `DB_INIT_QUERIES` causing full table scan on `UPDATE raw_mails ... WHERE message_id = ?`, sync `schema.sql` with init code, add v0.0.6 migration
|
||||||
- fix: |Docs| Fix User Mail API documentation incorrectly using `x-admin-auth`, changed to correct `x-user-token`
|
- fix: |Docs| Fix User Mail API documentation incorrectly using `x-admin-auth`, changed to correct `x-user-token`
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Context } from "hono";
|
|||||||
import { Jwt } from 'hono/utils/jwt'
|
import { Jwt } from 'hono/utils/jwt'
|
||||||
import { CONSTANTS } from "../constants";
|
import { CONSTANTS } from "../constants";
|
||||||
import { bindTelegramAddress, jwtListToAddressData, tgUserNewAddress, unbindTelegramAddress } from "./common";
|
import { bindTelegramAddress, jwtListToAddressData, tgUserNewAddress, unbindTelegramAddress } from "./common";
|
||||||
import { checkCfTurnstile } from "../utils";
|
import { checkCfTurnstile, checkIsAdmin } from "../utils";
|
||||||
import { TelegramSettings } from "./settings";
|
import { TelegramSettings } from "./settings";
|
||||||
import i18n from "../i18n";
|
import i18n from "../i18n";
|
||||||
|
|
||||||
@@ -131,6 +131,15 @@ async function getMail(c: Context<HonoCustomType>): Promise<Response> {
|
|||||||
const { initData, mailId } = await c.req.json();
|
const { initData, mailId } = await c.req.json();
|
||||||
const msgs = i18n.getMessagesbyContext(c);
|
const msgs = i18n.getMessagesbyContext(c);
|
||||||
try {
|
try {
|
||||||
|
if (checkIsAdmin(c)) {
|
||||||
|
const result = await c.env.DB.prepare(
|
||||||
|
`SELECT * FROM raw_mails where id = ?`
|
||||||
|
).bind(mailId).first();
|
||||||
|
if (!result) {
|
||||||
|
return c.text("Mail not found", 404);
|
||||||
|
}
|
||||||
|
return c.json(result);
|
||||||
|
}
|
||||||
const userId = await checkTelegramAuth(c, initData);
|
const userId = await checkTelegramAuth(c, initData);
|
||||||
const jwtList = await c.env.KV.get<string[]>(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, 'json') || [];
|
const jwtList = await c.env.KV.get<string[]>(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, 'json') || [];
|
||||||
const { addressList, addressIdMap } = await jwtListToAddressData(c, jwtList, msgs);
|
const { addressList, addressIdMap } = await jwtListToAddressData(c, jwtList, msgs);
|
||||||
|
|||||||
@@ -216,6 +216,13 @@ export const getAdminPasswords = (c: Context<HonoCustomType>): string[] => {
|
|||||||
return c.env.ADMIN_PASSWORDS.filter((item) => item.length > 0);
|
return c.env.ADMIN_PASSWORDS.filter((item) => item.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const checkIsAdmin = (c: Context<HonoCustomType>): boolean => {
|
||||||
|
const adminPasswords = getAdminPasswords(c);
|
||||||
|
if (!adminPasswords.length) return false;
|
||||||
|
const adminAuth = c.req.raw.headers.get("x-admin-auth");
|
||||||
|
return !!adminAuth && adminPasswords.includes(adminAuth);
|
||||||
|
}
|
||||||
|
|
||||||
export const getEnvStringList = (value: string | string[] | undefined): string[] => {
|
export const getEnvStringList = (value: string | string[] | undefined): string[] => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return [];
|
return [];
|
||||||
@@ -359,6 +366,7 @@ export default {
|
|||||||
getAnotherWorkerList,
|
getAnotherWorkerList,
|
||||||
getPasswords,
|
getPasswords,
|
||||||
getAdminPasswords,
|
getAdminPasswords,
|
||||||
|
checkIsAdmin,
|
||||||
getEnvStringList,
|
getEnvStringList,
|
||||||
sendAdminInternalMail,
|
sendAdminInternalMail,
|
||||||
checkCfTurnstile,
|
checkCfTurnstile,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { api as telegramApi } from './telegram_api'
|
|||||||
import i18n from './i18n';
|
import i18n from './i18n';
|
||||||
import { email } from './email';
|
import { email } from './email';
|
||||||
import { scheduled } from './scheduled';
|
import { scheduled } from './scheduled';
|
||||||
import { getAdminPasswords, getPasswords, getBooleanValue, getStringArray } from './utils';
|
import { getPasswords, getBooleanValue, getStringArray, checkIsAdmin } from './utils';
|
||||||
import { checkAccessControl } from './ip_blacklist';
|
import { checkAccessControl } from './ip_blacklist';
|
||||||
|
|
||||||
const API_PATHS = [
|
const API_PATHS = [
|
||||||
@@ -215,13 +215,9 @@ app.use('/user_api/*', async (c, next) => {
|
|||||||
app.use('/admin/*', async (c, next) => {
|
app.use('/admin/*', async (c, next) => {
|
||||||
|
|
||||||
// check header x-admin-auth
|
// check header x-admin-auth
|
||||||
const adminPasswords = getAdminPasswords(c);
|
if (checkIsAdmin(c)) {
|
||||||
if (adminPasswords && adminPasswords.length > 0) {
|
await next();
|
||||||
const adminAuth = c.req.raw.headers.get("x-admin-auth");
|
return;
|
||||||
if (adminAuth && adminPasswords.includes(adminAuth)) {
|
|
||||||
await next();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const lang = c.req.raw.headers.get("x-lang") || c.env.DEFAULT_LANG;
|
const lang = c.req.raw.headers.get("x-lang") || c.env.DEFAULT_LANG;
|
||||||
const msgs = i18n.getMessages(lang);
|
const msgs = i18n.getMessages(lang);
|
||||||
|
|||||||
Reference in New Issue
Block a user