diora-web/templates/accounts/login.html
mrwnslz 077e6d4543
Some checks failed
Build and push Docker image / build (push) Successful in 17s
Test / test (push) Successful in 11m22s
Test / e2e (push) Failing after 1m29s
Anmelden mit Authelia als zweiter Weg, Bücher auf neuen Geräten per Code entsperren (sw CACHE v161)
Auf der Login-Seite gibt es „Mit Authelia anmelden“, wenn der Server dafür
eingerichtet ist. Das eigene Konto wird einmal in den Einstellungen verknüpft,
die Anmeldung mit Passwort bleibt. Fremde Authelia-Konten kommen nicht hinein,
neue Konten entstehen darüber nicht.

Fehlt einem Gerät der Bücher-Schlüssel (nach der Authelia-Anmeldung oder nach
gelöschtem Speicher), erzeugt diora keinen neuen mehr, der die Bücher
unlesbar machen würde. Stattdessen fragt es: Ein schon entsperrtes Gerät zeigt
denselben Code und gibt den Schlüssel verschlüsselt frei, oder man gibt einmal
das diora-Passwort ein. Der Server sieht den Schlüssel dabei nie.

Details: docs/accounts.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 15:01:25 +01:00

67 lines
2.2 KiB
HTML

{% extends "base.html" %}
{% block title %}Anmelden — diora{% endblock %}
{% block content %}
<div class="auth-container">
<h1 class="auth-title">Anmelden</h1>
<form method="post" class="auth-form">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% if field.errors %}
<ul class="field-errors">
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
{% if form.non_field_errors %}
<div class="form-errors">
{% for error in form.non_field_errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
<button type="submit" class="btn btn-primary btn-full">Anmelden</button>
</form>
{% if oidc_enabled %}
<div class="auth-alt">
<div class="auth-or"><span>oder</span></div>
<a class="btn btn-full" href="{% url 'oidc_start' %}{% if request.GET.next %}?next={{ request.GET.next|urlencode }}{% endif %}">Mit {{ oidc_provider }} anmelden</a>
</div>
{% endif %}
<p class="auth-switch">
Noch kein Konto? <a href="{% url 'register' %}">Registrieren</a>
</p>
</div>
{% endblock %}
{% block extra_js %}
<script>
(function () {
var form = document.querySelector('.auth-form');
if (!form) return;
form.addEventListener('submit', async function (e) {
var u = form.querySelector('[name=username]');
var p = form.querySelector('[name=password]');
if (!u || !p || !u.value || !p.value) return;
e.preventDefault();
try {
var enc = new TextEncoder();
var mat = await crypto.subtle.importKey('raw', enc.encode(p.value), 'PBKDF2', false, ['deriveKey']);
var key = await crypto.subtle.deriveKey(
{name: 'PBKDF2', salt: enc.encode('diora:' + u.value), iterations: 200000, hash: 'SHA-256'},
mat, {name: 'AES-GCM', length: 256}, true, ['encrypt', 'decrypt']
);
var raw = await crypto.subtle.exportKey('raw', key);
localStorage.setItem('diora_pending_enc_key', btoa(String.fromCharCode(...new Uint8Array(raw))));
} catch (err) {}
form.submit();
});
})();
</script>
{% endblock %}