diff --git a/src/ephios/extra/middleware.py b/src/ephios/extra/middleware.py index cfea5da57..b47a1ccb9 100644 --- a/src/ephios/extra/middleware.py +++ b/src/ephios/extra/middleware.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.http import HttpResponse from ephios.core.services.notifications.types import NOTIFICATION_READ_PARAM_NAME @@ -41,3 +42,15 @@ def __call__(self, request): notification.read = True notification.save(update_fields=["read"]) return response + + +class CacheControlMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + response: HttpResponse = self.get_response(request) + # To prevent storing sensitive data in the cache as well as + # to prevent outdated data being shown to users + response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" + return response diff --git a/src/ephios/settings.py b/src/ephios/settings.py index 4fba2f360..d8f631af8 100644 --- a/src/ephios/settings.py +++ b/src/ephios/settings.py @@ -132,6 +132,7 @@ "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "ephios.extra.middleware.EphiosLocaleMiddleware", + "ephios.extra.middleware.CacheControlMiddleware", "ephios.extra.middleware.EphiosNotificationMiddleware", "ephios.core.services.files.EphiosMediaFileMiddleware", "django.middleware.common.CommonMiddleware", diff --git a/src/ephios/static/ephios/js/main.js b/src/ephios/static/ephios/js/main.js index 90089869e..3ca36d742 100644 --- a/src/ephios/static/ephios/js/main.js +++ b/src/ephios/static/ephios/js/main.js @@ -91,6 +91,11 @@ function handleForms(elem) { }); } +function blurForUnload() { + $('.blur-on-unload').addClass("unloading"); + $('#unloading-spinner').removeClass("d-none"); +} + $(document).ready(function () { // Configure all prerendered Forms handleForms($(document)); @@ -116,15 +121,9 @@ $(document).ready(function () { // https://stackoverflow.com/a/41749865 if (navigator.standalone || window.matchMedia('(display-mode: standalone)').matches) { $(window).on('beforeunload', function () { - $('.blur-on-unload').addClass("unloading"); - $('#unloading-spinner').removeClass("d-none"); + blurForUnload(); }); } - // when hitting "back" button in browser, the page is not reloaded so we need to remove the blur manually - window.addEventListener('pageshow', function (event) { - $('.blur-on-unload').removeClass("unloading"); - $('#unloading-spinner').addClass("d-none"); - }); if ($("body").data("pwa-network") === "offline") { // disable all forms and post buttons @@ -181,21 +180,21 @@ $(document).ready(function () { // We need to store the prompt to be able to show the install button later on. // We show the prompt to the user if they did not decline in the last month and are logged in window.addEventListener('beforeinstallprompt', (e) => { - e.preventDefault(); - deferredInstallPrompt = e; - if (!getCookie("pwaPrompt") && document.body.dataset.userIsAuthenticated === "True") { - pwaAndroidBsOffcanvas.show(); - } + e.preventDefault(); + deferredInstallPrompt = e; + if (!getCookie("pwaPrompt") && document.body.dataset.userIsAuthenticated === "True") { + pwaAndroidBsOffcanvas.show(); + } }); // When the user clicks on the install button in our PWA install prompt, we can used the saved prompt // from the browser event to actually trigger the installation const buttonInstall = document.getElementById("pwaInstall"); buttonInstall.addEventListener('click', async () => { - deferredInstallPrompt.prompt(); - await deferredInstallPrompt.userChoice; - pwaAndroidBsOffcanvas.hide(); - deferredInstallPrompt = null; + deferredInstallPrompt.prompt(); + await deferredInstallPrompt.userChoice; + pwaAndroidBsOffcanvas.hide(); + deferredInstallPrompt = null; }); // iOS does not support programmatic installation, so we show an offcanvas with instructions instead @@ -204,16 +203,23 @@ $(document).ready(function () { } setTimeout(() => { - // Only show this prompt inside of the PWA (with display-mode: standalone) for logged in user that did not decline in the last month + // Only show this prompt inside the PWA (with display-mode: standalone) for logged in user that did not decline in the last month // isPushEnabled is set by webpush.js from django-webpush if ((window.matchMedia('(display-mode: standalone)').matches || navigator.standalone) && typeof isPushEnabled !== undefined && !isPushEnabled && !getCookie("notificationPrompt")) { document.getElementById("webpush-subscribe-button") - .addEventListener("click", _ => notificationBsOffcanvas.hide()) + .addEventListener("click", _ => notificationBsOffcanvas.hide()) notificationBsOffcanvas.show(); } }, 2000); // isPushEnabled is only set to true after a request to the backend, so it takes some time +}); -}) +window.addEventListener('pageshow', (event) => { + if (event.persisted) { + // Force a reload if the page is shown from the bfcache. + blurForUnload(); + location.reload(); + } +}); function rememberDismissed(key) { const date = new Date(); diff --git a/src/ephios/templates/base.html b/src/ephios/templates/base.html index 3ba734af1..3a39a7618 100644 --- a/src/ephios/templates/base.html +++ b/src/ephios/templates/base.html @@ -204,27 +204,33 @@
{% blocktranslate trimmed with platform_name=platform_name %} You can install {{ platform_name }} on your device and use it like any other app! {% endblocktranslate %} {% translate "Simply click the button below to continue." %}
- +{% blocktranslate trimmed with platform_name=platform_name %} You can install {{ platform_name }} on your device and use it like any other app! - {% endblocktranslate %} {%translate "Simply follow the steps below." %}
+ {% endblocktranslate %} {% translate "Simply follow the steps below." %}{% blocktranslate trimmed with platform_name=platform_name %}{{ platform_name }} can send you push notifications so that you stay up to date. Do you want to activate them?" {% endblocktranslate %}
+{% blocktranslate trimmed with platform_name=platform_name %}{{ platform_name }} can send you push + notifications so that you stay up to date. Do you want to activate them?" {% endblocktranslate %}