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:
parent
52e0566695
commit
239092b872
|
@ -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>
|
|
@ -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 %}
|
||||||
|
|
|
@ -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 }}",
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
|
@ -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 []
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Reference in New Issue