Go to file
dimitar 3ff24cda0b feat(security): Phase 1 — harden auth, rate limiting, CSRF, upload validation
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).
2026-08-02 10:24:28 +02:00
.next_old superAdmin and admin implemented 2026-08-01 23:42:42 +02:00
docs superAdmin and admin implemented 2026-08-01 23:42:42 +02:00
nginx/conf.d init 2026-06-20 18:17:30 +02:00
prisma feat(db): add AdminUser and Code models with migration 2026-07-29 18:54:40 +02:00
public init 2026-06-20 18:17:30 +02:00
scripts feat(security): Phase 1 — harden auth, rate limiting, CSRF, upload validation 2026-08-02 10:24:28 +02:00
src feat(security): Phase 1 — harden auth, rate limiting, CSRF, upload validation 2026-08-02 10:24:28 +02:00
.env.example feat(security): Phase 1 — harden auth, rate limiting, CSRF, upload validation 2026-08-02 10:24:28 +02:00
.gitignore docs: add implementation plan and gitignore for old build artifacts 2026-07-29 19:08:14 +02:00
docker-compose.dev.yaml local dev setup 2026-07-29 16:52:54 +02:00
docker-compose.yaml t v3 2026-06-22 23:28:41 +02:00
Dockerfile prisma fix 2026-06-22 05:14:47 +02:00
Dockerfile.dev local dev setup 2026-07-29 16:52:54 +02:00
eslint.config.mjs init 2026-06-20 18:17:30 +02:00
next.config.ts init 2026-06-20 18:17:30 +02:00
package-lock.json feat(security): Phase 1 — harden auth, rate limiting, CSRF, upload validation 2026-08-02 10:24:28 +02:00
package.json feat(security): Phase 1 — harden auth, rate limiting, CSRF, upload validation 2026-08-02 10:24:28 +02:00
postcss.config.mjs init 2026-06-20 18:17:30 +02:00
tsconfig.json init 2026-06-20 18:17:30 +02:00

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:

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.