From 10ed30c2df603e359ee86b09a6b6544b40b102f2 Mon Sep 17 00:00:00 2001 From: Devang Date: Mon, 26 Aug 2024 18:09:47 +0530 Subject: [PATCH 01/11] Generate and provide a wrapper link if only SB is enabled for a quiz --- classes/local/api/tracker.php | 54 ++++++++++++++++++++++++++++++++++- classes/local/injector.php | 5 ++++ version.php | 4 +-- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index 322402a..d8af881 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -87,10 +87,46 @@ public static function storeFallbackDetails($attempt_no, $proview_url, $proctor_ ]); return $response; } + private static function redirect_to_wrapper($proctoring_payload, $quiz) + { + // TODO Add check if wrapper URL already exists + $wrapper_response = self::create_sb_wrapper($proctoring_payload, $quiz); + redirect($wrapper_response->signed_short_url); + return; + } + + private static function create_sb_wrapper($proctoring_payload, $quiz) + { + global $PAGE; + $curl = new \curl(); + $api_base_url = trim(get_config('quizaccess_proctor', 'proview_callback_url')); + $auth_payload = new \stdClass(); + $auth_payload->username = trim(get_config('quizaccess_proctor', 'proview_admin_username')); + $auth_payload->password = trim(get_config('quizaccess_proctor', 'proview_admin_password')); + $auth_response = self::generate_auth_token($api_base_url, $auth_payload); + $auth_token = $auth_response['access_token']; + $url = $api_base_url . '/v1/wrapper/create'; + $data = array( + 'session_external_id' => $proctoring_payload->session_id, + 'attendee_external_id' => $proctoring_payload->profile_id, + 'redirect_url' => $PAGE->url->__toString(), + 'expiry' => date(DATE_ISO8601, $quiz->timeclose == 0 ? strtotime("+3 days") : $quiz->timeclose ), + 'is_secure_browser' => true + ); + var_dump($data); + try { + $curl->setHeader(array('Content-Type: application/json', 'app-id: b37ec896-f62b-4cbe-b39f-8dd21881dfd3', 'Authorization: Bearer ' . $auth_token)); + $response = $curl->post($url, json_encode($data)); + $decoded_response = json_decode($response, false); + return $decoded_response; + } catch (\Throwable $err) { + self::capture_error($err); + } + } -private static function generate_auth_token($api_base_url, $payload) + private static function generate_auth_token($api_base_url, $payload) { $curl = new \curl(); $headers = array('Content-Type: application/json'); @@ -148,6 +184,21 @@ public static function insert_tracking() $attempt = $attempt->attempt; } $template->current_attempt = $attempt; + $quizaccess_proctor_setting = $DB->get_record('quizaccess_proctor', array('quizid' => $quiz->id)); + if ($quizaccess_proctor_setting) { + $template->session_type = $quizaccess_proctor_setting->proctortype; + } else { + $template->session_type = "ai_proctor"; + } + $template->session_id = $template->session_type === "live_proctor" ? $quiz->id.'-'.$USER->id : $quiz->id.'-'.$USER->id.'-'.$attempt; + if (strpos($PAGE->url, ('mod/quiz/attempt')) && + $quizaccess_proctor_setting && + $quizaccess_proctor_setting->proctortype == 'noproctor' && + $quizaccess_proctor_setting->tsbenabled && + strpos($_SERVER ['HTTP_USER_AGENT'], "Proview-SB") === FALSE) { + self::redirect_to_wrapper($template, $quiz); + return; + } if (strpos($PAGE->url, ('mod/quiz/report'))) { $quiz_attempts = $DB->get_records('quiz_attempts', array('quiz' => $quiz->id)); @@ -160,6 +211,7 @@ public static function insert_tracking() $template->attempts = json_encode($quiz_attempts); } } + if ($pageinfo && !empty($template->token)) { // The templates only contains a "{js}" block; so we don't care about // the output; only that the $PAGE->requires are filled. diff --git a/classes/local/injector.php b/classes/local/injector.php index 39e291c..5e2153b 100644 --- a/classes/local/injector.php +++ b/classes/local/injector.php @@ -79,6 +79,11 @@ public static function inject() { $quizaccess_proctor_setting = $DB->get_record('quizaccess_proctor', array('quizid' => $quiz->id)); if ((!$quizaccess_proctor_setting) || ($quizaccess_proctor_setting && $quizaccess_proctor_setting->proctortype == 'noproctor')) { + if (($quizaccess_proctor_setting->tsbenabled && strpos($_SERVER ['HTTP_USER_AGENT'], "Proview-SB") === FALSE)) { + $t = new api\tracker(); + $t::insert_tracking(); + return; + } self::inject_password($PAGE, $quiz); return; } diff --git a/version.php b/version.php index 8ab605b..dd86fb5 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024081301; +$plugin->version = 2024082601; $plugin->requires = 2020061500; -$plugin->release = '3.3.4 (Build: 2024081301)'; +$plugin->release = '3.3.5 (Build: 2024082601)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From 9ecb3b220e1c4d125276d056d15748c19fe0ae1a Mon Sep 17 00:00:00 2001 From: Devang Date: Tue, 27 Aug 2024 14:40:35 +0530 Subject: [PATCH 02/11] Fix wrapper not generating from proxy api --- classes/local/api/tracker.php | 2 +- version.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index d8af881..6e7bf48 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -105,7 +105,7 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) $auth_payload->password = trim(get_config('quizaccess_proctor', 'proview_admin_password')); $auth_response = self::generate_auth_token($api_base_url, $auth_payload); $auth_token = $auth_response['access_token']; - $url = $api_base_url . '/v1/wrapper/create'; + $url = $api_base_url . '/proview/wrapper/create'; $data = array( 'session_external_id' => $proctoring_payload->session_id, 'attendee_external_id' => $proctoring_payload->profile_id, diff --git a/version.php b/version.php index dd86fb5..d15949b 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024082601; +$plugin->version = 2024082604; $plugin->requires = 2020061500; -$plugin->release = '3.3.5 (Build: 2024082601)'; +$plugin->release = '3.3.5 (Build: 2024082604)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From 22004de9e5b416d31837d52648920705280b365e Mon Sep 17 00:00:00 2001 From: Devang Date: Fri, 20 Sep 2024 11:19:09 +0530 Subject: [PATCH 03/11] Remove not requried app-id --- classes/local/api/tracker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index 6e7bf48..b2f6c9f 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -115,7 +115,7 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) ); var_dump($data); try { - $curl->setHeader(array('Content-Type: application/json', 'app-id: b37ec896-f62b-4cbe-b39f-8dd21881dfd3', 'Authorization: Bearer ' . $auth_token)); + $curl->setHeader(array('Content-Type: application/json', 'Authorization: Bearer ' . $auth_token)); $response = $curl->post($url, json_encode($data)); $decoded_response = json_decode($response, false); return $decoded_response; From 891e600078e0238453461e1fe60229677d4b6113 Mon Sep 17 00:00:00 2001 From: Devang Date: Thu, 24 Oct 2024 15:50:56 +0530 Subject: [PATCH 04/11] Bump Plugin Version --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index d15949b..534a634 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024082604; +$plugin->version = 2024102401; $plugin->requires = 2020061500; -$plugin->release = '3.3.5 (Build: 2024082604)'; +$plugin->release = '3.3.6 (Build: 2024102401)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From 20e192068ca8c44c2975e1888ca3d9ebae247409 Mon Sep 17 00:00:00 2001 From: Devang Date: Sat, 26 Oct 2024 01:49:38 +0530 Subject: [PATCH 05/11] Update Sentry DSN to self Hosted Servers --- classes/local/api/tracker.php | 2 +- classes/local/injector.php | 4 +++- frame.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index b2f6c9f..b897ebc 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -151,7 +151,7 @@ private static function generate_auth_token($api_base_url, $payload) private static function capture_error(\Throwable $err) { - \Sentry\init(['dsn' => 'https://61facdc5414c4c73ab2b17fe902bf9ba@o286634.ingest.sentry.io/5304587']); + \Sentry\init(['dsn' => 'https://577c4f60f7bd37671bdd8ad626d63a7d@sentry.talview.org/149']); \Sentry\captureException($err); } diff --git a/classes/local/injector.php b/classes/local/injector.php index 5e2153b..77f5736 100644 --- a/classes/local/injector.php +++ b/classes/local/injector.php @@ -77,6 +77,7 @@ public static function inject() { if ($PAGE->cm) { $quiz = $DB->get_record('quiz', array('id' => $PAGE->cm->instance)); $quizaccess_proctor_setting = $DB->get_record('quizaccess_proctor', array('quizid' => $quiz->id)); + //Logic for launching Secure Browser without Proctoring Starts if ((!$quizaccess_proctor_setting) || ($quizaccess_proctor_setting && $quizaccess_proctor_setting->proctortype == 'noproctor')) { if (($quizaccess_proctor_setting->tsbenabled && strpos($_SERVER ['HTTP_USER_AGENT'], "Proview-SB") === FALSE)) { @@ -87,6 +88,7 @@ public static function inject() { self::inject_password($PAGE, $quiz); return; } + //Logic for launching Secure Browser without Proctoring Ends } // Logic for enabling proview for course level and quiz level ends. @@ -131,7 +133,7 @@ public static function inject() { $t::insert_tracking(); return; } catch (\Throwable $error) { - \Sentry\init(['dsn' => 'https://61facdc5414c4c73ab2b17fe902bf9ba@o286634.ingest.sentry.io/5304587' ]); + \Sentry\init(['dsn' => 'https://577c4f60f7bd37671bdd8ad626d63a7d@sentry.talview.org/149' ]); \Sentry\captureException($error); die; ?> diff --git a/frame.php b/frame.php index 8ea05fe..18684e4 100644 --- a/frame.php +++ b/frame.php @@ -57,7 +57,7 @@ "; return; } @@ -113,7 +114,7 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) 'expiry' => date(DATE_ISO8601, $quiz->timeclose == 0 ? strtotime("+3 days") : $quiz->timeclose ), 'is_secure_browser' => true ); - var_dump($data); + // var_dump($data); try { $curl->setHeader(array('Content-Type: application/json', 'Authorization: Bearer ' . $auth_token)); $response = $curl->post($url, json_encode($data)); diff --git a/templates/tracker.mustache b/templates/tracker.mustache index 359777f..542ecf3 100644 --- a/templates/tracker.mustache +++ b/templates/tracker.mustache @@ -88,7 +88,7 @@ parent.postMessage({type: 'stopProview',url: window.location.href}, childOrigin); } }) - if( window.self == window.top) { + if( window.self == window.top && '{{session_type}}' !== 'noproctor') { let params = new URLSearchParams({ url: current, clear: false, @@ -97,6 +97,20 @@ }); window.location.href = '{{root_dir}}local/proview/frame.php?'+params.toString(); } + // Hide back Button from quiz if exam is launched in SB Starts + // NOTE: This will only work for English Language due to string matching + if (window.navigator.userAgent.match(/Proview-SB/)) { + console.log("User Agent: ", window.navigator.userAgent); + document.querySelectorAll('a').forEach(link => { + const urlContainsIndex = link.href.includes('moodle/mod/quiz/view.php'); + const textContainsBack = link.textContent.trim().toLowerCase().includes('back'); + if (urlContainsIndex && textContainsBack) { + // Hide the element by setting its display style to none + link.style.display = 'none'; + } + }); + } + // Hide back Button from quiz if exam is launched in SB Starts } if(current.match('mod/quiz/view') ) { if(window.self != window.top && window.parent.previousUrl) { //checking if the request is coming from summary @@ -108,7 +122,7 @@ let div = document.getElementsByClassName("singlebutton quizstartbuttondiv"); div[0].getElementsByTagName("*")[3].addEventListener("click", function(event){ $(".moodle-dialogue-base").hide(); - if( window.self == window.top) { + if( window.self == window.top && '{{session_type}}' !== 'noproctor') { let params = new URLSearchParams({ url : current, clear : false, diff --git a/version.php b/version.php index 534a634..3b6d79d 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024102401; +$plugin->version = 2024102601; $plugin->requires = 2020061500; -$plugin->release = '3.3.6 (Build: 2024102401)'; +$plugin->release = '3.3.7 (Build: 2024102601)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From 1e19ba879b563cb5c923a5852d5c659c15a35441 Mon Sep 17 00:00:00 2001 From: Devang Date: Mon, 28 Oct 2024 15:49:32 +0530 Subject: [PATCH 07/11] Fix Back button stil visible in SB --- classes/local/injector.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/classes/local/injector.php b/classes/local/injector.php index 77f5736..fe88bc6 100644 --- a/classes/local/injector.php +++ b/classes/local/injector.php @@ -79,12 +79,9 @@ public static function inject() { $quizaccess_proctor_setting = $DB->get_record('quizaccess_proctor', array('quizid' => $quiz->id)); //Logic for launching Secure Browser without Proctoring Starts if ((!$quizaccess_proctor_setting) || - ($quizaccess_proctor_setting && $quizaccess_proctor_setting->proctortype == 'noproctor')) { - if (($quizaccess_proctor_setting->tsbenabled && strpos($_SERVER ['HTTP_USER_AGENT'], "Proview-SB") === FALSE)) { - $t = new api\tracker(); - $t::insert_tracking(); - return; - } + ($quizaccess_proctor_setting && $quizaccess_proctor_setting->proctortype == 'noproctor' && $quizaccess_proctor_setting->tsbenabled)) { + $t = new api\tracker(); + $t::insert_tracking(); self::inject_password($PAGE, $quiz); return; } From 5a522002ee023280843f41faa1e65ce3fe3a866a Mon Sep 17 00:00:00 2001 From: Devang Date: Mon, 28 Oct 2024 15:51:19 +0530 Subject: [PATCH 08/11] Bump version --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 3b6d79d..a37a61b 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024102601; +$plugin->version = 2024102805; $plugin->requires = 2020061500; -$plugin->release = '3.3.7 (Build: 2024102601)'; +$plugin->release = '3.3.7 (Build: 2024102805)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From ad872fb04e8aea2675366f268f3eecd0fcea0ed2 Mon Sep 17 00:00:00 2001 From: Rohan Sharma Sitoula Date: Mon, 4 Nov 2024 17:36:10 +0530 Subject: [PATCH 09/11] Add additional secure browser configurations and update version - Introduced new parameters for secure browser configurations, including blacklisted software for Windows and Mac, screen protection, and minimize options. - Updated `startProview` function to handle new secure browser parameters. - Modified `redirect_to_wrapper` and `create_sb_wrapper` functions to incorporate secure browser settings. - Enhanced `datastore.php` to populate secure browser settings based on quiz access proctor settings. - Bumped plugin version to 2024110401. --- classes/local/api/tracker.php | 23 ++++++++++++----- datastore.php | 9 +++++++ frame.php | 47 ++++++++++++++++++++++++++--------- version.php | 4 +-- 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index e531bca..9e813b2 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -87,10 +87,10 @@ public static function storeFallbackDetails($attempt_no, $proview_url, $proctor_ ]); return $response; } - private static function redirect_to_wrapper($proctoring_payload, $quiz) + private static function redirect_to_wrapper($proctoring_payload, $quiz, $quizaccess_proctor_setting) { // TODO Add check if wrapper URL already exists - $wrapper_response = self::create_sb_wrapper($proctoring_payload, $quiz); + $wrapper_response = self::create_sb_wrapper($proctoring_payload, $quiz, $quizaccess_proctor_setting); // redirect($wrapper_response->signed_short_url); echo ""; return; @@ -107,14 +107,24 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) $auth_response = self::generate_auth_token($api_base_url, $auth_payload); $auth_token = $auth_response['access_token']; $url = $api_base_url . '/proview/wrapper/create'; + + $blacklisted_softwares_mac = isset($quiz->blacklisted_softwares_mac) ? (array) $quiz->blacklisted_softwares_mac : []; + $blacklisted_softwares_windows = isset($quiz->blacklisted_softwares_win) ? (array) $quiz->blacklisted_softwares_win : []; + $data = array( 'session_external_id' => $proctoring_payload->session_id, 'attendee_external_id' => $proctoring_payload->profile_id, 'redirect_url' => $PAGE->url->__toString(), - 'expiry' => date(DATE_ISO8601, $quiz->timeclose == 0 ? strtotime("+3 days") : $quiz->timeclose ), - 'is_secure_browser' => true + 'expiry' => date(DATE_ISO8601, $quiz->timeclose == 0 ? strtotime("+3 days") : $quiz->timeclose), + 'is_secure_browser' => true, + "secure_browser" => [ + "blacklisted_softwares_mac" => $blacklisted_softwares_mac, + "blacklisted_softwares_windows" => $blacklisted_softwares_windows, + "is_record_screen" => isset($quiz->sb_content_protection) ? boolval($quiz->sb_content_protection) : false, + "is_minimize" => isset($quiz->sb_kiosk_mode) ? boolval($quiz->sb_kiosk_mode) : false, + ], ); - // var_dump($data); + try { $curl->setHeader(array('Content-Type: application/json', 'Authorization: Bearer ' . $auth_token)); $response = $curl->post($url, json_encode($data)); @@ -127,6 +137,7 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) + private static function generate_auth_token($api_base_url, $payload) { $curl = new \curl(); @@ -197,7 +208,7 @@ public static function insert_tracking() $quizaccess_proctor_setting->proctortype == 'noproctor' && $quizaccess_proctor_setting->tsbenabled && strpos($_SERVER ['HTTP_USER_AGENT'], "Proview-SB") === FALSE) { - self::redirect_to_wrapper($template, $quiz); + self::redirect_to_wrapper($template, $quiz, $quizaccess_proctor_setting); return; } diff --git a/datastore.php b/datastore.php index a78e28d..2784801 100644 --- a/datastore.php +++ b/datastore.php @@ -89,6 +89,15 @@ $template->profile_id = $USER->id; $template->instructions = $quizaccess_proctor_setting->instructions; $template->reference_link= $quizaccess_proctor_setting->reference_link; + if ($quizaccess_proctor_setting->tsbenabled === "1" ) { + $template->tsb_enabled = true; + $template->sb_blacklisted_software_windows= isset($quizaccess_proctor_setting->blacklisted_softwares_win) ? $quizaccess_proctor_setting->blacklisted_softwares_win : ''; + $template->sb_blacklisted_software_mac= isset($quizaccess_proctor_setting->blacklisted_softwares_mac) ? $quizaccess_proctor_setting->blacklisted_softwares_mac : ''; + $template->minimize_permitted= isset($quizaccess_proctor_setting->sb_kiosk_mode) ? !boolval($quizaccess_proctor_setting->sb_kiosk_mode) : true; + $template->screen_protection= isset($quizaccess_proctor_setting->sb_content_protection) ? boolval($quizaccess_proctor_setting->sb_content_protection) : false; + }else{ + $template->tsb_enabled = false; + } $template->session_id = $template->session_type === "live_proctor" ? $quizid.'-'.$USER->id : $quizid.'-'.$USER->id.'-'.$attempt; // Do not append attempt number for live proctoring. Re-attempting same quiz not supported in live proctoring. $template->proview_url = trim(get_config('local_proview', 'proview_url')); $template->token = trim(get_config('local_proview', 'token')); diff --git a/frame.php b/frame.php index 18684e4..ae44ec6 100644 --- a/frame.php +++ b/frame.php @@ -84,17 +84,20 @@ function receiveMessage(event) { function startProview( - authToken, - profileId, - session, - session_type = "ai_proctor", - proview_url, + authToken, + profileId, + session, + session_type, + proview_url, additionalInstruction, reference_link, proview_playback_url, - skipHardwareTest, - previewStyle, - clear) { + blacklistedSoftwaresWindows, + blacklistedSoftwaresMac, + isScreenProtectionEnabled, + minimizeOption, + tsbenabled + ) { const referenceLinksArray = reference_link.match(/\[([^\]]+)\]\(([^)]+)\)/g)?.map(markdownLink => { const match = markdownLink.match(/\[([^\]]+)\]\(([^)]+)\)/); if (match) { @@ -117,9 +120,14 @@ function startProview( session_type: session_type, additionalInstruction: additionalInstruction, referenceLinks: JSON.stringify(referenceLinksArray), - clear: clear || false, - skipHardwareTest: skipHardwareTest || false, - previewStyle: previewStyle || 'position: fixed; bottom: 0px;', + clear: false, + skipHardwareTest: false, + previewStyle: 'position: fixed; bottom: 0px;', + enforceTSB: tsbenabled, + blacklistedSoftwaresWindows: blacklistedSoftwaresWindows, + blacklistedSoftwaresMac: blacklistedSoftwaresMac, + isScreenProtectionEnabled: isScreenProtectionEnabled, + minimizeOption: minimizeOption, initCallback: createCallback(proview_playback_url, profileId, session_type)/* onProviewStart */ }); } @@ -220,7 +228,22 @@ function run(){ response=xmlhttp.responseText; response=JSON.parse(response); window.quizPassword = response.quiz_password; - startProview(response.token, response.profile_id, response.session_id, response.session_type, response.proview_url, response.instructions, response.reference_link, response.proview_playback_url); + console.log(response); + startProview( + response.token, + response.profile_id, + response.session_id, + response.session_type, + response.proview_url, + response.instructions, + response.reference_link, + response.proview_playback_url, + response.sb_blacklisted_software_windows, + response.sb_blacklisted_software_mac, + response.screen_protection, + response.minimize_permitted, + response.tsb_enabled + ); } } xmlhttp.open("GET", "datastore.php?quiz_id=" + urlParams.get('quizId') + "&sesskey=" + "" , true); diff --git a/version.php b/version.php index a37a61b..2b9239c 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024102805; +$plugin->version = 2024110401; $plugin->requires = 2020061500; -$plugin->release = '3.3.7 (Build: 2024102805)'; +$plugin->release = '3.3.7 (Build: 2024110401)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From a05440579f0e3804183f5927c15ef9af11266eba Mon Sep 17 00:00:00 2001 From: Rohan Sharma Sitoula Date: Tue, 5 Nov 2024 11:15:59 +0530 Subject: [PATCH 10/11] Update secure browser logic and bump plugin version to 3.3.8 --- classes/local/api/tracker.php | 3 +-- frame.php | 1 - version.php | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index 9e813b2..c3690cb 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -89,7 +89,6 @@ public static function storeFallbackDetails($attempt_no, $proview_url, $proctor_ } private static function redirect_to_wrapper($proctoring_payload, $quiz, $quizaccess_proctor_setting) { - // TODO Add check if wrapper URL already exists $wrapper_response = self::create_sb_wrapper($proctoring_payload, $quiz, $quizaccess_proctor_setting); // redirect($wrapper_response->signed_short_url); echo ""; @@ -116,7 +115,7 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) 'attendee_external_id' => $proctoring_payload->profile_id, 'redirect_url' => $PAGE->url->__toString(), 'expiry' => date(DATE_ISO8601, $quiz->timeclose == 0 ? strtotime("+3 days") : $quiz->timeclose), - 'is_secure_browser' => true, + 'is_secure_browser' => isset($quiz->tsbenabled) ? boolval($quiz->tsbenabled) : false, "secure_browser" => [ "blacklisted_softwares_mac" => $blacklisted_softwares_mac, "blacklisted_softwares_windows" => $blacklisted_softwares_windows, diff --git a/frame.php b/frame.php index ae44ec6..4695e6b 100644 --- a/frame.php +++ b/frame.php @@ -228,7 +228,6 @@ function run(){ response=xmlhttp.responseText; response=JSON.parse(response); window.quizPassword = response.quiz_password; - console.log(response); startProview( response.token, response.profile_id, diff --git a/version.php b/version.php index 2b9239c..8a1a727 100644 --- a/version.php +++ b/version.php @@ -28,9 +28,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2024110401; +$plugin->version = 2024110501; $plugin->requires = 2020061500; -$plugin->release = '3.3.7 (Build: 2024110401)'; +$plugin->release = '3.3.8 (Build: 2024110501)'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'local_proview'; From a71a3c30e7a8ae630e506c15037dbaac9299f291 Mon Sep 17 00:00:00 2001 From: Rohan Sharma Sitoula Date: Tue, 5 Nov 2024 12:07:05 +0530 Subject: [PATCH 11/11] Refactor `create_sb_wrapper` to use `quizaccess_proctor_setting` for secure browser configurations --- classes/local/api/tracker.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/classes/local/api/tracker.php b/classes/local/api/tracker.php index c3690cb..51e2fd0 100644 --- a/classes/local/api/tracker.php +++ b/classes/local/api/tracker.php @@ -95,7 +95,7 @@ private static function redirect_to_wrapper($proctoring_payload, $quiz, $quizacc return; } - private static function create_sb_wrapper($proctoring_payload, $quiz) + private static function create_sb_wrapper($proctoring_payload, $quiz, $quizaccess_proctor_setting) { global $PAGE; $curl = new \curl(); @@ -107,20 +107,29 @@ private static function create_sb_wrapper($proctoring_payload, $quiz) $auth_token = $auth_response['access_token']; $url = $api_base_url . '/proview/wrapper/create'; - $blacklisted_softwares_mac = isset($quiz->blacklisted_softwares_mac) ? (array) $quiz->blacklisted_softwares_mac : []; - $blacklisted_softwares_windows = isset($quiz->blacklisted_softwares_win) ? (array) $quiz->blacklisted_softwares_win : []; + $blacklisted_softwares_mac = isset($quizaccess_proctor_setting->blacklisted_softwares_mac) + ? array_filter((array) $quizaccess_proctor_setting->blacklisted_softwares_mac, function($item) { + return !empty($item); + }) + : []; + + $blacklisted_softwares_windows = isset($quizaccess_proctor_setting->blacklisted_softwares_win) + ? array_filter((array) $quizaccess_proctor_setting->blacklisted_softwares_win, function($item) { + return !empty($item); + }) + : []; $data = array( 'session_external_id' => $proctoring_payload->session_id, 'attendee_external_id' => $proctoring_payload->profile_id, 'redirect_url' => $PAGE->url->__toString(), 'expiry' => date(DATE_ISO8601, $quiz->timeclose == 0 ? strtotime("+3 days") : $quiz->timeclose), - 'is_secure_browser' => isset($quiz->tsbenabled) ? boolval($quiz->tsbenabled) : false, + 'is_secure_browser' => isset($quizaccess_proctor_setting->tsbenabled) ? boolval($quizaccess_proctor_setting->tsbenabled) : false, "secure_browser" => [ "blacklisted_softwares_mac" => $blacklisted_softwares_mac, "blacklisted_softwares_windows" => $blacklisted_softwares_windows, - "is_record_screen" => isset($quiz->sb_content_protection) ? boolval($quiz->sb_content_protection) : false, - "is_minimize" => isset($quiz->sb_kiosk_mode) ? boolval($quiz->sb_kiosk_mode) : false, + "is_record_screen" => isset($quizaccess_proctor_setting->sb_content_protection) ? boolval($quizaccess_proctor_setting->sb_content_protection) : false, + "is_minimize" => isset($quizaccess_proctor_setting->sb_kiosk_mode) ? boolval($quizaccess_proctor_setting->sb_kiosk_mode) : false, ], );