Step 05 adds secure admin authentication and the first protected CMS dashboard.
/admin/login- PostgreSQL-backed admin account
- Password hashing with bcrypt
- Signed HTTP-only session cookie
- Seven-day admin sessions
- Logout
- Protected
/adminroutes - Admin dashboard statistics
- Responsive admin navigation
- Login redirects to the dashboard
- Unauthenticated dashboard requests are rejected server-side
npm install bcryptjs zod
npm install -D tsx dotenvCopy .env.example to .env.
Set a strong AUTH_SECRET.
For local development you can use:
AUTH_SECRET="replace-with-a-long-random-secret"
ADMIN_EMAIL="admin@example.com"
ADMIN_PASSWORD="ChangeMe123!"For production, generate a random secret:
openssl rand -hex 32Do not commit .env to Git.
If you already completed Step 04, the Admin table is already in the Prisma schema.
Run:
npx prisma generate
npx prisma migrate dev --name admin-authIf this is a fresh project:
npx prisma generate
npx prisma migrate dev --name initRun:
npx prisma db seedThe seed uses ADMIN_EMAIL and ADMIN_PASSWORD.
Do not use the example password on a public deployment.
npm run devOpen:
http://localhost:3000/admin/login
Then sign in using your configured admin credentials.
The password is never stored as plaintext.
The login route:
- Finds the admin by email.
- Compares the submitted password with the bcrypt hash.
- Creates a signed session cookie.
- Redirects the user to
/admin.
The admin layout calls requireAdmin() on the server before rendering any protected admin page.
The session cookie is:
- HTTP-only
- SameSite=Lax
- Secure in production
- Scoped to the entire site
- Automatically expired after seven days
This is a strong foundation for the CMS, but before a high-traffic public launch we should add:
- Rate limiting for login attempts
- CSRF protection for state-changing operations
- Password reset/change flow
- Admin account management
- Optional two-factor authentication
- Audit logging
- Session revocation
#Neon Database connect Neon database with DATABASE_URL
See README-COMPLETE-UPGRADE.md for the latest security hardening notes, safe deployment checklist, and staging tests. This patch improves one-time customer purchase recovery and idempotent PayPal webhook processing without introducing a database migration.
See README-STEP-20-ERC20-USDT.md for Ethereum Mainnet USDT checkout, chain verification, environment configuration, PayPal 40/60 allocation tracking, database changes, and production checklist. PayPal-to-USDT conversion remains manual until a compatible, approved crypto payout provider is configured.
The .env.example and .env.production.example templates are prefilled with the provided Ethereum Mainnet USDT receiving address: 0x0c0b7871720635cC3eE4eCe01c78058292C9aA41. Verify the address carefully in your own wallet and set ERC20_USDT_RECEIVE_ADDRESS in your actual server/deployment environment. Never configure a private key or recovery phrase. PayPal crypto allocation remains manual until a compatible, approved provider is configured.
See README-VOICE-TEXT-CHATBOT.md for setup. Configure OPENAI_API_KEY in .env.local (server-side only) before testing the floating chatbot.
The floating voice/text chatbot uses OpenRouter. Configure OPENROUTER_API_KEY and OPENROUTER_MODEL in .env.local; see README-VOICE-TEXT-CHATBOT.md. Do not use NEXT_PUBLIC_ for API keys.
