@newtonschool/react_proctoring_library 0.0.12 → 0.0.15

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.
@@ -7,6 +7,8 @@ exports.default = exports.ProctorApp = void 0;
7
7
 
8
8
  require("core-js/modules/web.dom-collections.iterator.js");
9
9
 
10
+ require("core-js/modules/es.promise.js");
11
+
10
12
  var _react = _interopRequireWildcard(require("react"));
11
13
 
12
14
  var _ = require(".");
@@ -21,73 +23,135 @@ var _permissions = require("./permissions");
21
23
 
22
24
  var _useWebcamData = _interopRequireDefault(require("../hooks/useWebcamData"));
23
25
 
26
+ var _breachUtils = require("../utils/breachUtils");
27
+
28
+ var _webcamMicrophoneUtils = require("../utils/webcamMicrophoneUtils");
29
+
24
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
31
 
26
32
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
33
 
28
34
  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
35
 
36
+ 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; }
37
+
38
+ 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; }
39
+
40
+ 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; }
41
+
42
+ const isWebcamProcessingReliable = (0, _utils.isGPUAvailable)();
43
+
30
44
  const ProctorApp = _ref => {
31
45
  let {
32
46
  proctoringIdentifier,
33
47
  children,
34
- proctoringParams = {
35
- userCount: true,
36
- tabSwitch: true,
37
- fullscreenExit: true,
38
- lookedAway: true,
39
- isWebcamDataReliable: true
40
- },
41
- sendData = () => {},
42
- shouldSendDataOnBreach = false
48
+ config,
49
+ getProctorParamValues = () => {},
50
+ getWebcamSnapshot = () => {},
51
+ getScreengrab = () => {}
43
52
  } = _ref;
44
53
  const webcamReference = (0, _react.useRef)(null);
45
54
  const canvasReference = (0, _react.useRef)(null);
55
+ const screenshareReference = (0, _react.useRef)(null);
46
56
  const statistics = (0, _react.useRef)(_defaults.INITIAL_STATISTICS);
47
- const [audioPermission, setAudioPermission] = (0, _react.useState)(false);
48
- const [videoPermission, setVideoPermission] = (0, _react.useState)(false);
57
+
58
+ const proctorParams = _objectSpread(_objectSpread({}, {
59
+ people: true,
60
+ tabSwitch: true,
61
+ fullscreenExit: true,
62
+ lookedAway: true
63
+ }), config.proctorParams);
64
+
65
+ const {
66
+ recurring = false,
67
+ recurringFetchInterval = 0
68
+ } = config;
69
+ const [audioPermission, setAudioPermission] = (0, _react.useState)();
70
+ const [videoPermission, setVideoPermission] = (0, _react.useState)();
71
+ const [screensharePermission, setScreensharePermission] = (0, _react.useState)();
49
72
  const firstFullScreenDone = (0, _react.useRef)(false);
73
+ const recurringFetchIntervalRef = (0, _react.useRef)(null);
74
+ const sendScreengrab = (0, _react.useCallback)(async function () {
75
+ let isBreach = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
76
+ let breachData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
77
+ const screenshot = await (0, _webcamMicrophoneUtils.captureScreenshot)();
78
+ getScreengrab(proctoringIdentifier, screenshot, isBreach, breachData.breachedParam);
79
+ }, [getScreengrab, proctoringIdentifier]);
80
+ (0, _react.useEffect)(() => {
81
+ if (recurring) {
82
+ recurringFetchIntervalRef.current = setInterval(() => {
83
+ getProctorParamValues(proctoringIdentifier, statistics.current, false);
84
+ const webcamSnapshot = (0, _utils.captureWebcamSnapshot)(webcamReference);
85
+
86
+ if (webcamReference) {
87
+ getWebcamSnapshot(proctoringIdentifier, webcamSnapshot, false);
88
+ }
89
+
90
+ sendScreengrab();
91
+ }, recurringFetchInterval);
92
+ }
93
+
94
+ return () => {
95
+ clearInterval(recurringFetchIntervalRef.current);
96
+ };
97
+ }, [recurring, recurringFetchInterval, proctoringIdentifier, getWebcamSnapshot, getProctorParamValues, sendScreengrab]);
50
98
  const {
51
99
  isFullscreen,
52
100
  setFullscreen,
53
101
  fullScreenExitCount
54
102
  } = (0, _hooks.useFullscreenData)(firstFullScreenDone);
55
- const [userCount, lookedAwayCount, isWebcamDataReliable] = (0, _useWebcamData.default)(webcamReference, canvasReference);
103
+ const [userCount, lookedAwayCount] = (0, _useWebcamData.default)(webcamReference, canvasReference);
56
104
  const tabSwitchCount = (0, _hooks.useTabSwitchCount)(firstFullScreenDone);
57
105
  (0, _react.useEffect)(() => {
58
- (0, _utils.removeStatsFromLocalStorage)(proctoringIdentifier);
59
- }, [proctoringIdentifier]);
60
- (0, _react.useEffect)(() => {
61
- if (shouldSendDataOnBreach) {
62
- (0, _utils.sendDataOnBreach)(statistics, {
63
- userCount,
64
- tabSwitchCount,
65
- fullScreenExitCount,
66
- lookedAwayCount,
67
- isWebcamDataReliable
68
- }, proctoringIdentifier, sendData);
106
+ const currentStats = {
107
+ userCount,
108
+ tabSwitchCount,
109
+ fullScreenExitCount,
110
+ lookedAwayCount,
111
+ isWebcamDataReliable: isWebcamProcessingReliable
112
+ };
113
+ const breachData = (0, _breachUtils.getDataOnBreach)(statistics, currentStats);
114
+
115
+ if (breachData) {
116
+ getProctorParamValues(breachData.proctoringIdentifier, breachData.data, true, breachData.breachedParam);
117
+
118
+ if (breachData.breachedParam === "LOOKED_AWAY_COUNT" || breachData.breachedParam === "USER_COUNT_MAX") {
119
+ const webcamSnapshot = (0, _utils.captureWebcamSnapshot)(webcamReference);
120
+
121
+ if (webcamSnapshot) {
122
+ getWebcamSnapshot(proctoringIdentifier, webcamSnapshot, true, breachData.breachedParam);
123
+ }
124
+ } else {
125
+ sendScreengrab(true, breachData);
126
+ }
69
127
  }
70
128
 
71
- (0, _utils.updateStatistics)(statistics, tabSwitchCount, fullScreenExitCount, lookedAwayCount, userCount, isWebcamDataReliable);
72
- (0, _utils.addOrUpdateStatsToLocalStorage)(proctoringIdentifier, statistics.current);
73
- }, [userCount, tabSwitchCount, fullScreenExitCount, lookedAwayCount, isWebcamDataReliable, proctoringIdentifier, sendData, shouldSendDataOnBreach]);
129
+ (0, _utils.updateStatistics)(statistics, currentStats);
130
+ }, [userCount, tabSwitchCount, fullScreenExitCount, lookedAwayCount, getProctorParamValues, getWebcamSnapshot, sendScreengrab, proctoringIdentifier]);
131
+ const updateScreensharePermission = (0, _react.useCallback)(() => {
132
+ (0, _webcamMicrophoneUtils.setupScreensharePermission)(setScreensharePermission, screenshareReference);
133
+ }, []);
74
134
 
75
135
  if (proctoringIdentifier === undefined) {
76
136
  // todo
77
137
  return;
78
138
  }
79
139
 
80
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_permissions.Permission, {
140
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isFullscreen && audioPermission && videoPermission && screensharePermission && children, /*#__PURE__*/_react.default.createElement(_permissions.Permission, {
81
141
  isFullscreen: isFullscreen,
82
142
  audioPermisison: audioPermission,
83
143
  videoPermission: videoPermission,
84
- setFullscreen: setFullscreen
144
+ setFullscreen: setFullscreen,
145
+ screensharePermission: screensharePermission,
146
+ updateScreensharePermission: updateScreensharePermission
85
147
  }), /*#__PURE__*/_react.default.createElement(_.ActivityTracker, {
86
148
  setAudioPermission: setAudioPermission,
87
149
  setVideoPermission: setVideoPermission,
88
150
  webcamReference: webcamReference,
89
- canvasReference: canvasReference
90
- }), isFullscreen && audioPermission && videoPermission && children);
151
+ canvasReference: canvasReference,
152
+ screenshareReference: screenshareReference,
153
+ updateScreensharePermission: updateScreensharePermission
154
+ }));
91
155
  };
92
156
 
93
157
  exports.ProctorApp = ProctorApp;
@@ -34,12 +34,15 @@ const ActivityTracker = _ref => {
34
34
  webcamReference,
35
35
  canvasReference,
36
36
  setAudioPermission,
37
- setVideoPermission
37
+ setVideoPermission,
38
+ updateScreensharePermission,
39
+ screenshareReference
38
40
  } = _ref;
39
41
  (0, _react.useEffect)(() => {
40
42
  if (isChrome) {
41
43
  (0, _webcamMicrophoneUtils.updateVideoPermissions)(setVideoPermission);
42
44
  (0, _webcamMicrophoneUtils.updateAudioPermissions)(setAudioPermission);
45
+ updateScreensharePermission();
43
46
  (0, _webcamMicrophoneUtils.getVideoPermissionQuery)().then(status => {
44
47
  status.onchange = evt => {
45
48
  (0, _webcamMicrophoneUtils.updateVideoPermissions)(setVideoPermission);
@@ -55,10 +58,11 @@ const ActivityTracker = _ref => {
55
58
  (0, _webcamMicrophoneUtils.updateAudioPermissions)("Audio Permission", err);
56
59
  });
57
60
  }
58
- }, [setVideoPermission, setAudioPermission]);
61
+ }, [setVideoPermission, setAudioPermission, updateScreensharePermission]);
59
62
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactWebcam.default, {
60
63
  audio: true,
61
64
  muted: true,
65
+ screenshotFormat: "image/jpeg",
62
66
  ref: webcamReference,
63
67
  onUserMedia: stream => {
64
68
  if (!isChrome) {
@@ -136,7 +140,12 @@ const ActivityTracker = _ref => {
136
140
  className: "captured-video-canvas"
137
141
  }), /*#__PURE__*/_react.default.createElement("canvas", {
138
142
  ref: canvasReference,
139
- className: "captured-video-canvas"
143
+ className: "captured-video-canvas",
144
+ id: "wc-ref"
145
+ }), /*#__PURE__*/_react.default.createElement("video", {
146
+ ref: screenshareReference,
147
+ className: "captured-video-canvas",
148
+ id: "ss-ref"
140
149
  }));
141
150
  };
142
151
 
@@ -30,9 +30,12 @@ const Permission = _ref => {
30
30
  isFullscreen,
31
31
  audioPermisison,
32
32
  videoPermission,
33
- setFullscreen
33
+ setFullscreen,
34
+ screensharePermission,
35
+ trackScreenshare,
36
+ updateScreensharePermission
34
37
  } = _ref;
35
- const showPermissionModal = !isFullscreen || !audioPermisison || !videoPermission;
38
+ const showPermissionModal = isFullscreen === false || audioPermisison === false || videoPermission === false || trackScreenshare && screensharePermission === false;
36
39
  return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal, {
37
40
  show: showPermissionModal,
38
41
  size: "lg",
@@ -41,7 +44,7 @@ const Permission = _ref => {
41
44
  centered: true
42
45
  }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Header, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Title, null, text.PERMISSION_TITLE)), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Body, {
43
46
  className: "font-medium"
44
- }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
47
+ }, /*#__PURE__*/_react.default.createElement("div", {
45
48
  style: {
46
49
  borderRadius: "20px"
47
50
  }
@@ -58,8 +61,13 @@ const Permission = _ref => {
58
61
  }), text.VIDEO_UNSUPPORTED_IN_BROWSER)), /*#__PURE__*/_react.default.createElement(_permissionBody.PermissionBody, {
59
62
  showFullscreenText: !isFullscreen,
60
63
  showAudioPermissionText: !audioPermisison,
61
- showVideoPermissionText: !videoPermission
62
- }))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Footer, null, !isFullscreen && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
64
+ showVideoPermissionText: !videoPermission,
65
+ showScreensharePermission: !screensharePermission && trackScreenshare
66
+ })), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Footer, null, !screensharePermission && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
67
+ onClick: () => {
68
+ updateScreensharePermission();
69
+ }
70
+ }, text.ALLOW_SCREENSHARE), !isFullscreen && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
63
71
  variant: "primary",
64
72
  onClick: () => {
65
73
  setFullscreen();
@@ -25,11 +25,16 @@ const PermissionBody = _ref => {
25
25
  let {
26
26
  showFullscreenText,
27
27
  showAudioPermissionText,
28
- showVideoPermissionText
28
+ showVideoPermissionText,
29
+ showScreensharePermission
29
30
  } = _ref;
30
31
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
31
32
  className: "mb-2"
32
- }, text.PERMISSION_GENERIC), showAudioPermissionText && showVideoPermissionText ? /*#__PURE__*/_react.default.createElement("div", {
33
+ }, text.PERMISSION_GENERIC), showScreensharePermission && /*#__PURE__*/_react.default.createElement("div", {
34
+ className: "mb-2"
35
+ }, /*#__PURE__*/_react.default.createElement("span", {
36
+ className: "pr-2 font-weight-bold"
37
+ }, "Screenshare:"), text.PERMISSION_SCREENSHARE), showAudioPermissionText && showVideoPermissionText ? /*#__PURE__*/_react.default.createElement("div", {
33
38
  className: "mb-2"
34
39
  }, /*#__PURE__*/_react.default.createElement("span", {
35
40
  className: "pr-2 font-weight-bold"
@@ -38,5 +38,5 @@ const glancePercentageToPass = 60;
38
38
  exports.glancePercentageToPass = glancePercentageToPass;
39
39
  const evaluateVideoIntervalInSeconds = 1;
40
40
  exports.evaluateVideoIntervalInSeconds = evaluateVideoIntervalInSeconds;
41
- const gpuTypes = ["apple", "amd", "radeon", "nvidia", "geforce"];
41
+ const gpuTypes = ["intel", "apple", "amd", "radeon", "nvidia", "geforce"];
42
42
  exports.gpuTypes = gpuTypes;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.WATCHING_SCREEN = exports.VIDEO_UNSUPPORTED_IN_BROWSER = exports.USER_COUNT_LABEL = exports.REQUEST_VIDEO_AUDIO_PERMISSIONS_HEADING = exports.REQUEST_VIDEO_AUDIO_PERMISSIONS_DESC = exports.REQUEST_PERMISSION = exports.PERMISSION_VIDEO = exports.PERMISSION_TITLE = exports.PERMISSION_GENERIC = exports.PERMISSION_FULLSCREEN = exports.PERMISSION_AUDIO_VIDEO = exports.PERMISSION_AUDIO = exports.NO_CAMERA_AVAILABLE = exports.NO_AUDIO_DEVICE_AVAILABLE = exports.NOT_WATCHING_SCREEN = exports.MESSAGE = exports.FULLSCREEN_ERROR_MESSAGE = exports.DENY_FULLSCREEN = exports.CAMERA_UNAVAILABLE_INSECURE_CONN = exports.BROWSER_BLOCKED_PERMISSION_RESOLVED_RECHECK = exports.BROWSER_BLOCKED_PERMISSION_NEXT_STEP = exports.BROWSER_BLOCKED_PERMISSION_DIRECTION = exports.BROWSER_BLOCKED_PERMISSION_DIALOG = exports.BROWSER_BLOCKED_PERMISSION = exports.ALLOW_FULLSCREEN = void 0;
6
+ exports.WATCHING_SCREEN = exports.VIDEO_UNSUPPORTED_IN_BROWSER = exports.USER_COUNT_LABEL = exports.REQUEST_VIDEO_AUDIO_PERMISSIONS_HEADING = exports.REQUEST_VIDEO_AUDIO_PERMISSIONS_DESC = exports.REQUEST_PERMISSION = exports.PERMISSION_VIDEO = exports.PERMISSION_TITLE = exports.PERMISSION_SCREENSHARE = exports.PERMISSION_GENERIC = exports.PERMISSION_FULLSCREEN = exports.PERMISSION_AUDIO_VIDEO = exports.PERMISSION_AUDIO = exports.NO_CAMERA_AVAILABLE = exports.NO_AUDIO_DEVICE_AVAILABLE = exports.NOT_WATCHING_SCREEN = exports.MESSAGE = exports.FULLSCREEN_ERROR_MESSAGE = exports.DENY_FULLSCREEN = exports.CAMERA_UNAVAILABLE_INSECURE_CONN = exports.BROWSER_BLOCKED_PERMISSION_RESOLVED_RECHECK = exports.BROWSER_BLOCKED_PERMISSION_NEXT_STEP = exports.BROWSER_BLOCKED_PERMISSION_DIRECTION = exports.BROWSER_BLOCKED_PERMISSION_DIALOG = exports.BROWSER_BLOCKED_PERMISSION = exports.ALLOW_SCREENSHARE = exports.ALLOW_FULLSCREEN = void 0;
7
7
  const WATCHING_SCREEN = "You are watching the screen";
8
8
  exports.WATCHING_SCREEN = WATCHING_SCREEN;
9
9
  const NOT_WATCHING_SCREEN = "You are not watching the screen";
@@ -20,6 +20,8 @@ const DENY_FULLSCREEN = "Deny";
20
20
  exports.DENY_FULLSCREEN = DENY_FULLSCREEN;
21
21
  const ALLOW_FULLSCREEN = "Switch to Fullscreen";
22
22
  exports.ALLOW_FULLSCREEN = ALLOW_FULLSCREEN;
23
+ const ALLOW_SCREENSHARE = "Share Screen";
24
+ exports.ALLOW_SCREENSHARE = ALLOW_SCREENSHARE;
23
25
  const NO_CAMERA_AVAILABLE = "No Camera available for use.";
24
26
  exports.NO_CAMERA_AVAILABLE = NO_CAMERA_AVAILABLE;
25
27
  const NO_AUDIO_DEVICE_AVAILABLE = "No audio device available for use";
@@ -53,4 +55,6 @@ exports.PERMISSION_AUDIO_VIDEO = PERMISSION_AUDIO_VIDEO;
53
55
  const PERMISSION_VIDEO = "Your browser or system settings have disallowed Camera permissions. Please permit this website to access the camera. Refresh after you've given the permission to access the screen";
54
56
  exports.PERMISSION_VIDEO = PERMISSION_VIDEO;
55
57
  const PERMISSION_AUDIO = "Your browser or system settings have disallowed Microphone permissions. Please permit this website to access the microphone. Refresh after you've given the permission to access the screen";
56
- exports.PERMISSION_AUDIO = PERMISSION_AUDIO;
58
+ exports.PERMISSION_AUDIO = PERMISSION_AUDIO;
59
+ const PERMISSION_SCREENSHARE = "Please share your entire screen";
60
+ exports.PERMISSION_SCREENSHARE = PERMISSION_SCREENSHARE;
@@ -42,18 +42,12 @@ const getIsWatching = async (network, video) => {
42
42
  }
43
43
  };
44
44
 
45
- const deviceHasGPU = (0, _utils.isGPUAvailable)();
46
-
47
45
  function useWebcamData(webcamReference, canvasReference) {
48
46
  const [userCount, setUserCount] = (0, _react.useState)(_defaults.initialValues.userCount);
49
47
  const [isWatching, setIsWatching] = (0, _react.useState)(_defaults.initialValues.isWatching);
50
48
  const [lookedAwayCount, setLookedAwayCount] = (0, _react.useState)(_defaults.initialValues.lookedAwayCount);
51
- const [isWebcamDataReliable, setIsWebcamDataReliable] = (0, _react.useState)(_defaults.initialValues.isWebcamDataReliable);
52
- (0, _react.useEffect)(() => {
53
- setIsWebcamDataReliable(deviceHasGPU);
54
- }, []);
55
49
  (0, _react.useEffect)(() => {
56
- if (deviceHasGPU) {
50
+ if ((0, _utils.isGPUAvailable)()) {
57
51
  const loadBodyPixModel = async () => {
58
52
  try {
59
53
  const network = await bodyPix.load();
@@ -95,5 +89,5 @@ function useWebcamData(webcamReference, canvasReference) {
95
89
  setLookedAwayCount(lookedAwayCount => lookedAwayCount + 1);
96
90
  }
97
91
  }, [isWatching]);
98
- return [userCount, lookedAwayCount, isWebcamDataReliable];
92
+ return [userCount, lookedAwayCount];
99
93
  }
package/dist/index.js CHANGED
@@ -9,13 +9,5 @@ Object.defineProperty(exports, "ProctorApp", {
9
9
  return _components.ProctorApp;
10
10
  }
11
11
  });
12
- Object.defineProperty(exports, "getStatistics", {
13
- enumerable: true,
14
- get: function get() {
15
- return _utils.getStatistics;
16
- }
17
- });
18
-
19
- var _components = require("./components");
20
12
 
21
- var _utils = require("./utils");
13
+ var _components = require("./components");
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.sendDataOnBreach = void 0;
6
+ exports.getDataOnBreach = void 0;
7
7
 
8
8
  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
9
 
@@ -11,7 +11,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
11
11
 
12
12
  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
13
 
14
- const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendData) => {
14
+ const getDataOnBreach = (statistics, currentData) => {
15
15
  const {
16
16
  userCount,
17
17
  tabSwitchCount,
@@ -23,59 +23,54 @@ const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendDat
23
23
  const data = statistics.current;
24
24
 
25
25
  if (data.IS_WEBCAM_DATA_RELIABLE !== isWebcamDataReliable) {
26
- sendData({
27
- proctoringIdentifier,
28
- breach: "IS_WEBCAM_DATA_RELIABLE",
26
+ return {
27
+ breachedParam: "IS_WEBCAM_DATA_RELIABLE",
29
28
  timestamp,
30
29
  data: _objectSpread(_objectSpread({}, data), {}, {
31
30
  IS_WEBCAM_DATA_RELIABLE: isWebcamDataReliable
32
31
  })
33
- });
32
+ };
34
33
  }
35
34
 
36
35
  if (data.USER_COUNT_MAX < userCount) {
37
- sendData({
38
- proctoringIdentifier,
39
- breach: "USER_COUNT_MAX",
36
+ return {
37
+ breachedParam: "USER_COUNT_MAX",
40
38
  timestamp,
41
39
  data: _objectSpread(_objectSpread({}, data), {}, {
42
40
  USER_COUNT_MAX: userCount
43
41
  })
44
- });
42
+ };
45
43
  }
46
44
 
47
45
  if (data.TAB_SWITCH_COUNT !== tabSwitchCount) {
48
- sendData({
49
- proctoringIdentifier,
50
- breach: "TAB_SWITCH_COUNT",
46
+ return {
47
+ breachedParam: "TAB_SWITCH_COUNT",
51
48
  timestamp,
52
49
  data: _objectSpread(_objectSpread({}, data), {}, {
53
50
  TAB_SWITCH_COUNT: tabSwitchCount
54
51
  })
55
- });
52
+ };
56
53
  }
57
54
 
58
55
  if (data.FULLSCREEN_EXIT_COUNT !== fullScreenExitCount) {
59
- sendData({
60
- proctoringIdentifier,
61
- breach: "FULLSCREEN_EXIT_COUNT",
56
+ return {
57
+ breachedParam: "FULLSCREEN_EXIT_COUNT",
62
58
  timestamp,
63
59
  data: _objectSpread(_objectSpread({}, data), {}, {
64
60
  FULLSCREEN_EXIT_COUNT: fullScreenExitCount
65
61
  })
66
- });
62
+ };
67
63
  }
68
64
 
69
65
  if (data.LOOKED_AWAY_COUNT !== lookedAwayCount) {
70
- sendData({
71
- proctoringIdentifier,
72
- breach: "LOOKED_AWAY_COUNT",
66
+ return {
67
+ breachedParam: "LOOKED_AWAY_COUNT",
73
68
  timestamp,
74
69
  data: _objectSpread(_objectSpread({}, data), {}, {
75
70
  LOOKED_AWAY_COUNT: lookedAwayCount
76
71
  })
77
- });
72
+ };
78
73
  }
79
74
  };
80
75
 
81
- exports.sendDataOnBreach = sendDataOnBreach;
76
+ exports.getDataOnBreach = getDataOnBreach;
@@ -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,15 +3,42 @@
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.setupScreensharePermission = exports.isWebcamVideoValid = exports.getVideoPermissionQuery = exports.getVideoPermission = exports.getGlancePercentage = exports.getAudioVideoPermission = exports.getAudioPermissionQuery = exports.getAudioPermission = exports.captureWebcamSnapshot = exports.captureScreenshot = void 0;
7
+
8
+ require("core-js/modules/es.regexp.exec.js");
9
+
10
+ require("core-js/modules/es.string.split.js");
11
+
12
+ require("core-js/modules/es.array-buffer.slice.js");
13
+
14
+ require("core-js/modules/es.typed-array.uint8-array.js");
15
+
16
+ require("core-js/modules/es.typed-array.set.js");
17
+
18
+ require("core-js/modules/es.typed-array.sort.js");
19
+
20
+ require("core-js/modules/es.typed-array.to-locale-string.js");
21
+
22
+ require("core-js/modules/es.promise.js");
7
23
 
8
24
  var _ = require(".");
9
25
 
26
+ var _html2canvas = _interopRequireDefault(require("html2canvas"));
27
+
28
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
+
10
30
  const isWebcamVideoValid = webcamReference => webcamReference !== null && webcamReference !== undefined && typeof webcamReference.current !== "undefined" && webcamReference.current !== null && webcamReference.current.video.readyState === 4;
11
31
 
12
32
  exports.isWebcamVideoValid = isWebcamVideoValid;
13
33
 
14
- const updateStatistics = (statistics, tabSwitchCount, fullScreenExitCount, lookedAwayCount, userCount, isWebcamDataReliable) => {
34
+ const updateStatistics = (statistics, currentStats) => {
35
+ const {
36
+ tabSwitchCount,
37
+ fullScreenExitCount,
38
+ lookedAwayCount,
39
+ userCount,
40
+ isWebcamDataReliable
41
+ } = currentStats;
15
42
  statistics.current.TAB_SWITCH_COUNT = tabSwitchCount;
16
43
  statistics.current.FULLSCREEN_EXIT_COUNT = fullScreenExitCount;
17
44
  statistics.current.LOOKED_AWAY_COUNT = lookedAwayCount;
@@ -103,6 +130,34 @@ const updateVideoPermissions = setVideoPermission => {
103
130
 
104
131
  exports.updateVideoPermissions = updateVideoPermissions;
105
132
 
133
+ const setupScreensharePermission = (setScreensharePermission, screenshareReference) => navigator.mediaDevices.getDisplayMedia({
134
+ video: true
135
+ }).then(stream => {
136
+ const track = stream.getTracks()[0];
137
+
138
+ if (track.getSettings().displaySurface === "monitor") {
139
+ screenshareReference.current.srcObject = stream;
140
+
141
+ screenshareReference.current.onloadedmetadata = e => {
142
+ screenshareReference.current.play();
143
+ };
144
+
145
+ track.onended = e => {
146
+ setScreensharePermission(false);
147
+ };
148
+
149
+ setScreensharePermission(true);
150
+ } else {
151
+ screenshareReference.current = null;
152
+ setScreensharePermission(false);
153
+ }
154
+ }).catch(e => {
155
+ screenshareReference.current = null;
156
+ setScreensharePermission(false);
157
+ });
158
+
159
+ exports.setupScreensharePermission = setupScreensharePermission;
160
+
106
161
  const getVideoPermissionQuery = () => navigator.permissions.query({
107
162
  name: "camera"
108
163
  });
@@ -113,4 +168,39 @@ const getAudioPermissionQuery = () => navigator.permissions.query({
113
168
  name: "microphone"
114
169
  });
115
170
 
116
- exports.getAudioPermissionQuery = getAudioPermissionQuery;
171
+ exports.getAudioPermissionQuery = getAudioPermissionQuery;
172
+
173
+ const b64DataURItoBlob = dataURI => {
174
+ const byteString = window.atob(dataURI.split(",")[1]);
175
+ const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
176
+ const u8arr = new Uint8Array(byteString.length);
177
+
178
+ for (let i = 0; i < byteString.length; i += 1) {
179
+ u8arr[i] = byteString.charCodeAt(i);
180
+ }
181
+
182
+ return new Blob([u8arr], {
183
+ type: mimeString
184
+ });
185
+ };
186
+
187
+ const captureWebcamSnapshot = webcamReference => {
188
+ try {
189
+ const b64Snapshot = webcamReference.current.getScreenshot();
190
+ return b64DataURItoBlob(b64Snapshot);
191
+ } catch (e) {// pass
192
+ }
193
+ };
194
+
195
+ exports.captureWebcamSnapshot = captureWebcamSnapshot;
196
+
197
+ const captureScreenshot = async () => {
198
+ try {
199
+ const canvas = await (0, _html2canvas.default)(document.querySelector("#ss-ref"));
200
+ const b64Snapshot = canvas.toDataURL("image/jpeg");
201
+ return b64DataURItoBlob(b64Snapshot);
202
+ } catch (e) {// pass
203
+ }
204
+ };
205
+
206
+ exports.captureScreenshot = captureScreenshot;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newtonschool/react_proctoring_library",
3
- "version": "0.0.12",
3
+ "version": "0.0.15",
4
4
  "description": "Used to proctor online tests",
5
5
  "author": "ayushkagrawal,shreyachandra",
6
6
  "main": "dist/index.js",
@@ -17,6 +17,7 @@
17
17
  "@tensorflow/tfjs": "^3.9.0",
18
18
  "bootstrap": "^5.1.3",
19
19
  "core-js": "^3.22.7",
20
+ "html2canvas": "^1.4.1",
20
21
  "react-bootstrap": "^2.0.4",
21
22
  "react-webcam": "^6.0.0"
22
23
  },