core: fix messages not being shown when no client is connected

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-10-10 13:18:08 +03:00
parent 52e0566695
commit 239092b872
8 changed files with 38 additions and 24 deletions

View file

@ -0,0 +1,20 @@
<script>
window.authentik = {};
window.authentik.locale = "{{ tenant.default_locale }}";
window.authentik.config = JSON.parse('{{ config_json|escapejs }}');
window.authentik.tenant = JSON.parse('{{ tenant_json|escapejs }}');
window.addEventListener("DOMContentLoaded", () => {
{% for message in messages %}
window.dispatchEvent(
new CustomEvent("ak-message", {
bubbles: true,
composed: true,
detail: {
level: "{{ message.tags|escapejs }}",
message: "{{ message.message|escapejs }}",
},
}),
);
{% endfor %}
});
</script>

View file

@ -9,12 +9,7 @@
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<link rel="icon" href="{{ tenant.branding_favicon }}"> <link rel="icon" href="{{ tenant.branding_favicon }}">
<link rel="shortcut icon" href="{{ tenant.branding_favicon }}"> <link rel="shortcut icon" href="{{ tenant.branding_favicon }}">
<script> {% include "base/header_js.html" %}
window.authentik = {};
window.authentik.locale = "{{ tenant.default_locale }}";
window.authentik.config = JSON.parse('{{ config_json|escapejs }}');
window.authentik.tenant = JSON.parse('{{ tenant_json|escapejs }}');
</script>
{% endblock %} {% endblock %}
{% block body %} {% block body %}

View file

@ -11,11 +11,8 @@
{% if flow.compatibility_mode and not inspector %} {% if flow.compatibility_mode and not inspector %}
<script>ShadyDOM = { force: !navigator.webdriver };</script> <script>ShadyDOM = { force: !navigator.webdriver };</script>
{% endif %} {% endif %}
{% include "base/header_js.html" %}
<script> <script>
window.authentik = {};
window.authentik.locale = "{{ tenant.default_locale }}";
window.authentik.config = JSON.parse('{{ config_json|escapejs }}');
window.authentik.tenant = JSON.parse('{{ tenant_json|escapejs }}');
window.authentik.flow = { window.authentik.flow = {
"layout": "{{ flow.layout }}", "layout": "{{ flow.layout }}",
}; };

View file

@ -9,12 +9,7 @@
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)"> <meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)">
<link rel="icon" href="{{ tenant.branding_favicon }}"> <link rel="icon" href="{{ tenant.branding_favicon }}">
<link rel="shortcut icon" href="{{ tenant.branding_favicon }}"> <link rel="shortcut icon" href="{{ tenant.branding_favicon }}">
<script> {% include "base/header_js.html" %}
window.authentik = {};
window.authentik.locale = "{{ tenant.default_locale }}";
window.authentik.config = JSON.parse('{{ config_json|escapejs }}');
window.authentik.tenant = JSON.parse('{{ tenant_json|escapejs }}');
</script>
{% endblock %} {% endblock %}
{% block body %} {% block body %}

View file

@ -6,6 +6,7 @@
{% block head_before %} {% block head_before %}
<link rel="prefetch" href="/static/dist/assets/images/flow_background.jpg" /> <link rel="prefetch" href="/static/dist/assets/images/flow_background.jpg" />
<link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly.min.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly.min.css' %}">
{% include "base/header_js.html" %}
{% endblock %} {% endblock %}
{% block head %} {% block head %}

View file

@ -55,7 +55,7 @@ class StageViewSet(
): ):
"""Stage Viewset""" """Stage Viewset"""
queryset = Stage.objects.all().select_related("flow_set") queryset = Stage.objects.none()
serializer_class = StageSerializer serializer_class = StageSerializer
search_fields = ["name"] search_fields = ["name"]
filterset_fields = ["name"] filterset_fields = ["name"]

View file

@ -1,12 +1,15 @@
"""Channels Messages storage""" """Channels Messages storage"""
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer from channels.layers import get_channel_layer
from django.contrib.messages.storage.base import BaseStorage, Message from django.contrib.messages.storage.base import Message
from django.contrib.messages.storage.session import SessionStorage
from django.core.cache import cache from django.core.cache import cache
from django.http.request import HttpRequest from django.http.request import HttpRequest
SESSION_KEY = "_messages"
class ChannelsStorage(BaseStorage):
class ChannelsStorage(SessionStorage):
"""Send contrib.messages over websocket""" """Send contrib.messages over websocket"""
def __init__(self, request: HttpRequest) -> None: def __init__(self, request: HttpRequest) -> None:
@ -14,12 +17,13 @@ class ChannelsStorage(BaseStorage):
super().__init__(request) super().__init__(request)
self.channel = get_channel_layer() self.channel = get_channel_layer()
def _get(self):
return [], True
def _store(self, messages: list[Message], response, *args, **kwargs): def _store(self, messages: list[Message], response, *args, **kwargs):
prefix = f"user_{self.request.session.session_key}_messages_" prefix = f"user_{self.request.session.session_key}_messages_"
keys = cache.keys(f"{prefix}*") keys = cache.keys(f"{prefix}*")
# if no active connections are open, fallback to storing messages in the
# session, so they can always be retrieved
if len(keys) < 1:
return super()._store(messages, response, *args, **kwargs)
for key in keys: for key in keys:
uid = key.replace(prefix, "") uid = key.replace(prefix, "")
for message in messages: for message in messages:
@ -33,3 +37,4 @@ class ChannelsStorage(BaseStorage):
"message": message.message, "message": message.message,
}, },
) )
return []

View file

@ -44,11 +44,11 @@ export class MessageContainer extends AKElement {
constructor() { constructor() {
super(); super();
this.addEventListener(EVENT_WS_MESSAGE, ((e: CustomEvent<WSMessage>) => { window.addEventListener(EVENT_WS_MESSAGE, ((e: CustomEvent<WSMessage>) => {
if (e.detail.message_type !== WS_MSG_TYPE_MESSAGE) return; if (e.detail.message_type !== WS_MSG_TYPE_MESSAGE) return;
this.addMessage(e.detail as unknown as APIMessage); this.addMessage(e.detail as unknown as APIMessage);
}) as EventListener); }) as EventListener);
this.addEventListener(EVENT_MESSAGE, ((e: CustomEvent<APIMessage>) => { window.addEventListener(EVENT_MESSAGE, ((e: CustomEvent<APIMessage>) => {
this.addMessage(e.detail); this.addMessage(e.detail);
}) as EventListener); }) as EventListener);
} }
@ -61,6 +61,7 @@ export class MessageContainer extends AKElement {
} }
} }
this.messages.push(message); this.messages.push(message);
this.requestUpdate();
} }
render(): TemplateResult { render(): TemplateResult {