exam-proctor-sdk-bundled
v1.1.0
Published
exam-proctor-sdk with models included (offline use)
Downloads
122
Readme
exam-proctor-sdk
Drop-in browser-based exam proctoring SDK for Node.js/Express exam platforms.
This package embeds your existing proctoring stack directly into the host exam app (same origin), so there is no sidecar FastAPI server and no iframe/postMessage bridge.
Installation
npm install exam-proctor-sdkSetup (Express server)
const express = require('express');
const examProctor = require('exam-proctor-sdk');
const app = express();
app.use(examProctor.middleware({
supabaseUrl: process.env.SUPABASE_URL,
supabaseAnonKey: process.env.SUPABASE_ANON_KEY,
supabaseJwtSecret: process.env.SUPABASE_JWT_SECRET,
allowedOrigins: ['http://localhost:3000'],
modelsPath: '/proctor/models'
}));HTML layout (add once)
<%- examProctor.configScriptTag() %>
<script src="/proctor/proctor-bundle.js"></script>The config script must be rendered before proctor-bundle.js.
Exam page JS
<script>
// On exam start
ExamProctor.start(sessionId, studentName);
// On submit button click or timer end
ExamProctor.stop();
</script>Exposed routes
The middleware mounts these under /proctor/*:
GET /proctor/api/healthGET /proctor/api/session-token?sessionId=...GET /proctor/proctor-bundle.jsGET /proctor/proctoringWorker.jsGET /proctor/face-utils.jsGET /proctor/utils/motionScore.jsGET /proctor/lib/face-api.min.jsGET /proctor/models/*
Security behavior
- COOP/COEP/CORP headers are applied only to
/proctor/*routes. - CORS origin checks are applied only to
/proctor/*routes. - Client start calls are rate-limited to 3 starts / 5 seconds.
- Supabase credentials are read from
window.__PROCTOR_CONFIGat runtime. - Supabase read JWTs are minted from
/proctor/api/session-tokenusingSUPABASE_JWT_SECRET.
Environment variables
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_JWT_SECRET=Optional:
SESSION_TOKEN_TTL_SECONDS=21600Database Setup
Each organization must create their own Supabase project.
Your violation data never passes through our servers.
- Create free project at supabase.com
- Run the schema SQL (see
schema.sql) - Add your credentials to the middleware config
Optional: Self-Host Models
If your organization prefers hosting model assets on its own domain/CDN:
node node_modules/exam-proctor-sdk/download-models.jsThis downloads model assets to:
./public/proctor-models/
Then configure:
app.use(examProctor.middleware({
// ...
modelsBaseUrl: '/proctor-models'
}));API
examProctor.middleware(config)
Creates an Express middleware that mounts all proctor routes.
Config shape:
{
supabaseUrl: string,
supabaseAnonKey: string,
supabaseJwtSecret: string,
allowedOrigins: string[] | string,
modelsPath?: string, // default '/proctor/models'
mountPath?: string, // default '/proctor'
sessionTokenTtlSeconds?: number
}examProctor.configScriptTag()
Returns an inline script string:
<script>
window.__PROCTOR_CONFIG = {
supabaseUrl: "...",
supabaseAnonKey: "...",
modelsPath: "/proctor/models",
sessionTokenUrl: "/proctor/api/session-token",
...
};
</script>Migration Guide (from sidecar to plugin)
Remove from exam project
Delete old sidecar integration assets:
public/js/proctor-embed.js- any iframe bootstrapping logic for
http://localhost:8765/proctor-embed - any postMessage START/STOP bridge code
Remove from server startup
Before:
# two processes
python server/app.py # 8765
node server.js # 3000After:
# single process
node server.jsServer code before/after
Before:
app.use(express.static('public'));
// plus sidecar process, iframe communicationAfter:
const examProctor = require('exam-proctor-sdk');
app.use(examProctor.middleware({
supabaseUrl: process.env.SUPABASE_URL,
supabaseAnonKey: process.env.SUPABASE_ANON_KEY,
supabaseJwtSecret: process.env.SUPABASE_JWT_SECRET,
allowedOrigins: ['http://localhost:3000']
}));Exam page before/after
Before:
<script src="/js/proctor-embed.js"></script>
<script>
startProctor(sessionId, studentName);
// ...
stopProctor();
</script>After:
<%- examProctor.configScriptTag() %>
<script src="/proctor/proctor-bundle.js"></script>
<script>
ExamProctor.start(sessionId, studentName);
// ...
ExamProctor.stop();
</script>Local package build
npm run buildThis generates:
client/proctor-bundle.js
Notes
- Worker script is intentionally not bundled and is served separately at
/proctor/proctoringWorker.js. - Binary model assets (
.onnx,.wasm,.binarypb) are served as static files and are not JS-bundled. - ONNX Runtime Web (
ort.min.js) is loaded by the worker from/proctor/models/ort.min.js.
