feat: refactor setup handling and enhance asset serving with bootstrap integration

This commit is contained in:
shuaiplus
2026-03-16 23:48:08 +08:00
parent b5f8ef28cc
commit 0ba85229a9
14 changed files with 217 additions and 107 deletions
+8 -21
View File
@@ -7,7 +7,6 @@ import {
handleAccessSendFileV2,
handleDownloadSendFile,
} from './handlers/sends';
import { handleSetupStatus } from './handlers/setup';
import { handleKnownDevice } from './handlers/devices';
import { handleToken, handlePrelogin, handleRevocation } from './handlers/identity';
import {
@@ -23,6 +22,13 @@ import { jsonResponse } from './utils/response';
import type { Env } from './types';
type PublicRateLimiter = (category?: string, maxRequests?: number) => Promise<Response | null>;
type JwtUnsafeReason = 'missing' | 'default' | 'too_short' | null;
export interface WebBootstrapResponse {
defaultKdfIterations: number;
jwtUnsafeReason: JwtUnsafeReason;
jwtSecretMinLength: number;
}
function isSameOriginWriteRequest(request: Request): boolean {
const targetOrigin = new URL(request.url).origin;
@@ -111,7 +117,7 @@ async function handleWebsiteIcon(host: string): Promise<Response> {
}
}
export function buildWebConfigResponse(env: Env, origin: string) {
export function buildWebBootstrapResponse(env: Env): WebBootstrapResponse {
const secret = (env.JWT_SECRET || '').trim();
const jwtUnsafeReason =
!secret
@@ -126,9 +132,6 @@ export function buildWebConfigResponse(env: Env, origin: string) {
defaultKdfIterations: LIMITS.auth.defaultKdfIterations,
jwtUnsafeReason,
jwtSecretMinLength: LIMITS.auth.jwtSecretMinLength,
_icon_service_url: buildIconServiceTemplate(origin),
_icon_service_csp: buildIconServiceCsp(origin),
iconServiceUrl: buildIconServiceTemplate(origin),
};
}
@@ -139,18 +142,6 @@ export async function handlePublicRoute(
method: string,
enforcePublicRateLimit: PublicRateLimiter
): Promise<Response | null> {
if (path === '/setup/status' && method === 'GET') {
const blocked = await enforcePublicRateLimit('public-read', LIMITS.rateLimit.publicReadRequestsPerMinute);
if (blocked) return blocked;
return handleSetupStatus(request, env);
}
if (path === '/api/web/config' && method === 'GET') {
const blocked = await enforcePublicRateLimit('public-read', LIMITS.rateLimit.publicReadRequestsPerMinute);
if (blocked) return blocked;
return jsonResponse(buildWebConfigResponse(env, new URL(request.url).origin));
}
if (path === '/.well-known/appspecific/com.chrome.devtools.json' && method === 'GET') {
return new Response('{}', {
status: 200,
@@ -161,10 +152,6 @@ export async function handlePublicRoute(
});
}
if ((path === '/favicon.ico' || path === '/favicon.svg') && method === 'GET') {
return handleNwFavicon();
}
const iconMatch = path.match(/^\/icons\/([^/]+)\/icon\.png$/i);
if (iconMatch && method === 'GET') {
return handleWebsiteIcon(iconMatch[1]);