Compare commits
5 Commits
5000bfc0fe
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
5478d943e5 | ||
|
9c5d022604 | ||
|
83f49d14bc | ||
|
bfddca6495 | ||
|
1ebc4c4ec2 |
@@ -2,8 +2,10 @@
|
|||||||
root * /usr/share/caddy
|
root * /usr/share/caddy
|
||||||
file_server
|
file_server
|
||||||
|
|
||||||
# Behandle die HTML-Datei als Index
|
@notStatic {
|
||||||
try_files {path} /Just%20a%20QR%20Code.html
|
not path_regexp static \.\(js|css|png|jpg|jpeg|gif|svg|ico|json|webmanifest|map|txt|woff2?\)$
|
||||||
|
}
|
||||||
|
try_files {path} /index.html @notStatic
|
||||||
|
|
||||||
# CORS-Header für Cross-Origin-Requests
|
# CORS-Header für Cross-Origin-Requests
|
||||||
header {
|
header {
|
||||||
|
@@ -2,6 +2,7 @@ FROM caddy:2-alpine
|
|||||||
|
|
||||||
# Kopiere die HTML-Datei
|
# Kopiere die HTML-Datei
|
||||||
COPY index.html /usr/share/caddy/
|
COPY index.html /usr/share/caddy/
|
||||||
|
COPY main.js /usr/share/caddy/
|
||||||
|
|
||||||
# Kopiere den Ordner mit den JavaScript-Dateien
|
# Kopiere den Ordner mit den JavaScript-Dateien
|
||||||
COPY assets /usr/share/caddy/assets/
|
COPY assets /usr/share/caddy/assets/
|
||||||
|
34
README.md
34
README.md
@@ -2,18 +2,22 @@
|
|||||||
|
|
||||||
Ein einfacher QR-Code-Generator, der vollständig im Browser läuft. Keine Daten werden an externe Server gesendet.
|
Ein einfacher QR-Code-Generator, der vollständig im Browser läuft. Keine Daten werden an externe Server gesendet.
|
||||||
|
|
||||||
|
Dieses Projekt basiert auf dem Code von https://qr.alster.space/. Er wurde um verschiedene praktische Funktionen erweitert.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- ✅ Vollständig clientseitig (keine Server-Kommunikation)
|
- Vollständig clientseitig (keine Server-Kommunikation)
|
||||||
- ✅ URL-Parameter für alle Einstellungen
|
- URL-Parameter für alle Einstellungen
|
||||||
- ✅ Anpassbare Größen und Farben
|
- Anpassbare Größen und Farben
|
||||||
- ✅ Verschiedene Fehlerkorrektur-Level
|
- Verschiedene Fehlerkorrektur-Level
|
||||||
- ✅ Download-Funktion
|
- Download-Funktion
|
||||||
- ✅ Responsive Design
|
- Teilen-Funktion (Link mit aktuellen Einstellungen kopieren)
|
||||||
- ✅ **WiFi QR-Code Unterstützung mit eigener UI**
|
- Hinweis bei WiFi: Passwort im Link im Klartext
|
||||||
- ✅ **Dynamische Klartext-Anzeige**
|
- Responsive Design
|
||||||
- ✅ **Automatische QR-Code-Generierung**
|
- WiFi QR-Code Unterstützung mit eigener UI
|
||||||
- ✅ **Sicher gegen XSS (Content Security Policy, validierte Eingaben, kein Inline-JS)**
|
- Dynamische Klartext-Anzeige
|
||||||
|
- Automatische QR-Code-Generierung
|
||||||
|
- Sicher gegen XSS (Content Security Policy, validierte Eingaben, kein Inline-JS)
|
||||||
|
|
||||||
## Docker Setup
|
## Docker Setup
|
||||||
|
|
||||||
@@ -27,7 +31,7 @@ docker-compose up -d
|
|||||||
docker-compose down
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mit Docker direkt
|
### Docker build/run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Image bauen
|
# Image bauen
|
||||||
@@ -88,6 +92,8 @@ http://localhost:8080/?ssid=MeinWLAN&password=MeinPasswort123
|
|||||||
http://localhost:8080/?ssid=OffenesWLAN
|
http://localhost:8080/?ssid=OffenesWLAN
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Achtung:** Das WLAN-Passwort ist im Link im Klartext sichtbar!
|
||||||
|
|
||||||
## WiFi QR-Code Format
|
## WiFi QR-Code Format
|
||||||
|
|
||||||
Die App generiert automatisch QR-Codes im Standard-WiFi-Format:
|
Die App generiert automatisch QR-Codes im Standard-WiFi-Format:
|
||||||
@@ -125,6 +131,12 @@ Das Smartphone erkennt automatisch, dass es sich um WiFi-Daten handelt und biete
|
|||||||
- WiFi-Passwort ohne SSID wird als Fehler angezeigt
|
- WiFi-Passwort ohne SSID wird als Fehler angezeigt
|
||||||
- Leere Eingaben werden entsprechend behandelt
|
- Leere Eingaben werden entsprechend behandelt
|
||||||
|
|
||||||
|
### Teilen-Funktion
|
||||||
|
|
||||||
|
Mit dem Button "Teilen" kann ein Link mit allen aktuellen Einstellungen (inkl. WiFi-Daten) in die Zwischenablage kopiert werden. Dieser Link kann weitergegeben werden und öffnet die App direkt mit den gewählten Einstellungen.
|
||||||
|
|
||||||
|
**Achtung:** Wenn ein WLAN-Passwort eingegeben ist, wird dieses im Link im Klartext übertragen!
|
||||||
|
|
||||||
## Sicherheit & Content Security Policy (CSP)
|
## Sicherheit & Content Security Policy (CSP)
|
||||||
|
|
||||||
Die Anwendung ist gegen XSS-Angriffe abgesichert:
|
Die Anwendung ist gegen XSS-Angriffe abgesichert:
|
||||||
|
16
index.html
16
index.html
File diff suppressed because one or more lines are too long
47
main.js
47
main.js
@@ -16,6 +16,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const infoPanel = document.getElementById('info-panel');
|
const infoPanel = document.getElementById('info-panel');
|
||||||
const infoClose = document.getElementById('info-close');
|
const infoClose = document.getElementById('info-close');
|
||||||
const titleElement = document.getElementById('title');
|
const titleElement = document.getElementById('title');
|
||||||
|
const shareBtn = document.getElementById('share');
|
||||||
|
const shareHint = document.getElementById('share-hint');
|
||||||
|
|
||||||
// Title Easter egg
|
// Title Easter egg
|
||||||
let titleClickCount = 0;
|
let titleClickCount = 0;
|
||||||
@@ -292,4 +294,49 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Update clear button visibility
|
// Update clear button visibility
|
||||||
toggleClearButton();
|
toggleClearButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateShareHint() {
|
||||||
|
const wifiPassword = wifiPasswordInput.value.trim();
|
||||||
|
if (wifiPassword) {
|
||||||
|
shareHint.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
shareHint.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wifiPasswordInput.addEventListener('input', updateShareHint);
|
||||||
|
wifiSsidInput.addEventListener('input', updateShareHint);
|
||||||
|
textInput.addEventListener('input', updateShareHint);
|
||||||
|
// Initial anzeigen, falls Passwort schon gesetzt
|
||||||
|
updateShareHint();
|
||||||
|
|
||||||
|
shareBtn.addEventListener('click', function() {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
const text = textInput.value.trim();
|
||||||
|
const wifiSsid = wifiSsidInput.value.trim();
|
||||||
|
const wifiPassword = wifiPasswordInput.value.trim();
|
||||||
|
const size = sizeSelect.value;
|
||||||
|
const errorCorrection = errorCorrectionSelect.value;
|
||||||
|
const fgColor = foregroundColor.value;
|
||||||
|
const bgColor = backgroundColor.value;
|
||||||
|
|
||||||
|
// Entscheide, was kodiert werden soll
|
||||||
|
if (wifiSsid) params.set('ssid', wifiSsid);
|
||||||
|
if (wifiPassword) params.set('password', wifiPassword);
|
||||||
|
if (!wifiSsid && !wifiPassword && text) params.set('text', text);
|
||||||
|
if (size !== '256') params.set('size', size);
|
||||||
|
if (errorCorrection !== 'M') params.set('errorCorrection', errorCorrection);
|
||||||
|
if (fgColor !== '#000000') params.set('foreground', fgColor);
|
||||||
|
if (bgColor !== '#ffffff') params.set('background', bgColor);
|
||||||
|
|
||||||
|
const url = window.location.origin + window.location.pathname + '?' + params.toString();
|
||||||
|
// In Zwischenablage kopieren
|
||||||
|
navigator.clipboard.writeText(url).then(() => {
|
||||||
|
const original = shareBtn.textContent;
|
||||||
|
shareBtn.textContent = 'Link kopiert!';
|
||||||
|
setTimeout(() => { shareBtn.textContent = original; }, 2000);
|
||||||
|
}, () => {
|
||||||
|
alert('Konnte Link nicht kopieren.');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
Reference in New Issue
Block a user