feat: F5.2 sign-in with the dashboard's ticket and the service way
Server F checks the dashboard's entry ticket as itsdangerous does (tools/ticket-oracle: tickets made by itsdangerous 2.2.0 itself), redeems it at /__auth for a session cookie (only the key's SHA-256 is kept) and decides at /sync by the session's grant: none, read or write; a frozen project is read by everyone; every refusal names its reason (one list in packages/protocol/src/sync.ts). A WebSocket from a page of another origin is refused. /svc/* with the service key makes, deletes, freezes and thaws projects, ends a person's grant or all their sessions (connections let go) and lists the sessions. Snapshots, restoring and copying move to F6 (they need the canonical doc.json and an epoch). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Public surface of the wire protocol.
|
||||
export * from './host.js';
|
||||
export * from './sim.js';
|
||||
export * from './sync.js';
|
||||
export * from './terminal.js';
|
||||
export * from './dns.js';
|
||||
export * from './echo.js';
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// What F tells an editor about its place in a shared document (/sync, plan
|
||||
// §5, §8.5) besides the document itself — the one list both sides import:
|
||||
// why a connection is refused, why F lets it go, and the message that its
|
||||
// access changed while it is connected (a project frozen or thawed).
|
||||
|
||||
/** Why F refuses a connection to a project (Hocuspocus' permission-denied, with this as its reason). */
|
||||
export const SYNC_REFUSALS = [
|
||||
/** The name is not a project's id. */
|
||||
'notAProject',
|
||||
/** No session (no cookie, or it ran out): the dashboard issues a new ticket. */
|
||||
'notSignedIn',
|
||||
/** A session, but no access to this project (never had one, or it was revoked). */
|
||||
'noAccess',
|
||||
/** F does not know the project (deleted). */
|
||||
'unknownProject',
|
||||
] as const;
|
||||
export type SyncRefusal = (typeof SYNC_REFUSALS)[number];
|
||||
|
||||
/** Why F closes a connection (Hocuspocus' close, with this as its reason). */
|
||||
export const SYNC_CLOSINGS = [
|
||||
/** The person's access to the project was taken away. */
|
||||
'revoked',
|
||||
/** The project was deleted. */
|
||||
'deleted',
|
||||
] as const;
|
||||
export type SyncClosing = (typeof SYNC_CLOSINGS)[number];
|
||||
|
||||
export const SYNC_PROTOCOL_VERSION = 1;
|
||||
|
||||
/** A stateless message from F: the connection's access now (sent when it changes on a connection that stays). */
|
||||
export interface AccessMessage {
|
||||
readonly v: 1;
|
||||
readonly kind: 'access';
|
||||
readonly readOnly: boolean;
|
||||
/** The project is frozen (its deadline passed): no one writes, whatever their level. */
|
||||
readonly frozen: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user