Second-brain scheme (logo + six cards with rays) reworked from the old
platform's infographic. Root stays role-redirecting for signed-in users;
middleware opens "/" as an exact match only.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- /api/internal/grant: secret-auth endpoint for payment-router to
provision access on a paid order — find-or-create user (emailVerified,
temp password, mustChangePassword), enroll by course slug list,
AccessLog, delivery email. Idempotent by order_id.
- User.mustChangePassword flag (+ migration); (student) layout redirects
flagged users to /change-password (forced first-login change).
- email.ts: sendCourseGrantEmail (temp password for new buyers).
- middleware: /api/internal is public (own secret auth).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Block direct /api/auth/sign-up at the middleware (404): it bypassed
the Turnstile/honeypot wrapper. /api/register is unaffected — it
invokes auth.handler programmatically, not through HTTP.
- Tighten rate limits on send-verification-email and forget-password
(3/min/IP): both send emails to arbitrary addresses and shared the
loose global 100/min limit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Turnstile/honeypot wrapper /api/register was missing from
PUBLIC_ROUTES, so unauthenticated POSTs were redirected to /login (307).
The register form followed the redirect, got HTML, and failed to parse
it — surfacing as "connection error". This silently broke signups for
new users. Add /api/register alongside /api/auth.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fix Prisma import: use @/generated/prisma alias (resolves Turbopack issue)
- Replace middleware.ts with proxy.ts (Next.js 16 convention)
- middleware function renamed to proxy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>