58 lines
1.8 KiB
Plaintext
58 lines
1.8 KiB
Plaintext
{% extends 'layouts/base.njk' %}
|
|
|
|
{% set h1 = 'Authentication lobby' %}
|
|
{% set title = app.name + ' ' + h1 %}
|
|
|
|
{% block body %}
|
|
<div class="container">
|
|
<div class="panel">
|
|
{{ macros.message('success', 'We sent a link to ' + email + '. To authenticate, open it from any device.') }}
|
|
{{ macros.message('info', 'This link will be valid for <span id="countdown"></span> and can only be used once.', true, true) }}
|
|
|
|
<p class="center">Waiting for you to open the link...</p>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
const validUntil = {{ validUntil }}.0;
|
|
|
|
function isValid() {
|
|
return new Date().getTime() < validUntil;
|
|
}
|
|
|
|
function websocketListen(websocket, e) {
|
|
if (e.data === 'refresh') {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const countdown = document.getElementById('countdown');
|
|
|
|
if (!isValid()) return;
|
|
|
|
function animateCountdown() {
|
|
requestAnimationFrame(() => {
|
|
let diff = Math.max(0, validUntil - new Date().getTime());
|
|
if (diff === 0) {
|
|
return;
|
|
}
|
|
|
|
diff /= 1000;
|
|
const seconds = Math.floor(diff % 60).toFixed(0);
|
|
const minutes = Math.floor((diff - seconds) / 60).toFixed(0);
|
|
|
|
countdown.innerText = `${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
|
|
animateCountdown();
|
|
});
|
|
}
|
|
|
|
animateCountdown();
|
|
});
|
|
</script>
|
|
|
|
{{ macros.websocket(websocketUrl, 'websocketListen', 1, 'isValid') }}
|
|
{% endblock %}
|