WebSDK-based Integration Guide

The Supervisor SDK is a JavaScript library that can be injected into the page of any Learning Management System (LMS) to implement seamless integration with the OctoProctor proctoring system. Full documentation for the WebSDK is available at https://demo.proctoring.app/sdk/doc/.

LMS Requirements:

  • Proctoring pages in the LMS must be opened using the HTTPS protocol, with a valid SSL certificate installed on the web server. You can verify the validity of the certificate on your server using an SSL checker service or issue a free Let's Encrypt certificate.
  • Assessment pages should not be completely reloaded when switching between questions. The WebSDK code should be launched at the beginning of the assessment and remain loaded until the end. The page can be reloaded by the user.

Note: The following integration parameters may change:

  • Server address: demo.proctoring.app is used as an example only. In production, always use the address of your proctoring server.
  • Authorization provider: jwt is the default name, but it can be changed.
  • JWT secret key: your-256-bit-secret, used to sign the JWT token.
  • Webhooks API key: your-256-bit-secret, specified in the X-Api-Key header of the webhook to authenticate the request.

1. Proctoring scenario

The scenario of interaction of the test-taker and the proctor with the proctoring system and LMS in the general case is as follows:

  1. The test-taker logs in to the LMS, opens the assessment, and initiates the start of the proctoring session.
  2. Before the session, the test-taker completes several steps: agrees to the rules of the assessment, checks equipment, takes a photo of their face and passport, connects a mobile camera, and others.
  3. The test-taker starts the proctoring session and the assessment in parallel.
  4. During the assessment, video recordings of the webcam (with sound) and the computer screen are captured, violations are automatically tracked, and the test-taker is continuously verified and identified.
  5. During the session, the proctor can observe test-takers, and the system indicates in real time which test-takers need attention.
  6. The proctor can interact with test-takers via chat or through video and audio communication and can prematurely end the proctoring session in case of gross violations.
  7. After the assessment is completed, an assessment of the confidence level in the assessment results and a video protocol with detailed violations records are generated.
  8. Results are sent to the LMS via a webhook.

Technical implementation of the scenario:

  • Server-Side (LMS): Implement an API to generate a JWT token and pass it to the front-end, where the proctoring session will be initialized using the Supervisor SDK’s start() function with this token.
  • Token Structure (see sections 2.1 and 2.2):
    • Header: Specifies the HS256 algorithm and JWT type.
    • Payload: Contains user and session parameters in JSON format.
    • Signature: Formed based on the payload data and the secret key.
  • Front-End (LMS): Implement a mechanism to receive a token for the current user and assessment via the API. Pass the received JWT token to the token field in the start() function of the Web SDK (see section 2.3).
  • Proctoring System: When the proctoring session is initialized, a user and proctoring session are created (or updated) with parameters from the JWT payload. The test-taker sees preliminary steps before starting the session, after which tracking and recording begin.
  • Test Display: Display assessment content to the test-taker only after successfully executing the start() function (see section 2.4). Otherwise, the test-taker could access the assessment without proctoring.
  • Session Termination: When the assessment is finished, call the stop() function to end the proctoring session (see section 2.5). Use the stop event to handle this.
  • Results Delivery: After processing on the proctoring server, results are sent to the LMS via a webhook, using the URL specified in the api field (in the JWT payload), as a POST request in application/json or multipart/form-data format.

Below is a visualization of the scenario.

WebSDK scenario visualization
WebSDK scenario visualization

Before starting the session, each user completes preconfigured steps to meet proctoring requirements (each step can be enabled or disabled via add-ons). These include agreeing to assessment rules, checking equipment, capturing facial and passport photos, connecting a mobile camera, and others.

The following interfaces may be displayed to the user before starting a proctoring session. The SDK user interfaces appear at the top of the current page and require no special preparation:

1. Rules and regulations of the assessment
1. Rules and regulations of the assessment
2. Equipment check
2. Equipment check

3. Facial capture
3. Facial capture
4. ID capture
4. ID capture

5. Smartphone camera connection
5. Smartphone camera connection

The computer equipment check includes verifying the browser, webcam, microphone, network, and screen capture. If no issues are found, the check passes automatically; otherwise, the user receives a message with a description of the problem and resolution options

If all stages are successful, the proctoring session begins, observing the user. In this mode, the user can view video from their camera (preview), receive notifications of issues (violations are automatically detected), and access a chat to contact the proctor. A proctor can contact the user via chat, video, or audio and may end the session prematurely with a conclusion (positive or negative) and a comment, displaying a message to the user.

The session page should be opened in a single instance; the system monitors this independently. If the session is opened in multiple tabs, browsers, or computers, previous pages are automatically locked, and proctoring stops in those pages without terminating the session. The session can only resume in the last opened tab.

Webcamera preview (in circle) and chat with proctor (text, audio, video);
Webcamera preview (in circle) and chat with proctor (text, audio, video);
Content blocking screen (e.g in incident mode)
Content blocking screen (e.g in incident mode)

The session is completed by proctor
The session is completed by proctor
The page has been re-opened in another tab
The page has been re-opened in another tab

Notifications of problems (irregularities) are automatically displayed to the user, giving them the opportunity to correct the situation if the problem was unintentional. If the user does not respond to messages within a minute, then access to the content is automatically blocked until the problem is resolved (this behavior is controlled by the “lock" add-on).

Violation notification
Violation notification

Content copy protection mode prohibits copying text and images from the page using the clipboard and context menu, and also prohibits saving the page using the print dialog.

When the assessment is complete, the proctoring session should be stopped and all interfaces are hidden. The proctoring results are transferred to the LMS by webhook from the proctoring server.

2. Implementing integration

2.1. JSON Web Token (RFC 7519)

For secure transmission of parameters for a proctoring session with protection from changes on the part of the user, tokens are used according to the JSON Web Token (RFC 7519). The integration consists in implementing the JWT generation mechanism on the side of your LMS and using the WebSDK functions to manage the proctoring session.

JSON Web Token (JWT) is a JSON object that is defined in the open standard RFC 7519. It is considered one of the safest ways to transfer information between two participants. To create it, you need to define a header with general information on the token, payload data, such as the user name, his role, etc. and signature. The diagram below shows the principle of user interaction with assessment and proctoring systems using JWT.

JWT Interaction diagram
JWT Interaction diagram

The general interaction scenario is as follows:

  1. The user of the LMS is authorized in it using the authorization mechanisms provided by the system.
  2. Before the start of each individual proctoring session, the LMS generates a JWT using a predefined secret key that should not be accessible to users. The key storage method is selected by the LMS itself.
  3. The JWT is transmitted to the user on the front-end, and the user initiates a session in the proctoring system via the WebSDK using the token received from the LMS. The JWT payload stores the user identifier (the “username” field), the proctoring session identifier (the “identifier” field), and other session parameters.
  4. The proctoring system server receives the JWT, checks its validity, and then starts the proctoring session for this user.

2.2. Token generation

Token generation should be performed on the server, and only the token string should be transmitted to the client. To create a token:

  1. Generate payload data in JSON format that describes the user and a specific session of this user in the following format:

JWT Payload

{
 "username": "a34c1a1a-53ef-4728-8dc5-9c4779a8586e",
 "nickname": "John Doe",
 "identifier": "565b30b8-5cfb-42e2-a292-478d20630d1b",
 "template": "default",
 "subject": "Tutorial: proctoring",
 "tags": [ "male" ]
}
  1. Generate a token on the LMS server based on the payload data using a library (see the information on the jwt.io website). The encryption algorithm is HS256 and the token type is JWT. For the “demo.proctoring.app” server, the secret key used to generate tokens is “your-256-bit-secret”. Using the payload above should produce the following token:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImEzNGMxYTFhLTUzZWYtNDcyOC04ZGM1LTljNDc3OWE4NTg2ZSIsIm5pY2tuYW1lIjoiSm9obiBEb2UiLCJpZGVudGlmaWVyIjoiNTY1YjMwYjgtNWNmYi00MmUyLWEyOTItNDc4ZDIwNjMwZDFiIiwidGVtcGxhdGUiOiJkZWZhdWx0Iiwic3ViamVjdCI6IlR1dG9yaWFsOiBwcm9jdG9yaW5nIiwidGFncyI6WyJtYWxlIl19.1sHajdMz3n82hQEsfJTE3bii6mV3nOtTLkxTe6qwzuI

A description of the parameters that can be used in the JWT payload is given in table below. Please try to use the required minimum of parameters, usually these are: exp, username, nickname, template, identifier, subject, tags, api. It is advisable to use the rest of the parameters only if their change is foreseen by the LMS. If you need to specify different session parameters for different cases, it is better to use session templates.

Description of parameters

Parameter
Type
Description
JWT Validation
exp*
Number
UNIX time (in seconds), after which the token becomes invalid
User Profile
username*
String
unique user id, use of characters is allowed: A-Za-z0-9_-, there should be only one ID for each user
role
String
user’s role (“student” or “proctor”), by default is “student”
nickname
String
user‘s visible name
group
String
user‘s group (for the “proctor” role only)
labels
String[]
tags for search the user
lang
String
UI language (e.g. “en”), by default is the browser language
referrer
String
redirection page after logging out of the proctoring system
Proctoring Session
identifier*
String
unique proctoring session identifier, use of characters is allowed: A-Za-z0-9_-, each individual session must have its own ID
template*
String
template identifier for the proctoring session, use of characters is allowed: A-Za-z0-9_-
subject
String
title of the session
timeout
Number
session timeout in minutes after which it should be stopped if the session is inactive (integer)
lifetime
Number
session lifetime in minutes after which it should be stopped (integer)
openAt
Date
date and time until which the session cannot start (in ISO-8601 format **)
closeAt
Date
date and time after which the session will automatically end (in ISO-8601 format **)
members
String[]
list of proctor’s logins to add to the members in the session
tags
String[]
tags for search the session
url
String
URL of a assessment page to be opened in IFRAME
code
String
access code to inject into a assessment page in IFRAME
api
String
API address to send results for this session to another server via webhooks
  • — required parameters ** — ISO-8601 format (in UTC): YYYY-MM-DDTHH:mm:ss.sssZ

2.3. Integration code

Below is a sample of the WebSDK integration code:

HTML+JS

<script src="//demo.proctoring.app/sdk/supervisor.js"></script>
<script>
 // create Supervisor instance
 var supervisor = new Supervisor({
   url: 'https://demo.proctoring.app',
 });
 // add a handler for the "start" event
 supervisor.on('start', function () {
   // start assessment in the e-learning system here
 });
 // add a handler for the "stop" and "fail" events
 supervisor.on(['stop', 'fail'], function () {
   // log out of the session with redirection to home page
   supervisor.logout({ redirect: '/' });
 });
 // initialize the session and start it
 supervisor.start({
   // set your provider name
   provider: 'jwt',
   // get JWT string from your server
   token: fetch('/api/token').then(function (response) {
     if (response.ok) return response.text();
     else throw Error('Failed to get JWT');
   })
 });
 // stop the session after assessment in the e-learning system is over,
 // the timeout function is used here as an example
 setTimeout(function () {
   // stop the session
   supervisor.stop();
 }, 5 * 60 * 1000); // 5 minutes
</script>

First of all, you should add the “supervisor.js” script to the page where you want to use the proctoring service:

HTML

<script src="//demo.proctoring.app/sdk/supervisor.js"></script>

In general, working with the WebSDK for a user in the "student" role means inserting a small piece of JavaScript code on each page where proctoring is required. After loading the script, you should create an instance of the “Supervisor” class:

JS

// create Supervisor instance
var supervisor = new Supervisor({
  url: 'https://demo.proctoring.app',
});

It is important that the “supervisor.js” script is loaded from the same proctoring server as specified in the “url” field. Otherwise, after the proctoring server has been updated, a WebSDK version and a server version may be different, which will cause problems in the functioning of the proctoring service. It is also recommended to use only one instance on a page. Next, you should call the start() function with parameters to initialize and start the proctoring session. It is necessary to pass the JWT string to the client to the browser and use it in the start() function in the “token” field:

JS

// initialize the session and start it
supervisor.start({
  // set your provider name
  provider: 'jwt',
  // get JWT string from your server
  token: fetch('/api/token').then(function (response) {
    if (response.ok) return response.text();
    else throw Error('Failed to get JWT');
  })
});

The “provider” may have a different name, so you should make arrangements to change it. Note that the start() function with parameters is a shortcut for sequential calls to the init() and start() functions:

JS

// initialize the session
supervisor.init({ ...payload }).then(function () {
  // start the session
  return supervisor.start();
});

If the init() or start() function parameters is empty object, the proctoring session starts in self-registration mode:

JS

// start the session in self-registration mode
supervisor.start({});

In most cases, such as when the page is refreshed in the browser, the session can be resumed. In this case, use the same identifier and username in the JWT payload and call the start() function again. When the session is successfully started by the start() function, the “start” event is invoked, which can be subscribed to using the following script:

JS

// subscribe to the session start event
supervisor.on('start', function () {
  console.log('started');
});

While the session is initializing and starting, a critical error may have occurred, interrupting the process. You should handle this error by subscribing to the “fail” event. For example, you can redirect the user to another page when the error occurs:

JS

// subscribe to the session critical error
supervisor.on('fail', function () {
  // log out of the session with redirection to home page
  supervisor.logout({ redirect: '/' });
});

When an assessment is completed, it is also necessary to call the stop() function to terminate the proctoring session. Otherwise, the last minute may not be saved and the session will not be automatically terminated until the time specified by the timeout has elapsed.

JS

// stop the session
supervisor.stop();

When the session is finished (the session can be finished by a participant, a proctor, or automatically by timeout or deadline), the "stop" event is invoked, which can be subscribed to as follows:

JS

// subscribe to the session stop event
supervisor.on('stop', function () {
  // log out of the session with redirection to home page
  supervisor.logout({ redirect: '/' });
});

If you do not subscribe to the "stop" event, the redirect to the referrer page will occur automatically after the session is stopped by a proctor, the lifetime has expired, or the deadline has exceeded. By the way, you can subscribe to multiple events at once, just pass an array of event names to the on() function:

JS

// add a handler for the "stop" and "fail" events
supervisor.on(['stop', 'fail'], function () {
  // log out of the session with redirection to referrer page
  supervisor.logout({ redirect: true });
});

The logout() function is used to log out of the current session and redirect to the specified page if the "redirect" parameter is filled. You can specify a page URL or pass “true” to redirect to the referrer page, which is automatically determined or passed by the "referrer" field in the JWT payload.

2.4. Data-attributes for session initialization

For simple WebSDK use cases, there is an automatic initialization and session startup, as well as a payload transfer using the data attributes of the script. Table below lists the supported data-attributes.

Data-attributes for automatic session initialization

Parameter
Description
data-supervisor
If this parameter is set up it indicates that automatic WebSDK initialization is required. Two values are supported:

- sync to start the proctoring session with the JWT session token from the "token" query parameter;
- init to start the proctoring session in self-registration mode or with a payload from data-attributes.
data-*
Other possible fields for a payload that can be used for the specified provider.

This initialization method can be used in conjunction with other integrations, such as LTI or JWT links. In this case, an additional parameter "redirect" is specified in the authorisation link, which must contain the address of the page (/api/auth/?redirect=/path/to/sdk) that hosts the code with automatic WebSDK initialization with one single data attribute "data-supervisor". A code sample:

HTML

<script src="//demo.proctoring.app/sdk/supervisor.js" data-supervisor="sync"></script>

The "data-supervisor" attribute with the value "init" can be used to start a proctoring session on the LMS side with self-registration or with a payload. A code sample:

HTML

<script src="//demo.proctoring.app/sdk/supervisor.js" data-supervisor="init"></script>

3. Real-time observation and access to reports

A user with the “proctor” role can log in to real-time sessions and view reports by logging in to the proctoring system with a JWT token, username and password, or by a unique shared link. In the observation interface, a proctor sees only those sessions of which he or she is a member. A proctor can log into the proctoring system using a username and password. To do this, proctor accounts must be created in advance through the admin panel, and their logins must be added to the appropriate sessions (the "invites" field). You can create specific links to go to a particular session report. These links allow you to open the session report without being a system user. To allow sessions to be opened from a link without authorization, you must enable the “shared” add-on for a particular session (you can also enable this add-on in the session template). In this case, it is recommended to use complex session identifiers that are protected from brute-force attacks. A link to a report is formed as follows:

https://demo.proctoring.app/api/report/<identifier>

Variables to replace:

  • demo.proctoring.app is your proctoring server domain,
  • is the session identifier.

You can authorize a specific proctor with automatic account creation in the proctoring system using a link with a JWT string. Here is an example of how to fill in the JWT payload fields to authorize a proctor:

JWT Payload

{
  "username": "proctor1",
  "role": "proctor"
}

Here is an example of a link with authorization by JWT string:

https://demo.proctoring.app/api/auth/jwt?token=<JWT>

Variables to replace:

  • demo.proctoring.app is your proctoring server domain,
  • jwt is the name of the authorization provider,
  • is the generated token string.

If you specify the "identifier" field, the specified report will be opened immediately after authorization.

4. Retrieve proctoring results via webhooks

The proctoring system can use webhooks in JSON format to send the results of proctored sessions to the LMS. This is useful if you want to combine assessment results and proctoring results directly on your side. Results are sent immediately after the test-taker or proctor finishes the session, when the session is automatically terminated by a timeout, or when the proctor's conclusion is issued (or changed) after reviewing the report for some time after the session ends.

The results are sent from the proctoring system server to the LMS server via an HTTP request by the POST method using the URL specified in the “api” field of each session. The content type (the “Content-Type” header) is “application/json”. Access to the API should be restricted by the key passed in the header of the HTTP request (by default, this is the “X-Api-Key” header). A request with one "identifier" can be executed several times with different data, therefore it is necessary to provide for its update in the LMS when data is received again from the proctoring system. If all goes well, the response code should be 200, the content of the response body is not taken into account and is usually left blank. In the case of an error, the API should return a response code other than 200. Table below shows all the JSON fields in the response.

Fields description

Field
Type
Description
identifier*
String
Session ID
status
String
Session status:
started - In progress
skipped - Not started before deadline
stopped - Completed, not rated
accepted - Positively rated
rejected - Negatively rated
duration
Number
Actual duration of the session (in minutes)
createdAt
Date
Date and time the session was created
startedAt
Date
Date and time of the actual start of the session
stoppedAt
Date
Date and time of the actual end of the session
score
Number
Automatic session scoring (0-100)
averages
Object
Metric averages per session, in "metric: value" format
student
String
Test-taker's username
proctor
String
Proctor's username who rated the session
comment
String
Proctor's comment on the session
signedAt
Date
Date and time of proctor submission
link
String
URL to the session report

** — required fields, other fields may not be sent or may take a “null” value.*

Optionally, you can include additional files in the webhook request (in the host configuration by manager role):

  • photo of the participant's face (JPEG);
  • photo of the participant's document (JPEG);
  • PDF report file for the session.

In this case, the Content-Type header changes to multipart/form-data, containing a JSON file with results and additional binary files.

Webhook Results Example
Webhook Results Example

The webhook.site service can be used to test the webhook results API. To do this, specify the URL listed on the service page in the "api" field of the session created via JWT. Then start and stop the session, and a few minutes after the session ends, a request will be made to the specified URL. You can see the request parameters in the interface of this service.

5. Setting up the proctoring host

To connect the integration API with your LMS, you need to load the following configuration with integration parameters under the proctoring system manager:

{
 "id": "<Host_ID>",
 "key": "<License_Key>",
 "params": {
   "webhooks": {
     "jwt": {
       "authorizer": "jwt",
       "integrator": "generic",
       "secretOrKey": "your-256-bit-secret",
       "callbackURL": "query.redirect",
       "profile": {
         "username": "payload.username",
         "role": "payload.role==='proctor'?'proctor':'student'",
         "nickname": "payload.nickname",
         "lang": "payload.lang",
         "group": "payload.group",
         "referrer": "payload.referrer",
         "labels": "payload.labels"
       },
       "register": {
         "identifier": "payload.identifier",
         "template": "payload.template",
         "subject": "payload.subject",
         "timeout": "payload.timeout",
         "lifetime": "payload.lifetime",
         "members": "payload.members",
         "invites": "payload.invites",
         "metrics": "payload.metrics",
         "weights": "payload.weights",
         "addons": "payload.addons",
         "threshold": "payload.threshold",
         "locale": "payload.locale",
         "timezone": "payload.timezone",
         "url": "payload.url",
         "code": "payload.code",
         "api": "payload.api",
         "tags": "payload.tags",
         "openAt": "payload.openAt",
         "closeAt": "payload.closeAt",
         "rules": "payload.rules",
         "expires": "payload.expires"
       },
       "submit": {
         "uri": "room.api",
         "method": "POST",
         "headers": {
           "x-api-key": "your-256-bit-secret"
         },
         "body": {
           "identifier": "room.identifier",
           "link": "`https://${room.host}/api/report/${room.identifier}`",
           "status": "room.status",
           "duration": "room.duration",
           "createdAt": "room.createdAt",
           "startedAt": "room.startedAt",
           "stoppedAt": "room.stoppedAt",
           "score": "room.score",
           "student": "room.student.username",
           "proctor": "room.proctor.username",
           "comment": "room.comment",
           "signedAt": "room.signedAt",
           "conclusion": "room.conclusion",
           "averages": "room.averages",
           "verified": "room.student.verified"
         }
       }
     }
   }
 }
}

Note: You should replace secretOrKey and x-api-key with a randomly generated sequence (Latin letters, mixed case, numbers; recommended length: 24 characters). id is the host’s internal identifier (omit to create a new host). key is the host’s license key.

6. Integration checklist

To verify that the WebSDK integration is correct, use the following checklist:

  1. The Supervisor.js script must be downloaded by the client-side from the same server it connects to, to avoid version mismatches causing errors. Make sure to replace demo.proctoring.app with your proctoring host.
  2. Proctoring starting with the start() function is usually performed just before assessment with proctoring. During the initialization process, the user will see interfaces with preliminary steps (assessment rules, equipment check, take photos, connect mobile camera, and others). The start() function may return an error, in which case the assessment cannot be started.
  3. After successful proctoring starts, the assessment should appear to the user. Training or some preliminary actions should not be included in the proctoring session, only the assessment itself (with a time limit), otherwise it may negatively affect the proctoring scoring.
  4. When the page is refreshed (F5 or closing and reopening), the assessment and proctoring session should be restored in the same way as the first run through the start() function, in which case the session identifier (the “identifier” field) and the user (the “username” field) should not change.
  5. After the assessment is completed, the proctoring session should be terminated with the stop() function.
  6. The start() and stop() functions can crash with a critical error. But you should handle this by subscribing to the ”fail” event. You can use the logout() function within this handler to redirect to another page.
  7. When a proctoring session ends, access to the assessment should be closed. A proctoring session can be terminated by a participant, a proctor, or automatically by timeout and deadline. The ”stop” event subscription can be used to handle this. You can use the logout() function within this handler to redirect to another page.
  8. You can use the webhook.site service to test receiving results via webhooks.