NAV
javascript

Introduction

Welcome to the AutoProctor SDK! AutoProctor is an automated tool which ensures that users do not cheat while taking online exams. It tracks their environment and actions using data from sources like their mic and camera. It monitors these data and detects anomalous events.

With our JavaScript SDK, you can enable AutoProctor on your own site. You can view code examples in the dark area to the right.

Authentication

Key Pair

AutoProctor uses a pair of API keys to authorize requests. There is a public PUBLIC_KEY key and a secret SECRET_KEY key. You can get your key pair by registering on our developer portal.

HMAC

AutoProctor uses HMAC with SHA256 for Authentication. Your SECRET_KEY is the key for HMAC, and the relevant parameter is the message. Also, every request must carry your PUBLIC_KEY. Therefore, every request will carry the PUBLIC_KEY, the message and the HMAC of the message.

For instance, if you want to check that your key pair is valid, you may make a request to http://localhost:5000/api/validate/ as shown in the code. If you receive a response with the same message as in the query parameter, it means that your key pair is valid.

To verify if your key pair is valid

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

const PUBLIC_KEY = "Hdy13o87";
const SECRET_KEY = "Jbso5da3H86m";

const message = "Hello";
const hmacMessage = CryptoJS.HmacSHA256(message, SECRET_KEY).toString(CryptoJS.enc.Hex);

const searchParams = new URLSearchParams({
  "publicKey": PUBLIC_KEY,
  "message": message,
  "hmacMessage": hmacMessage
});

let url = "http://localhost:5000/api/validate/";
url.search = searchParams;

await fetch(url);

Make sure to replace PUBLIC_KEY and SECRET_KEY with your values

Initialization

Test Attempt ID

AutoProctor doesn't need details of your users, or the test they attempted, and so on. It identifies each test attempt by a testAttemptId. This is a unique ID that your own platform generates. For example, if User 4 attempted Quiz 3 twice, your platform must be able to generate two testAttemptIds. It is this testAttemptId that you will use to identify sessions on AutoProctor.

Including JS Library

On the webpage where you want to enable AutoProctor, you include our JS library and initialise it as shown in the code. The last part of the code must load after the DOM has loaded. So, wait for the window.onload event. apOptions is a dictionary object with the following mandatory keys:

To initialize, first include these two JS files in your <head> tag

<script src='https://cdn.autoproctor.co/autoproctor.min.js'></script>
<script src='https://cdn.autoproctor.co/tenant.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

const PUBLIC_KEY = "Hdy13o87";
const SECRET_KEY = "Jbso5da3H86m";

const testAttemptId = CryptoJS.lib.WordArray.random(8).toString(CryptoJS.enc.Hex);
const hmacTestAttemptId = CryptoJS.HmacSHA256(testAttemptId, SECRET_KEY).toString(CryptoJS.enc.Hex);

const trackingOptions = {"audio": false, "numFaces": false};

const apOptions = {
  'publicKey': PUBLIC_KEY,
  'testAttemptId': testAttemptId,
  'hmacTestAttemptId': hmacTestAttemptId,
  'trackingOptions': trackingOptions
}

Then, within $(document).ready or window.onload, have the following line

autoProctorInstance = await initAutoProctor(apOptions);

apOptions

Parameter Properties Description
publicKey string, required Your PUBLIC_KEY that identifies you as the sender of the data
testAttemptId string, required The unique identifier for the test attempt
hmacTestAttemptId string, required The SHA-256 HMAC of the testAttemptId with your SECRET_KEY
trackingOptions dictionary What AutoProctor will track and record. Described below

trackingOptions

These are the main parameters that would be part of your trackingOptions dictionary. There are a few additional parameters that are mentioned in the next Section.

Parameter Datatype Default Description
audio bool true Track Audio?
numHumans bool true Check only one face looking at camera
tabSwitch bool true Detect if user switched tabs/application
photosAtRandom bool true Take photos randomly throughout the test
numPhotosAtRandom int 5 How many random photos to take
userScreen bool true Capture screenshot if user switches tab
captureSwitchedTab bool true Capture screenshot if user switches tab
preventMultipleScreens bool true Detect multiple monitors (browser-dependent)

Additional Tracking Options

Apart from the parameters mentioned above, you may add the following parameters too:

Parameter Datatype Default Description
informUser bool true Should the user get notified of the violations?
restrictConsole bool false If true then nobody will be able to use the console once the test starts. This option is recommended for Production
userDetails dict {} Any additional information about the user that you share, so that you can later search by the user
evidencePushInterval int 15 Frequency (in seconds) at which violation data are pushed to the server

Results

Get Attempt Result

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

const PUBLIC_KEY = "Hdy13o87";
const SECRET_KEY = "Jbso5da3H86m";

const testAttemptId = //Insert Test Attempt ID//;
const hmacTestAttemptId = CryptoJS.HmacSHA256(testAttemptId, SECRET_KEY).toString(CryptoJS.enc.Hex);

const searchParams = new URLSearchParams({
  "publicKey": PUBLIC_KEY,
  "hmacTestAttemptId": hmacTestAttemptId
});

let url = "http://localhost:5000/api/test-attempts/" + testAttemptId;
url.search = searchParams;

await fetch(url);

The above command returns JSON structured like this:

{
  "attemptDetails": {
    "startedAt": "2021-05-11T17:27:28+0000",
    "finishedAt": "2021-05-11T18:15:28+0000",
    "trustScore": 0.83,
    "device": "Mobile",
  },
  "proctorSettings": {
    "track": {"audio": false, "numFaces": false},
    "parameters": {}
  },
  "evidence": [
    ["no-face-looking-at-camera", "2021-05-11T17:32:18+0000", true, "sampleevidenceurl.com"],
    ["noise-detected", "2021-05-11T17:42:28+0000", true, "sampleevidenceurl.com"],
    ["random-photo", "2021-05-11T18:02:22+0000", false, "sampleevidenceurl.com"],
    ["tab-focus-lost", "2021-05-11T18:12:39+0000", true, null]
  ]
}

This endpoint retrieves the results of a given Test Attempt. It contains details like the Trust Score and a list of all the violations, their evidence, etc.

HTTP Request

GET https://www.autoproctor.co/api/test-attempts/<test_attempt_id>/

Query Parameters

Parameter Description
publicKey PUBLIC_KEY
hmacTestAttemptId The SHA-256 HMAC of the testAttemptId with your SECRET_KEY

Response

Parameter Type Description
evidence list [evidence_label, evidence_iso_datetime, is_violation?, evidence_url]

Customising SDK Behaviour

Introduction

Most of AutoProctor’s functionality is driven by JavaScript’s Custom Events. For instance, if the SDK detects that there are multiple faces detected by the camera, it emits an event, with a specific event code. The SDK then handles the event, based on the event code. This is the default behaviour.

Event Types

There are three events that the SDK emits:

Type Description
autoproctorStatusEvent Emitted as the SDK loads and starts tracking the user. Each event is a ‘good’ event, in that every time an event is emitted, it means that the SDK has finished the current stage of loading, and is proceeding to the next stage.
autoproctorErrorEvent Occurs when there is an issue loading the SDK or starting the proctoring. For example, if a user denies access to her camera, this event is triggered.
autoproctorEvidenceEvent Occurs after the proctoring has started. Each violation is an event.

For example, the multiple faces detected is an autoproctorEvidenceEvent. The event code for the event is 5002. So, if you want to stop the test if multiple faces are detected, you listen to the autoproctorEvidenceEvent and if the code is 5002, you can stop showing the test, say. Look at the sample code for a simple implementation.

If you want to extend the functionality, you would add something like this

window.addEventListener("autoproctorErrorEvent", (e) => {
  const { errorCode, errorDetails } = e.detail;
  if (errorCode === 5002) {
    alert(You cannot proceed with the test.);
  }
}

Event Codes

Code Violation? Event Type Explanation
2001 - autoproctorStatusEvent Browser is compatible. User has granted permissions
2003 - autoproctorStatusEvent Video and ML model loaded. Ready to start face detection
4001 - autoproctorErrorEvent Incompatible Browser. Doesn't pass checkBrowserCompatiblity()
4002 - autoproctorErrorEvent From permissions API, user has already blocked access to camera
4003 - autoproctorErrorEvent From permissions API, user has already blocked access to microphone
4004 - autoproctorErrorEvent User has proactively declined access to camera/microphone. Or, the page is being loaded within an insecure context.
4005 - autoproctorErrorEvent Hardware error, insecure context, or some other error.
4006 - autoproctorErrorEvent From permissions API, user has already blocked access to camera and mic
4007 - autoproctorErrorEvent Audio Not Readable Error in getUserMedia
4008 - autoproctorErrorEvent Video Not Readable Error in getUserMedia
4007 - autoproctorErrorEvent Mic Not Found in getUserMedia
4008 - autoproctorErrorEvent Camera Not Found in getUserMedia
4009 - autoproctorErrorEvent We weren't able to find a microphone on your device. You need to enable your microphone, or use another device that has a microphone to take this test.
4010 - autoproctorErrorEvent We weren't able to find a camera (or webcam) on your device. You need to enable your camera, or use another device that has a camera to take this test.
4011 - autoproctorErrorEvent Permission to access a screen area was denied by the user, or the current browsing instance is not permitted access to screen sharing. Please reload the page to provide the access.
4012 - autoproctorErrorEvent The user selected a screen, window, tab, or other source of screen data, but a hardware or operating system level error or lockout occurred, preventing the sharing of the selected source.
4013 - autoproctorErrorEvent No sources of screen video are available for capture.
4014 - autoproctorErrorEvent You must share your entire screen in order to proceed with the test. Please reload the page to select again.
4015 - autoproctorErrorEvent We have detected multiple monitors. Please disconnect the extra monitor (or displays like Chromecast). If you continue without disconnecting, your teacher will be informed of multiple monitors.
4016 - autoproctorErrorEvent Use latest version of Safari on iPhone or iPad. Else, use Chrome
4017 - autoproctorErrorEvent Please use Chrome or Firefox, if you want to procced with the test. (if forceCaptureSwitchedTab is true)
5001 Yes autoproctorEvidenceEvent No one looking at camera Yes
5002 Yes autoproctorEvidenceEvent More than 1 Person in Video
5003 No autoproctorEvidenceEvent Random photo taken No
5004 Yes autoproctorEvidenceEvent Audio above background levels Yes
5005 Yes autoproctorEvidenceEvent User switched away from current tab to another tab or application Yes
5006 No autoproctorEvidenceEvent User returned to test tab from another tab or application No
5007 - autoproctorEvidenceEvent Multiple Monitors detected