Setting User Collaboration Permissions

Information

Instant sync and collaboration is available when using the Web SDK with Document Engine in server-backed operational mode.

The permission to perform different actions on a document is defined in the JSON Web Token (JWT) using the collaboration_permissions property:

const token = {
  ...otherProperties,
  collaboration_permissions: [
    "annotations:view:all",
    "annotations:edit:all"
  ],
  user_id: "John"
};

The value of the collaboration_permissions property is an array of permission strings. A permission string consists of three parts written in the <content-type>:<action>:<scope> format. This guide covers all the possible values of content-type, action, and scope, one by one.

content-type

This refers to the type of record you want to apply a particular permission to. Currently, we support annotations, comments, and form fields, so content-type has the following possible values:

  • annotations — This applies to all the annotations (excluding widget annotations) in the document.

  • form-fields — This applies to all the form fields, the associated widget annotations, and the form field values in the document.

  • comments — This applies to all the comments present in the document. To use comments in the document, you’ll need a separate license for Comments and Replies.

action

This defines the action for which you want to define the permission. The following actions are supported:

  • view — This defines whether or not a content type is visible to a user.

  • edit — This defines whether or not a user is allowed to edit a content type.

  • delete — This defines whether or not a user is allowed to delete a content type.

  • fill — This defines whether or not a user is allowed to fill out a form field. This action is only applicable to the form-fields content type.

  • reply — This defines whether or not a user is allowed to reply to a comment thread. This action is only applicable to the comments content type.

  • set-group — This is a special permission that allows a user to create a content type with a group that’s different from the default group defined in the JWT. It’s also needed if you want to allow a user to change the group of existing annotations, comments, or form fields. You can read more about this below in the group section.

scope

This is used to scope the annotations, comments, and form fields the permissions should be applied to. You can define this in the following ways:

  • all — This means that the action is allowed for all the content types. For example, annotations:edit:all means a user is allowed to edit all the annotations.

  • self — This means that the action is allowed for all the content types that were created by the current user. For example, annotations:delete:self means that a user is allowed to delete the annotations they created. This scope doesn’t work for form fields. In the case of form fields, use the group-based scope instead.

  • createdBy=: This means that the action is allowed for the content types created by a particular user ID. If you don’t pass the value of the user ID, the action is applicable to all the content types with the user ID null. For example, annotations:view:createdBy= means that all annotations with the user ID null are visible. This scope cannot be used for form fields. In the case of form fields, use the group-based scope instead.

  • group=: This means that the action is allowed for all the content types with a particular group. If you don’t pass the group value, the permission is applicable to all the records with the group set to null. For example, annotations:view:group= means that all annotations with the group set to null are visible.

The user_id defined in the JWT parameters helps us define creator-based permissions like self and createdBy=<user-id>.

We combine all the three properties described above to form the collaboration permissions configuration.

group

The new group property was introduced to allow greater flexibility when declaring permissions and managing access to content. Unlike the creator, the group of each annotation, comment, and form field is mutable, which means it can be changed if the user who is changing it has the appropriate permissions.

This helps us with filtering the annotations, comments, or form fields where we want to apply the permission. For example, annotations:edit:group=foo means that a user is allowed to edit all the annotations in the document whose group is set to foo.

You can view the group of a particular annotation, comment, or form field by accessing the group property:

console.log(formField.group);
console.log(comment.group);
console.log(annotation.group);

Default Group

If you want to set one group for all the annotations, comments, and form fields created by a user, you have to set a default_group property in the JWT. If set, whenever you create a new annotation, comment, or form field, it’ll automatically assign that group to them.

Updating the Group

In case you want to use a group different from the default group or update the existing group of a record, you’ll need the permission for the set-group action. For example, annotations:set-group:group=teacher allows a user to update the group of the annotations whose initial group was teacher:

const annotations = await instance.getAnnotations(0);
const ann = annotations.get(0);
console.log(ann.group); // teacher

const updatedAnnotation = ann.set("group", "student");
await instance.update(updatedAnnotation);

const savedAnnotation = (await instance.getAnnotations(0)).find(
  (a) => a.id === ann.id
);
console.log(savedAnnotation.group); // student

In case you want to change the defaultGroup so that a new group applies to all the newly created annotations, comments, and form fields automatically, you can use PSPDFKit.Instance#setGroup(). Please keep in mind that this only stores the new group locally to add it to the newly created annotations, comments, or form fields. This won’t change the original default_group stored on the server.

You can also undo this change and go back to the original default_group set in the JWT by using PSPDFKit.Instance#resetGroup().

You can read more about the different ways in which you can change the permission of a record in our Changing Permissions guide.

Form Fields

When you define permissions for form fields, the same permission is applied to the corresponding widget annotations. This means that the annotations scope isn’t applicable for widget annotations, as widget annotations inherit permissions from related form fields.

Accessing Permission

In addition to the group property, we also added the following new properties that will share details about the permission attached to an individual annotation, comment, and form field:

  • isEditable — This says whether or not a user is allowed to edit the annotation, comment, or widget annotation linked to the form field.

  • isDeletable — This says whether or not a user is allowed to delete the annotation, comment, or widget annotation linked to the form field.

  • canSetGroup — This says whether or not a user is allowed to change the group of annotations, comments, or form fields (including the related form field values and widget annotations).

  • isFillable — This says whether or not a user can fill out a form field. This property is only available for form fields.

  • canReply — This says whether or not a user is allowed to reply to the comment thread of a particular root annotation. This is only applicable for annotations that are also the root annotations of a comment thread. In other words, this is applicable to comment marker annotations or highlight annotations with isCommentThreadRoot set to true

All five properties mentioned above are read-only. PSPDFKit will throw an error if you try to update them. The only way to change the permissions is to change the record’s group.

We’ll take a look at an example involving a landlord and tenant in our Landlord and Tenant Example guide.