@newtonschool/react_proctoring_library 0.0.10 → 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.
@@ -27,6 +27,8 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
27
27
 
28
28
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
29
 
30
+ const isWebcamProcessingReliable = (0, _utils.isGPUAvailable)();
31
+
30
32
  const ProctorApp = _ref => {
31
33
  let {
32
34
  proctoringIdentifier,
@@ -35,7 +37,8 @@ const ProctorApp = _ref => {
35
37
  userCount: true,
36
38
  tabSwitch: true,
37
39
  fullscreenExit: true,
38
- lookedAway: true
40
+ lookedAway: true,
41
+ isWebcamDataReliable: true
39
42
  },
40
43
  sendData = () => {},
41
44
  shouldSendDataOnBreach = false
@@ -43,7 +46,6 @@ const ProctorApp = _ref => {
43
46
  const webcamReference = (0, _react.useRef)(null);
44
47
  const canvasReference = (0, _react.useRef)(null);
45
48
  const statistics = (0, _react.useRef)(_defaults.INITIAL_STATISTICS);
46
- const gpuAvailable = (0, _utils.isGPUAvailable)();
47
49
  const [audioPermission, setAudioPermission] = (0, _react.useState)(false);
48
50
  const [videoPermission, setVideoPermission] = (0, _react.useState)(false);
49
51
  const firstFullScreenDone = (0, _react.useRef)(false);
@@ -52,34 +54,27 @@ const ProctorApp = _ref => {
52
54
  setFullscreen,
53
55
  fullScreenExitCount
54
56
  } = (0, _hooks.useFullscreenData)(firstFullScreenDone);
55
- const [userCount, lookedAwayCount] = gpuAvailable ? (0, _useWebcamData.default)(webcamReference, canvasReference) : [-1, -1];
57
+ const [userCount, lookedAwayCount, isWebcamDataReliable] = (0, _useWebcamData.default)(webcamReference, canvasReference);
56
58
  const tabSwitchCount = (0, _hooks.useTabSwitchCount)(firstFullScreenDone);
57
- (0, _react.useEffect)(() => {
58
- if (!gpuAvailable & shouldSendDataOnBreach) {
59
- (0, _utils.sendDataOnBreach)(statistics, {
60
- userCount,
61
- tabSwitchCount,
62
- fullScreenExitCount,
63
- lookedAwayCount
64
- }, proctoringIdentifier, sendData);
65
- }
66
- }, []);
67
59
  (0, _react.useEffect)(() => {
68
60
  (0, _utils.removeStatsFromLocalStorage)(proctoringIdentifier);
69
61
  }, [proctoringIdentifier]);
70
62
  (0, _react.useEffect)(() => {
63
+ const currentStats = {
64
+ userCount,
65
+ tabSwitchCount,
66
+ fullScreenExitCount,
67
+ lookedAwayCount,
68
+ isWebcamDataReliable: isWebcamProcessingReliable
69
+ };
70
+
71
71
  if (shouldSendDataOnBreach) {
72
- (0, _utils.sendDataOnBreach)(statistics, {
73
- userCount,
74
- tabSwitchCount,
75
- fullScreenExitCount,
76
- lookedAwayCount
77
- }, proctoringIdentifier, sendData);
72
+ (0, _utils.sendDataOnBreach)(statistics, currentStats, proctoringIdentifier, sendData, webcamReference);
78
73
  }
79
74
 
80
- (0, _utils.updateStatistics)(statistics, tabSwitchCount, fullScreenExitCount, lookedAwayCount, userCount);
75
+ (0, _utils.updateStatistics)(statistics, currentStats);
81
76
  (0, _utils.addOrUpdateStatsToLocalStorage)(proctoringIdentifier, statistics.current);
82
- }, [userCount, tabSwitchCount, fullScreenExitCount, lookedAwayCount, proctoringIdentifier, sendData, shouldSendDataOnBreach]);
77
+ }, [userCount, tabSwitchCount, fullScreenExitCount, lookedAwayCount, isWebcamDataReliable, proctoringIdentifier, sendData, shouldSendDataOnBreach]);
83
78
 
84
79
  if (proctoringIdentifier === undefined) {
85
80
  // todo
@@ -59,6 +59,7 @@ const ActivityTracker = _ref => {
59
59
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactWebcam.default, {
60
60
  audio: true,
61
61
  muted: true,
62
+ screenshotFormat: "image/jpeg",
62
63
  ref: webcamReference,
63
64
  onUserMedia: stream => {
64
65
  if (!isChrome) {
@@ -7,6 +7,7 @@ exports.initialValues = exports.gpuTypes = exports.glancePercentageToPass = expo
7
7
  const initialValues = {
8
8
  tabSwitchCount: 0,
9
9
  userCount: 0,
10
+ isWebcamDataReliable: true,
10
11
  isWatching: true,
11
12
  canOpenFullScreen: false,
12
13
  fullScreenExitCount: 0,
@@ -18,7 +19,8 @@ const INITIAL_STATISTICS = {
18
19
  TAB_SWITCH_COUNT: initialValues.tabSwitchCount,
19
20
  FULLSCREEN_EXIT_COUNT: initialValues.fullScreenExitCount,
20
21
  LOOKED_AWAY_COUNT: initialValues.lookedAwayCount,
21
- USER_COUNT_MAX: initialValues.userCount
22
+ USER_COUNT_MAX: initialValues.userCount,
23
+ IS_WEBCAM_DATA_RELIABLE: initialValues.isWebcamDataReliable
22
24
  };
23
25
  exports.INITIAL_STATISTICS = INITIAL_STATISTICS;
24
26
  const bodyPixConfigs = {
@@ -36,5 +38,5 @@ const glancePercentageToPass = 60;
36
38
  exports.glancePercentageToPass = glancePercentageToPass;
37
39
  const evaluateVideoIntervalInSeconds = 1;
38
40
  exports.evaluateVideoIntervalInSeconds = evaluateVideoIntervalInSeconds;
39
- const gpuTypes = ["apple", "amd", "radeon", "nvidia", "geforce"];
41
+ const gpuTypes = ["intel", "apple", "amd", "radeon", "nvidia", "geforce"];
40
42
  exports.gpuTypes = gpuTypes;
@@ -47,40 +47,42 @@ function useWebcamData(webcamReference, canvasReference) {
47
47
  const [isWatching, setIsWatching] = (0, _react.useState)(_defaults.initialValues.isWatching);
48
48
  const [lookedAwayCount, setLookedAwayCount] = (0, _react.useState)(_defaults.initialValues.lookedAwayCount);
49
49
  (0, _react.useEffect)(() => {
50
- const loadBodyPixModel = async () => {
51
- try {
52
- const network = await bodyPix.load();
53
- setInterval(async () => {
54
- if ((0, _utils.isWebcamVideoValid)(webcamReference)) {
55
- var _users$length;
56
-
57
- const video = webcamReference.current.video;
58
- const {
59
- videoWidth,
60
- videoHeight
61
- } = video;
62
- video.width = videoWidth;
63
- video.height = videoHeight;
64
- canvasReference.current.width = videoWidth;
65
- canvasReference.current.height = videoHeight;
66
- const users = await getUsers(network, video);
67
- const count = (_users$length = users === null || users === void 0 ? void 0 : users.length) !== null && _users$length !== void 0 ? _users$length : 0;
68
- setUserCount(count);
69
-
70
- if (count) {
71
- setIsWatching(getIsWatching(network, video));
72
- } else {
73
- setIsWatching(false);
50
+ if ((0, _utils.isGPUAvailable)()) {
51
+ const loadBodyPixModel = async () => {
52
+ try {
53
+ const network = await bodyPix.load();
54
+ setInterval(async () => {
55
+ if ((0, _utils.isWebcamVideoValid)(webcamReference)) {
56
+ var _users$length;
57
+
58
+ const video = webcamReference.current.video;
59
+ const {
60
+ videoWidth,
61
+ videoHeight
62
+ } = video;
63
+ video.width = videoWidth;
64
+ video.height = videoHeight;
65
+ canvasReference.current.width = videoWidth;
66
+ canvasReference.current.height = videoHeight;
67
+ const users = await getUsers(network, video);
68
+ const count = (_users$length = users === null || users === void 0 ? void 0 : users.length) !== null && _users$length !== void 0 ? _users$length : 0;
69
+ setUserCount(count);
70
+
71
+ if (count) {
72
+ setIsWatching(getIsWatching(network, video));
73
+ } else {
74
+ setIsWatching(false);
75
+ }
74
76
  }
75
- }
76
- }, _defaults.evaluateVideoIntervalInSeconds * 1000);
77
- } catch (err) {
78
- console.log("Error Trace:", err);
79
- return;
80
- }
81
- };
82
-
83
- loadBodyPixModel();
77
+ }, _defaults.evaluateVideoIntervalInSeconds * 1000);
78
+ } catch (err) {
79
+ console.log("Error Trace:", err);
80
+ return;
81
+ }
82
+ };
83
+
84
+ loadBodyPixModel();
85
+ }
84
86
  }, [webcamReference, canvasReference]);
85
87
  (0, _react.useEffect)(() => {
86
88
  if (!isWatching) {
@@ -5,30 +5,46 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.sendDataOnBreach = void 0;
7
7
 
8
+ var _ = require(".");
9
+
8
10
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
9
11
 
10
12
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
11
13
 
12
14
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
15
 
14
- const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendData) => {
16
+ const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendData, webcamReference) => {
15
17
  const {
16
18
  userCount,
17
19
  tabSwitchCount,
18
20
  fullScreenExitCount,
19
- lookedAwayCount
21
+ lookedAwayCount,
22
+ isWebcamDataReliable
20
23
  } = currentData;
21
24
  const timestamp = Date.now();
22
25
  const data = statistics.current;
23
26
 
27
+ if (data.IS_WEBCAM_DATA_RELIABLE !== isWebcamDataReliable) {
28
+ sendData({
29
+ proctoringIdentifier,
30
+ breach: "IS_WEBCAM_DATA_RELIABLE",
31
+ timestamp,
32
+ data: _objectSpread(_objectSpread({}, data), {}, {
33
+ IS_WEBCAM_DATA_RELIABLE: isWebcamDataReliable
34
+ })
35
+ });
36
+ }
37
+
24
38
  if (data.USER_COUNT_MAX < userCount) {
39
+ const webcamSnapshot = (0, _.captureWebcamSnapshot)(webcamReference);
25
40
  sendData({
26
41
  proctoringIdentifier,
27
42
  breach: "USER_COUNT_MAX",
28
43
  timestamp,
29
44
  data: _objectSpread(_objectSpread({}, data), {}, {
30
45
  USER_COUNT_MAX: userCount
31
- })
46
+ }),
47
+ webcamSnapshot
32
48
  });
33
49
  }
34
50
 
@@ -55,13 +71,15 @@ const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendDat
55
71
  }
56
72
 
57
73
  if (data.LOOKED_AWAY_COUNT !== lookedAwayCount) {
74
+ const webcamSnapshot = (0, _.captureWebcamSnapshot)(webcamReference);
58
75
  sendData({
59
76
  proctoringIdentifier,
60
77
  breach: "LOOKED_AWAY_COUNT",
61
78
  timestamp,
62
79
  data: _objectSpread(_objectSpread({}, data), {}, {
63
80
  LOOKED_AWAY_COUNT: lookedAwayCount
64
- })
81
+ }),
82
+ webcamSnapshot
65
83
  });
66
84
  }
67
85
  };
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
2
 
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isGPUAvailable = void 0;
7
+
3
8
  require("core-js/modules/web.dom-collections.iterator.js");
4
9
 
5
10
  require("core-js/modules/es.array.includes.js");
@@ -19,4 +24,6 @@ const isGPUAvailable = () => {
19
24
  }
20
25
 
21
26
  return false;
22
- };
27
+ };
28
+
29
+ exports.isGPUAvailable = isGPUAvailable;
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "addOrUpdateStatsToLocalStorage", {
9
9
  return _localStorageUtils.addOrUpdateStatsToLocalStorage;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "captureWebcamSnapshot", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _webcamMicrophoneUtils.captureWebcamSnapshot;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "getAudioPermission", {
13
19
  enumerable: true,
14
20
  get: function get() {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.updateVideoPermissions = exports.updateStatistics = exports.updateAudioPermissions = exports.isWebcamVideoValid = exports.getVideoPermissionQuery = exports.getVideoPermission = exports.getGlancePercentage = exports.getAudioVideoPermission = exports.getAudioPermissionQuery = exports.getAudioPermission = void 0;
6
+ exports.updateVideoPermissions = exports.updateStatistics = exports.updateAudioPermissions = exports.isWebcamVideoValid = exports.getVideoPermissionQuery = exports.getVideoPermission = exports.getGlancePercentage = exports.getAudioVideoPermission = exports.getAudioPermissionQuery = exports.getAudioPermission = exports.captureWebcamSnapshot = void 0;
7
7
 
8
8
  var _ = require(".");
9
9
 
@@ -11,11 +11,19 @@ const isWebcamVideoValid = webcamReference => webcamReference !== null && webcam
11
11
 
12
12
  exports.isWebcamVideoValid = isWebcamVideoValid;
13
13
 
14
- const updateStatistics = (statistics, tabSwitchCount, fullScreenExitCount, lookedAwayCount, userCount) => {
14
+ const updateStatistics = (statistics, currentStats) => {
15
+ const {
16
+ tabSwitchCount,
17
+ fullScreenExitCount,
18
+ lookedAwayCount,
19
+ userCount,
20
+ isWebcamDataReliable
21
+ } = currentStats;
15
22
  statistics.current.TAB_SWITCH_COUNT = tabSwitchCount;
16
23
  statistics.current.FULLSCREEN_EXIT_COUNT = fullScreenExitCount;
17
24
  statistics.current.LOOKED_AWAY_COUNT = lookedAwayCount;
18
25
  statistics.current.USER_COUNT_MAX = Math.max(userCount, statistics.current.USER_COUNT_MAX);
26
+ statistics.current.IS_WEBCAM_DATA_RELIABLE = isWebcamDataReliable;
19
27
  };
20
28
 
21
29
  exports.updateStatistics = updateStatistics;
@@ -112,4 +120,10 @@ const getAudioPermissionQuery = () => navigator.permissions.query({
112
120
  name: "microphone"
113
121
  });
114
122
 
115
- exports.getAudioPermissionQuery = getAudioPermissionQuery;
123
+ exports.getAudioPermissionQuery = getAudioPermissionQuery;
124
+
125
+ const captureWebcamSnapshot = webcamReference => {
126
+ return webcamReference.current.getScreenshot();
127
+ };
128
+
129
+ exports.captureWebcamSnapshot = captureWebcamSnapshot;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newtonschool/react_proctoring_library",
3
- "version": "0.0.10",
3
+ "version": "0.0.13",
4
4
  "description": "Used to proctor online tests",
5
5
  "author": "ayushkagrawal,shreyachandra",
6
6
  "main": "dist/index.js",