Skip to content

Commit 80c866e

Browse files
authored
Prevented check_timeout calls when window is inactive or session has expired (#8074)
1 parent af1bd4b commit 80c866e

5 files changed

Lines changed: 64 additions & 11 deletions

File tree

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
### 🚨 Breaking changes
88

99
### ✨ New features and improvements
10+
- Improved Session Timeout Logic: `check_timeout` polling paused when user is not focused on the MarkUs tab and polling stops after user session has timed out (#8074)
1011
- Migrated Groups Manager students and groups tables to use `react-table` v8 (#8068)
1112
- Decreased size of QR codes on scanned assessments and ignored whitespace in OCR of page labels (#8076)
1213
- Added automatic collection of scanned exam submissions once a paper's pages are all present and error-free (#8069)
Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,60 @@
11
(function () {
2+
let intervalId;
3+
let sessionExpired = false;
4+
25
const domContentLoadedCB = () => {
3-
setInterval(() => {
4-
$.get(Routes.check_timeout_main_index_path());
6+
startPolling();
7+
};
8+
9+
const startPolling = () => {
10+
if (intervalId) return;
11+
12+
intervalId = setInterval(() => {
13+
checkTimeout();
514
}, 120000);
615
};
716

17+
const stopPolling = () => {
18+
clearInterval(intervalId);
19+
intervalId = null;
20+
};
21+
22+
const checkTimeout = () => {
23+
fetch(Routes.check_timeout_main_index_path())
24+
.then(response => {
25+
if (response.status === 401) {
26+
sessionExpired = true;
27+
stopPolling();
28+
return;
29+
}
30+
31+
return response.json();
32+
})
33+
.then(data => {
34+
if (!data) return;
35+
36+
if (data.time_remaining <= 300) {
37+
timeout_imminent_modal.open();
38+
39+
$("#timeout-imminent-modal-close")
40+
.off("click")
41+
.on("click", function () {
42+
refreshOrLogout();
43+
timeout_imminent_modal.close();
44+
});
45+
}
46+
});
47+
};
48+
849
document.addEventListener("DOMContentLoaded", domContentLoadedCB);
50+
document.addEventListener("visibilitychange", () => {
51+
if (document.hidden) {
52+
stopPolling();
53+
} else {
54+
checkTimeout();
55+
if (!sessionExpired) {
56+
startPolling();
57+
}
58+
}
59+
});
960
})();

app/controllers/main_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ def page_not_found
123123
end
124124

125125
def check_timeout
126-
head :ok unless check_imminent_expiry
126+
if session_expired?
127+
head :unauthorized
128+
else
129+
render json: { time_remaining: session_time_remaining }
130+
end
127131
end
128132

129133
def refresh_session

app/lib/session_handler.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@ def session_expired?
148148
Time.zone.parse(session[:timeout]) < Time.current
149149
end
150150

151-
def check_imminent_expiry
152-
return false if remote_auth?
153-
!session[:timeout].nil? && (Time.zone.parse(session[:timeout]) - Time.current) <= 5.minutes
151+
def session_time_remaining
152+
return 0 if remote_auth?
153+
return 0 if session[:timeout].nil?
154+
155+
(Time.zone.parse(session[:timeout]) - Time.current).to_i
154156
end
155157

156158
# Clear this current user's session set by this app

app/views/main/check_timeout.js.erb

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)