ueberdosis / hocuspocus

The CRDT Yjs WebSocket backend for conflict-free real-time collaboration in your app.
https://tiptap.dev/docs/hocuspocus/introduction
MIT License
1.29k stars 125 forks source link

Unable to find documentation on refreshing / replacing the auth token #755

Closed overbyte closed 9 months ago

overbyte commented 10 months ago

Part of the documentation? I’ve read the following page of the documentation

What is the best approach to refresh the token when using the HocusPocusProvider?

We're sending the server token in the setup:

  const provider = ref();

  function setupProvider() {
    provider.value = new HocuspocusProvider({
      url: config.hocusPocusUrl,
      name: `document-${name}`,
      document: ydoc,
      token
    });
  }

but I can't see any documentation on how to provide a refresh token or how to manually update the token. Our token lasts 24 hours, after that we get an authentication error from the provider and the document is non-writable (we disable the document in this case to avoid the user losing any work done after the error) until the user refreshes the page (running the hocus pocus provider initialisation again).

The use case is when a user leaves a document in their browser overnight and attempts to pick up where they left off in the morning

My current thinking is to listen for an authentication failure event and re-create the provider with a new token but this would mean that any existing listeners would need to be removed and re-applied which seems error prone.

overbyte commented 10 months ago

Is there any updated on this question please?

starptr commented 10 months ago

Are you using the JWT that's been "auto generated for testing" from the settings? I believe you need to compute the JWT (i.e. the token) from the "App Secret" value in your Tiptap Cloud Settings. The auto generated token is frequently revoked so it will not work in prod. (I believe you don't want it to work in prod anyways because it grants access over all of the documents.)

janthurau commented 9 months ago

We currently don't have the option to refresh the token in the provider, I believe the best option would be to just destroy / recreate the provider. As you are working with ydocs, the user won't notice and it can run fully in the background (create the ydoc separately and pass it to provider, don't use the default doc that the provider creates)

A feature request is already open here: #752.

overbyte commented 9 months ago

Are you using the JWT that's been "auto generated for testing" from the settings? I believe you need to compute the JWT (i.e. the token) from the "App Secret" value in your Tiptap Cloud Settings. The auto generated token is frequently revoked so it will not work in prod. (I believe you don't want it to work in prod anyways because it grants access over all of the documents.)

This is using our own token to validate the hocus pocus provider against the backend as documented here rather than the tiptap JWT https://tiptap.dev/docs/hocuspocus/provider/configuration

token An authentication token that will be passed to the server (works with strings, functions and Promises).

overbyte commented 9 months ago

We currently don't have the option to refresh the token in the provider, I believe the best option would be to just destroy / recreate the provider. As you are working with ydocs, the user won't notice and it can run fully in the background (create the ydoc separately and pass it to provider, don't use the default doc that the provider creates)

A feature request is already open here: #752.

Thankyou.

We have a separate ydoc so it sounds like this will be cool. If we're using the configuration event callbacks for the events

const provider = new HocuspocusProvider({
  url: "ws://127.0.0.1:1234",
  name: "example-document",
  document: ydoc,
  onSynced: ({ state }) => {
    // …
  },

versus bound events

provider.on("synced", handleSynced);

Will these be cleared up correctly or should we switch to using bound events for everything so they can be unbound when we destroy the provider?

fuadsaud commented 4 months ago

Here's an anecdotal description of a problem we are having with regards to token management:

At first, a token might not be available. In this case, we want to connect without a token, in read-only mode. If/when a token becomes available, we want to supply that token to the provider so that the connection is, potentally, upgraded to read/write. When the token expires we want to be able to set a new, fresh token. Historically we would destroy and recreate the provider, which is a bit clunky, but works. However, we started hitting problems when we started using the CollaborationCursor extensions from Tiptap. That extension depends on the provider, so every time the provider is recreated, we need to reinitialize the extension and, therefore, the Tiptap editor itself. Restarting the Editor, however, throws away quite a lot of state, for example, the user selection/cursor position, and state from other extensions.

This could, perhaps, be solved on the CollaborationCursor extension's side - perhaps by exposing a command that allows to set the provider without reinitializing it, but given that refreshing a token is a common operation, it does feel like it should be fixed in hocuspocus itself.