Security hardening covering credentials, brute-force protection, CSRF, TOCTOU races, upload validation, and migration failure handling. Secret rotation is deferred; the existing secrets in .env will be rotated in a later phase. This phase reduces the attack surface and removes the most exploitable issues. Removed: - Hardcoded 'super'/'admin' super-admin credentials in src/app/api/admin/login/route.ts. Username/hash are now loaded from env (SUPER_ADMIN_USERNAME / SUPER_ADMIN_PASSWORD_HASH) and verified via bcrypt like regular admins. Added: - src/lib/config.ts: single source of truth for APP_DOMAIN, APP_URL, subdomain regex/lengths, validation bounds, admin password policy, image-key allow-list regex, and super-admin env credentials. - src/lib/rate-limit.ts: in-memory LRU (via lru-cache) rate limiters — admin login (5/min), validate-code (20/min), check-subdomain (60/min), upload (10/min) — keyed by client IP, returning 429 with X-RateLimit-* headers. - requireAdmin / requireAdminPost / requireSuperAdminPost guards in src/lib/admin-session.ts. All admin mutating routes now enforce same-origin (Origin/Referer/Host check against NEXT_PUBLIC_APP_URL) before running — CSRF protection for the custom admin auth layer. - Logout now imports COOKIE_NAME_ADMIN instead of hardcoding the string. - Server-side magic-byte detection for image uploads (no new dep) — rejects spoofed Content-Type. GIF removed from allowed types. - /api/publish is now transactional (prisma.) with explicit P2002 → 409 handling for subdomain collisions. - /api/image validates the key against an allow-list regex and returns Macedonian error messages (was the only English-localized file). - /api/validate-code enforces a 12-hex-char pattern and uses updateMany with usedByUserId=null guard to make the claim atomic. - /api/check-subdomain validates the slug against the shared regex before hitting the DB and returns a short private Cache-Control. - Admin password minimum length bumped from 6 to 12 with letter+digit complexity requirement across change-password, users POST and users/[id] PUT. Changed: - scripts/start.sh: prisma migrate deploy failures now exit non-zero instead of silently continuing (prevents schema drift in prod). - .env.example: documents SUPER_ADMIN_USERNAME / SUPER_ADMIN_PASSWORD_HASH with example bcrypt-hash generation. - package.json: lru-cache added as direct dependency (already present transitively, promoted to explicit). |
||
|---|---|---|
| .next_old | ||
| docs | ||
| nginx/conf.d | ||
| prisma | ||
| public | ||
| scripts | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.dev.yaml | ||
| docker-compose.yaml | ||
| Dockerfile | ||
| Dockerfile.dev | ||
| eslint.config.mjs | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| tsconfig.json | ||
This is a Next.js project bootstrapped with create-next-app.
Getting Started
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.