Skip to content

Z0R-603 anonymous guest cursors#14878

Closed
z0rgoyok wants to merge 43 commits intotoeverything:canaryfrom
z0rgoyok:Z0R-603
Closed

Z0R-603 anonymous guest cursors#14878
z0rgoyok wants to merge 43 commits intotoeverything:canaryfrom
z0rgoyok:Z0R-603

Conversation

@z0rgoyok
Copy link
Copy Markdown

@z0rgoyok z0rgoyok commented Apr 26, 2026

Implements anonymous guest themed names and visible cursors for anonymous boards.\n\nChecks run locally:\n- yarn affine @affine/server ava src/core/anonymous-doc-access/tests/service.spec.ts --serial --concurrency 1\n- yarn lint:ox changed files\n- yarn eslint changed files\n- yarn prettier --check changed files\n- yarn typecheck\n- local Playwright two anonymous sessions on non-standard ports 58719/58711

Summary by CodeRabbit

  • New Features

    • Added anonymous document access with shareable links and guest sessions
    • Introduced access token scopes for fine-grained document-level permissions
    • Added dedicated desktop page for accessing shared anonymous boards
    • Enhanced version compatibility checking for fork deployments
  • Bug Fixes

    • Fixed blob storage key handling to respect normalized key names
    • Improved remote cursor synchronization on widget connection
    • Corrected self-hosted instance quota identification
  • Documentation

    • Added operational guides for database maintenance and testing workflows
    • Included fork deployment documentation with validation steps

z0rgoyok added 30 commits April 25, 2026 15:38
Merge anonymous board access via PR #3.
Wrap anonymous board editor in the same Scrollable.Viewport contract used by detail/share pages.
fix: show tools on anonymous boards
Fix anonymous board blob loading
fix: restrict anonymous deletes to own content
@z0rgoyok z0rgoyok requested a review from a team as a code owner April 26, 2026 20:19
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions Bot added docs Improvements or additions to documentation mod:dev app:server test Related to test cases app:core mod:server-native labels Apr 26, 2026
@z0rgoyok
Copy link
Copy Markdown
Author

Opened against upstream by mistake; this fork-specific production change is being handled in z0rgoyok/AFFiNE.

@z0rgoyok z0rgoyok closed this Apr 26, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 26, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4b6c4c9c-a94e-420e-9439-664d54ae0db2

📥 Commits

Reviewing files that changed from the base of the PR and between df482c9 and 5e8449f.

⛔ Files ignored due to path filters (1)
  • packages/backend/server/src/__tests__/models/__snapshots__/feature-user.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (74)
  • .codex/skills/affine-bot-db-ops/SKILL.md
  • .codex/skills/affine-bot-db-ops/agents/openai.yaml
  • .codex/skills/affine-bot-db-ops/references/paths.md
  • .codex/skills/affine-bot-db-ops/scripts/bot_db_ops.py
  • .codex/skills/affine-full-test-cycle/SKILL.md
  • .codex/skills/affine-full-test-cycle/agents/openai.yaml
  • .codex/skills/affine-full-test-cycle/references/test-matrix.md
  • .github/workflows/build-fork-image.yml
  • .github/workflows/build-images.yml
  • .github/workflows/build-test.yml
  • .gitignore
  • blocksuite/affine/widgets/remote-selection/src/edgeless/index.ts
  • blocksuite/affine/widgets/remote-selection/src/manager/remote-color-manager.ts
  • blocksuite/framework/sync/src/__tests__/blob.unit.spec.ts
  • blocksuite/framework/sync/src/blob/engine.ts
  • docs/fork-deploy.md
  • packages/backend/native/index.js
  • packages/backend/native/package.json
  • packages/backend/server/migrations/20260425193000_anonymous_doc_access/migration.sql
  • packages/backend/server/migrations/20260426130000_add_access_token_scopes/migration.sql
  • packages/backend/server/schema.prisma
  • packages/backend/server/src/__tests__/models/__snapshots__/feature-user.spec.ts.md
  • packages/backend/server/src/__tests__/version.spec.ts
  • packages/backend/server/src/base/utils/client-version.ts
  • packages/backend/server/src/core/access-token/__tests__/scopes.spec.ts
  • packages/backend/server/src/core/access-token/index.ts
  • packages/backend/server/src/core/access-token/resolver.ts
  • packages/backend/server/src/core/access-token/scopes.ts
  • packages/backend/server/src/core/access-token/types.ts
  • packages/backend/server/src/core/anonymous-doc-access/__tests__/service.spec.ts
  • packages/backend/server/src/core/anonymous-doc-access/index.ts
  • packages/backend/server/src/core/anonymous-doc-access/service.ts
  • packages/backend/server/src/core/auth/guard.ts
  • packages/backend/server/src/core/auth/session.ts
  • packages/backend/server/src/core/sync/gateway.ts
  • packages/backend/server/src/core/sync/index.ts
  • packages/backend/server/src/core/version/service.ts
  • packages/backend/server/src/core/workspaces/controller.ts
  • packages/backend/server/src/core/workspaces/index.ts
  • packages/backend/server/src/core/workspaces/resolvers/anonymous-doc-access.ts
  • packages/backend/server/src/core/workspaces/resolvers/blob.ts
  • packages/backend/server/src/core/workspaces/resolvers/index.ts
  • packages/backend/server/src/models/access-token.ts
  • packages/backend/server/src/models/common/feature.ts
  • packages/backend/server/src/plugins/copilot/mcp/__tests__/provider.spec.ts
  • packages/backend/server/src/plugins/copilot/mcp/provider.ts
  • packages/backend/server/src/schema.gql
  • packages/common/graphql/src/graphql/anonymous-doc-access-create.gql
  • packages/common/graphql/src/graphql/anonymous-doc-access-resolve.gql
  • packages/common/graphql/src/graphql/anonymous-doc-access-revoke.gql
  • packages/common/graphql/src/graphql/blob-set.gql
  • packages/common/graphql/src/graphql/blob-upload-abort.gql
  • packages/common/graphql/src/graphql/blob-upload-complete.gql
  • packages/common/graphql/src/graphql/blob-upload-create.gql
  • packages/common/graphql/src/graphql/blob-upload-part-url.gql
  • packages/common/graphql/src/graphql/index.ts
  • packages/common/graphql/src/schema.ts
  • packages/common/nbstore/src/__tests__/cloud-blob.spec.ts
  • packages/common/nbstore/src/frontend/blob.ts
  • packages/common/nbstore/src/impls/cloud/awareness.ts
  • packages/common/nbstore/src/impls/cloud/blob.ts
  • packages/common/nbstore/src/impls/cloud/doc.ts
  • packages/common/nbstore/src/impls/cloud/socket.ts
  • packages/common/nbstore/src/storage/blob.ts
  • packages/frontend/core/src/__tests__/selfhost-login-version-guard.spec.ts
  • packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor.tsx
  • packages/frontend/core/src/blocksuite/block-suite-editor/lit-adaper.tsx
  • packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx
  • packages/frontend/core/src/desktop/pages/anonymous-board/index.tsx
  • packages/frontend/core/src/desktop/pages/anonymous-board/styles.css.ts
  • packages/frontend/core/src/desktop/route-paths.ts
  • packages/frontend/core/src/desktop/router.tsx
  • packages/frontend/core/src/modules/workspace/entities/workspace.ts
  • tools/cli/src/bundle-shared.ts

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Walkthrough

This PR introduces anonymous document access functionality to AFFiNE, enabling guest access to shared documents through token-based links. Changes include backend services and database migrations for guest sessions/access links, scoped access tokens, GraphQL mutations/queries for link management, cloud storage/sync gateway support for anonymous guests, a frontend anonymous board page, and operational deployment documentation.

Changes

Cohort / File(s) Summary
Anonymous Document Access - Core Backend
packages/backend/server/migrations/202604*, packages/backend/server/schema.prisma, packages/backend/server/src/core/anonymous-doc-access/*
New NestJS service (AnonymousDocAccessService) managing anonymous access links and guest sessions; Prisma models for links, guest sessions, and guest updates; comprehensive authorization logic including Yjs struct-level deletion validation and doc/blob access control.
Anonymous Document Access - GraphQL API
packages/backend/server/src/core/workspaces/resolvers/anonymous-doc-access.ts, packages/backend/server/src/schema.gql, packages/common/graphql/src/graphql/anonymous-doc-access-*.gql, packages/common/graphql/src/schema.ts
New GraphQL resolver with mutations for creating/revoking/resolving anonymous links and reverting guest sessions; schema types for access links, guest sessions, and updates; new GraphQL operations for client-side token resolution and link listing.
Anonymous Document Access - Frontend
packages/frontend/core/src/desktop/pages/anonymous-board/index.tsx, packages/frontend/core/src/desktop/pages/anonymous-board/styles.css.ts, packages/frontend/core/src/desktop/route-paths.ts, packages/frontend/core/src/desktop/router.tsx
New anonymous board page component resolving access tokens, establishing guest sessions, initializing collaborative sync, rendering shared documents in edgeless mode; routing and styling.
Access Token Enhancements
packages/backend/server/src/core/access-token/resolver.ts, packages/backend/server/src/core/access-token/scopes.ts, packages/backend/server/src/core/access-token/types.ts, packages/backend/server/src/models/access-token.ts
Adds scope support to access tokens enabling fine-grained authorization (workspace/doc-level action constraints); new assertion function (assertAccessTokenCanUseDocAction) and GraphQL input types.
Cloud Storage & Sync for Anonymous Guests
packages/common/nbstore/src/impls/cloud/blob.ts, packages/common/nbstore/src/impls/cloud/doc.ts, packages/common/nbstore/src/impls/cloud/awareness.ts, packages/common/nbstore/src/impls/cloud/socket.ts, packages/common/nbstore/src/storage/blob.ts
Extends cloud storage implementations to support anonymous guest tokens; adds optional storageKey transformation for namespacing anonymous blob keys; socket authentication now accepts direct authData for guest token passing.
Blob Storage & Handling
packages/common/nbstore/src/frontend/blob.ts, blocksuite/framework/sync/src/blob/engine.ts
BlobFrontend.set now applies storage-key transformation and returns the transformed key; BlobEngine.set consistently uses the key returned by the main source for shadow uploads and return value.
Blob GraphQL Operations
packages/common/graphql/src/graphql/blob-*.gql, packages/common/graphql/src/graphql/index.ts
Five blob upload/set mutations/queries updated to accept optional anonymousGuestToken parameter for anonymous guest blob operations.
Backend Auth & Gateway
packages/backend/server/src/core/auth/guard.ts, packages/backend/server/src/core/auth/session.ts, packages/backend/server/src/core/sync/gateway.ts, packages/backend/server/src/core/sync/index.ts, packages/backend/server/src/core/workspaces/controller.ts, packages/backend/server/src/core/workspaces/index.ts
Websocket auth now validates anonymous guest tokens and establishes guest principals; sync gateway supports anonymous guests joining workspace/awareness rooms with read-only synthetic doc handling; workspace blob endpoint accepts guest tokens; version checks use new normalization function.
Client Version Handling
packages/backend/server/src/base/utils/client-version.ts, packages/backend/server/src/core/version/service.ts, packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx
New version normalization functions (normalizeComparableClientVersion, satisfiesComparableClientVersion, testComparableClientVersion) with prerelease numeric segment normalization; frontend guard uses exported helper for robust version comparison.
Quota & Feature Configuration
packages/backend/server/src/models/common/feature.ts
New self-hosted feature quota preset distinct from Pro plan; self-hosted instances now use correct storage quota instead of enterprise preset.
Operational Skills & Documentation
.codex/skills/affine-bot-db-ops/*, .codex/skills/affine-full-test-cycle/*, docs/fork-deploy.md
New operational skills documenting production database operations workflow for the anonymous board bot and comprehensive AFFiNE validation cycle; fork deployment guide for canary branch deployment targeting doska.wastelandw.ru.
GitHub Actions & Build Config
.github/workflows/build-fork-image.yml, .github/workflows/build-images.yml, .github/workflows/build-test.yml, packages/backend/native/*, tools/cli/src/bundle-shared.ts, .gitignore
New canary fork image build workflow; removed environment gating from build jobs and narrowed native build targets to x86_64-unknown-linux-gnu only; disabled cross-browser E2E tests by default via variable gate; added Python cache and build artifact ignores; dev server now uses environment-driven port and backend URL configuration.
BlockSuite Remote Selection & Sync
blocksuite/affine/widgets/remote-selection/src/edgeless/index.ts, blocksuite/affine/widgets/remote-selection/src/manager/remote-color-manager.ts
Remote cursor positions initialized immediately on widget connection; remote color manager prioritizes existing local awareness color on construction.
Test Coverage
packages/backend/server/src/__tests__/models/__snapshots__/feature-user.spec.ts.md, packages/backend/server/src/__tests__/version.spec.ts, packages/backend/server/src/core/access-token/__tests__/scopes.spec.ts, packages/backend/server/src/core/anonymous-doc-access/__tests__/service.spec.ts, packages/common/nbstore/src/__tests__/cloud-blob.spec.ts, packages/frontend/core/src/__tests__/selfhost-login-version-guard.spec.ts, packages/backend/server/src/plugins/copilot/mcp/__tests__/provider.spec.ts
Snapshot updates for self-hosted quota; new tests for version normalization, access token scopes, anonymous doc access service authorization logic, cloud blob anonymous upload, version guard prerelease handling; MCP tool contract validation.
Copilot MCP Provider
packages/backend/server/src/plugins/copilot/mcp/provider.ts
Tool naming updated to snake_case (doc_read, doc_semantic_search, doc_keyword_search, doc_create, doc_update, doc_update_meta); write-capable tools now require env.selfhosted flag in addition to dev/canary checks.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Frontend Client
    participant Resolver as GraphQL Resolver<br/>(resolveAnonymousDocAccessLink)
    participant Service as AnonymousDocAccessService
    participant DB as Database
    participant Gateway as Sync Gateway
    participant Storage as Cloud Storage

    Client->>Resolver: resolveAnonymousDocAccessLink(token, displayName)
    Resolver->>Service: resolveLink(token)
    Service->>DB: Query anonymousDocAccessLink by token hash
    DB-->>Service: Link record (enabled, not revoked)
    Service->>DB: Create/fetch anonymousDocGuestSession
    DB-->>Service: Guest session with guestToken
    Service-->>Resolver: {guestToken, link, guest}
    Resolver-->>Client: guestToken + link metadata
    
    Client->>Gateway: WebSocket connect with anonymousGuestToken
    Gateway->>Service: Validate guest token
    Service->>DB: Verify guestToken hash & link status
    DB-->>Service: Valid guest principal
    Service-->>Gateway: Guest principal established
    Gateway-->>Client: Authenticated as anonymous guest
    
    Client->>Gateway: space:join (workspace/doc)
    Gateway->>Service: assertCanAccessDoc(guest, docId)
    Service-->>Gateway: Access allowed
    Gateway->>Storage: Load workspace sync state
    Storage-->>Gateway: Initial sync state
    Gateway-->>Client: Doc state synced
    
    Client->>Gateway: space:push-doc-update (Yjs update)
    Gateway->>Service: assertUpdatesDeleteOnlyGuestContent(update)
    Service->>Service: Validate struct deletions (analyze Yjs ranges)
    Service-->>Gateway: Update allowed/denied
    Gateway->>DB: recordUpdates(guestSessionId, update)
    DB-->>Gateway: Update recorded
    Gateway-->>Client: Update applied
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:core app:server docs Improvements or additions to documentation mod:dev mod:server-native test Related to test cases

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants