Make stage mail + base URL configurable; seed password overrides
All checks were successful
CD / Build and push images (push) Successful in 1m49s
CI / Lint, typecheck, test (push) Successful in 1m15s
CI / Auth e2e pack (push) Successful in 1m41s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 7s
CD / Smoke tests against Test (push) Successful in 1m5s
CD / Promote to Int (push) Successful in 9s

- compose: pass APP_BASE_URL and SMTP_* through to the api container so
  stages can use a real relay (defaults still match the dev Mailpit
  overlay); document the new keys in .env.example and stages.md
- seed: FIXTURE_ADMIN_PASSWORD / FIXTURE_USER_PASSWORD env overrides so
  shared stages get non-public fixture passwords; credential is re-hashed
  on every run so re-seeding applies a changed password

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UpQz6ypHJsLfMf4S6fyQEB
This commit is contained in:
Claude Fable 5 2026-07-05 10:42:32 +02:00
parent d05c36701b
commit bef6d8e4dc
4 changed files with 53 additions and 3 deletions

View File

@ -8,7 +8,9 @@
* fixture-pending registered but e-mail not verified
*
* All fixture accounts share the password below they exist only on
* dev machines and disposable CI/Test databases.
* dev machines and disposable CI/Test databases. On shared stages
* (test/int), set FIXTURE_ADMIN_PASSWORD / FIXTURE_USER_PASSWORD to give
* those two accounts non-public passwords.
*/
import { PrismaClient, UserStatus } from '@prisma/client';
@ -16,6 +18,11 @@ import { hashPassword } from '../src/users/password';
export const FIXTURE_PASSWORD = 'fixture passwort 123';
const PASSWORD_OVERRIDES: Record<string, string | undefined> = {
'fixture-admin': process.env.FIXTURE_ADMIN_PASSWORD,
'fixture-user': process.env.FIXTURE_USER_PASSWORD,
};
const prisma = new PrismaClient();
interface FixtureUser {
@ -54,15 +61,17 @@ async function upsertFixtureUser(fixture: FixtureUser): Promise<void> {
isSiteAdmin: fixture.isSiteAdmin,
},
});
// Re-hash on every run so a changed override takes effect on re-seed.
const credential = await hashPassword(PASSWORD_OVERRIDES[fixture.username] ?? FIXTURE_PASSWORD);
await prisma.userIdentity.upsert({
where: { provider_subject: { provider: 'password', subject: user.id } },
create: {
userId: user.id,
provider: 'password',
subject: user.id,
credential: await hashPassword(FIXTURE_PASSWORD),
credential,
},
update: {},
update: { credential },
});
}

View File

@ -24,3 +24,17 @@ LOG_LEVEL=info
# Compose project name; set per stage (dorfteich-test, dorfteich-int, …).
COMPOSE_PROJECT_NAME=dorfteich
# --- public URL + mail --------------------------------------------------------
# Public base URL of the stage (scheme + host). E-mail links and the CSRF
# origin check are derived from it — it must match what browsers use.
APP_BASE_URL=https://test.dorfteich.cloud
# SMTP relay for outgoing mail (verification, password reset). Leave unset
# to keep the Mailpit dev defaults; real stages need a real relay.
SMTP_HOST=mail.example.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=wiki@example.com
SMTP_PASS=change-me
SMTP_FROM=Dorfteich <wiki@example.com>

View File

@ -45,6 +45,16 @@ services:
PORT: '3000'
LOG_LEVEL: ${LOG_LEVEL:-info}
DATABASE_URL: postgresql://dorfteich:${POSTGRES_PASSWORD:?set in .env}@db:5432/dorfteich
# Public URL of this stage — e-mail links and the CSRF origin check
# depend on it matching what browsers actually use.
APP_BASE_URL: ${APP_BASE_URL:-http://localhost:5173}
# SMTP relay; defaults are only useful with the dev Mailpit overlay.
SMTP_HOST: ${SMTP_HOST:-localhost}
SMTP_PORT: ${SMTP_PORT:-1025}
SMTP_SECURE: ${SMTP_SECURE:-false}
SMTP_USER: ${SMTP_USER:-}
SMTP_PASS: ${SMTP_PASS:-}
SMTP_FROM: ${SMTP_FROM:-Dorfteich <no-reply@localhost>}
ports:
- '127.0.0.1:${API_PORT:-8101}:3000'
networks: [frontend, internal]

View File

@ -29,6 +29,23 @@ each stage directory. Set per stage in `.env` (mode 600):
- `WEB_PORT`/`API_PORT`: 8100/8101 (test), 8110/8111 (int)
- `IMAGE_PREFIX=gitea.101010.cloud/stwaidele/dorfteich`
- `TAG`: managed by the CD pipeline (`<git-sha>` on test, `int` on int)
- `APP_BASE_URL`: `https://test.dorfteich.cloud` / `https://int.dorfteich.cloud`
— e-mail links and the CSRF origin check depend on it
- `SMTP_HOST`/`SMTP_PORT`/`SMTP_SECURE`/`SMTP_USER`/`SMTP_PASS`/`SMTP_FROM`:
real relay credentials (both non-prod stages share one mailbox); without
them, signup/reset mails queue up and fail
Fixture accounts on the stages are created with the regular seed, but with
stage-specific passwords (never the public dev password):
```sh
FIXTURE_ADMIN_PASSWORD=… FIXTURE_USER_PASSWORD=… \
DATABASE_URL=postgresql://dorfteich:…@localhost:<tunnel-port>/dorfteich \
pnpm --filter @dorfteich/api db:seed
```
(The stage db is not published; tunnel to the db container, e.g.
`ssh -L 15432:<db-container-ip>:5432 root@188.245.116.44`.)
## 2. Reverse proxy vhosts **[root]**