@newtonschool/react_proctoring_library 0.0.133-beta.2 → 0.0.135

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.
@@ -77,6 +77,24 @@ const ProctorApp = _ref => {
77
77
  return releaseWakeUpLock;
78
78
  }, []);
79
79
  const CustomPermissionView = customPermissionView;
80
+ const proctoringSessionId = (0, _react.useMemo)(() => {
81
+ const {
82
+ proctoredEntityType,
83
+ proctoredEntityHash
84
+ } = permissionPassedProps;
85
+ if (!proctoredEntityType || !proctoredEntityHash) {
86
+ return null;
87
+ }
88
+ return "".concat(proctoredEntityType, "-").concat(proctoredEntityHash);
89
+ }, [permissionPassedProps]);
90
+ const sessionScopedFirebaseClient = (0, _react.useMemo)(() => {
91
+ if (!firebaseClient) {
92
+ return firebaseClient;
93
+ }
94
+ return _objectSpread(_objectSpread({}, firebaseClient), {}, {
95
+ proctoringSessionId
96
+ });
97
+ }, [firebaseClient, proctoringSessionId]);
80
98
  const proctorParams = (0, _react.useMemo)(() => _objectSpread(_objectSpread({}, _defaults.defaultConfig), config.proctorParams), [config.proctorParams]);
81
99
  const shouldShowProctoredComponent = (0, _react.useMemo)(() => (0, _breachUtils.showProctoredComponent)(proctorParams, permissions), [proctorParams, permissions, _breachUtils.showProctoredComponent]);
82
100
  const allPermissionsGrantedCallback = () => {
@@ -133,7 +151,7 @@ const ProctorApp = _ref => {
133
151
  permissions: permissions,
134
152
  proctoredContext: proctoredContext,
135
153
  isSecondaryDevice: isSecondaryDevice,
136
- firebaseClient: firebaseClient,
154
+ firebaseClient: sessionScopedFirebaseClient,
137
155
  allPermissionGranted: allPermissionGrantedOnce.current
138
156
  }), proctorParams.webcamSnapshots && /*#__PURE__*/(0, _jsxRuntime.jsx)(_webcamActivityTracker.default, {
139
157
  logger: logger,
@@ -143,7 +161,7 @@ const ProctorApp = _ref => {
143
161
  getWebcamSnapshot: getWebcamSnapshot,
144
162
  proctoringIdentifier: proctoringIdentifier,
145
163
  setAskPermissionAction: setAskPermissionAction,
146
- firebaseClient: firebaseClient,
164
+ firebaseClient: sessionScopedFirebaseClient,
147
165
  isSecondaryDevice: isSecondaryDevice
148
166
  }), proctorParams.screenshareSnapshots && /*#__PURE__*/(0, _jsxRuntime.jsx)(_screenshareActivityTracker.default, {
149
167
  config: config,
@@ -10,7 +10,6 @@ var _proctoringStatusUtils = require("../../utils/proctoringStatusUtils");
10
10
  var _permission = require("../../utils/permission");
11
11
  var _breachUtils = require("../../utils/breachUtils");
12
12
  var _usePageActivity = _interopRequireDefault(require("../../hooks/usePageActivity"));
13
- var _proctoringDebugUtils = require("../../utils/proctoringDebugUtils");
14
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
14
  const SecondaryDevice = _ref => {
16
15
  let {
@@ -28,36 +27,10 @@ const SecondaryDevice = _ref => {
28
27
  const [secondaryDeviceOnline, setSecondaryDeviceOnline] = (0, _react.useState)(true);
29
28
  const [secondaryDeviceAllPermissionGranted, setSecondaryDeviceAllPermissionGranted] = (0, _react.useState)(true);
30
29
  const {
31
- isActive: isCurrentDeviceActive,
32
- isVisible,
33
- isFocused,
34
- isLifecycleActive
30
+ isActive: isCurrentDeviceActive
35
31
  } = (0, _usePageActivity.default)();
36
32
  const allPermissionGranted = (0, _permission.hasAllPermissions)((0, _breachUtils.getRequiredPermissionsFromProctorParams)(proctorParams), permissions);
37
33
  const effectiveAllPermissionGranted = allPermissionGranted && isCurrentDeviceActive;
38
- (0, _react.useEffect)(() => {
39
- if (!isSecondaryDevice) {
40
- return;
41
- }
42
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_session_started', {
43
- deviceType: 'secondary',
44
- userUuid: (firebaseClient === null || firebaseClient === void 0 ? void 0 : firebaseClient.userUuid) || null,
45
- requiredPermissions: (0, _breachUtils.getRequiredPermissionsFromProctorParams)(proctorParams),
46
- userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown'
47
- }, firebaseClient);
48
- }, [firebaseClient === null || firebaseClient === void 0 ? void 0 : firebaseClient.userUuid, isSecondaryDevice, proctorParams]);
49
- (0, _react.useEffect)(() => {
50
- if (!isSecondaryDevice) {
51
- return;
52
- }
53
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_page_activity_state_changed', {
54
- deviceType: 'secondary',
55
- isVisible,
56
- isFocused,
57
- isLifecycleActive,
58
- isActive: isCurrentDeviceActive
59
- }, firebaseClient);
60
- }, [firebaseClient, isCurrentDeviceActive, isFocused, isLifecycleActive, isSecondaryDevice, isVisible]);
61
34
  (0, _react.useEffect)(() => {
62
35
  const cleanup = (0, _proctoringStatusUtils.setupDeviceStatusListeners)({
63
36
  firebaseClient,
@@ -20,7 +20,6 @@ var _webcamMicrophoneUtils = require("../../utils/webcamMicrophoneUtils");
20
20
  var _dom = require("../../constants/dom");
21
21
  var _useBreachData = require("../../hooks/useBreachData");
22
22
  var _proctoringStatusUtils = require("../../utils/proctoringStatusUtils");
23
- var _proctoringDebugUtils = require("../../utils/proctoringDebugUtils");
24
23
  var _jsxRuntime = require("react/jsx-runtime");
25
24
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
26
25
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -47,7 +46,6 @@ const WebWebCam = _ref => {
47
46
  references,
48
47
  permissions
49
48
  } = (0, _react.useContext)(proctoredContext);
50
- const deviceType = isSecondaryDevice ? 'secondary' : 'primary';
51
49
  const recurringFetchIntervalRef = (0, _react.useRef)(null);
52
50
  const {
53
51
  recurring = false,
@@ -110,13 +108,6 @@ const WebWebCam = _ref => {
110
108
  screenshotFormat: "image/jpeg",
111
109
  ref: webcamReference,
112
110
  onUserMedia: () => {
113
- if (isSecondaryDevice) {
114
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_webcam_user_media_succeeded', {
115
- deviceType,
116
- retryCount,
117
- userUuid: (firebaseClient === null || firebaseClient === void 0 ? void 0 : firebaseClient.userUuid) || null
118
- }, firebaseClient);
119
- }
120
111
  setVideoPermission(true);
121
112
  if (firebaseClient) {
122
113
  if (isSecondaryDevice) {
@@ -127,17 +118,6 @@ const WebWebCam = _ref => {
127
118
  }
128
119
  },
129
120
  onUserMediaError: err => {
130
- if (isSecondaryDevice) {
131
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_webcam_user_media_failed', {
132
- deviceType,
133
- retryCount,
134
- userUuid: (firebaseClient === null || firebaseClient === void 0 ? void 0 : firebaseClient.userUuid) || null,
135
- error: {
136
- name: (err === null || err === void 0 ? void 0 : err.name) || null,
137
- message: (err === null || err === void 0 ? void 0 : err.message) || String(err)
138
- }
139
- }, firebaseClient);
140
- }
141
121
  logger("Retry Count = ".concat(retryCount, " | Webcam error, onUserMediaError | ").concat(err.toString()));
142
122
  if (retryCount === 0) {
143
123
  setVideoPermission(false);
@@ -5,32 +5,24 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.updateCurrentDeviceStatus = exports.setupDeviceStatusListeners = exports.setSecondaryDeviceConnected = exports.setPrimaryDeviceConnected = void 0;
7
7
  var _defaults = require("../constants/defaults");
8
- var _proctoringDebugUtils = require("./proctoringDebugUtils");
9
8
  const HEARTBEAT_INTERVAL_MS = 5000;
10
9
  const OTHER_DEVICE_HEARTBEAT_TIMEOUT_MS = 20000;
11
10
  const SERVER_TIMESTAMP = {
12
11
  '.sv': 'timestamp'
13
12
  };
14
- const getErrorPayload = error => ({
15
- name: (error === null || error === void 0 ? void 0 : error.name) || null,
16
- message: (error === null || error === void 0 ? void 0 : error.message) || String(error)
17
- });
18
- const getObservedStatusPayload = function getObservedStatusPayload(status) {
19
- let now = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
20
- return {
21
- connected: Boolean(status === null || status === void 0 ? void 0 : status.connected),
22
- allPermissionGranted: typeof (status === null || status === void 0 ? void 0 : status.allPermissionGranted) === 'boolean' ? status.allPermissionGranted : null,
23
- lastHeartbeatAt: typeof (status === null || status === void 0 ? void 0 : status.lastHeartbeatAt) === 'number' ? status.lastHeartbeatAt : null,
24
- heartbeatAgeMs: typeof now === 'number' && typeof (status === null || status === void 0 ? void 0 : status.lastHeartbeatAt) === 'number' ? now - status.lastHeartbeatAt : null,
25
- deviceId: (status === null || status === void 0 ? void 0 : status.deviceId) || null
26
- };
27
- };
28
- const hasRelevantObservedChange = (previousStatus, nextStatus) => {
29
- const previous = getObservedStatusPayload(previousStatus);
30
- const next = getObservedStatusPayload(nextStatus);
31
- return previous.connected !== next.connected || previous.allPermissionGranted !== next.allPermissionGranted || previous.deviceId !== next.deviceId;
13
+ const getProctoringStatusBasePath = function getProctoringStatusBasePath() {
14
+ let {
15
+ userUuid,
16
+ proctoringSessionId
17
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18
+ if (!userUuid) {
19
+ return null;
20
+ }
21
+ if (proctoringSessionId) {
22
+ return "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(userUuid, "/").concat(proctoringSessionId);
23
+ }
24
+ return "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(userUuid);
32
25
  };
33
-
34
26
  /**
35
27
  * Marks the primary device as connected in Firebase. Call when desktop webcam
36
28
  * connects successfully. No-op if firebaseClient is missing required fields.
@@ -46,7 +38,11 @@ const setPrimaryDeviceConnected = firebaseClient => {
46
38
  updateValue: update,
47
39
  getRef: ref
48
40
  } = firebaseClient;
49
- const primaryDeviceRef = ref(firebaseClient.myFirebaseDB, "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(firebaseClient.userUuid, "/primaryDevice"));
41
+ const statusBasePath = getProctoringStatusBasePath(firebaseClient);
42
+ if (!statusBasePath) {
43
+ return undefined;
44
+ }
45
+ const primaryDeviceRef = ref(firebaseClient.myFirebaseDB, "".concat(statusBasePath, "/primaryDevice"));
50
46
  const payload = {
51
47
  connected: true
52
48
  };
@@ -71,17 +67,15 @@ const setSecondaryDeviceConnected = firebaseClient => {
71
67
  updateValue: update,
72
68
  getRef: ref
73
69
  } = firebaseClient;
74
- const secondaryDeviceRef = ref(firebaseClient.myFirebaseDB, "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(firebaseClient.userUuid, "/secondaryDevice"));
70
+ const statusBasePath = getProctoringStatusBasePath(firebaseClient);
71
+ if (!statusBasePath) {
72
+ return undefined;
73
+ }
74
+ const secondaryDeviceRef = ref(firebaseClient.myFirebaseDB, "".concat(statusBasePath, "/secondaryDevice"));
75
75
  const payload = {
76
76
  connected: true
77
77
  };
78
78
  return update(secondaryDeviceRef, payload).then(() => {}).catch(error => {
79
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_device_status_write_failed', {
80
- deviceType: 'secondary',
81
- userUuid: firebaseClient.userUuid,
82
- payload,
83
- error: getErrorPayload(error)
84
- }, firebaseClient);
85
79
  console.error('::[proctoringStatusUtils] Failed to set secondary device status online:', error);
86
80
  });
87
81
  };
@@ -110,8 +104,12 @@ const updateCurrentDeviceStatus = _ref => {
110
104
  updateValue: update,
111
105
  getRef: ref
112
106
  } = firebaseClient;
107
+ const statusBasePath = getProctoringStatusBasePath(firebaseClient);
108
+ if (!statusBasePath) {
109
+ return undefined;
110
+ }
113
111
  const deviceKey = isSecondaryDevice ? 'secondaryDevice' : 'primaryDevice';
114
- const deviceStatusRef = ref(firebaseClient.myFirebaseDB, "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(firebaseClient.userUuid, "/").concat(deviceKey));
112
+ const deviceStatusRef = ref(firebaseClient.myFirebaseDB, "".concat(statusBasePath, "/").concat(deviceKey));
115
113
  const payload = {
116
114
  allPermissionGranted
117
115
  };
@@ -119,12 +117,6 @@ const updateCurrentDeviceStatus = _ref => {
119
117
  if (!isSecondaryDevice) {
120
118
  return;
121
119
  }
122
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_device_status_write_failed', {
123
- deviceType: 'secondary',
124
- userUuid: firebaseClient.userUuid,
125
- payload,
126
- error: getErrorPayload(error)
127
- }, firebaseClient);
128
120
  console.error('::[proctoringStatusUtils] Failed to update current device status:', error);
129
121
  });
130
122
  };
@@ -154,6 +146,7 @@ const setupDeviceStatusListeners = _ref2 => {
154
146
  const {
155
147
  userUuid,
156
148
  firestoreAuthStatus,
149
+ proctoringSessionId,
157
150
  myFirebaseDB,
158
151
  setValue: set,
159
152
  getRef: ref,
@@ -161,12 +154,18 @@ const setupDeviceStatusListeners = _ref2 => {
161
154
  onDisconnect,
162
155
  getValue: onValue
163
156
  } = firebaseClient || {};
164
- const deviceType = isSecondaryDevice ? 'secondary' : 'primary';
165
157
  if (!userUuid || !firestoreAuthStatus || !ref || !set || !onDisconnect || !onValue) {
166
158
  return () => {};
167
159
  }
168
- const primaryDeviceStatusRef = ref(myFirebaseDB, "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(userUuid, "/primaryDevice"));
169
- const secondaryDeviceStatusRef = ref(myFirebaseDB, "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(userUuid, "/secondaryDevice"));
160
+ const statusBasePath = getProctoringStatusBasePath({
161
+ userUuid,
162
+ proctoringSessionId
163
+ });
164
+ if (!statusBasePath) {
165
+ return () => {};
166
+ }
167
+ const primaryDeviceStatusRef = ref(myFirebaseDB, "".concat(statusBasePath, "/primaryDevice"));
168
+ const secondaryDeviceStatusRef = ref(myFirebaseDB, "".concat(statusBasePath, "/secondaryDevice"));
170
169
  const currentDeviceStatusRef = isSecondaryDevice ? secondaryDeviceStatusRef : primaryDeviceStatusRef;
171
170
  const otherDeviceStatusRef = isSecondaryDevice ? primaryDeviceStatusRef : secondaryDeviceStatusRef;
172
171
  const serverTimeOffsetRef = ref(myFirebaseDB, '.info/serverTimeOffset');
@@ -184,51 +183,27 @@ const setupDeviceStatusListeners = _ref2 => {
184
183
  onDisconnect(currentDeviceStatusRef).update({
185
184
  connected: false
186
185
  }).then(() => {}).catch(err => {
187
- if (!isSecondaryDevice) {
188
- return;
189
- }
190
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_device_status_write_failed', {
191
- deviceType,
192
- userUuid,
193
- payload: {
194
- connected: false,
195
- source: 'onDisconnect'
196
- },
197
- error: getErrorPayload(err)
198
- }, firebaseClient);
199
186
  console.error('::[proctoringStatusUtils] Failed to mark current device disconnected:', err);
200
187
  });
201
188
 
202
189
  // Get initial values and update callbacks immediately
203
- const applyPrimarySnapshot = function applyPrimarySnapshot(snapshot) {
190
+ const applyPrimarySnapshot = snapshot => {
204
191
  var _snapshot$val, _snapshot$val2;
205
- let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'subscription';
206
- const previousValue = latestPrimaryDeviceStatus;
207
192
  const val = (_snapshot$val = snapshot === null || snapshot === void 0 ? void 0 : (_snapshot$val2 = snapshot.val) === null || _snapshot$val2 === void 0 ? void 0 : _snapshot$val2.call(snapshot)) !== null && _snapshot$val !== void 0 ? _snapshot$val : snapshot;
208
193
  latestPrimaryDeviceStatus = val;
209
194
  onPrimaryDeviceStatusChange(Boolean(val === null || val === void 0 ? void 0 : val.connected));
210
195
  };
211
- const applySecondarySnapshot = function applySecondarySnapshot(snapshot) {
196
+ const applySecondarySnapshot = snapshot => {
212
197
  var _snapshot$val3, _snapshot$val4;
213
- let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'subscription';
214
- const previousValue = latestSecondaryDeviceStatus;
215
198
  const val = (_snapshot$val3 = snapshot === null || snapshot === void 0 ? void 0 : (_snapshot$val4 = snapshot.val) === null || _snapshot$val4 === void 0 ? void 0 : _snapshot$val4.call(snapshot)) !== null && _snapshot$val3 !== void 0 ? _snapshot$val3 : snapshot;
216
199
  latestSecondaryDeviceStatus = val;
217
- if (isSecondaryDevice && (source === 'initial_get' || hasRelevantObservedChange(previousValue, val))) {
218
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_device_status_observed', {
219
- deviceType,
220
- observedDeviceType: 'secondary',
221
- source,
222
- observedStatus: getObservedStatusPayload(val, getComparableNow())
223
- }, firebaseClient);
224
- }
225
200
  onSecondaryDeviceStatusChange(Boolean(val === null || val === void 0 ? void 0 : val.connected), val === null || val === void 0 ? void 0 : val.allPermissionGranted);
226
201
  };
227
202
  if (typeof (primaryDeviceStatusRef === null || primaryDeviceStatusRef === void 0 ? void 0 : primaryDeviceStatusRef.get) === 'function') {
228
- primaryDeviceStatusRef.get().then(snapshot => applyPrimarySnapshot(snapshot, 'initial_get')).catch(() => {});
203
+ primaryDeviceStatusRef.get().then(snapshot => applyPrimarySnapshot(snapshot)).catch(() => {});
229
204
  }
230
205
  if (typeof (secondaryDeviceStatusRef === null || secondaryDeviceStatusRef === void 0 ? void 0 : secondaryDeviceStatusRef.get) === 'function') {
231
- secondaryDeviceStatusRef.get().then(snapshot => applySecondarySnapshot(snapshot, 'initial_get')).catch(() => {});
206
+ secondaryDeviceStatusRef.get().then(snapshot => applySecondarySnapshot(snapshot)).catch(() => {});
232
207
  }
233
208
 
234
209
  // Subscribe to updates
@@ -248,54 +223,19 @@ const setupDeviceStatusListeners = _ref2 => {
248
223
  let heartbeatIntervalId = null;
249
224
  if (typeof window !== 'undefined' && typeof setInterval === 'function') {
250
225
  heartbeatIntervalId = setInterval(() => {
251
- const clientNow = Date.now();
252
226
  const comparableNow = getComparableNow();
253
227
  if (isCurrentDeviceActive) {
254
228
  update(currentDeviceStatusRef, {
255
229
  connected: true,
256
230
  lastHeartbeatAt: SERVER_TIMESTAMP
257
231
  }).then(() => {}).catch(error => {
258
- if (!isSecondaryDevice) {
259
- return;
260
- }
261
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_heartbeat_write_failed', {
262
- deviceType,
263
- userUuid,
264
- isCurrentDeviceActive,
265
- now: comparableNow !== null && comparableNow !== void 0 ? comparableNow : clientNow,
266
- isSecondaryDevice,
267
- error: getErrorPayload(error)
268
- }, firebaseClient);
269
232
  console.error('::[proctoringStatusUtils] Failed to send heartbeat for current device:', error);
270
233
  });
271
234
  }
272
235
  if (!isCurrentDeviceActive) {
273
236
  update(currentDeviceStatusRef, {
274
237
  connected: false
275
- }).then(() => {
276
- if (!isSecondaryDevice) {
277
- return;
278
- }
279
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_current_device_marked_inactive', {
280
- deviceType,
281
- userUuid,
282
- now: comparableNow !== null && comparableNow !== void 0 ? comparableNow : clientNow,
283
- isSecondaryDevice
284
- }, firebaseClient);
285
- }).catch(error => {
286
- if (!isSecondaryDevice) {
287
- return;
288
- }
289
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_device_status_write_failed', {
290
- deviceType,
291
- userUuid,
292
- now: comparableNow !== null && comparableNow !== void 0 ? comparableNow : clientNow,
293
- payload: {
294
- connected: false,
295
- source: 'inactive_page_state'
296
- },
297
- error: getErrorPayload(error)
298
- }, firebaseClient);
238
+ }).then(() => {}).catch(error => {
299
239
  console.error('::[proctoringStatusUtils] Failed to mark current device inactive:', error);
300
240
  });
301
241
  }
@@ -307,41 +247,7 @@ const setupDeviceStatusListeners = _ref2 => {
307
247
  if (typeof comparableNow === 'number' && isConnected && typeof lastBeat === 'number' && comparableNow - lastBeat > OTHER_DEVICE_HEARTBEAT_TIMEOUT_MS) {
308
248
  update(otherDeviceStatusRef, {
309
249
  connected: false
310
- }).then(() => {
311
- const isMarkingSecondaryDeviceStale = !isSecondaryDevice;
312
- if (!isMarkingSecondaryDeviceStale) {
313
- return;
314
- }
315
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('primary_marked_secondary_inactive_due_to_stale_heartbeat', {
316
- deviceType: 'primary',
317
- userUuid,
318
- now: comparableNow,
319
- timeoutMs: OTHER_DEVICE_HEARTBEAT_TIMEOUT_MS,
320
- heartbeatDiffMs: comparableNow - lastBeat,
321
- payload: {
322
- connected: false,
323
- source: 'stale_other_device',
324
- otherDeviceType: 'secondary',
325
- otherDeviceStatus: getObservedStatusPayload(otherDeviceStatus, comparableNow)
326
- }
327
- }, firebaseClient);
328
- }).catch(otherErr => {
329
- const isMarkingSecondaryDeviceStale = !isSecondaryDevice;
330
- if (!isMarkingSecondaryDeviceStale) {
331
- return;
332
- }
333
- (0, _proctoringDebugUtils.emitProctoringDebugLog)('secondary_device_status_write_failed', {
334
- deviceType: 'secondary',
335
- userUuid,
336
- now: comparableNow,
337
- payload: {
338
- connected: false,
339
- source: 'stale_other_device',
340
- otherDeviceType: 'secondary',
341
- otherDeviceStatus: getObservedStatusPayload(otherDeviceStatus, comparableNow)
342
- },
343
- error: getErrorPayload(otherErr)
344
- }, firebaseClient);
250
+ }).then(() => {}).catch(otherErr => {
345
251
  console.error('::[proctoringStatusUtils] Failed to mark other device disconnected due to stale heartbeat:', otherErr);
346
252
  });
347
253
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newtonschool/react_proctoring_library",
3
- "version": "0.0.133-beta.2",
3
+ "version": "0.0.135",
4
4
  "description": "Used to proctor online tests",
5
5
  "author": "ayushkagrawal,shreyachandra,weastel",
6
6
  "main": "dist/index.js",
@@ -1,92 +0,0 @@
1
- "use strict";
2
-
3
- require("core-js/modules/es.symbol.description.js");
4
- require("core-js/modules/esnext.iterator.constructor.js");
5
- require("core-js/modules/esnext.iterator.filter.js");
6
- require("core-js/modules/esnext.iterator.for-each.js");
7
- Object.defineProperty(exports, "__esModule", {
8
- value: true
9
- });
10
- exports.emitProctoringDebugLog = void 0;
11
- require("core-js/modules/es.json.stringify.js");
12
- require("core-js/modules/es.promise.js");
13
- var _defaults = require("../constants/defaults");
14
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
17
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
18
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
19
- const DEBUG_LOG_PREFIX = '::[secondary-device-debug]';
20
- const WEB_REPORT_LOG_ENDPOINT = '/api/v1/user/report/web/';
21
- const safeJsonStringify = value => {
22
- try {
23
- return JSON.stringify(value);
24
- } catch (error) {
25
- return JSON.stringify({
26
- ts: Date.now(),
27
- serializationError: (error === null || error === void 0 ? void 0 : error.message) || String(error)
28
- });
29
- }
30
- };
31
- const postDebugMessage = message => {
32
- if (typeof window === 'undefined') {
33
- return;
34
- }
35
- try {
36
- if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {
37
- const body = new Blob([safeJsonStringify({
38
- message
39
- })], {
40
- type: 'application/json'
41
- });
42
- navigator.sendBeacon(WEB_REPORT_LOG_ENDPOINT, body);
43
- } else if (typeof fetch === 'function') {
44
- fetch(WEB_REPORT_LOG_ENDPOINT, {
45
- method: 'POST',
46
- headers: {
47
- 'Content-Type': 'application/json'
48
- },
49
- body: safeJsonStringify({
50
- message
51
- }),
52
- keepalive: true
53
- }).catch(() => {});
54
- }
55
- } catch (_) {}
56
- };
57
- const isDebugLogEnabled = async firebaseClient => {
58
- if (!(firebaseClient !== null && firebaseClient !== void 0 && firebaseClient.userUuid) || !(firebaseClient !== null && firebaseClient !== void 0 && firebaseClient.myFirebaseDB) || !(firebaseClient !== null && firebaseClient !== void 0 && firebaseClient.getRef) || !(firebaseClient !== null && firebaseClient !== void 0 && firebaseClient.getValue)) {
59
- return false;
60
- }
61
- const {
62
- getRef: ref,
63
- getValue
64
- } = firebaseClient;
65
- const debugEnabledRef = ref(firebaseClient.myFirebaseDB, "".concat(_defaults.PROCTORING_STATUS_PATH, "/").concat(firebaseClient.userUuid, "/isDebugEnabled"));
66
- try {
67
- return await new Promise(resolve => {
68
- getValue(debugEnabledRef, snapshot => {
69
- var _snapshot$val, _snapshot$val2;
70
- const value = (_snapshot$val = snapshot === null || snapshot === void 0 ? void 0 : (_snapshot$val2 = snapshot.val) === null || _snapshot$val2 === void 0 ? void 0 : _snapshot$val2.call(snapshot)) !== null && _snapshot$val !== void 0 ? _snapshot$val : snapshot;
71
- resolve(Boolean(value));
72
- }, () => resolve(false), {
73
- onlyOnce: true
74
- });
75
- });
76
- } catch (_) {
77
- return false;
78
- }
79
- };
80
- const emitProctoringDebugLog = exports.emitProctoringDebugLog = function emitProctoringDebugLog(event) {
81
- let payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
82
- let firebaseClient = arguments.length > 2 ? arguments[2] : undefined;
83
- const message = "".concat(DEBUG_LOG_PREFIX, " ").concat(event, " ").concat(safeJsonStringify(_objectSpread({
84
- ts: Date.now()
85
- }, payload)));
86
- isDebugLogEnabled(firebaseClient).then(enabled => {
87
- if (!enabled) {
88
- return;
89
- }
90
- postDebugMessage(message);
91
- });
92
- };