-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.php
More file actions
65 lines (60 loc) · 2.53 KB
/
Copy pathlib.php
File metadata and controls
65 lines (60 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
defined('MOODLE_INTERNAL') || die();
/**
* Injecte le heartbeat + le verrou de page sur les pages d'examen (quiz), quand
* une session SEB live existe pour l'utilisateur. Le JS bat toutes les 5 s ;
* si le serveur répond kill=1 (ré-attestation tampered, trou, révocation), il
* recouvre la page d'un voile bloquant => la session déjà ouverte ne sert plus.
*
* Callback `standard_after_main_region_html` (Moodle 4.x : itéré par le hook
* after_standard_main_region_html_generation::process_legacy_callbacks) — RETOURNE
* la chaîne, injectée en bas de la région principale. `standard_end_of_body_html`
* n'itère plus les plugins en 4.5.
*
* NB : un client cracké peut tenter de retirer ce JS ; le contrôle robuste reste
* serveur (révocation du token + balayage). Ici le JS rend l'invalidation
* immédiate à l'écran ; un sous-plugin quizaccess (TODO) la rendrait inviolable.
*/
function local_sebfix_standard_after_main_region_html() {
global $PAGE, $USER, $CFG;
if (!isloggedin() || isguestuser()) {
return '';
}
// (string) sur modname : cm_info renvoie une valeur magique non strictement
// string, donc `!== 'quiz'` partait en faux positif sans le cast.
$cm = $PAGE->cm;
if (empty($cm) || (string) $cm->modname !== 'quiz') {
return '';
}
$sess = \local_sebfix\session::live_for((int) $USER->id, (int) $cm->id);
if (!$sess) {
return '';
}
$hburl = $CFG->wwwroot . '/local/sebfix/heartbeat.php';
$tid = (int) $sess->id;
$sk = sesskey();
$iv = \local_sebfix\heartbeat_manager::INTERVAL * 1000;
$msg = addslashes(get_string('session_locked', 'local_sebfix'));
return <<<HTML
<script>
(function(){
var TID={$tid}, SK="{$sk}", URL="{$hburl}", IV={$iv};
function lock(reason){
if(document.getElementById('sebfix-lock'))return;
var d=document.createElement('div'); d.id='sebfix-lock';
d.style.cssText='position:fixed;inset:0;z-index:2147483647;background:#6e211e;color:#fff;display:flex;align-items:center;justify-content:center;font:600 20px/1.5 sans-serif;text-align:center;padding:2rem';
d.textContent="{$msg} ("+reason+")";
document.body.appendChild(d);
}
function beat(){
var b=new URLSearchParams(); b.set('id',TID); b.set('sesskey',SK);
fetch(URL,{method:'POST',body:b,credentials:'same-origin'})
.then(function(r){return r.json();})
.then(function(j){ if(j && j.kill){ lock(j.reason||'invalid'); } })
.catch(function(){});
}
beat(); setInterval(beat, IV);
})();
</script>
HTML;
}