Accounts: a new page for the user accounts, projects and sessions; API lists auth/session, auth/login and auth/logout and the 401 without a session, Architecture the auth modules, Concepts the sign-in and the Logout button that changes what the canvas draws instead of reloading, Development the check sum 1118 and how the tools sign in
1 parent
685f72c5d3
commit
c10fd83436
7 files changed
+93
-4
No files matched your search
+9
@@ -2,6 +2,9 @@ All routes go through `api/index.php?r=…` (the site's nginx does not pass `PAT
|
||||
|
||||
| Method | Route | Body → Result |
|
||||
|---|---|---|
|
||||
| GET | `auth/session` | `{user}` — the name of whoever is signed in, `null` when nobody is. Always 200, and the only route that needs no session |
|
||||
| POST | `auth/login` | `{username,password}` → `{user}` and the session cookie; **401** `{error}` for a wrong pair |
|
||||
| POST | `auth/logout` | 204, and the cookie is cleared |
|
||||
| GET | `projects` | `[{id,name,revision,updatedAt}]` |
|
||||
| POST | `projects` | `{name}` → project document (201) |
|
||||
| GET | `projects/{id}` | `{id,name,revision,updatedAt,project}` |
|
||||
@@ -20,6 +23,12 @@ All routes go through `api/index.php?r=…` (the site's nginx does not pass `PAT
|
||||
| GET | `plugins/{file}` | the module source as `text/javascript` (`nosniff`, `no-cache`); 403 while the plugin is switched off, 404 for anything but a bare file name there — see [Plugins](Plugins) |
|
||||
| PUT | `plugins/{file}` | `{active}` → the entry as above. Switches a plugin on or off, server-wide, stored in `data/plugins/plugins.json`; 422 when `active` is not a boolean |
|
||||
|
||||
**Everything but `auth/*` needs a session** and answers **401** `{"error":"Sign in first"}` without
|
||||
one. Projects belong to an account: `projects` lists only the caller's own, and somebody else's
|
||||
project answers **404**, not 403 — that an id exists is already more than a stranger should learn.
|
||||
Images, fonts, sounds and plugins are shared between accounts; being signed in is still the price
|
||||
of admission. See [Accounts](Accounts).
|
||||
|
||||
Every project document carries `formatVersion` (`PROJECT_FORMAT_VERSION` in `core/model/Project.ts`,
|
||||
currently 2). There are no load-time migrations: `serialize.ts` reads what it recognises and drops
|
||||
the rest.
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
Since #177 the editor is behind a sign-in screen: every project belongs to an account, and
|
||||
nothing is loaded before somebody is signed in.
|
||||
|
||||
## Signing in
|
||||
|
||||
The sign-in screen is drawn in the same canvas as the editor — no second canvas, no HTML form.
|
||||
It asks for a user name and a password; Enter moves from the first field to the second and sends
|
||||
the form from there. The password is drawn as bullets and never appears as itself.
|
||||
|
||||
A refused attempt says what went wrong under the form: *Enter your password* before anything is
|
||||
sent, *Wrong user name or password* when the server refuses the pair.
|
||||
|
||||
The **Logout** button sits at the far right of the toolbar. It ends the session and brings the
|
||||
sign-in screen back. Who is signed in stands in the window title (`Game Maker — user`), not in
|
||||
the toolbar, which has no room to spare.
|
||||
|
||||
Signing in and out never reloads the page and never builds a second canvas: the picture changes,
|
||||
nothing else. What is unsaved is written before the session ends, the editor then lets go of
|
||||
everything it held — its tabs, the project, the running plugins, the console lines — and the
|
||||
sign-in screen is drawn in its place. Signing in builds a fresh editor in the same canvas, so a
|
||||
second account starts from nothing the first one left behind.
|
||||
|
||||
## The session outlasts a deployment
|
||||
|
||||
A login is kept on the server (`data/sessions/`, one file per session, named after the hash of
|
||||
the token in the cookie) and lasts **30 days** of not being used; every request pushes that out
|
||||
again. So `npm run build` — which is the deployment — replaces the editor under an open tab
|
||||
without asking for the password again, and so does closing the browser overnight.
|
||||
|
||||
PHP's own session handler would not do that: it throws sessions away after
|
||||
`session.gc_maxlifetime`, 24 minutes by default.
|
||||
|
||||
## The accounts
|
||||
|
||||
There are three, and for now they are made on the server, not through the editor:
|
||||
|
||||
| Account | What it holds |
|
||||
|---|---|
|
||||
| `admin` | no projects; the account that will get the admin role |
|
||||
| `e2e` | the four projects the check tools write: fixture, Jump and Run, Tetris, Actor demo |
|
||||
| `user` | every other project |
|
||||
|
||||
A project file carries its owner (`owner` in `data/projects/{id}.json`). A file without one
|
||||
belongs to nobody and is invisible to everybody — the safe way round, and the one that shows up
|
||||
straight away when a new project file is put there by hand without an owner.
|
||||
|
||||
## Making an account
|
||||
|
||||
php tools/make-user.php <username> <password> # creates it, or sets the password
|
||||
php tools/make-user.php --list
|
||||
|
||||
Passwords are stored as hashes (`password_hash`) in `data/users.json`, which is git-ignored, as
|
||||
is `data/sessions/`. There is no route for signing up: registration (#178), administering users
|
||||
(#179), roles (#180), shared projects (#181) and changing one's own password (#182) are
|
||||
follow-ups of their own.
|
||||
|
||||
## What the check tools do
|
||||
|
||||
Every seed, smoke and e2e run signs in as `e2e` first and sends the same session cookie a browser
|
||||
would (`tools/lib/auth.mjs`). The password comes from `GAME_MAKER_E2E_PASSWORD` or from
|
||||
`data/e2e-password.txt`, which is git-ignored — CI writes its own on a fresh checkout and makes
|
||||
the account with it (`tools/ci/serve.sh`).
|
||||
|
||||
The browser in an e2e run is handed that session as a cookie, so it starts on the editor. The
|
||||
sign-in screen itself is driven by hand in step 45, the one step that sees it.
|
||||
+7
-2
@@ -79,6 +79,7 @@ src/core/graph/ graph model, NodeRegistry/NodeContext/values, interpreter
|
||||
src/core/particles/ nodes (the catalogue), compile (a graph → one function per output),
|
||||
emission (which particles are alive at a second — a pure rule, no state)
|
||||
src/core/store/ serialize (untrusted JSON → Project), tilemapCells (the compact form of a layer's cells in the file), http (one API call), ProjectStore/HttpProjectStore,
|
||||
AuthStore/HttpAuthStore (signing in and out, #177),
|
||||
FileStore (what the server holds of one kind) + HttpFileStore (one generic client over the three
|
||||
file collections) — TextureStore, FontStore and SoundStore are its type parameters, nothing else
|
||||
src/core/time.ts the global clock: one scaled step a frame, shared by the world, the particles, the shaders and the animation preview
|
||||
@@ -102,7 +103,9 @@ src/viewport/ view (transforms), items (what to draw), symbols (how to
|
||||
drawOrder (objects and tilemap layers by z, #174), activeCamera — no editor concepts,
|
||||
so tests reach it freely
|
||||
src/editor/ App → Editor (layout + ticker), PlaySession (the run), ProjectSession (load/create),
|
||||
EditorRun (run in editor), state, actions, shortcuts, debugHook, autosave,
|
||||
EditorRun (run in editor), state, actions, shortcuts, debugHook,
|
||||
textProbe (finding widgets by their text — the ground floor of the test hook, shared with the sign-in screen),
|
||||
auth/LoginScreen + auth/loginRules (the sign-in screen in the canvas and what it may complain about, #177), autosave,
|
||||
polygonEdit (corners of an outline: what is under the pointer, whether a point is inside, put / move / take away – scene view and Texture tab),
|
||||
fileImport (drop/paste) → assetImport (one upload pipeline, an ImportKind per sort) ← textureImport / fontImport / soundImport,
|
||||
FilePicker (the shared "+ → Texture / Font / Sound" dialog; ImagePicker/FontPicker/SoundPicker only describe their row),
|
||||
@@ -144,7 +147,9 @@ src/editor/particles/ ParticlesEditor (graph canvas left of a preview panel, sp
|
||||
ParticlePreview (the panel: the asset's own particles, wearing its own rows)
|
||||
src/editor/list/ ListEditor (a row per item), slot (which list is being edited, and how it is written back)
|
||||
src/editor/console/ log (ring buffer, argument formatting, the console.* capture), ConsolePanel (the tail under the tabs)
|
||||
api/ PHP backend: index.php (routing), lib/{Store,TextureStore,FontStore,SoundStore,PluginStore,OriginalName,Response}.php
|
||||
api/ PHP backend: index.php (routing and the sign-in gate),
|
||||
lib/{Store,TextureStore,FontStore,SoundStore,PluginStore,OriginalName,Response}.php,
|
||||
lib/{Auth,UserStore,SessionStore}.php (#177: accounts in data/users.json, sessions in data/sessions/)
|
||||
data/projects/ persisted projects, data/textures/ + data/fonts/ + data/sounds/ content-addressed uploads,
|
||||
data/plugins/ editor plugins and plugins.json (which are switched on); filled from plugins/ by the build and the seeder
|
||||
tests/ Vitest unit tests tools/ seed-*, e2e (steps in tools/e2e/, rig in tools/e2e/lib/), smoke-*, lib/, assets/ (the walk demo's sheet)
|
||||
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
| Term | Meaning |
|
||||
|---|---|
|
||||
| **Account** | Who you are signed in as. The editor asks for a user name and a password before it loads anything, and every project belongs to one account — see [Accounts](Accounts). The **Logout** button is at the far right of the toolbar; signing in and out changes what the canvas draws, it never reloads the page. |
|
||||
| **Asset** | Named thing with a type (`scene`, `camera`, `sprite`, `text`, `behavior`, `collider`, `container`, `texture`, `animation`, `statemachine`, `shader`, `font`, `sound`, `particles`, `variables`) and typed properties. Assets have **no position**. |
|
||||
| **Texture** | An uploaded image. Scenes, textures, animations, state machines, shaders, fonts, sounds and Variables assets are the eight types that cannot be placed: a texture has no position, it is *worn* by a sprite through the ordinary property `texture`. See [Textures](Textures). |
|
||||
| **Font** | An uploaded typeface, worn by a text through the ordinary property `font`; no font means the editor's own. Uploaded and picked exactly like a texture, and stored the same way. See [Fonts](Fonts). |
|
||||
|
||||
+9
-2
@@ -12,7 +12,8 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
|
||||
# code is lost (tail's is reported), so a red run reads as green
|
||||
npm run build # writes dist/ and regenerates index.html
|
||||
./build.sh # the same under `set -o pipefail`, for callers that pipe the output
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1109 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
php tools/make-user.php <name> <password> # an account; every tool signs in (see Accounts)
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1118 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
|
||||
./e2e.sh start [GM_STEPS] # the same run detached, see below
|
||||
./e2e.sh status # live progress, or the last run's result
|
||||
@@ -22,6 +23,12 @@ node tools/seed-actor.mjs && node tools/smoke-actor.mjs # 21 checks: the w
|
||||
node tools/seed-e2e.mjs && node tools/perf-shaders.mjs # what a shader costs per sprite; a measuring tool, not a check
|
||||
```
|
||||
|
||||
**Every tool signs in first.** Since #177 the API answers 401 without a session, so the seeds, the
|
||||
smokes and the e2e run log in as the `e2e` account (`tools/lib/auth.mjs`) and send the cookie a
|
||||
browser would; the e2e browser is handed the same session over CDP. The password comes from
|
||||
`GAME_MAKER_E2E_PASSWORD` or from the git-ignored `data/e2e-password.txt`. A machine that has
|
||||
neither fails with a message saying exactly that — see [Accounts](Accounts).
|
||||
|
||||
**A run needs a working GPU.** An idle editor page keeps rendering a picture that never changes, and
|
||||
in software that is ruinous: measured here on an idle page over 20 s, software WebGL costs **373% of
|
||||
a core at 8 fps**, the same page on the Intel HD 630 via ANGLE/Vulkan costs **69% at 56 fps**. The
|
||||
@@ -64,7 +71,7 @@ The e2e run is a list of steps in `tools/e2e/` (hierarchy, inspector, play, asse
|
||||
graph, parenting, colliders, containers, text/enabled, menus, textures, frames, overflow, aspect,
|
||||
container tab, run-in-editor, pause, nested behaviors, key repeat, list tab, struct variable,
|
||||
variable nodes, property nodes, animations, state machines, console, shaders, transforms, fonts,
|
||||
particles, shared scope, render on change, sounds, load scene, graph groups, nine-slice, plugins, tiles, tilemaps, physics, shapes, queries, documents) that build on each other's
|
||||
particles, shared scope, render on change, sounds, load scene, graph groups, nine-slice, plugins, tiles, tilemaps, physics, shapes, queries, documents, sign-in) that build on each other's
|
||||
scene state and share the CDP driver in `tools/lib/harness.mjs` — `press`, `undo`, `play`,
|
||||
`object(id)`, `world()`, `mutate(js)` and friends, so a check reads like the interaction it
|
||||
exercises.
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ Live: <https://nockal.com/game-maker/> · Widget playground: <https://nockal.com
|
||||
| Page | What it covers |
|
||||
|---|---|
|
||||
| [Concepts](Concepts) | Assets, scene objects, overrides, containers, play mode, the camera, the console, editing while playing, running without Play |
|
||||
| [Accounts](Accounts) | Signing in and out, the three accounts, who a project belongs to, how a session outlives a deployment |
|
||||
| [Scenes](Scenes) | The active scene and the start scene, the switch next to Play, `Load scene` and what a swap keeps |
|
||||
| [Scene editing](Scene-editing) | Placing by drag, editor symbols, z-order, hierarchy and parenting, the editor offset |
|
||||
| [Behaviors](Behaviors) | Node graphs: variables and properties, Variables assets, the node set, structs and lists, loops, behaviors as nodes, editing the graph, the live view |
|
||||
|
||||
+1
@@ -1,6 +1,7 @@
|
||||
**Using the editor**
|
||||
|
||||
- [Concepts](Concepts)
|
||||
- [Accounts](Accounts)
|
||||
- [Scenes](Scenes)
|
||||
- [Scene editing](Scene-editing)
|
||||
- [Behaviors](Behaviors)
|
||||
|
||||
Reference in new issue
Block a user