Refactor environment validation, admin auth, and error handling#1
Open
Refactor environment validation, admin auth, and error handling#1
Conversation
…schema, proper boundaries Critical fixes: - Add zod env validation (src/lib/env.ts); all required vars parsed at boot - Fix admin session: sign with dedicated ADMIN_SESSION_SECRET (min 32 chars) instead of falling back to ADMIN_PASSWORD - Rewrite admin-session helpers on Web Crypto so proxy.ts (edge) works - Add real better-auth schema tables (user/session/account/verification) and wire drizzleAdapter to them; consolidate Lemon Squeezy fields onto user - Remove all mock/sample data (SAMPLE_ROASTS, SAMPLE_ROAST, placeholder screenshot divs, stale TODO); pages now show real empty/error states - Wire up actual screenshot rendering on home, category, and roast pages via next/image with thumbnails joined in a single extra query - Fix seed source whitelist: scraper sourceName was "seed-saaslandingpage" but allowlist expected "seed-saaslandingpage.com"; add regression test - Swap Google Fonts for local `geist` package (already in deps) Quality: - Add error.tsx + loading.tsx at root and /admin - Rewrite webhook with zod, tolerant of string/number id/customer_id - Admin buttons now surface server action errors inline (ActionButton / ConfirmButton using useTransition) - Health page does real reachability probes (DB SELECT 1, R2 HeadBucket, Postmark /server, Lemon Squeezy /users/me) with 3s timeouts - Shared in-memory rate limiter (createRateLimiter); applied to admin-login + /api/auth/register - Pricing CTA hooked up to LEMONSQUEEZY_CHECKOUT_URL env var; disabled button when not configured - Remove unused CategoryPill, drop unused imports; eliminate `any` in postmark.ts; tighten types across actions Tests: - admin-session (round-trip, tamper, expiry, wrong secret) - rate-limit (window, eviction, IP extraction) - env validation (required, URL format, optional fields) - auth utils (UUID, escapeHtml, domain allow/deny list) - lemonsqueezy signature verify - scrapers source whitelist regression Docs: - Updated README with architecture notes, script reference, env table - Updated .env.example with ADMIN_SESSION_SECRET and LEMONSQUEEZY_CHECKOUT_URL https://claude.ai/code/session_015tozJhgdCwsq2cibcqQX8h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces centralized environment variable validation, refactors admin authentication to use HMAC-signed sessions, improves error handling across the application, and adds comprehensive test coverage for critical utilities.
Key Changes
Environment & Configuration
src/lib/env.ts: Centralized environment validation using Zod that runs at startup, ensuring all required variables are present and properly formatted before the app startsenv()instead of directly accessingprocess.envAdmin Authentication
src/lib/admin-session.ts: Replaced simple session verification with HMAC-SHA256 signed cookies using Web Crypto APIbetter-authfor admin sessions; now uses separateADMIN_SESSION_SECRETsrc/app/api/auth/admin-login/route.tswith proper rate limiting and validationRate Limiting
src/lib/rate-limit.ts: In-memory sliding-window rate limiter for single-node deploymentsError Handling & Resilience
force-dynamicmode with proper error boundaries (src/app/error.tsx,src/app/admin/error.tsx)Database & Schema
userstable touser(better-auth standard naming)booleantype import to schemaUI & Components
src/components/roast/roast-card.tsx: Extracted reusable card component for roast gallerysrc/components/admin/action-button.tsx: Simplified action button for non-destructive operationsConfirmButtonto useuseTransitionfor better UXTesting
tests/unit/env.test.ts: Environment validationtests/unit/admin-session.test.ts: HMAC session creation/verificationtests/unit/rate-limit.test.ts: Rate limiter behaviortests/unit/auth-utils.test.ts: UUID and domain validationtests/unit/lemonsqueezy.test.ts: Webhook signature verificationtests/unit/scrapers.test.ts: Scraper source validationData Fetching
getPublishedPoststogetPublishedPostsWithThumbnailswith proper screenshot handlinggetPostScreenshotsquery for hero image selectionPromise.all()Documentation
Notable Implementation Details
crypto.subtlefor cross-runtime compatibilitygenerateStaticParamsreturns empty list when DB unavailable,https://claude.ai/code/session_015tozJhgdCwsq2cibcqQX8h