@newtonschool/react_proctoring_library 0.0.13 → 0.0.16
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/dist/components/ProctorApp.js +82 -23
- package/dist/components/activity-tracker/index.js +8 -2
- package/dist/components/permissions/index.js +12 -5
- package/dist/components/permissions/permission-body.js +7 -2
- package/dist/constants/text.js +6 -2
- package/dist/index.js +1 -9
- package/dist/utils/breachUtils.js +20 -31
- package/dist/utils/webcamMicrophoneUtils.js +80 -3
- package/package.json +2 -1
|
@@ -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,44 +23,85 @@ 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
|
+
|
|
30
42
|
const isWebcamProcessingReliable = (0, _utils.isGPUAvailable)();
|
|
31
43
|
|
|
32
44
|
const ProctorApp = _ref => {
|
|
33
45
|
let {
|
|
34
46
|
proctoringIdentifier,
|
|
35
47
|
children,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
lookedAway: true,
|
|
41
|
-
isWebcamDataReliable: true
|
|
42
|
-
},
|
|
43
|
-
sendData = () => {},
|
|
44
|
-
shouldSendDataOnBreach = false
|
|
48
|
+
config,
|
|
49
|
+
getProctorParamValues = () => {},
|
|
50
|
+
getWebcamSnapshot = () => {},
|
|
51
|
+
getScreengrab = () => {}
|
|
45
52
|
} = _ref;
|
|
46
53
|
const webcamReference = (0, _react.useRef)(null);
|
|
47
54
|
const canvasReference = (0, _react.useRef)(null);
|
|
55
|
+
const screenshareReference = (0, _react.useRef)(null);
|
|
48
56
|
const statistics = (0, _react.useRef)(_defaults.INITIAL_STATISTICS);
|
|
49
|
-
|
|
50
|
-
const
|
|
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)();
|
|
51
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]);
|
|
52
98
|
const {
|
|
53
99
|
isFullscreen,
|
|
54
100
|
setFullscreen,
|
|
55
101
|
fullScreenExitCount
|
|
56
102
|
} = (0, _hooks.useFullscreenData)(firstFullScreenDone);
|
|
57
|
-
const [userCount, lookedAwayCount
|
|
103
|
+
const [userCount, lookedAwayCount] = (0, _useWebcamData.default)(webcamReference, canvasReference);
|
|
58
104
|
const tabSwitchCount = (0, _hooks.useTabSwitchCount)(firstFullScreenDone);
|
|
59
|
-
(0, _react.useEffect)(() => {
|
|
60
|
-
(0, _utils.removeStatsFromLocalStorage)(proctoringIdentifier);
|
|
61
|
-
}, [proctoringIdentifier]);
|
|
62
105
|
(0, _react.useEffect)(() => {
|
|
63
106
|
const currentStats = {
|
|
64
107
|
userCount,
|
|
@@ -67,31 +110,47 @@ const ProctorApp = _ref => {
|
|
|
67
110
|
lookedAwayCount,
|
|
68
111
|
isWebcamDataReliable: isWebcamProcessingReliable
|
|
69
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);
|
|
70
120
|
|
|
71
|
-
|
|
72
|
-
|
|
121
|
+
if (webcamSnapshot) {
|
|
122
|
+
getWebcamSnapshot(proctoringIdentifier, webcamSnapshot, true, breachData.breachedParam);
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
sendScreengrab(true, breachData);
|
|
126
|
+
}
|
|
73
127
|
}
|
|
74
128
|
|
|
75
129
|
(0, _utils.updateStatistics)(statistics, currentStats);
|
|
76
|
-
|
|
77
|
-
|
|
130
|
+
}, [userCount, tabSwitchCount, fullScreenExitCount, lookedAwayCount, getProctorParamValues, getWebcamSnapshot, sendScreengrab, proctoringIdentifier]);
|
|
131
|
+
const updateScreensharePermission = (0, _react.useCallback)(() => {
|
|
132
|
+
(0, _webcamMicrophoneUtils.setupScreensharePermission)(setScreensharePermission, screenshareReference);
|
|
133
|
+
}, []);
|
|
78
134
|
|
|
79
135
|
if (proctoringIdentifier === undefined) {
|
|
80
136
|
// todo
|
|
81
137
|
return;
|
|
82
138
|
}
|
|
83
139
|
|
|
84
|
-
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, {
|
|
85
141
|
isFullscreen: isFullscreen,
|
|
86
142
|
audioPermisison: audioPermission,
|
|
87
143
|
videoPermission: videoPermission,
|
|
88
|
-
setFullscreen: setFullscreen
|
|
144
|
+
setFullscreen: setFullscreen,
|
|
145
|
+
screensharePermission: screensharePermission,
|
|
146
|
+
updateScreensharePermission: updateScreensharePermission
|
|
89
147
|
}), /*#__PURE__*/_react.default.createElement(_.ActivityTracker, {
|
|
90
148
|
setAudioPermission: setAudioPermission,
|
|
91
149
|
setVideoPermission: setVideoPermission,
|
|
92
150
|
webcamReference: webcamReference,
|
|
93
|
-
canvasReference: canvasReference
|
|
94
|
-
|
|
151
|
+
canvasReference: canvasReference,
|
|
152
|
+
screenshareReference: screenshareReference
|
|
153
|
+
}));
|
|
95
154
|
};
|
|
96
155
|
|
|
97
156
|
exports.ProctorApp = ProctorApp;
|
|
@@ -34,7 +34,8 @@ const ActivityTracker = _ref => {
|
|
|
34
34
|
webcamReference,
|
|
35
35
|
canvasReference,
|
|
36
36
|
setAudioPermission,
|
|
37
|
-
setVideoPermission
|
|
37
|
+
setVideoPermission,
|
|
38
|
+
screenshareReference
|
|
38
39
|
} = _ref;
|
|
39
40
|
(0, _react.useEffect)(() => {
|
|
40
41
|
if (isChrome) {
|
|
@@ -137,7 +138,12 @@ const ActivityTracker = _ref => {
|
|
|
137
138
|
className: "captured-video-canvas"
|
|
138
139
|
}), /*#__PURE__*/_react.default.createElement("canvas", {
|
|
139
140
|
ref: canvasReference,
|
|
140
|
-
className: "captured-video-canvas"
|
|
141
|
+
className: "captured-video-canvas",
|
|
142
|
+
id: "wc-ref"
|
|
143
|
+
}), /*#__PURE__*/_react.default.createElement("video", {
|
|
144
|
+
ref: screenshareReference,
|
|
145
|
+
className: "captured-video-canvas",
|
|
146
|
+
id: "ss-ref"
|
|
141
147
|
}));
|
|
142
148
|
};
|
|
143
149
|
|
|
@@ -30,9 +30,11 @@ const Permission = _ref => {
|
|
|
30
30
|
isFullscreen,
|
|
31
31
|
audioPermisison,
|
|
32
32
|
videoPermission,
|
|
33
|
-
setFullscreen
|
|
33
|
+
setFullscreen,
|
|
34
|
+
screensharePermission,
|
|
35
|
+
updateScreensharePermission
|
|
34
36
|
} = _ref;
|
|
35
|
-
const showPermissionModal =
|
|
37
|
+
const showPermissionModal = isFullscreen === false || audioPermisison === false || videoPermission === false || !screensharePermission;
|
|
36
38
|
return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal, {
|
|
37
39
|
show: showPermissionModal,
|
|
38
40
|
size: "lg",
|
|
@@ -41,7 +43,7 @@ const Permission = _ref => {
|
|
|
41
43
|
centered: true
|
|
42
44
|
}, /*#__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
45
|
className: "font-medium"
|
|
44
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
46
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
45
47
|
style: {
|
|
46
48
|
borderRadius: "20px"
|
|
47
49
|
}
|
|
@@ -58,8 +60,13 @@ const Permission = _ref => {
|
|
|
58
60
|
}), text.VIDEO_UNSUPPORTED_IN_BROWSER)), /*#__PURE__*/_react.default.createElement(_permissionBody.PermissionBody, {
|
|
59
61
|
showFullscreenText: !isFullscreen,
|
|
60
62
|
showAudioPermissionText: !audioPermisison,
|
|
61
|
-
showVideoPermissionText: !videoPermission
|
|
62
|
-
|
|
63
|
+
showVideoPermissionText: !videoPermission,
|
|
64
|
+
showScreensharePermission: !screensharePermission
|
|
65
|
+
})), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Footer, null, !screensharePermission && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
|
|
66
|
+
onClick: () => {
|
|
67
|
+
updateScreensharePermission();
|
|
68
|
+
}
|
|
69
|
+
}, text.ALLOW_SCREENSHARE), screensharePermission && !isFullscreen && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
|
|
63
70
|
variant: "primary",
|
|
64
71
|
onClick: () => {
|
|
65
72
|
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),
|
|
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"
|
package/dist/constants/text.js
CHANGED
|
@@ -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;
|
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
|
|
13
|
+
var _components = require("./components");
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
var _ = require(".");
|
|
6
|
+
exports.getDataOnBreach = void 0;
|
|
9
7
|
|
|
10
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; }
|
|
11
9
|
|
|
@@ -13,7 +11,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
13
11
|
|
|
14
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; }
|
|
15
13
|
|
|
16
|
-
const
|
|
14
|
+
const getDataOnBreach = (statistics, currentData) => {
|
|
17
15
|
const {
|
|
18
16
|
userCount,
|
|
19
17
|
tabSwitchCount,
|
|
@@ -25,63 +23,54 @@ const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendDat
|
|
|
25
23
|
const data = statistics.current;
|
|
26
24
|
|
|
27
25
|
if (data.IS_WEBCAM_DATA_RELIABLE !== isWebcamDataReliable) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
breach: "IS_WEBCAM_DATA_RELIABLE",
|
|
26
|
+
return {
|
|
27
|
+
breachedParam: "IS_WEBCAM_DATA_RELIABLE",
|
|
31
28
|
timestamp,
|
|
32
29
|
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
33
30
|
IS_WEBCAM_DATA_RELIABLE: isWebcamDataReliable
|
|
34
31
|
})
|
|
35
|
-
}
|
|
32
|
+
};
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
if (data.USER_COUNT_MAX < userCount) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
proctoringIdentifier,
|
|
42
|
-
breach: "USER_COUNT_MAX",
|
|
36
|
+
return {
|
|
37
|
+
breachedParam: "USER_COUNT_MAX",
|
|
43
38
|
timestamp,
|
|
44
39
|
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
45
40
|
USER_COUNT_MAX: userCount
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
});
|
|
41
|
+
})
|
|
42
|
+
};
|
|
49
43
|
}
|
|
50
44
|
|
|
51
45
|
if (data.TAB_SWITCH_COUNT !== tabSwitchCount) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
breach: "TAB_SWITCH_COUNT",
|
|
46
|
+
return {
|
|
47
|
+
breachedParam: "TAB_SWITCH_COUNT",
|
|
55
48
|
timestamp,
|
|
56
49
|
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
57
50
|
TAB_SWITCH_COUNT: tabSwitchCount
|
|
58
51
|
})
|
|
59
|
-
}
|
|
52
|
+
};
|
|
60
53
|
}
|
|
61
54
|
|
|
62
55
|
if (data.FULLSCREEN_EXIT_COUNT !== fullScreenExitCount) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
breach: "FULLSCREEN_EXIT_COUNT",
|
|
56
|
+
return {
|
|
57
|
+
breachedParam: "FULLSCREEN_EXIT_COUNT",
|
|
66
58
|
timestamp,
|
|
67
59
|
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
68
60
|
FULLSCREEN_EXIT_COUNT: fullScreenExitCount
|
|
69
61
|
})
|
|
70
|
-
}
|
|
62
|
+
};
|
|
71
63
|
}
|
|
72
64
|
|
|
73
65
|
if (data.LOOKED_AWAY_COUNT !== lookedAwayCount) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
proctoringIdentifier,
|
|
77
|
-
breach: "LOOKED_AWAY_COUNT",
|
|
66
|
+
return {
|
|
67
|
+
breachedParam: "LOOKED_AWAY_COUNT",
|
|
78
68
|
timestamp,
|
|
79
69
|
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
80
70
|
LOOKED_AWAY_COUNT: lookedAwayCount
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
});
|
|
71
|
+
})
|
|
72
|
+
};
|
|
84
73
|
}
|
|
85
74
|
};
|
|
86
75
|
|
|
87
|
-
exports.
|
|
76
|
+
exports.getDataOnBreach = getDataOnBreach;
|
|
@@ -3,10 +3,30 @@
|
|
|
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 = exports.captureWebcamSnapshot = 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;
|
|
@@ -110,6 +130,34 @@ const updateVideoPermissions = setVideoPermission => {
|
|
|
110
130
|
|
|
111
131
|
exports.updateVideoPermissions = updateVideoPermissions;
|
|
112
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
|
+
|
|
113
161
|
const getVideoPermissionQuery = () => navigator.permissions.query({
|
|
114
162
|
name: "camera"
|
|
115
163
|
});
|
|
@@ -122,8 +170,37 @@ const getAudioPermissionQuery = () => navigator.permissions.query({
|
|
|
122
170
|
|
|
123
171
|
exports.getAudioPermissionQuery = getAudioPermissionQuery;
|
|
124
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
|
+
|
|
125
187
|
const captureWebcamSnapshot = webcamReference => {
|
|
126
|
-
|
|
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
|
+
}
|
|
127
204
|
};
|
|
128
205
|
|
|
129
|
-
exports.
|
|
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.
|
|
3
|
+
"version": "0.0.16",
|
|
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
|
},
|