diff --git a/src/yhub-server/README.md b/src/yhub-server/README.md index 0d517869f..a0653e42e 100644 --- a/src/yhub-server/README.md +++ b/src/yhub-server/README.md @@ -31,18 +31,17 @@ It is not a fork of yhub — it is a thin wrapper: `X-User-Id` header naming the user the initial content is attributed to), which seeds a document's initial Yjs state from a raw binary update (`Y.encodeStateAsUpdate` / pycrdt `get_update()` output posted as - `application/octet-stream` — no lib0 encoding, unlike yhub's built-in - `PATCH .../ydoc/`), so the Django backend can create documents - server-side. Strict create: 409 when the document already has content. - Guarded by standard document write access (the admin JWT, or a user - session with update ability), + `application/octet-stream`), so the Django backend can create documents + server-side. The built-in `PATCH .../ydoc/` takes the same update, but this + one is a **strict create** — 409 when the document already has content — and + it credits the content to `X-User-Id` instead of to the caller. Guarded by + standard document write access (the admin JWT, or a user session with update + ability). Reading needs neither, and goes through the built-in `GET + .../ydoc/`, which since 0.5.0 answers JSON (the update base64 encoded) to a + request sending `Accept: application/json`, - exposes `POST /collaboration/migrate/v1/{org}/{docid}`, which replays a document's **full** legacy version history out of the S3 media bucket (see "Full migration" below) — admin JWT only, like `reset-connections`, -- exposes `GET /collaboration/get-ydoc/v1/{org}/{docid}`, the read counterpart - of `create-ydoc`: the current state of a document as a raw binary update - (204 when it has no content), which the Django backend reads to export or - duplicate a document. Guarded by standard document read access, - notifies the Django backend on `POST /api/v1.0/documents/{id}/content-updated/` whenever the worker persists new content for a document, so that lists ordered by `updated_at` diff --git a/src/yhub-server/server.js b/src/yhub-server/server.js index dbafe6da4..3c952b387 100644 --- a/src/yhub-server/server.js +++ b/src/yhub-server/server.js @@ -459,45 +459,18 @@ const api = [ }, }, }), - // GET /collaboration/get-ydoc/v1/{org}/{docid} — the current state of a - // document as a RAW binary update (`Y.encodeStateAsUpdate` output), the read - // counterpart of create-ydoc: yhub's built-in `GET ydoc` answers a lib0-any - // encoded `{ doc, awareness }` envelope Django cannot decode. Answers 204 - // when the room holds no content. Default access purpose: guarded like the - // built-in ydoc routes (read access on the doc — the admin JWT, or a user - // session able to retrieve it). - createApiEndpoint('get-ydoc', { - get: { - handler: async (req) => { - if (req.org !== ORG) { - return jsonResponse(400, { error: 'Unknown org' }); - } - if (!UUID4.test(req.docid)) { - return jsonResponse(400, { error: 'Room name is invalid' }); - } - const { gcDoc } = await req.yhub.getDoc( - req.room, - { gc: true, nongc: false }, - { gcOnMerge: false }, - ); - // <= 3 bytes is yhub's "no effective content" convention (an empty - // update encodes to 2 bytes) — nothing to copy. `null` answers 204. - if (gcDoc == null || gcDoc.byteLength <= 3) { - return null; - } - // a Uint8Array is served as application/octet-stream, untouched - return gcDoc; - }, - }, - }), // POST /collaboration/create-ydoc/v1/{org}/{docid} — create a document's // initial Yjs state from a RAW binary update (`Y.encodeStateAsUpdate` / - // pycrdt `get_update()` output) posted as application/octet-stream. Unlike - // yhub's built-in `PATCH ydoc`, the body is not lib0-any encoded, so Django - // can call it with a plain `requests.post(url, data=raw_bytes)`. Strict - // create: 409 when the room already has content. Default access purpose: - // guarded like the built-in ydoc routes (write access on the doc — the - // admin JWT, or a user session with update ability). + // pycrdt `get_update()` output) posted as application/octet-stream. + // + // The built-in `PATCH ydoc` takes the same update (base64, in a json body + // since 0.5.0) but neither of the two things this endpoint exists for: it is + // a strict create, answering 409 when the room already has content, and it + // attributes the content to the user named in `X-User-Id` rather than to the + // backend making the call. Reads have no such needs and use the built-in + // `GET ydoc`. Default access purpose: guarded like the built-in ydoc routes + // (write access on the doc — the admin JWT, or a user session with update + // ability). createApiEndpoint('create-ydoc', { post: { handler: async (req) => {