easyproctor 0.0.9 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1,56 +1,335 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
6
8
  var __export = (target, all) => {
9
+ __markAsModule(target);
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
9
12
  };
10
- var __reExport = (target, module2, copyDefault, desc) => {
13
+ var __reExport = (target, module2, desc) => {
11
14
  if (module2 && typeof module2 === "object" || typeof module2 === "function") {
12
15
  for (let key of __getOwnPropNames(module2))
13
- if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
16
+ if (!__hasOwnProp.call(target, key) && key !== "default")
14
17
  __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
15
18
  }
16
19
  return target;
17
20
  };
18
- var __toCommonJS = /* @__PURE__ */ ((cache) => {
19
- return (module2, temp) => {
20
- return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
21
- };
22
- })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
21
+ var __toModule = (module2) => {
22
+ return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
23
+ };
23
24
 
24
25
  // src/index.ts
25
- var src_exports = {};
26
- __export(src_exports, {
26
+ __export(exports, {
27
27
  useProctoring: () => useProctoring
28
28
  });
29
- function useProctoring(key) {
30
- const start = () => {
31
- return new Promise((resolve, reject) => resolve());
29
+
30
+ // src/modules/database.ts
31
+ var databaseName = "EasyProctorPlugin";
32
+ var databaseVersion = 1;
33
+ function initializeDatabase(table) {
34
+ return new Promise((resolve, reject) => {
35
+ const request = indexedDB.open(databaseName, databaseVersion);
36
+ request.onupgradeneeded = () => {
37
+ request.result.createObjectStore("cameraBuffers", { keyPath: "id", autoIncrement: true });
38
+ request.result.createObjectStore("screenBuffers", { keyPath: "id", autoIncrement: true });
39
+ };
40
+ request.onerror = (e) => {
41
+ console.log(e);
42
+ reject("N\xE3o foi poss\xEDvel inicializar a biblioteca, por favor, entre em contato com o suporte e informe o erro acima");
43
+ };
44
+ request.onsuccess = () => {
45
+ const db = request.result;
46
+ const tableRef = db.transaction(table, "readwrite");
47
+ const store = tableRef.objectStore(table);
48
+ resolve(store);
49
+ };
50
+ });
51
+ }
52
+ async function getBuffers(table) {
53
+ const store = await initializeDatabase(table);
54
+ return new Promise((resolve, reject) => {
55
+ const request = store.getAll();
56
+ request.onsuccess = () => {
57
+ const data = request.result;
58
+ const blobs = data.reduce((acc, el) => [...acc, ...el.data], []);
59
+ resolve(blobs);
60
+ };
61
+ request.onerror = (e) => reject(e);
62
+ });
63
+ }
64
+ async function clearBuffers(table) {
65
+ const store = await initializeDatabase(table);
66
+ return new Promise((resolve, reject) => {
67
+ const request = store.clear();
68
+ request.onsuccess = () => resolve();
69
+ request.onerror = (e) => reject(e);
70
+ });
71
+ }
72
+
73
+ // src/modules/recorder.ts
74
+ function recorder(stream, buffer) {
75
+ let resolvePromise;
76
+ const options = {
77
+ mimeType: "video/webm; codecs=vp9",
78
+ videoBitsPerSecond: 128e3,
79
+ audioBitsPerSecond: 64 * 1e3
80
+ };
81
+ const mediaRecorder = new MediaRecorder(stream, options);
82
+ mediaRecorder.ondataavailable = (e) => {
83
+ if (e.data.size > 0) {
84
+ buffer.push(e.data);
85
+ }
86
+ resolvePromise && resolvePromise();
32
87
  };
33
- const finish = () => {
88
+ mediaRecorder.start();
89
+ function stopRecording() {
34
90
  return new Promise((resolve) => {
35
- const cameraFile = new File([], `${Date.now()}.webm`, { type: "video/webm" });
36
- const screenFile = new File([], `${Date.now()}.webm`, { type: "video/webm" });
37
- resolve([cameraFile, screenFile]);
91
+ resolvePromise = resolve;
92
+ mediaRecorder.stop();
93
+ stream.getTracks().forEach((el) => {
94
+ el.stop();
95
+ });
38
96
  });
97
+ }
98
+ return stopRecording;
99
+ }
100
+
101
+ // src/modules/startCameraCapture.ts
102
+ async function startCameraCapture(buffer) {
103
+ const constraints = {
104
+ audio: true,
105
+ video: {
106
+ width: { max: 1280, ideal: 640 },
107
+ height: { max: 720, ideal: 480 },
108
+ frameRate: 15
109
+ }
39
110
  };
40
- const pause = () => {
41
- return new Promise((resolve) => resolve());
111
+ const stream = await navigator.mediaDevices.getUserMedia(constraints);
112
+ const stopRecording = recorder(stream, buffer);
113
+ return stopRecording;
114
+ }
115
+
116
+ // src/modules/startScreenCapture.ts
117
+ async function startScreenCapture(buffer) {
118
+ const displayMediaStreamConstraints = {
119
+ video: {
120
+ cursor: "always"
121
+ },
122
+ audio: false
42
123
  };
43
- const resume = () => {
44
- return new Promise((resolve) => resolve());
124
+ const stream = await navigator.mediaDevices.getDisplayMedia(displayMediaStreamConstraints);
125
+ const stopRecording = recorder(stream, buffer);
126
+ return stopRecording;
127
+ }
128
+
129
+ // src/modules/upload.ts
130
+ var import_storage_blob = __toModule(require("@azure/storage-blob"));
131
+ var account = "iarisprod";
132
+ var containerName = "iaris";
133
+ var sas = "?sv=2020-08-04&ss=bfqt&srt=sco&sp=rwdlacupitfx&se=2025-12-28T06:34:02Z&st=2021-12-27T22:34:02Z&spr=https&sig=1rsgx389pHZCnJYd44peuWSfeCUdN8bQ9EfcLoMOdDc%3D";
134
+ var blobServiceClient = new import_storage_blob.BlobServiceClient(`https://${account}.blob.core.windows.net${sas}`);
135
+ async function upload(data) {
136
+ const { file, onProgress } = data;
137
+ const containerClient = blobServiceClient.getContainerClient(containerName);
138
+ const blockBlobClient = containerClient.getBlockBlobClient(file.name);
139
+ const progressCallback = (e) => {
140
+ const progress = e.loadedBytes / file.size * 100;
141
+ onProgress && onProgress(Math.round(progress));
45
142
  };
143
+ await blockBlobClient.upload(file, file.size, { onProgress: progressCallback });
144
+ }
145
+ var upload_default = upload;
146
+
147
+ // src/modules/http.ts
148
+ var baseUrl = "https://iaris.easyproctor.tech/api";
149
+ async function makeRequest(data) {
150
+ var _a;
151
+ const { url, method, body, jwt } = data;
152
+ const resp = await fetch(baseUrl + url, {
153
+ method,
154
+ body: body != null ? JSON.stringify(body) : void 0,
155
+ headers: {
156
+ "Authorization": `Bearer ${jwt}`,
157
+ "Content-Type": "application/json"
158
+ }
159
+ });
160
+ if (resp.status >= 400) {
161
+ throw "N\xE3o foi poss\xEDvel realizar a requisi\xE7\xE3o, tente novamente mais tarde";
162
+ }
163
+ const isJson = (_a = resp.headers.get("content-type")) == null ? void 0 : _a.includes("application/json");
164
+ const responseData = isJson ? await resp.json() : null;
165
+ return responseData;
166
+ }
167
+
168
+ // src/index.ts
169
+ var azureBlobUrl = "https://iarisprod.azureedge.net/iaris";
170
+ function useProctoring(proctoringOptions) {
171
+ ["examId", "clientId", "token"].forEach((el) => {
172
+ const key = el;
173
+ if (!proctoringOptions[key]) {
174
+ throw `O campo ${key} \xE9 obrigat\xF3rio`;
175
+ }
176
+ });
177
+ let focusCallback;
178
+ let lostFocusCallback;
179
+ if (!navigator.mediaDevices.getDisplayMedia) {
180
+ throw "Voc\xEA est\xE1 utilizando uma vers\xE3o muito antiga do navegador, por favor, atualize a vers\xE3o";
181
+ }
182
+ if (!window.indexedDB) {
183
+ throw "Voc\xEA est\xE1 usando uma vers\xE3o muito antiga do navegador, n\xE3o \xE9 poss\xEDvel relizar a requisi\xE7\xE3o";
184
+ }
185
+ function download(file) {
186
+ const url = URL.createObjectURL(file);
187
+ const a = document.createElement("a");
188
+ document.body.appendChild(a);
189
+ a.style.display = "none";
190
+ a.href = url;
191
+ a.download = file.name;
192
+ a.click();
193
+ window.URL.revokeObjectURL(url);
194
+ }
195
+ let cameraBuffer = [];
196
+ let screenBuffer = [];
197
+ let proctoringId = "";
198
+ let cancelCallback = null;
199
+ async function _startCapture() {
200
+ if (!document.body) {
201
+ throw "A execu\xE7\xE3o do script deve ser feita por algum elemento dentro do <body> da p\xE1gina html";
202
+ }
203
+ if (cancelCallback != null) {
204
+ throw "Uma grava\xE7\xE3o ja est\xE1 em andamento";
205
+ }
206
+ let cancelCameraCapture = null;
207
+ let cancelScreenCapture = null;
208
+ try {
209
+ if (focusCallback)
210
+ window.removeEventListener("focus", focusCallback);
211
+ if (lostFocusCallback)
212
+ window.removeEventListener("blur", lostFocusCallback);
213
+ cancelScreenCapture = await startScreenCapture(screenBuffer);
214
+ if (focusCallback)
215
+ window.addEventListener("focus", () => window.addEventListener("focus", focusCallback), { once: true });
216
+ if (lostFocusCallback)
217
+ window.addEventListener("blur", lostFocusCallback);
218
+ cancelCameraCapture = await startCameraCapture(cameraBuffer);
219
+ cancelCallback = async function() {
220
+ await Promise.all([cancelCameraCapture(), cancelScreenCapture()]);
221
+ };
222
+ } catch (error) {
223
+ cancelCallback = null;
224
+ cancelScreenCapture && await cancelScreenCapture();
225
+ cancelCameraCapture && await cancelCameraCapture();
226
+ cameraBuffer = [];
227
+ screenBuffer = [];
228
+ throw "N\xE3o foi poss\xEDvel iniciar a captura, por favor, verifique as permiss\xF5es de camera e microfone";
229
+ }
230
+ }
231
+ async function start(options = { override: false }) {
232
+ const { override } = options;
233
+ if (override) {
234
+ await Promise.all([clearBuffers("cameraBuffers"), clearBuffers("screenBuffers")]);
235
+ } else {
236
+ const [storedCameraBuffers, storedScreenBuffers] = await Promise.all([getBuffers("cameraBuffers"), getBuffers("screenBuffers")]);
237
+ if (storedCameraBuffers.length > 0 || storedScreenBuffers.length > 0) {
238
+ throw "Existe uma grava\xE7\xE3o iniciada, por favor, execute o m\xE9todo resume() para retomar, ou utilize o parametro start({ override: true }) para limpar os dados";
239
+ }
240
+ }
241
+ await _startCapture();
242
+ try {
243
+ const resp = await makeRequest({
244
+ url: `/proctoring/start/${proctoringOptions.examId}`,
245
+ method: "POST",
246
+ body: { clientId: proctoringOptions.clientId },
247
+ jwt: proctoringOptions.token
248
+ });
249
+ proctoringId = resp.id;
250
+ return resp;
251
+ } catch (error) {
252
+ cancelCallback && cancelCallback();
253
+ throw error;
254
+ }
255
+ }
256
+ async function pause() {
257
+ throw "Ainda n\xE3o implementado";
258
+ }
259
+ async function resume() {
260
+ throw "Ainda n\xE3o implementado";
261
+ }
262
+ async function finish(options = {}) {
263
+ const { onProgress } = options;
264
+ if (cancelCallback) {
265
+ await cancelCallback();
266
+ }
267
+ const time = new Date().toISOString();
268
+ const finalCameraBuffer = cameraBuffer;
269
+ const finalScreenBuffer = screenBuffer;
270
+ if (finalCameraBuffer.length == 0 || finalScreenBuffer.length == 0) {
271
+ throw "N\xE3o existe nenhuma grava\xE7\xE3o iniciada";
272
+ }
273
+ const cameraFileName = `EP_${proctoringOptions.examId}_${time}_camera_0.webm`;
274
+ const screenFIleName = `EP_${proctoringOptions.examId}_${time}_screen_0.webm`;
275
+ const cameraFile = new File(finalCameraBuffer, cameraFileName, { type: "video/webm" });
276
+ const screenFile = new File(finalScreenBuffer, screenFIleName, { type: "video/webm" });
277
+ let cameraProgress = 0;
278
+ const screenProgress = 0;
279
+ const handleOnProgress = () => {
280
+ onProgress && onProgress((cameraProgress + screenProgress) / 2);
281
+ };
282
+ await Promise.all([
283
+ upload_default({ file: cameraFile, onProgress: (progress) => {
284
+ cameraProgress = progress;
285
+ handleOnProgress();
286
+ } }),
287
+ upload_default({ file: screenFile, onProgress: (progress) => {
288
+ cameraProgress = progress;
289
+ handleOnProgress();
290
+ } })
291
+ ]);
292
+ await makeRequest({
293
+ url: "/proctoring/save-screen",
294
+ method: "POST",
295
+ jwt: proctoringOptions.token,
296
+ body: {
297
+ proctoringId,
298
+ alerts: []
299
+ }
300
+ });
301
+ await makeRequest({
302
+ url: `/proctoring/finish/${proctoringOptions.examId}`,
303
+ method: "POST",
304
+ body: {
305
+ endDate: time,
306
+ videoCameraUrl: `${azureBlobUrl}/${cameraFileName}`,
307
+ videoScreenUrl: `${azureBlobUrl}/${screenFIleName}`
308
+ },
309
+ jwt: proctoringOptions.token
310
+ });
311
+ await Promise.all([clearBuffers("cameraBuffers"), clearBuffers("screenBuffers")]);
312
+ cameraBuffer = [];
313
+ screenBuffer = [];
314
+ cancelCallback = null;
315
+ }
46
316
  const onLostFocus = (cb) => {
317
+ lostFocusCallback = cb;
318
+ window.addEventListener("blur", lostFocusCallback);
319
+ const dispose = () => window.removeEventListener("blur", lostFocusCallback);
320
+ return dispose;
321
+ };
322
+ const onReturnFocus = (cb) => {
323
+ focusCallback = cb;
324
+ window.addEventListener("focus", focusCallback);
325
+ const dispose = () => window.removeEventListener("focus", focusCallback);
326
+ return dispose;
47
327
  };
48
- return { start, finish, pause, resume, onLostFocus };
328
+ return { start, finish, pause, resume, onLostFocus, download, onReturnFocus };
49
329
  }
50
330
  if (typeof window !== "undefined") {
51
331
  window.useProctoring = useProctoring;
52
332
  }
53
- module.exports = __toCommonJS(src_exports);
54
333
  // Annotate the CommonJS export names for ESM import in node:
55
334
  0 && (module.exports = {
56
335
  useProctoring
@@ -0,0 +1,6 @@
1
+ declare type Tables = "cameraBuffers" | "screenBuffers";
2
+ export declare function initializeDatabase(table: string): Promise<IDBObjectStore>;
3
+ export declare function insertBuffer(table: Tables, buffer: Blob[]): Promise<void>;
4
+ export declare function getBuffers(table: Tables): Promise<Blob[]>;
5
+ export declare function clearBuffers(table: Tables): Promise<void>;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare function makeRequest<R>(data: {
2
+ url: string;
3
+ method: "GET" | "POST";
4
+ body?: any;
5
+ jwt: string;
6
+ }): Promise<R>;
@@ -0,0 +1 @@
1
+ export default function recorder(stream: MediaStream, buffer: Blob[]): () => Promise<void>;
@@ -1 +1 @@
1
- export default function startCameraCapture(): void;
1
+ export default function startCameraCapture(buffer: Blob[]): Promise<() => Promise<void>>;
@@ -1 +1 @@
1
- export default function startScreenCapture(): Promise<void>;
1
+ export default function startScreenCapture(buffer: Blob[]): Promise<() => Promise<void>>;
@@ -0,0 +1,6 @@
1
+ declare type UploadData = {
2
+ file: File;
3
+ onProgress?: (progress: number) => void;
4
+ };
5
+ declare function upload(data: UploadData): Promise<void>;
6
+ export default upload;
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "easyproctor",
3
- "version": "0.0.9",
3
+ "version": "0.0.13",
4
4
  "description": "Modulo web de gravação do EasyProctor",
5
5
  "main": "./index.js",
6
6
  "module": "./esm/index.js",
7
7
  "unpkg": "./unpkg/easyproctor.min.js",
8
8
  "types": "./index.d.ts",
9
- "keywords": ["proctoring"],
10
- "homepage": "https://github.com/Igor4505/render-function#readme",
9
+ "keywords": [
10
+ "proctoring"
11
+ ],
12
+ "homepage": "https://vsoft1.visualstudio.com/DefaultCollection/Iaris/_git/easyproctor-proctoring-componentJs",
11
13
  "repository": {
12
14
  "type": "git",
13
- "url": "git+https://github.com/Igor4505/render-function.git"
15
+ "url": "https://vsoft1.visualstudio.com/DefaultCollection/Iaris/_git/easyproctor-proctoring-componentJs"
14
16
  },
15
17
  "scripts": {
16
18
  "build": "node scripts/build.js && tsc",
@@ -19,10 +21,15 @@
19
21
  "author": "Igor Dantas",
20
22
  "license": "ISC",
21
23
  "devDependencies": {
22
- "@typescript-eslint/eslint-plugin": "^5.3.1",
23
- "@typescript-eslint/parser": "^5.3.1",
24
+ "@types/dom-mediacapture-record": "^1.0.11",
25
+ "@typescript-eslint/eslint-plugin": "^5.8.0",
26
+ "@typescript-eslint/parser": "^5.8.0",
24
27
  "esbuild": "^0.13.13",
28
+ "esbuild-serve": "^1.0.1",
25
29
  "eslint": "^8.2.0",
26
- "typescript": "^3.9.7"
30
+ "typescript": "^4.5.4"
31
+ },
32
+ "dependencies": {
33
+ "@azure/storage-blob": "^12.8.0"
27
34
  }
28
35
  }