mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-21 14:23:48 +00:00
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:
+12
-41
@@ -1,56 +1,27 @@
|
||||
import { Context } from "hono";
|
||||
import { Env, FeedConfig, FeedMetadata, EmailData } from "../types";
|
||||
import { Env } from "../types";
|
||||
import { generateAtomFeed } from "../utils/feed-generator";
|
||||
import { fetchFeedData } from "../utils/feed-fetcher";
|
||||
|
||||
export async function handle(c: Context): Promise<Response> {
|
||||
export async function handle(c: Context<{ Bindings: Env }>): Promise<Response> {
|
||||
try {
|
||||
const env = c.env as unknown as Env;
|
||||
|
||||
const feedId = c.req.param("feedId");
|
||||
|
||||
if (!feedId) {
|
||||
return new Response("Feed ID is required", { status: 400 });
|
||||
}
|
||||
|
||||
const emailStorage = env.EMAIL_STORAGE;
|
||||
|
||||
const feedMetadata = (await emailStorage.get(
|
||||
`feed:${feedId}:metadata`,
|
||||
"json",
|
||||
)) as FeedMetadata | null;
|
||||
|
||||
if (!feedMetadata) {
|
||||
const feedData = await fetchFeedData(feedId, c.env, "atom");
|
||||
if (!feedData) {
|
||||
return new Response("Feed not found", { status: 404 });
|
||||
}
|
||||
|
||||
const feedConfig = ((await emailStorage.get(
|
||||
`feed:${feedId}:config`,
|
||||
"json",
|
||||
)) as FeedConfig | null) || {
|
||||
title: `Newsletter Feed ${feedId}`,
|
||||
description: "Converted email newsletter",
|
||||
site_url: `https://${env.DOMAIN}/atom/${feedId}`,
|
||||
feed_url: `https://${env.DOMAIN}/atom/${feedId}`,
|
||||
language: "en",
|
||||
created_at: Date.now(),
|
||||
};
|
||||
|
||||
const emails = feedMetadata.emails.slice(0, 20);
|
||||
const emailsData: EmailData[] = [];
|
||||
|
||||
for (const email of emails) {
|
||||
const emailData = (await emailStorage.get(
|
||||
email.key,
|
||||
"json",
|
||||
)) as EmailData | null;
|
||||
if (emailData) {
|
||||
emailsData.push(emailData);
|
||||
}
|
||||
}
|
||||
|
||||
const baseUrl = `https://${env.DOMAIN}`;
|
||||
const atomXml = generateAtomFeed(feedConfig, emailsData, baseUrl, feedId);
|
||||
|
||||
const baseUrl = `https://${c.env.DOMAIN}`;
|
||||
const atomXml = generateAtomFeed(
|
||||
feedData.feedConfig,
|
||||
feedData.emails,
|
||||
baseUrl,
|
||||
feedId,
|
||||
);
|
||||
const linkHeader = [
|
||||
`<${baseUrl}/hub>; rel="hub"`,
|
||||
`<${baseUrl}/atom/${feedId}>; rel="self"`,
|
||||
|
||||
Reference in New Issue
Block a user