Let guests try a demo project without an account (#428)
The editor was only open to somebody with an account. A guest now picks
a demo project on the sign-in screen and gets the whole editor on a copy
held in the tab. The server writes nothing for a guest, so there is no
guest session, no guest folder and no quota to keep.
- Demo copies are frozen copies like a release, in data/demos/. An
administrator makes, updates and removes one with "Demo copy..." in
the project's main menu. GET demos and GET demos/{token} need no
session. An empty project is just a demo that is empty.
- Demo material: an administrator offers an uploaded file with "Offer
as demo" in the pickers (PATCH {demo}, data/demo-files.json). Every
list carries it with demo: true, for accounts and guests alike.
Signed out, a list holds the demo material alone, without the owner.
- An offered file is only an administrator's to delete. A file a demo
copy names counts as used, like one a release names.
- The guest's project lives in MemoryProjectStore. Every store that
would write refuses in the tab before a request is made, and the
autosave is not attached at all.
- The main menu drops projects, snapshots and release for a guest. The
pickers drop Upload and Delete, a dropped or pasted file is refused,
and a recording is saved as a download.
- The toolbar says the work is not saved. The Account menu holds
"Sign in..." instead of Logout and the password.
- A guest's demo never goes into the address: a reload brings the
sign-in screen back, not the copy. Found by e2e 70.
- GET plugins needs no session any more, since a demo may switch one
on. It only reads the server's own modules.
Tests:
- e2e 70 (atx): ALL PASSED, 13 checks. Counter-test with the guest
autosave sent to the server: 70f and 70g red on the PUT.
- tests/core/guest.test.ts: 9 tests. PHP: demos 20, files 46,
rights 80 checks (the matrix asks every new route).
- Gate (atx): CHECK EXIT 0, 314 files, 4852 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ce1f25f2eb
commit
925a39a276
30 files changed
+1397
-128
No files matched your search
@@ -0,0 +1,52 @@
|
||||
import type { Role } from '../core/store/AuthStore';
|
||||
|
||||
/**
|
||||
* Who sits at the editor (#428): somebody signed in, with their role, or a guest trying a demo
|
||||
* copy without an account.
|
||||
*/
|
||||
export interface Session {
|
||||
guest: boolean;
|
||||
role: Role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Everything the editor does that writes to the server or manages it. A guest's project lives in
|
||||
* the tab alone, so a guest does none of these; an account does all of them but the
|
||||
* administrators' own.
|
||||
*/
|
||||
export type SessionAction =
|
||||
| 'save'
|
||||
| 'upload'
|
||||
| 'deleteFile'
|
||||
| 'projects'
|
||||
| 'snapshots'
|
||||
| 'release'
|
||||
| 'password'
|
||||
| 'users'
|
||||
| 'demoCopy'
|
||||
| 'offerDemo';
|
||||
|
||||
const ADMINISTRATORS_ONLY: ReadonlySet<SessionAction> = new Set(['users', 'demoCopy', 'offerDemo']);
|
||||
|
||||
/** Whether `session` may do `action`. The server decides again; this is what the editor offers. */
|
||||
export function sessionAllows(session: Session, action: SessionAction): boolean {
|
||||
if (session.guest) return false;
|
||||
return !ADMINISTRATORS_ONLY.has(action) || session.role === 'admin';
|
||||
}
|
||||
|
||||
/** What a guest is told when something would need the server. */
|
||||
export const GUEST_REFUSAL = 'Guests keep nothing on the server – sign in to keep your work';
|
||||
|
||||
let current: Session = { guest: false, role: 'user' };
|
||||
|
||||
/**
|
||||
* The session of this page, for the places that are not handed the account: the pickers, a file
|
||||
* dropped on the editor, a finished recording. One page holds one session at a time.
|
||||
*/
|
||||
export function setSession(session: Session): void {
|
||||
current = session;
|
||||
}
|
||||
|
||||
export function allows(action: SessionAction): boolean {
|
||||
return sessionAllows(current, action);
|
||||
}
|
||||
Reference in new issue
Block a user