diff options
| -rw-r--r-- | FASSUNGEN.txt | 107 | ||||
| -rw-r--r-- | README.adoc | 67 | ||||
| -rw-r--r-- | deploy/nginx-aendggner.conf | 101 | ||||
| -rwxr-xr-x | deploy/webpaket.sh | 73 | ||||
| -rw-r--r-- | pom.xml | 20 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/datenschutz.html | 43 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/favicon.svg | 9 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/impressum.html | 45 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/index.html | 17 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/style.css | 27 |
10 files changed, 442 insertions, 67 deletions
diff --git a/FASSUNGEN.txt b/FASSUNGEN.txt index ec8aeb5..ad304ba 100644 --- a/FASSUNGEN.txt +++ b/FASSUNGEN.txt @@ -21,6 +21,113 @@ Vorbemerkung zur Führung dieses Verzeichnisses ════════════════════════════════════════════════════════════════════════════════ + Fassung vom 16. August 2026, + zuletzt geändert durch die am 16. August 2026 vorgenommenen Änderungen +════════════════════════════════════════════════════════════════════════════════ + +Die Browserfassung war bislang für den öffentlichen Betrieb gesperrt: Die +Anbieterkennzeichnung und die Datenschutzerklärung führten Platzhalter, und der +Verweis auf den Quelltext, den die Lizenz des Erzeugnisses beim Netzbetrieb +verlangt, zeigte auf keine Adresse. Mit dieser Fassung wird die Sperre +aufgehoben; zugleich wird die Auslieferung auf den Betrieb unter einem Unterpfad +einer bestehenden Domain eingerichtet. + + +Artikel 1 +Anbieterkennzeichnung und Datenschutzerklärung + +(1) Die Anbieterkennzeichnung (impressum.html) wird mit den Angaben nach § 5 DDG + versehen; hinzu treten die Bezeichnung des nach § 18 Abs. 2 MStV + Verantwortlichen sowie ein Hinweis darauf, dass der Dienst unentgeltlich und + nichtkommerziell erbracht wird und die Synopsen ohne Gewähr ergehen. + +(2) Die Datenschutzerklärung (datenschutz.html) wird um die Bezeichnung des + Verantwortlichen (Art. 4 Nr. 7 DSGVO) und um die Rechte der betroffenen + Personen (Art. 15 bis 21, Art. 77 DSGVO) ergänzt. Für die Zugriffsprotokolle + werden die Rechtsgrundlage (Art. 6 Abs. 1 lit. f DSGVO) und die + Aufbewahrungsfrist (vierzehn Tage) benannt. + +(3) Die Aussage über die Dateien der Nutzer:innen bleibt unverändert; sie trifft + zu, weil die Verarbeitung ausschließlich im Browser stattfindet. + + +Artikel 2 +Beilegung des Quelltextes + +(1) Es wird das Skript deploy/webpaket.sh eingeführt. Es tritt in der Phase + „package“ des Profils -Pwasm hinter den Übersetzer und macht aus dessen + Ergebnis ein auslieferbares Verzeichnis: + a) Der Textzwischenschritt (aendggner.js.wat) wird entfernt. + b) Der Quelltext der gebauten Fassung wird als aendggner-quelltext.tar.gz + nebst der Kennung der Fassung (quelltext-fassung.txt) beigelegt. + c) Die großen Dateien werden nach .gz und .br vorkomprimiert. + +(2) Trägt der Arbeitsbaum uneingecheckte Änderungen, so bricht der Bau ab. Der + Grund ist folgender: Der beigelegte Quelltext wäre alsdann nicht derjenige + der ausgelieferten Fassung, und die Auflage des § 13 AGPLv3 wäre verfehlt. + Für Probeläufe kann die Prüfung durch QUELLTEXT_UNGEPRUEFT=1 abbedungen + werden. + +(3) Der Fuß der Startseite (index.html) verweist fortan auf den beigelegten + Quelltext; die fortlaufende Quelle wird als Zweitverweis daneben genannt. + + +Artikel 3 +Auslieferungsvorlage + +Die Vorlage (deploy/nginx-aendggner.conf) wird vom eigenen server-Block auf ein +location-Schnipsel umgestellt, das in den bestehenden Server eingefügt wird. Sie +wird wie folgt geändert: + +1. Aufgenommen wird die Weiterleitung des Pfades ohne abschließenden + Schrägstrich; ohne sie zielten sämtliche relativen Verweise der Seite auf die + Wurzel der Domain. + +2. Die Dateien werden über „root“ statt über „alias“ zugeordnet, weil try_files + in einer Präfix-Location gegen den root auflöst und mit alias fehlgeht. + +3. Die Haltefrist von sieben Tagen entfällt und wird durch Revalidierung + ersetzt. Der Grund ist folgender: Die Dateinamen tragen keine + Fassungskennung; ein Browser mit altem Steuerskript und neuem Rechenwerk + erhielte sonst eine Mischfassung, die es nie gegeben hat. + +4. Die vorkomprimierten Dateien werden ausgeliefert, statt das Rechenwerk je + Abruf neu zu packen. + +5. Aufgenommen werden die Sicherheitskopfzeilen nebst einer Inhaltsrichtlinie. + Zwei ihrer Freigaben sind unvermeidlich und in der Vorlage begründet: + diejenige für die Instanziierung des Moduls und diejenige für eingebettete + Stile, weil die Synopse als blob:-Dokument die Richtlinie der erzeugenden + Seite erbt, ihr Stylesheet aber eingebettet trägt. + + +Artikel 4 +Ergänzungen der Oberfläche + +1. Die Startseite erhält einen Hinweis für den Fall abgeschalteten JavaScripts; + bislang blieb das Formular alsdann wortlos wirkungslos. + +2. Es wird ein Sinnbild (favicon.svg) eingeführt und in allen Seiten relativ + verwiesen; unter einem Unterpfad griffe der Abruf der Wurzel ins Leere. + +3. Die Startseite erhält eine Kurzbeschreibung und die Angabe ihrer kanonischen + Adresse; das Stilblatt wird um die Auszeichnung der Überschriften zweiter + Ordnung, der Anschriften und der Hinweise ergänzt. + + +Schlussbestimmung + +Die vorstehenden Änderungen sind durch die Prüfung sämtlicher Testfälle +(dreihundertvier an der Zahl) bestätigt worden. Die Inhaltsrichtlinie ist gegen +die laufende Anwendung erprobt worden: Der Lauf des IfSG-Falles im Browser hat +unter ihr achtundvierzig angewandte Befehle, siebenundzwanzig zur manuellen +Prüfung und einundzwanzig geänderte Normen ergeben, mithin dasselbe wie die +Befehlszeile, und keine Beanstandung hinterlassen; die Erforderlichkeit der +Freigabe für eingebettete Stile ist dadurch belegt, dass die Synopse ohne sie +unformatiert erscheint. + + +════════════════════════════════════════════════════════════════════════════════ Fassung vom 15. August 2026, zuletzt geändert durch die am 15. August 2026 vorgenommenen Änderungen ════════════════════════════════════════════════════════════════════════════════ diff --git a/README.adoc b/README.adoc index 586b17f..b2329b7 100644 --- a/README.adoc +++ b/README.adoc @@ -325,9 +325,15 @@ JAVA_HOME=/pfad/zu/oracle-graalvm ./mvnw -Pwasm package ---- Ergebnis ist `target/web/` mit `index.html`, `app.js`, `worker.js`, -`style.css`, `aendggner.js` und `aendggner.js.wasm` (rund 20 MB, komprimiert -etwa 6 MB). Die daneben liegende `aendggner.js.wat` ist ein Zwischenschritt des -Übersetzers und gehört nicht auf den Server. +`style.css`, `favicon.svg`, `aendggner.js` und `aendggner.js.wasm` (rund 24 MB, +komprimiert etwa 7 MB). Das Verzeichnis ist so, wie es dasteht, auslieferbar: +`deploy/webpaket.sh` läuft am Ende desselben Befehls, wirft den mehrere hundert +Megabyte großen Textzwischenschritt `aendggner.js.wat` fort, legt den Quelltext +der gebauten Fassung als `aendggner-quelltext.tar.gz` samt +`quelltext-fassung.txt` bei und komprimiert die großen Dateien nach `.gz` und +`.br` vor. Trägt der Arbeitsbaum uneingecheckte Änderungen, bricht der Bau ab — +der beigelegte Quelltext wäre dann nicht der gebaute; für einen Probelauf hilft +`QUELLTEXT_UNGEPRUEFT=1`. Lokal ansehen — `file://` genügt nicht, Browser laden Wasm-Module und Worker nur über HTTP (http://localhost:8000/): @@ -337,11 +343,48 @@ nur über HTTP (http://localhost:8000/): jwebserver -d target/web ---- -Der öffentliche Betrieb braucht nur einen Webserver für statische Dateien; -eine `nginx`-Vorlage liegt unter `deploy/nginx-aendggner.conf`. Die -Befehlszeilenfassung bleibt davon unberührt und ist weiterhin der Weg für +Die Befehlszeilenfassung bleibt davon unberührt und ist weiterhin der Weg für Massenläufe. +=== Ausrollen + +Betrieben wird die Fassung unter einem Unterpfad einer bestehenden Domain, +https://matthias.benkard.de/aendggner/ — ein eigener Server und ein eigenes +Zertifikat sind dafür nicht nötig. Nötig ist nur ein Webserver für statische +Dateien. + +[source,shell script] +---- +JAVA_HOME=/pfad/zu/oracle-graalvm ./mvnw -Pwasm package +rsync -av --delete target/web/ server:/var/www/aendggner/ +---- + +`deploy/nginx-aendggner.conf` ist dafür kein eigener `server`-Block, sondern ein +Schnipsel zum Einfügen in den vorhandenen (`include`). Er bringt mit: + +* die Weiterleitung von `/aendggner` auf `/aendggner/`, ohne die alle relativen + Verweise der Seite auf die Domainwurzel zielten; +* den MIME-Typ `application/wasm`, ohne den der Browser die Instanziierung des + Moduls verweigert; +* `gzip_static`/`brotli_static` für die vorkomprimierten Dateien, statt 24 MB je + Abruf neu zu packen; +* `Cache-Control: no-cache` statt einer Haltefrist: Die Dateinamen tragen keine + Fassungskennung, und ein Browser mit altem `app.js` und neuem `.wasm` bekäme + sonst eine Mischfassung, die es nie gegeben hat. Revalidiert wird per ETag, das + unveränderte Modul kostet dann ein 304 ohne Rumpf; +* die Sicherheitskopfzeilen samt einer Content-Security-Policy. Zwei ihrer + Freigaben sind unvermeidlich und in der Datei begründet: `'wasm-unsafe-eval'` + für die Instanziierung des Moduls und `'unsafe-inline'` für Stile, weil die + Synopse als `blob:`-Dokument die Richtlinie der erzeugenden Seite erbt, ihr + Stylesheet aber eingebettet trägt. + +Der Footer der Startseite verweist auf den beigelegten Quelltext-Tarball; das +verlangt AGPLv3 §13 für den Netzwerkbetrieb. Als fortlaufende Zweitquelle ist +https://gerrit.benkard.de/plugins/gitiles/aendggner genannt. `impressum.html` +und `datenschutz.html` tragen die Angaben nach § 5 DDG und Art. 13 DSGVO; die +dort genannte Aufbewahrungsfrist der Zugriffsprotokolle (14 Tage) muss zu der +des Servers passen. + === Warum WebAssembly und nicht ein Java-Server Der Kern ist reines Java ohne Dateisystem- oder Netzzugriff; nur vier Stellen @@ -360,18 +403,6 @@ vermerkt: Dateiinhalt wandert deshalb als Base64-Text über die JS-Grenze. -Vor dem produktiven, öffentlichen Betrieb sind zwingend zu erledigen: - -* `impressum.html` und `datenschutz.html` - (`src/main/resources/eu/mulk/aendggner/web/`) mit den tatsächlich - zutreffenden Angaben statt der `TODO`-Platzhalter füllen (Pflicht - nach § 5 DDG bzw. DSGVO für öffentlich erreichbare Dienste). -* Den Quellcode-Link im Footer von `index.html` auf das tatsächlich - öffentlich erreichbare Repository setzen — das Projekt steht unter - AGPLv3 (`COPYING`), dessen §13 bei Netzwerkbetrieb einen - Quellcode-Zugriff für Nutzer:innen verlangt. - - == Running the Tests To build and run the tests: diff --git a/deploy/nginx-aendggner.conf b/deploy/nginx-aendggner.conf index 46eacb5..78677b5 100644 --- a/deploy/nginx-aendggner.conf +++ b/deploy/nginx-aendggner.conf @@ -1,47 +1,80 @@ -# Vorlage für die Auslieferung der ÄndGgner-Browserfassung. Es gibt keinen -# Anwendungsprozess mehr: Der Server liefert nur statische Dateien aus -# (Inhalt von target/web/), gerechnet wird im Browser. +# Vorlage für die Auslieferung der ÄndGgner-Browserfassung unter +# https://matthias.benkard.de/aendggner/. # -# Vor dem Einsatz anpassen: server_name, ssl_certificate(_key) (z. B. via certbot), root. +# Es gibt keinen Anwendungsprozess: Der Server liefert nur statische Dateien aus +# (Inhalt von target/web/), gerechnet wird im Browser. Weil der Dienst unter einem +# Unterpfad einer bestehenden Domain läuft, ist dies kein eigener server-Block, +# sondern ein Schnipsel zum Einfügen in den vorhandenen — Zertifikat, HTTP→HTTPS +# und Domainname bleiben, wie sie sind: +# +# server { ... include /etc/nginx/snippets/aendggner.conf; ... } +# +# Ausgerollt wird nach /var/www/aendggner (siehe README.adoc, Abschnitt „Ausrollen“). -server { - listen 80; - listen [::]:80; - server_name aendggner.example.org; - return 301 https://$host$request_uri; +# Ohne diesen Schritt liefe /aendggner ins Leere, und alle relativen Verweise der +# Seite gingen von / statt von /aendggner/ aus. +location = /aendggner { + return 301 /aendggner/; } -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name aendggner.example.org; - - ssl_certificate /etc/letsencrypt/live/aendggner.example.org/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/aendggner.example.org/privkey.pem; - - # Inhalt von target/web/ — ohne aendggner.js.wat, das nur ein Zwischenschritt - # des Übersetzers ist. - root /var/www/aendggner; +location /aendggner/ { + # Bewusst „root /var/www“ (mit dem Verzeichnis /var/www/aendggner) statt + # „alias /var/www/aendggner/“: In einer Präfix-Location löst try_files $uri + # gegen den root auf, nicht gegen den alias, und liefert dann 404 für alles. + root /var/www; index index.html; - # Ohne diesen Typ lehnt der Browser die Streaming-Instanziierung des Moduls ab. + try_files $uri $uri/ =404; + + # Ohne den ersten Typ lehnt der Browser die Streaming-Instanziierung des Moduls + # ab. Ein types-Block in einer location ersetzt die Zuordnung vollständig, statt + # sie zu ergänzen — deshalb stehen hier alle vorkommenden Endungen. types { application/wasm wasm; + text/html html; + text/css css; + text/javascript js; + image/svg+xml svg; + text/plain txt; + application/gzip gz; } + default_type application/octet-stream; - gzip on; - gzip_types application/wasm application/javascript text/css text/html; - gzip_min_length 1024; + # Das Wasm-Modul ist rund 24 MB groß. deploy/webpaket.sh legt beim Bauen .gz + # und .br daneben; ausgeliefert wird die fertige Datei, statt sie je Abruf neu + # zu packen. gzip_static bringen die üblichen Distributionspakete mit; + # brotli_static setzt das Modul ngx_brotli voraus — fehlt es, die Zeile + # streichen, gzip_static genügt. + gzip_static on; + brotli_static on; - # Das Wasm-Modul ist einige Megabyte groß und ändert sich nur mit einer neuen - # Fassung; vorkomprimierte .gz/.br daneben zu legen lohnt sich (ngx_brotli bzw. - # gzip_static). - location ~ \.(wasm|js|css)$ { - expires 7d; - add_header Cache-Control "public"; - } + # Kein „expires 7d“: Die Dateinamen tragen keine Fassungskennung. Ein Browser + # mit altem app.js und neuem .wasm (oder umgekehrt) bekäme eine Mischfassung, + # die es nie gegeben hat. Stattdessen Revalidierung bei jedem Abruf; für das + # unveränderte Modul kostet das ein 304 ohne Rumpf. + add_header Cache-Control "no-cache" always; - location / { - try_files $uri $uri/ =404; - } + # add_header in einer location verdrängt sämtliche vom server-Block geerbten + # Header. Alles, was hier gelten soll, muss deshalb hier stehen — auch ein + # dort gesetztes HSTS. + # add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; + + # 'wasm-unsafe-eval' ist für die Instanziierung des Moduls nötig; echtes eval + # oder new Function kommt in der erzeugten aendggner.js nicht vor. + # + # style-src braucht 'unsafe-inline': Die fertige Synopse wird als blob:-Dokument + # geöffnet, und ein blob:-Dokument erbt die CSP des Dokuments, das es erzeugt + # hat. Der HtmlRenderer bettet sein Stylesheet als <style> ein — ohne die + # Freigabe erschiene die Synopse unformatiert. Skripte bleiben streng. + add_header Content-Security-Policy "default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer" always; + add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), usb=()" always; } + +# Eine robots.txt unter /aendggner/ wäre wirkungslos: Maßgeblich ist allein die im +# Wurzelverzeichnis der Domain. Wer die Seite von der Indizierung ausnehmen will, +# trage dort ein: +# +# User-agent: * +# Disallow: /aendggner/ diff --git a/deploy/webpaket.sh b/deploy/webpaket.sh new file mode 100755 index 0000000..2003134 --- /dev/null +++ b/deploy/webpaket.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# Macht aus dem Übersetzerergebnis ein auslieferbares Verzeichnis. Läuft in der Phase +# „package“ des Profils -Pwasm, unmittelbar nach native-image. +# +# 1. Der Textzwischenschritt aendggner.js.wat (mehrere hundert Megabyte) wird entfernt. +# 2. Der Quelltext der gebauten Fassung wird als Tarball beigelegt — AGPLv3 §13 verlangt +# beim Netzwerkbetrieb einen Quellcode-Zugang für die Nutzer:innen, und der Footer der +# Startseite verweist darauf. +# 3. Die großen Dateien werden vorkomprimiert, damit nginx sie mit gzip_static bzw. +# brotli_static ausliefern kann, statt 24 MB je Abruf neu zu packen. +# +# Aufruf: deploy/webpaket.sh <ausgabeverzeichnis> (Standard: target/web) + +set -eu + +ziel="${1:-target/web}" +quelle="$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)" + +if [ ! -d "$ziel" ]; then + echo "webpaket: $ziel gibt es nicht — erst -Pwasm package laufen lassen." >&2 + exit 1 +fi + +# 1. Zwischenschritt fort. +rm -f "$ziel/aendggner.js.wat" + +# 2. Quelltext der gebauten Fassung. +# +# Ein veränderter Arbeitsbaum bricht den Bau ab: Der angebotene Quelltext muss der +# ausgelieferten Fassung entsprechen, sonst ist die Auflage aus §13 verfehlt. Wer nur +# ausprobieren will, setzt QUELLTEXT_UNGEPRUEFT=1. +if ! git -C "$quelle" rev-parse --git-dir >/dev/null 2>&1; then + echo "webpaket: $quelle ist kein Git-Arbeitsbaum; ohne ihn lässt sich der Quelltext" >&2 + echo " der gebauten Fassung nicht beilegen (AGPLv3 §13)." >&2 + exit 1 +fi + +if [ -n "$(git -C "$quelle" status --porcelain)" ] && [ "${QUELLTEXT_UNGEPRUEFT:-}" != 1 ]; then + echo "webpaket: Der Arbeitsbaum trägt uneingecheckte Änderungen. Der beigelegte Quelltext" >&2 + echo " wäre dann nicht der gebaute. Erst einchecken — oder für einen Probelauf" >&2 + echo " QUELLTEXT_UNGEPRUEFT=1 setzen (dann nicht ausliefern)." >&2 + exit 1 +fi + +fassung="$(git -C "$quelle" rev-parse HEAD)" +git -C "$quelle" archive --format=tar.gz --prefix=aendggner/ HEAD \ + -o "$(CDPATH='' cd -- "$ziel" && pwd)/aendggner-quelltext.tar.gz" + +{ + echo "ÄndGgner — Quelltext der ausgelieferten Fassung" + echo + echo "Commit: $fassung" + echo "Gebaut: $(date -u '+%Y-%m-%dT%H:%M:%SZ')" + echo + echo "Vollständig in aendggner-quelltext.tar.gz; Bauanleitung darin in README.adoc." + echo "Fortlaufend: https://gerrit.benkard.de/plugins/gitiles/aendggner" +} > "$ziel/quelltext-fassung.txt" + +# 3. Vorkompression. Der Tarball ist bereits gepackt und bleibt außen vor. +for datei in "$ziel"/*.wasm "$ziel"/*.js "$ziel"/*.css "$ziel"/*.html "$ziel"/*.svg \ + "$ziel"/*.txt; do + [ -f "$datei" ] || continue + gzip -9 -f -k -- "$datei" + if command -v brotli >/dev/null 2>&1; then + brotli -f -- "$datei" + fi +done + +if ! command -v brotli >/dev/null 2>&1; then + echo "webpaket: brotli nicht gefunden — nur .gz angelegt." >&2 +fi + +echo "webpaket: $ziel ist auslieferbar (Fassung $(git -C "$quelle" rev-parse --short HEAD))." @@ -392,6 +392,26 @@ </arguments> </configuration> </execution> + + <!-- + Macht aus dem Übersetzerergebnis ein auslieferbares Verzeichnis: entfernt den + .wat-Zwischenschritt, legt den Quelltext der gebauten Fassung bei (AGPLv3 §13) + und komprimiert vor. Läuft in derselben Phase, aber nach „web-image“ — Maven + führt gleichphasige Ausführungen in Deklarationsreihenfolge aus. + --> + <execution> + <id>webpaket</id> + <phase>package</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <executable>${project.basedir}/deploy/webpaket.sh</executable> + <arguments> + <argument>${wasm.output.directory}</argument> + </arguments> + </configuration> + </execution> </executions> </plugin> diff --git a/src/main/resources/eu/mulk/aendggner/web/datenschutz.html b/src/main/resources/eu/mulk/aendggner/web/datenschutz.html index 5b9bbac..a8d046a 100644 --- a/src/main/resources/eu/mulk/aendggner/web/datenschutz.html +++ b/src/main/resources/eu/mulk/aendggner/web/datenschutz.html @@ -4,16 +4,24 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Datenschutz — ÄndGgner</title> + <link rel="icon" href="favicon.svg" type="image/svg+xml"> <link rel="stylesheet" href="style.css"> </head> <body> <main> <h1>Datenschutzerklärung</h1> + + <h2>Verantwortlicher</h2> <p> - <strong>TODO vor dem Livegang:</strong> Bitte prüfen und um die für diesen konkreten Server - zutreffenden Angaben ergänzen (Betreiber, Kontakt, tatsächliche Speicherdauer der - Zugriffslogs, Hosting-Anbieter). + Verantwortlicher im Sinne des Art. 4 Nr. 7 DSGVO ist: </p> + <address> + Matthias Benkard<br> + Machtlfinger Str. 29<br> + 81379 München<br> + Deutschland<br> + <a href="mailto:admin@mulk.eu">admin@mulk.eu</a> + </address> <h2>Ihre Dateien</h2> <p> @@ -28,15 +36,36 @@ <h2>Zugriffsprotokolle</h2> <p> Beim Abruf der Seite selbst und der zugehörigen Dateien werden wie bei jedem Webserver - technische Zugriffsdaten (u. a. IP-Adresse, Zeitpunkt, aufgerufene Adresse) für einen - begrenzten Zeitraum zur Absicherung des Betriebs protokolliert. Diese Protokolle enthalten - keine Angaben über die von Ihnen ausgewerteten Dokumente. + technische Zugriffsdaten (IP-Adresse, Zeitpunkt, aufgerufene Adresse, übertragene + Datenmenge, Statuscode sowie die vom Browser gemeldete Kennung und Verweisadresse) + protokolliert. Rechtsgrundlage ist Art. 6 Abs. 1 lit. f DSGVO; das berechtigte Interesse + liegt in der Absicherung und Fehlersuche des Betriebs. Die Protokolle werden nach + <strong>14 Tagen</strong> gelöscht. Sie enthalten keine Angaben über die von Ihnen + ausgewerteten Dokumente, denn diese erreichen den Server nicht. + </p> + <p> + Der Server wird gegebenenfalls bei einem Dienstleister innerhalb der Europäischen Union + betrieben, der insoweit als Auftragsverarbeiter nach Art. 28 DSGVO tätig ist. </p> <h2>Keine Cookies, keine Konten, kein Tracking</h2> <p> Dieser Dienst verwendet keine Cookies, erfordert keine Registrierung und bindet keine - Analyse- oder Tracking-Dienste Dritter ein. + Analyse- oder Tracking-Dienste Dritter ein. Es werden keine Daten an Dritte weitergegeben + und keine Inhalte von fremden Servern nachgeladen. + </p> + + <h2>Ihre Rechte</h2> + <p> + Ihnen stehen gegenüber dem Verantwortlichen die Rechte auf Auskunft (Art. 15 DSGVO), + Berichtigung (Art. 16), Löschung (Art. 17), Einschränkung der Verarbeitung (Art. 18), + Datenübertragbarkeit (Art. 20) sowie das Recht auf Widerspruch gegen die Verarbeitung + (Art. 21) zu. Wenden Sie sich dazu an die oben genannte Anschrift oder E-Mail-Adresse. + </p> + <p> + Unabhängig davon können Sie sich bei einer Aufsichtsbehörde beschweren (Art. 77 DSGVO). + Zuständig ist hier das Bayerische Landesamt für Datenschutzaufsicht, Promenade 27, + 91522 Ansbach. </p> </main> <footer><a href="index.html">Zurück zum Formular</a></footer> diff --git a/src/main/resources/eu/mulk/aendggner/web/favicon.svg b/src/main/resources/eu/mulk/aendggner/web/favicon.svg new file mode 100644 index 0000000..4f6a847 --- /dev/null +++ b/src/main/resources/eu/mulk/aendggner/web/favicon.svg @@ -0,0 +1,9 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="ÄndGgner"> + <!-- Farben wie in style.css: heller Grund, brauner Akzent. Ein Favicon erbt keine + CSS-Variablen, deshalb stehen die Werte hier ausgeschrieben. --> + <rect width="32" height="32" rx="6" fill="#fdfdfb"/> + <rect x="0.75" y="0.75" width="30.5" height="30.5" rx="5.25" fill="none" stroke="#d8d3c4" + stroke-width="1.5"/> + <text x="16" y="17" fill="#6b4423" font-family="Georgia, 'Times New Roman', serif" + font-size="22" text-anchor="middle" dominant-baseline="central">§</text> +</svg> diff --git a/src/main/resources/eu/mulk/aendggner/web/impressum.html b/src/main/resources/eu/mulk/aendggner/web/impressum.html index 525ef77..3832d03 100644 --- a/src/main/resources/eu/mulk/aendggner/web/impressum.html +++ b/src/main/resources/eu/mulk/aendggner/web/impressum.html @@ -4,22 +4,53 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Impressum — ÄndGgner</title> + <link rel="icon" href="favicon.svg" type="image/svg+xml"> <link rel="stylesheet" href="style.css"> </head> <body> <main> <h1>Impressum</h1> + + <h2>Angaben gemäß § 5 DDG</h2> + <address> + Matthias Benkard<br> + Machtlfinger Str. 29<br> + 81379 München<br> + Deutschland + </address> + + <h2>Kontakt</h2> <p> - <strong>TODO vor dem Livegang:</strong> Diese Seite muss durch die nach § 5 DDG - (Digitale-Dienste-Gesetz, vormals § 5 TMG) vorgeschriebenen Angaben ersetzt werden, bevor - dieser Dienst öffentlich betrieben wird. + E-Mail: <a href="mailto:admin@mulk.eu">admin@mulk.eu</a><br> + Telefon: +49-8856-8054002<br> + Fax: +49-89-20008761207 </p> + + <h2>Verantwortlich für den Inhalt nach § 18 Abs. 2 MStV</h2> <address> - [Name]<br> - [Straße, Hausnummer]<br> - [PLZ, Ort]<br> - [E-Mail-Adresse] + Matthias Benkard, Machtlfinger Str. 29, 81379 München </address> + + <h2>Zur Sache</h2> + <p> + ÄndGgner ist ein unentgeltlicher, nichtkommerzieller Dienst ohne Registrierung. Eine + Umsatzsteuer-Identifikationsnummer besteht nicht; eine berufsrechtliche Aufsicht besteht + nicht, da es sich weder um Rechtsberatung noch um eine sonstige reglementierte Tätigkeit + handelt. + </p> + <p> + Die erzeugten Synopsen entstehen selbsttätig und sind <strong>ohne Gewähr</strong> für + Vollständigkeit und Richtigkeit. Maßgeblich ist allein die amtliche Verkündung im + jeweiligen Gesetz- oder Verordnungsblatt. + </p> + <p> + Die zugrunde liegende Software steht unter der GNU Affero General Public License, + Version 3 (Wortlaut in der Datei <code>COPYING</code> des Quelltextes), und wird + ausdrücklich ohne jede Gewährleistung überlassen. Den + <a href="aendggner-quelltext.tar.gz">Quelltext der betriebenen Fassung</a> gibt es zum + Herunterladen; fortlaufend auch über + <a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Gerrit</a>. + </p> </main> <footer><a href="index.html">Zurück zum Formular</a></footer> </body> diff --git a/src/main/resources/eu/mulk/aendggner/web/index.html b/src/main/resources/eu/mulk/aendggner/web/index.html index 9f26889..9d1e343 100644 --- a/src/main/resources/eu/mulk/aendggner/web/index.html +++ b/src/main/resources/eu/mulk/aendggner/web/index.html @@ -4,6 +4,11 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ÄndGgner — Änderungsgesetze konsolidieren</title> + <meta name="description" content="Wendet Änderungsgesetze und Gesetzentwürfe selbsttätig auf ein + Stammgesetz an und zeigt das Ergebnis als zweispaltige Synopse. Die Auswertung läuft + vollständig im Browser; die gewählten Dateien werden nicht übertragen."> + <link rel="canonical" href="https://matthias.benkard.de/aendggner/"> + <link rel="icon" href="favicon.svg" type="image/svg+xml"> <link rel="stylesheet" href="style.css"> <script src="app.js" defer></script> </head> @@ -16,6 +21,15 @@ </header> <main> + <noscript> + <p class="noscript"> + Dieses Werkzeug rechnet im Browser statt auf dem Server: Es braucht JavaScript und + WebAssembly. Ohne sie bleibt das nachstehende Formular wirkungslos. Wer beides nicht + einschalten möchte, verwende die Befehlszeilenfassung — sie liegt dem + <a href="aendggner-quelltext.tar.gz">Quelltext</a> bei und leistet dasselbe. + </p> + </noscript> + <form id="synopse-formular"> <div class="field"> <label for="stamm">Stammgesetz</label> @@ -62,7 +76,8 @@ <footer> <a href="impressum.html">Impressum</a> · <a href="datenschutz.html">Datenschutz</a> · - <a href="https://TODO-QUELLCODE-URL-EINTRAGEN">Quellcode (AGPLv3)</a> + <a href="aendggner-quelltext.tar.gz">Quelltext dieser Fassung (AGPLv3)</a> + <span class="nebenquelle">(<a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Git</a>)</span> </footer> </body> </html> diff --git a/src/main/resources/eu/mulk/aendggner/web/style.css b/src/main/resources/eu/mulk/aendggner/web/style.css index cdea20e..8aa1e11 100644 --- a/src/main/resources/eu/mulk/aendggner/web/style.css +++ b/src/main/resources/eu/mulk/aendggner/web/style.css @@ -45,6 +45,21 @@ h1 { margin: 0; } +/* Impressum und Datenschutz. */ +h2 { + margin: 1.75rem 0 0.5rem; + font-size: 1.125rem; +} + +address { + font-style: normal; + margin: 0.5rem 0; +} + +a { + color: var(--accent); +} + .field { margin-bottom: 1.25rem; } @@ -92,6 +107,14 @@ button:hover { filter: brightness(1.1); } +.noscript { + margin: 0 0 2rem; + padding: 1rem; + border: 1px solid #a33; + border-radius: 6px; + font-size: 0.875rem; +} + .disclaimer { margin-top: 2rem; padding: 1rem; @@ -113,6 +136,10 @@ footer a { color: var(--accent); } +.nebenquelle { + font-size: 0.8125rem; +} + .meldung { margin-top: 1.25rem; padding: 0.75rem 1rem; |
