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:
Note: The following integration parameters may change:
demo.proctoring.app
is used as an example only. In production, always use the address of your proctoring server.jwt
is the default name, but it can be changed.your-256-bit-secret
, used to sign the JWT token.your-256-bit-secret
, specified in the X-Api-Key
header of the webhook to authenticate the request.The scenario of interaction of the test-taker and the proctor with the proctoring system and LMS in the general case is as follows:
Technical implementation of the scenario:
start()
function with this token.token
field in the start()
function of the Web SDK (see section 2.3).start()
function (see section 2.4). Otherwise, the test-taker could access the assessment without proctoring.stop()
function to end the proctoring session (see section 2.5). Use the stop
event to handle this.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.
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:
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.
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).
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.
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.
The general interaction scenario is as follows:
Token generation should be performed on the server, and only the token string should be transmitted to the client. To create a token:
JWT Payload
{
"username": "a34c1a1a-53ef-4728-8dc5-9c4779a8586e",
"nickname": "John Doe",
"identifier": "565b30b8-5cfb-42e2-a292-478d20630d1b",
"template": "default",
"subject": "Tutorial: proctoring",
"tags": [ "male" ]
}
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
YYYY-MM-DDTHH:mm:ss.sssZ
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.
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
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.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/
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>
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:
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:
If you specify the "identifier" field, the specified report will be opened immediately after authorization.
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
started
- In progressskipped
- Not started before deadlinestopped
- Completed, not ratedaccepted
- Positively ratedrejected
- Negatively rated"metric: value"
format** — 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):
In this case, the Content-Type
header changes to multipart/form-data
, containing a JSON file with results and additional binary files.
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.
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.
To verify that the WebSDK integration is correct, use the following checklist:
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.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.start()
function, in which case the session identifier (the “identifier” field) and the user (the “username” field) should not change.stop()
function.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.logout()
function within this handler to redirect to another page.