Prepare public GitHub mirror: scrub LAN IPs #10
+1
-1
@@ -6,7 +6,7 @@ PLAYKIT_ENV=dev
|
||||
PLAYKIT_LOG_LEVEL=info
|
||||
PLAYKIT_FORBID_PRIVATE_HOSTS=true
|
||||
# PLAYKIT_METRICS_ENABLED=true
|
||||
# PLAYKIT_PUSHGATEWAY_URL=http://10.0.10.24:9091
|
||||
# PLAYKIT_PUSHGATEWAY_URL=http://10.255.255.1:9091
|
||||
|
||||
# Mailtrap Email Testing (Sandbox) — emails only appear if app SMTP → sandbox.smtp.mailtrap.io
|
||||
# PLAYKIT_MAILTRAP_API_TOKEN=
|
||||
|
||||
@@ -65,7 +65,7 @@ test('sign-out stays on public host', async ({ page, playkitConfig, timings }) =
|
||||
| `PLAYKIT_PROJECT` | no | Metric / log label |
|
||||
| `PLAYKIT_ENV` | no | Metric / log label (`dev`/`qa`/`prod`) |
|
||||
| `PLAYKIT_METRICS_ENABLED` | no | Push timings to Pushgateway |
|
||||
| `PLAYKIT_PUSHGATEWAY_URL` | if metrics | e.g. `http://10.0.10.24:9091` |
|
||||
| `PLAYKIT_PUSHGATEWAY_URL` | if metrics | e.g. `http://10.255.255.1:9091` |
|
||||
| `PLAYKIT_LOG_LEVEL` | no | `debug` \| `info` \| `warn` \| `error` |
|
||||
|
||||
**Secrets:** put test credentials and pushgateway tokens in Infisical (`LevkinOps`) and sync into Gitea Actions — see ansible `docs/hardening/SECRETS.md`. Never commit passwords.
|
||||
@@ -166,7 +166,7 @@ await runPersistentSession({
|
||||
|
||||
`createMailInbox()` picks the provider from `PLAYKIT_MAIL_PROVIDER` (default
|
||||
`mailpit`) so specs don't need to know which backend is behind it. Prefer
|
||||
**Mailpit** — it's our homelab SMTP trap (`10.0.10.45`, no external
|
||||
**Mailpit** — it's our homelab SMTP trap (`10.255.255.1`, no external
|
||||
dependency); use Mailtrap only if you specifically want the SaaS sandbox.
|
||||
|
||||
```ts
|
||||
@@ -184,7 +184,7 @@ assertPublicHost(link!);
|
||||
```
|
||||
|
||||
**Important:** the mail client only sees mail if the app's SMTP actually
|
||||
points at that trap (Mailpit `10.0.10.45:1025` in DEV, or Mailtrap's
|
||||
points at that trap (Mailpit `10.255.255.1:1025` in DEV, or Mailtrap's
|
||||
`sandbox.smtp.mailtrap.io` + inbox credentials for SaaS). Sending via Gmail to
|
||||
a real address will not appear in either. See ansible `docs/hardening/SECRETS.md`
|
||||
(`## Playkit / punimtag e2e secrets`).
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ Store in Infisical `LevkinOps` / `Development` (path e.g. `/playkit/punimtag`):
|
||||
|
||||
- `PLAYKIT_BASE_URL=https://punimtagdev.levkin.ca`
|
||||
- `E2E_ADMIN_EMAIL` / `E2E_ADMIN_PASSWORD` (dedicated test user — not a human’s password)
|
||||
- optional `PLAYKIT_PUSHGATEWAY_URL=http://10.0.10.24:9091`
|
||||
- optional `PLAYKIT_PUSHGATEWAY_URL=http://10.255.255.1:9091`
|
||||
- optional `PLAYKIT_RETRY_PRESET=strictCi|flakyNetwork|default`
|
||||
- for mail specs: `PLAYKIT_MAIL_PROVIDER=mailpit` (default) + `MAILPIT_*`, or `MAILTRAP_*`
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ Living ops/status after releases. Update when an item closes.
|
||||
|
||||
| Item | Status |
|
||||
|------|--------|
|
||||
| Pushgateway + `live-playkit` Grafana board | Applied (`10.0.10.24:9091`) |
|
||||
| Pushgateway + `live-playkit` Grafana board | Applied (`10.255.255.1:9091`) |
|
||||
| Tag release workflow + `RELEASE_TOKEN` | Working (`v0.3.1`, `v0.4.0` Gitea releases) |
|
||||
| Selftest CI | Green (Playwright image pinned to package version) |
|
||||
| Outline **QA & Dev → Playkit** @ v0.4.0 | Synced via API 2026-07-15 → https://notes.levkin.ca/doc/playkit-CrPJq5x2qQ |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Example UI pattern (not executed in kit CI — consumers own Playwright projects).
|
||||
*
|
||||
* Critical assert: after sign-out, URL host must remain the public host.
|
||||
* This is the failure mode from punimtag #57 (redirect to 10.0.10.121:3001).
|
||||
* This is the failure mode from punimtag #57 (redirect to 10.255.255.1:3001).
|
||||
*/
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { loadConfig, waitForUrlHost, assertPublicHost, TimingCollector } from '../../src/index.js';
|
||||
|
||||
@@ -70,7 +70,7 @@ def playkit_markdown(version: str) -> str:
|
||||
|
||||
## Metrics
|
||||
|
||||
- Pushgateway: `http://10.0.10.24:9091` (LAN)
|
||||
- Pushgateway: `http://10.255.255.1:9091` (LAN)
|
||||
- Grafana: `dash.levkin.ca` → **Live — Playkit e2e** (`live-playkit`)
|
||||
- Enable in CI with `PLAYKIT_METRICS_ENABLED=true` + `PLAYKIT_PUSHGATEWAY_URL`
|
||||
|
||||
|
||||
@@ -101,10 +101,10 @@ describe('waitForUrlHost', () => {
|
||||
});
|
||||
|
||||
it('throws a descriptive error naming both hosts when the host never matches', async () => {
|
||||
const page = { url: () => 'http://10.0.10.45:3000/dashboard' } as unknown as Page;
|
||||
const page = { url: () => 'http://10.255.255.1:3000/dashboard' } as unknown as Page;
|
||||
await expect(
|
||||
waitForUrlHost(page, 'app.levkin.ca', { timeout: 0, logger: silentLogger }),
|
||||
).rejects.toThrow(/Expected URL host "app\.levkin\.ca" but got "10\.0\.10\.45"/);
|
||||
).rejects.toThrow(/Expected URL host "app\.levkin\.ca" but got "10\.255\.255\.1"/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -114,7 +114,7 @@ describe('assertPublicHost', () => {
|
||||
expect(() => assertPublicHost('punimtagdev.levkin.ca')).not.toThrow();
|
||||
});
|
||||
|
||||
it.each(['https://10.0.10.45:3000', 'http://localhost:3000', 'https://192.168.1.10', '127.0.0.1'])(
|
||||
it.each(['https://10.255.255.1:3000', 'http://localhost:3000', 'https://192.168.1.10', '127.0.0.1'])(
|
||||
'rejects private host %s',
|
||||
(input) => {
|
||||
expect(() => assertPublicHost(input)).toThrow(/Refusing private host/);
|
||||
@@ -122,7 +122,7 @@ describe('assertPublicHost', () => {
|
||||
);
|
||||
|
||||
it('allows private hosts when forbidPrivate is false (intentional LAN runs)', () => {
|
||||
expect(() => assertPublicHost('http://10.0.10.45:3000', false)).not.toThrow();
|
||||
expect(() => assertPublicHost('http://10.255.255.1:3000', false)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TimingCollector } from '../metrics/index.js';
|
||||
|
||||
describe('isPrivateHost', () => {
|
||||
it('detects LAN and localhost', () => {
|
||||
expect(isPrivateHost('10.0.10.121')).toBe(true);
|
||||
expect(isPrivateHost('10.255.255.1')).toBe(true);
|
||||
expect(isPrivateHost('192.168.1.1')).toBe(true);
|
||||
expect(isPrivateHost('172.16.0.2')).toBe(true);
|
||||
expect(isPrivateHost('localhost')).toBe(true);
|
||||
@@ -21,7 +21,7 @@ describe('loadConfig', () => {
|
||||
it('rejects private expected host by default', () => {
|
||||
expect(() =>
|
||||
loadConfig({
|
||||
PLAYKIT_BASE_URL: 'http://10.0.10.121:3001',
|
||||
PLAYKIT_BASE_URL: 'http://10.255.255.1:3001',
|
||||
}),
|
||||
).toThrow(/private/);
|
||||
});
|
||||
|
||||
@@ -9,12 +9,12 @@ describe('loadMailpitConfig', () => {
|
||||
it('loads base url and auth', () => {
|
||||
expect(
|
||||
loadMailpitConfig({
|
||||
MAILPIT_BASE_URL: 'http://10.0.10.45:8025',
|
||||
MAILPIT_BASE_URL: 'http://10.255.255.1:8025',
|
||||
MAILPIT_USER: 'u',
|
||||
MAILPIT_PASSWORD: 'p',
|
||||
}),
|
||||
).toEqual({
|
||||
baseUrl: 'http://10.0.10.45:8025',
|
||||
baseUrl: 'http://10.255.255.1:8025',
|
||||
user: 'u',
|
||||
password: 'p',
|
||||
});
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ function matchesSubject(subject: string, want?: string | RegExp): boolean {
|
||||
* Load Mailpit config from env. Returns null if MAILPIT_BASE_URL unset.
|
||||
*
|
||||
* Env:
|
||||
* - PLAYKIT_MAILPIT_BASE_URL / MAILPIT_BASE_URL (e.g. http://10.0.10.45:8025)
|
||||
* - PLAYKIT_MAILPIT_BASE_URL / MAILPIT_BASE_URL (e.g. http://10.255.255.1:8025)
|
||||
* - MAILPIT_USER / MAILPIT_PASSWORD (basic auth)
|
||||
*/
|
||||
export function loadMailpitConfig(env: NodeJS.ProcessEnv = process.env): MailpitConfig | null {
|
||||
|
||||
@@ -78,7 +78,7 @@ export interface MetricsPushOptions {
|
||||
|
||||
/**
|
||||
* Push metrics to a Prometheus Pushgateway.
|
||||
* Example URL: http://10.0.10.24:9091
|
||||
* Example URL: http://10.255.255.1:9091
|
||||
*/
|
||||
export async function pushPrometheusMetrics(
|
||||
collector: TimingCollector,
|
||||
|
||||
Reference in New Issue
Block a user