Skip to content

Commit 7ffc077

Browse files
kevin-vuong99Kevin Vuong
andauthored
Session timeout notification 2 (#12225)
* session-timeout-notification * add authenticated check before sending notification * add new line at end of context_processors file * manage aria-hidden attribute on session notification modal * remove docker-compose DD_SESSION_COOKIE_AGE tests --------- Co-authored-by: Kevin Vuong <kevin.vuong@hrsdc-rhdcc.gc>
1 parent 2f2db2d commit 7ffc077

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

dojo/context_processors.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,22 @@ def bind_announcement(request):
5757
).get(user=request.user)
5858
return {"announcement": user_announcement.announcement}
5959
return {}
60+
61+
62+
def session_expiry_notification(request):
63+
import time
64+
65+
try:
66+
if request.user.is_authenticated:
67+
last_activity = request.session.get("_last_activity", time.time())
68+
expiry_time = last_activity + settings.SESSION_COOKIE_AGE # When the session will expire
69+
warning_time = settings.SESSION_EXPIRE_WARNING # Show warning X seconds before expiry
70+
notify_time = expiry_time - warning_time
71+
else:
72+
notify_time = None
73+
except Exception:
74+
return {}
75+
else:
76+
return {
77+
"session_notify_time": notify_time,
78+
}

dojo/settings/settings.dist.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
DD_SECURE_HSTS_SECONDS=(int, 31536000), # One year expiration
4444
DD_SESSION_COOKIE_SECURE=(bool, False),
4545
DD_SESSION_EXPIRE_AT_BROWSER_CLOSE=(bool, False),
46+
DD_SESSION_EXPIRE_WARNING=(int, 300), # warning 5 mins before expiration
4647
DD_SESSION_COOKIE_AGE=(int, 1209600), # 14 days
4748
DD_CSRF_COOKIE_SECURE=(bool, False),
4849
DD_CSRF_TRUSTED_ORIGINS=(list, []),
@@ -756,6 +757,7 @@ def generate_url(scheme, double_slashes, user, password, host, port, path, param
756757
SECURE_HSTS_INCLUDE_SUBDOMAINS = env("DD_SECURE_HSTS_INCLUDE_SUBDOMAINS")
757758

758759
SESSION_EXPIRE_AT_BROWSER_CLOSE = env("DD_SESSION_EXPIRE_AT_BROWSER_CLOSE")
760+
SESSION_EXPIRE_WARNING = env("DD_SESSION_EXPIRE_WARNING")
759761
SESSION_COOKIE_AGE = env("DD_SESSION_COOKIE_AGE")
760762

761763
# ------------------------------------------------------------------------------
@@ -858,6 +860,7 @@ def generate_url(scheme, double_slashes, user, password, host, port, path, param
858860
"dojo.context_processors.bind_system_settings",
859861
"dojo.context_processors.bind_alert_count",
860862
"dojo.context_processors.bind_announcement",
863+
"dojo.context_processors.session_expiry_notification",
861864
],
862865
},
863866
},

dojo/templates/base.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,26 @@ <h3 class="no-margin-top" style="padding-bottom: 5px;">
10321032
</div>
10331033
<!-- /.dojo-modals-wrapper -->
10341034

1035+
<!-- Session Timeout Modal -->
1036+
<div class="modal fade" id="sessionTimeoutModal" tabindex="-1" role="dialog" aria-labelledby="sessionModalLabel" aria-hidden="true">
1037+
<div class="modal-dialog" role="document">
1038+
<div class="modal-content">
1039+
<div class="modal-header">
1040+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
1041+
<span aria-hidden="true">&times;</span>
1042+
</button>
1043+
<h4 class="modal-title" id="sessionModalLabel">Session Expiring Soon</h4>
1044+
</div>
1045+
<div class="modal-body">
1046+
Your session is about to expire due to inactivity.
1047+
</div>
1048+
<div class="modal-footer">
1049+
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
1050+
</div>
1051+
</div>
1052+
</div>
1053+
</div>
1054+
10351055
<!-- #footer-wrapper -->
10361056
<div id="footer-wrapper">
10371057
{% block footer %}
@@ -1083,6 +1103,27 @@ <h3 class="no-margin-top" style="padding-bottom: 5px;">
10831103
function() { $(this).popover('show'); }, // hover
10841104
function() { $(this).popover('hide'); } // unhover
10851105
);
1106+
1107+
{% if request.user.is_authenticated %}
1108+
function session_notifcation() {
1109+
var warningTime = "{{ session_notify_time|default:0|escapejs }}"; // When the warning will show
1110+
var currentTime = Math.floor(Date.now() / 1000); // Get current timestamp in seconds
1111+
var timeout = warningTime - currentTime; // how many seconds until warning needs to show
1112+
1113+
setTimeout(() => {
1114+
$('#sessionTimeoutModal').modal('show');
1115+
}, timeout * 1000);
1116+
1117+
}
1118+
session_notifcation();
1119+
$('#sessionTimeoutModal').on('show.bs.modal', function (event) {
1120+
$(this).attr('aria-hidden', 'false');
1121+
})
1122+
$('#sessionTimeoutModal').on('hidden.bs.modal', function (event) {
1123+
$(this).attr('aria-hidden', 'true');
1124+
})
1125+
{% endif %}
1126+
10861127
{% if request.user.is_authenticated and not 'DISABLE_ALERT_COUNTER'|setting_enabled %}
10871128
function get_alerts() {
10881129
$('.dropdown-alerts').html('<div class="text-center"><i class="fa-solid fa-spinner fa-spin"></i></div>');

0 commit comments

Comments
 (0)