feat: complete Phase 2 tech debt remediation

- Extract shared RSS/Atom fetch logic into feed-fetcher utility (P1-3)
- Split email-processor into validateEmail/storeEmail functions (P1-6)
- Add stateless HMAC-SHA256 CSRF protection to admin forms (P2-8)
- Fix Hono<{ Bindings: Env }> type safety across all routes (P3-13)
- Add entries.test.ts and files.test.ts with full coverage (P1-7)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-22 09:46:55 +02:00
parent f2981eec31
commit 7d375693b9
15 changed files with 485 additions and 152 deletions
+5 -3
View File
@@ -1,11 +1,13 @@
import { Hono, type Context } from "hono";
import { Env } from "../types";
type AppEnv = { Bindings: Env };
import {
verifyAndStoreSubscription,
verifyAndDeleteSubscription,
} from "../utils/websub";
function waitUntilSafe(c: Context, promise: Promise<unknown>) {
function waitUntilSafe(c: Context<AppEnv>, promise: Promise<unknown>) {
// Hono throws when ExecutionContext isn't present (e.g. Node unit tests).
try {
c.executionCtx.waitUntil(promise);
@@ -17,10 +19,10 @@ function waitUntilSafe(c: Context, promise: Promise<unknown>) {
const DEFAULT_LEASE_SECONDS = 86400;
const MAX_LEASE_SECONDS = 30 * 24 * 3600; // 30 days
export const hubRouter = new Hono();
export const hubRouter = new Hono<AppEnv>();
hubRouter.post("/", async (c) => {
const env = c.env as unknown as Env;
const env = c.env;
let form: FormData;
try {
form = await c.req.formData();