feat: add QR code generation support and rate limiting for known device probes

This commit is contained in:
shuaiplus
2026-02-27 22:07:37 +08:00
committed by Shuai
parent 829008db7f
commit 172f6626c0
8 changed files with 81 additions and 5 deletions
+3
View File
@@ -35,6 +35,9 @@
// /api/sync read request budget per minute.
// /api/sync 读请求每分钟配额。
syncReadRequestsPerMinute: 1000,
// /api/devices/knowndevice probe budget per IP per minute.
// /api/devices/knowndevice 每 IP 每分钟探测配额。
knownDeviceRequestsPerMinute: 10,
// Fixed window size for API rate limiting in seconds.
// API 限流固定窗口大小(秒)。
apiWindowSeconds: 60,
+7
View File
@@ -235,6 +235,13 @@ export async function handleRequest(request: Request, env: Env): Promise<Respons
// Known device check (no auth required)
if (path === '/api/devices/knowndevice' && method === 'GET') {
const rateLimit = new RateLimitService(env.DB);
const clientIp = getClientIdentifier(request);
const probeLimit = await rateLimit.consumeKnownDeviceProbeBudget(clientIp + ':known-device');
if (!probeLimit.allowed) {
// Keep compatibility simple: do not error, just answer "unknown device".
return jsonResponse(false);
}
return handleKnownDevice(request, env);
}
+11
View File
@@ -15,6 +15,8 @@ const CONFIG = {
API_WRITE_REQUESTS_PER_MINUTE: LIMITS.rateLimit.apiWriteRequestsPerMinute,
// Dedicated budget for GET /api/sync reads.
SYNC_READ_REQUESTS_PER_MINUTE: LIMITS.rateLimit.syncReadRequestsPerMinute,
// Dedicated budget for GET /api/devices/knowndevice probes.
KNOWN_DEVICE_REQUESTS_PER_MINUTE: LIMITS.rateLimit.knownDeviceRequestsPerMinute,
API_WINDOW_SECONDS: LIMITS.rateLimit.apiWindowSeconds,
};
@@ -222,6 +224,15 @@ export class RateLimitService {
CONFIG.API_WINDOW_SECONDS
);
}
// Probe budget for GET /api/devices/knowndevice.
async consumeKnownDeviceProbeBudget(identifier: string): Promise<{ allowed: boolean; remaining: number; retryAfterSeconds?: number }> {
return this.consumeFixedWindowBudget(
identifier,
CONFIG.KNOWN_DEVICE_REQUESTS_PER_MINUTE,
CONFIG.API_WINDOW_SECONDS
);
}
}
export function getClientIdentifier(request: Request): string {