From 15387449595938b2ebadc286bbf24dd3f69e75cb Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 19 Mar 2026 09:09:55 +0100 Subject: [PATCH] removed dev SMTP --- .env.example | 26 ++++++++++++++++++++++++++ .gitignore | 43 +++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 10 +++------- docker-compose.yml | 14 -------------- middleware.ts | 25 +++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 21 deletions(-) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 middleware.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2e2e718 --- /dev/null +++ b/.env.example @@ -0,0 +1,26 @@ +# ============================================================ +# MulliganMates — Environment Variables +# Copy to .env and fill in all values before starting. +# ============================================================ + +# ── Application ───────────────────────────────────────────── +APP_DOMAIN=golf.example.com +SITE_URL=https://golf.example.com +ADMIN_EMAIL=admin@example.com + +# ── Database ───────────────────────────────────────────────── +# Generate: node -e "console.log(require('crypto').randomBytes(24).toString('hex'))" +POSTGRES_PASSWORD=your-strong-postgres-password +POSTGRES_DB=postgres + +# ── Auth (better-auth) ─────────────────────────────────────── +# Generate: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" +BETTER_AUTH_SECRET=your-better-auth-secret-at-least-32-chars + +# ── Email ──────────────────────────────────────────────────── +# Set to your SMTP provider (e.g. smtp.resend.com, smtp.mailgun.org) +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=your-smtp-user +SMTP_PASS=your-smtp-password +SMTP_SENDER_NAME=MulliganMates diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de2207d --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files +.env +.env.local +.env.*.local + +# docker +volumes/ + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/CLAUDE.md b/CLAUDE.md index 8835356..4f19f18 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,10 +11,7 @@ MulliganMates is a social golf score tracking PWA. Multiple players in a group t All commands run inside Docker (Node.js is not installed on the host): ```bash -# Development (with Mailpit for email) -docker compose --profile dev up - -# Production +# Start docker compose up -d # Install a new npm package @@ -86,9 +83,8 @@ See `lib/handicap.ts` for `strokesReceived()`, `netStrokes()`, `formatVsPar()`, ## Infrastructure -- **Docker Compose** — `app` + `db` (postgres:17-alpine) + `mailpit` (dev profile) +- **Docker Compose** — `app` + `db` (postgres:17-alpine) - **Traefik** — external reverse proxy; services expose via labels only -- **Email dev:** Mailpit (`docker compose --profile dev up`) -- **Email prod:** Set `SMTP_HOST`, `SMTP_USER`, `SMTP_PASS` in `.env` +- **Email:** Set `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS` in `.env` - Copy `.env.example` → `.env` before first run - `BETTER_AUTH_URL` must equal the app's public URL for magic links to work diff --git a/docker-compose.yml b/docker-compose.yml index 57045c5..9ee157a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -49,20 +49,6 @@ services: networks: - internal - # ── Email: Python SMTP debug server (dev only) ──────────── - # Accepts all mail and prints it to stdout (docker compose logs smtp) - smtp: - build: - context: . - dockerfile_inline: | - FROM python:3-alpine - RUN pip install aiosmtpd --quiet - ENV PYTHONUNBUFFERED=1 - CMD ["python", "-m", "aiosmtpd", "-n", "-l", "0.0.0.0:1025"] - restart: unless-stopped - profiles: ["dev"] - networks: - - internal volumes: db_data: diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..05eb48d --- /dev/null +++ b/middleware.ts @@ -0,0 +1,25 @@ +import { NextResponse, type NextRequest } from 'next/server' + +const PUBLIC_PATHS = ['/login', '/api/auth'] + +export function middleware(request: NextRequest) { + const { pathname } = request.nextUrl + + if (PUBLIC_PATHS.some((p) => pathname.startsWith(p))) { + return NextResponse.next() + } + + const session = request.cookies.get('better-auth.session_token') + + if (!session) { + return NextResponse.redirect(new URL('/login', request.url)) + } + + return NextResponse.next() +} + +export const config = { + matcher: [ + '/((?!_next/static|_next/image|favicon.ico|icons|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)', + ], +}