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
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:
parent
d05c36701b
commit
bef6d8e4dc
@ -8,7 +8,9 @@
|
|||||||
* fixture-pending registered but e-mail not verified
|
* fixture-pending registered but e-mail not verified
|
||||||
*
|
*
|
||||||
* All fixture accounts share the password below — they exist only on
|
* 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';
|
import { PrismaClient, UserStatus } from '@prisma/client';
|
||||||
|
|
||||||
@ -16,6 +18,11 @@ import { hashPassword } from '../src/users/password';
|
|||||||
|
|
||||||
export const FIXTURE_PASSWORD = 'fixture passwort 123';
|
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();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
interface FixtureUser {
|
interface FixtureUser {
|
||||||
@ -54,15 +61,17 @@ async function upsertFixtureUser(fixture: FixtureUser): Promise<void> {
|
|||||||
isSiteAdmin: fixture.isSiteAdmin,
|
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({
|
await prisma.userIdentity.upsert({
|
||||||
where: { provider_subject: { provider: 'password', subject: user.id } },
|
where: { provider_subject: { provider: 'password', subject: user.id } },
|
||||||
create: {
|
create: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
provider: 'password',
|
provider: 'password',
|
||||||
subject: user.id,
|
subject: user.id,
|
||||||
credential: await hashPassword(FIXTURE_PASSWORD),
|
credential,
|
||||||
},
|
},
|
||||||
update: {},
|
update: { credential },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,3 +24,17 @@ LOG_LEVEL=info
|
|||||||
|
|
||||||
# Compose project name; set per stage (dorfteich-test, dorfteich-int, …).
|
# Compose project name; set per stage (dorfteich-test, dorfteich-int, …).
|
||||||
COMPOSE_PROJECT_NAME=dorfteich
|
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>
|
||||||
|
|||||||
@ -45,6 +45,16 @@ services:
|
|||||||
PORT: '3000'
|
PORT: '3000'
|
||||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||||
DATABASE_URL: postgresql://dorfteich:${POSTGRES_PASSWORD:?set in .env}@db:5432/dorfteich
|
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:
|
ports:
|
||||||
- '127.0.0.1:${API_PORT:-8101}:3000'
|
- '127.0.0.1:${API_PORT:-8101}:3000'
|
||||||
networks: [frontend, internal]
|
networks: [frontend, internal]
|
||||||
|
|||||||
@ -29,6 +29,23 @@ each stage directory. Set per stage in `.env` (mode 600):
|
|||||||
- `WEB_PORT`/`API_PORT`: 8100/8101 (test), 8110/8111 (int)
|
- `WEB_PORT`/`API_PORT`: 8100/8101 (test), 8110/8111 (int)
|
||||||
- `IMAGE_PREFIX=gitea.101010.cloud/stwaidele/dorfteich`
|
- `IMAGE_PREFIX=gitea.101010.cloud/stwaidele/dorfteich`
|
||||||
- `TAG`: managed by the CD pipeline (`<git-sha>` on test, `int` on int)
|
- `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]**
|
## 2. Reverse proxy vhosts **[root]**
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user