Y-SweetAdvancedAuth Endpoint

The Auth Endpoint

Part of setting up the client-side YSweetProvider is providing it with an endpoint it can use to authorize a user to access a given document. The reason for this design is that it allows the YSweetProvider to fetch a new client token behind the scenes when the old one expires so that the application doesn’t have to intervene or ask the user to refresh the page.

The YSweetProvider’s authEndpoint value can be configured either as a string or a function that returns a ClientToken. We’ll cover both approaches below.

Configuring the authEndpoint with a string

When configuring the YSweetProvider’s authEndpoint with a string, you will need to implement the endpoint following a few rules:

  1. The endpoint should handle POST requests
  2. The body of the request will contain the document’s ID. E.g., { "docId": "my-doc-id-123" }
  3. The endpoint should perform its own check to confirm the user is authorized to access the given document
  4. The endpoint should call getOrCreateDocAndToken() to create a client token that gives the client access to the document
  5. The endpoint should return the resulting client token as the body of the response.

When using React with Server Actions, you can pass a server action as the YDocProvider’s authEndpoint prop.

  npm add @y-sweet/sdk
App.tsx
  import { DocumentManager } from '@y-sweet/sdk'
  import { YDocProvider } from '@y-sweet/react'
 
  const manager = new DocumentManager(process.env.CONNECTION_STRING)
 
  export function App() {
    const docId = 'my-doc-id'
 
    async function getClientToken() {
      'use server'
      // In a production app, this is where you'd authenticate the user
      // and check that they are authorized to access the doc.
      return await manager.getOrCreateDocAndToken(docId)
    }
 
    return (
      <YDocProvider docId={docId} authEndpoint={getClientToken}>
        <MyCollaborativeApp />
      </YDocProvider>
    )
  }

The YSweetProvider can then be configured with a string referencing the endpoint’s URL:

my-app.ts
import { createYjsProvider } from '@y-sweet/client'
 
const doc = new Y.Doc()
const docId = 'my-doc-id'
await createYjsProvider(doc, docId, '/api/auth')

Or, if you are using @y-sweet/react, you can configure the <YDocProvider> component:

my-app.tsx
import { YDocProvider } from '@y-sweet/react'
 
const docId = 'my-doc-id'
 
<YDocProvider docId={docId} authEndpoint="/api/auth">
  <MyCollaborativeApp />
</YDocProvider>

Configuring the authEndpoint with a function

When configuring the YSweetProvider’s authEndpoint with a function, you still need to hit an endpoint you’ve implemented on the server that performs an auth check and creates a client token using the @y-sweet/sdk library’s getOrCreateDocAndToken(). But you have more flexibility in how you do the auth check. This approach is useful if you need to make the fetch request yourself (to add custom auth headers, or provide the doc ID in a different way, etc). Here’s an example of using a function as the authEndpoint value:

my-app.ts
import { createYjsProvider } from '@y-sweet/client'
 
const doc = new Y.Doc()
const docId = 'my-doc-id'
await createYjsProvider(doc, docId, async () => {
  const response = await fetch(`/api/auth?docId=${docId}`, {
    headers: { Authorization: `Bearer ${myCustomAuth}` }
  })
  return await response.json()
})
Built by Jamsocket.