This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/passbook/flows/templates/flows/shell.html

156 lines
5.0 KiB
HTML

{% extends 'login/base_full.html' %}
{% load static %}
{% load i18n %}
{% block head %}
{{ block.super }}
<style>
.pb-loading,
.pf-c-login__main >iframe {
display: flex;
height: 100%;
width: 100%;
justify-content: center;
align-items: center;
}
.pb-hidden {
display: none
}
</style>
{% endblock %}
{% block main_container %}
<main class="pf-c-login__main" id="flow-body">
<div class="pf-c-login__main-body pb-loading">
<span class="pf-c-spinner" role="progressbar" aria-valuetext="Loading...">
<span class="pf-c-spinner__clipper"></span>
<span class="pf-c-spinner__lead-ball"></span>
<span class="pf-c-spinner__tail-ball"></span>
</span>
</div>
</main>
<script>
const flowBodyUrl = "{{ exec_url }}";
const messagesUrl = "{{ msg_url }}";
const flowBody = document.querySelector("#flow-body");
const spinner = document.querySelector(".pb-loading");
const updateMessages = () => {
let messageContainer = document.querySelector(".pf-c-alert-group");
fetch(messagesUrl).then(response => {
messageContainer.innerHTML = "";
response.json().then(data => {
data.forEach(msg => {
let icon = "";
switch (msg.level_tag) {
case 'error':
icon = 'fas fa-exclamation-circle'
break;
case 'warning':
icon = 'fas fa-exclamation-triangle'
break;
case 'success':
icon = 'fas fa-check-circle'
break;
case 'info':
icon = 'fas fa-info'
break;
default:
break;
}
if (msg.level_tag === "error") {
msg.extra_tags = "pf-m-danger";
}
let item = `<li class="pf-c-alert-group__item">
<div class="pf-c-alert pf-m-${msg.level_tag} ${msg.extra_tags}">
<div class="pf-c-alert__icon">
<i class="${icon}"></i>
</div>
<h4 class="pf-c-alert__title">
${msg.message}
</h4>
</div>
</li>`;
var template = document.createElement('template');
template.innerHTML = item;
messageContainer.appendChild(template.content.firstChild);
});
});
});
};
const updateCard = (data) => {
switch (data.type) {
case "redirect":
window.location = data.to
break;
case "template":
flowBody.innerHTML = data.body;
checkAutofocus();
updateMessages();
loadFormCode();
setFormSubmitHandlers();
default:
break;
}
};
const showSpinner = () => {
flowBody.innerHTML = "";
flowBody.appendChild(spinner);
};
const loadFormCode = () => {
document.querySelectorAll("#flow-body script").forEach(script => {
let newScript = document.createElement("script");
newScript.src = script.src;
document.head.appendChild(newScript);
});
};
const checkAutofocus = () => {
const autofocusElement = document.querySelector("#flow-body [autofocus]");
if (autofocusElement !== null) {
autofocusElement.focus();
}
};
const updateFormAction = (form) => {
for (let index = 0; index < form.elements.length; index++) {
const element = form.elements[index];
if (element.value === form.action) {
console.log("pb-flow: Found Form action URL in form elements, not changing form action.");
return false;
}
}
form.action = flowBodyUrl;
console.log(`pb-flow: updated form.action ${flowBodyUrl}`);
return true;
};
const checkAutosubmit = (form) => {
if ("autosubmit" in form.attributes) {
return form.submit();
}
};
const setFormSubmitHandlers = () => {
document.querySelectorAll("#flow-body form").forEach(form => {
console.log(`pb-flow: Checking for autosubmit attribute ${form}`);
checkAutosubmit(form);
console.log(`pb-flow: Setting action for form ${form}`);
updateFormAction(form);
console.log(`pb-flow: Adding handler for form ${form}`);
form.addEventListener('submit', (e) => {
e.preventDefault();
let formData = new FormData(form);
showSpinner();
fetch(flowBodyUrl, {
method: 'post',
body: formData,
}).then(response => response.json()).then(data => {
updateCard(data);
});
});
form.classList.add("pb-flow-wrapped");
});
};
fetch(flowBodyUrl).then(response => response.json()).then(data => updateCard(data));
</script>
{% endblock %}