Serve the editor from feuerwerk.nockal.com as well
feuerwerk / gate (push) Successful in 4m45s
feuerwerk / suite (push) Successful in 19m52s

The subdomain proxies to the same folder, but the build had the path
/feuerwerk/ baked in. On feuerwerk.nockal.com the page loaded its
assets, the API and the data URLs from /feuerwerk/... and got 404. The
session cookie had Path=/feuerwerk/, so the browser would never have
sent it to /api/ there either.

- site.ts takes the base path from the folder of the open page:
  /feuerwerk/ on nockal.com, / on the subdomain. Release links point at
  the address you are working on.
- vite.config.ts builds with a relative base. The copy plugin rewrites
  the pages to ./dist/assets/ and stops the build if it finds nothing
  to rewrite. The dev server now runs at http://localhost:5175/.
- Auth.php sets the cookie without a Path, so it belongs to the API
  folder the browser sees. Sign-in and sign-out also clear the old
  /feuerwerk/ cookie, otherwise it would keep signing in after a
  logout. Existing sessions stay valid.
- README: the new dev server address.

Tests:
- curl on both addresses: pages, JS, CSS and API 200
- sign-in, session, sign-out on both addresses
- e2e 70 against both addresses: 13/13 each, no CSP violation
- tsc, lint, prettier clean, site and releases tests 14/14
- PHP tests 7 of 8 files green, videos.test.php fails only because
  the web-php-fpm container has no ffmpeg

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-16 08:40:18 +02:00
1 parent 5b9d084dfe
commit edef2b6323
5 files changed
+57 -17

No files matched your search

+21 -9
View File
@@ -1,27 +1,38 @@
import { copyFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { readFileSync, writeFileSync } from 'node:fs';
import { basename, dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { defineConfig, type Plugin } from 'vite';
import { publishPlugins } from './tools/lib/plugins.mjs';
import { SITE_PATH } from './src/core/site';
const __dirname = dirname(fileURLToPath(import.meta.url));
/**
* The workspace folder itself is what nginx serves under https://nockal.com/feuerwerk/.
* The workspace folder itself is what nginx serves under https://nockal.com/feuerwerk/, and the
* same folder answers at https://feuerwerk.nockal.com/. So the build knows no path: its base is
* relative, and the pages find the API and the data from where they are (src/core/site.ts).
* The Vite source pages live in `web/`: `index.html` is the editor, `play.html` a released game
* (#266). The build writes hashed assets into `dist/` and this plugin copies the built pages to the
* folder root, so that the site URLs load the production bundles while `api/` and `data/` sit next
* to them.
* to them. One folder up, their `./assets/` becomes `./dist/assets/`.
*/
const PAGES = ['index.html', 'play.html'];
function publishPages(): Plugin {
let outDir = '';
return {
name: 'feuerwerk:publish-pages',
apply: 'build',
configResolved(config) {
outDir = resolve(config.root, config.build.outDir);
},
closeBundle() {
for (const page of PAGES) copyFileSync(resolve(__dirname, 'dist', page), resolve(__dirname, page));
const folder = basename(outDir);
for (const page of PAGES) {
const html = readFileSync(resolve(outDir, page), 'utf8');
const published = html.replaceAll('"./assets/', `"./${folder}/assets/`);
if (published === html) throw new Error(`${page}: no ./assets/ link to move`);
writeFileSync(resolve(outDir, '..', page), published);
}
},
};
}
@@ -79,7 +90,7 @@ function shipPlugins(): Plugin {
export default defineConfig({
root: 'web',
base: `${SITE_PATH}dist/`,
base: './',
publicDir: false,
plugins: [contentSecurityPolicy(), publishPages(), shipPlugins()],
build: {
@@ -95,11 +106,12 @@ export default defineConfig({
},
server: {
port: 5175,
// During development the PHP API is served by the production nginx; proxy it.
// During development the PHP API and the data are served by the production nginx; proxy them.
proxy: {
[`${SITE_PATH}api`]: {
'^/(api|data)/': {
target: 'https://nockal.com',
changeOrigin: true,
rewrite: (path) => `/feuerwerk${path}`,
},
},
},