Sicherheit: CSP aktiviert, JavaScript ausgelagert, XSS-Schutz und README aktualisiert
This commit is contained in:
295
main.js
Normal file
295
main.js
Normal file
@@ -0,0 +1,295 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
const textInput = document.getElementById('text');
|
||||
const clearTextBtn = document.getElementById('clear-text');
|
||||
const wifiSsidInput = document.getElementById('wifi-ssid');
|
||||
const wifiPasswordInput = document.getElementById('wifi-password');
|
||||
const sizeSelect = document.getElementById('size');
|
||||
const errorCorrectionSelect = document.getElementById('errorCorrection');
|
||||
const foregroundColor = document.getElementById('foreground');
|
||||
const backgroundColor = document.getElementById('background');
|
||||
const downloadBtn = document.getElementById('download');
|
||||
const qrcodeCanvas = document.getElementById('qrcode');
|
||||
const qrcodeImg = document.getElementById('qrcode-img');
|
||||
const errorMessage = document.getElementById('error-message');
|
||||
const infoButton = document.getElementById('info-button');
|
||||
const infoPanel = document.getElementById('info-panel');
|
||||
const infoClose = document.getElementById('info-close');
|
||||
const titleElement = document.getElementById('title');
|
||||
|
||||
// Title Easter egg
|
||||
let titleClickCount = 0;
|
||||
let titleTimeoutId = null;
|
||||
|
||||
titleElement.addEventListener('click', function() {
|
||||
titleClickCount++;
|
||||
clearTimeout(titleTimeoutId);
|
||||
|
||||
if (titleClickCount === 1) {
|
||||
this.textContent = "Just a [bleep]ing QR Code";
|
||||
|
||||
titleTimeoutId = setTimeout(() => {
|
||||
this.textContent = "Just a QR Code";
|
||||
titleClickCount = 0;
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Info panel toggle
|
||||
infoButton.addEventListener('click', function() {
|
||||
infoPanel.classList.add('open');
|
||||
});
|
||||
|
||||
infoClose.addEventListener('click', function() {
|
||||
infoPanel.classList.remove('open');
|
||||
});
|
||||
|
||||
// Close info panel when clicking outside
|
||||
document.addEventListener('click', function(event) {
|
||||
if (infoPanel.classList.contains('open') &&
|
||||
!infoPanel.contains(event.target) &&
|
||||
event.target !== infoButton) {
|
||||
infoPanel.classList.remove('open');
|
||||
}
|
||||
});
|
||||
|
||||
// Close info panel with Escape key
|
||||
document.addEventListener('keydown', function(event) {
|
||||
if (event.key === 'Escape' && infoPanel.classList.contains('open')) {
|
||||
infoPanel.classList.remove('open');
|
||||
}
|
||||
});
|
||||
|
||||
// Set random compliment as default text and select it
|
||||
textInput.value = 'https://medisoftware.de';
|
||||
textInput.select();
|
||||
|
||||
// Show/hide clear button based on text input content
|
||||
function toggleClearButton() {
|
||||
if (textInput.value.length > 0) {
|
||||
clearTextBtn.style.display = 'block';
|
||||
} else {
|
||||
clearTextBtn.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize clear button visibility
|
||||
toggleClearButton();
|
||||
|
||||
// Clear text when clear button is clicked
|
||||
clearTextBtn.addEventListener('click', function() {
|
||||
textInput.value = '';
|
||||
wifiSsidInput.value = '';
|
||||
wifiPasswordInput.value = '';
|
||||
toggleClearButton();
|
||||
textInput.focus();
|
||||
generateQRCode();
|
||||
});
|
||||
|
||||
// Update clear button visibility when text changes
|
||||
textInput.addEventListener('input', function() {
|
||||
toggleClearButton();
|
||||
// Only generate QR code if no wifi data is being entered
|
||||
const wifiSsid = wifiSsidInput.value.trim();
|
||||
const wifiPassword = wifiPasswordInput.value.trim();
|
||||
if (!wifiSsid && !wifiPassword) {
|
||||
generateQRCode();
|
||||
}
|
||||
});
|
||||
|
||||
let qr = null;
|
||||
|
||||
// Generate QR code when settings change
|
||||
sizeSelect.addEventListener('change', generateQRCode);
|
||||
errorCorrectionSelect.addEventListener('change', generateQRCode);
|
||||
foregroundColor.addEventListener('input', generateQRCode);
|
||||
backgroundColor.addEventListener('input', generateQRCode);
|
||||
|
||||
// Generate QR code when wifi settings change
|
||||
wifiSsidInput.addEventListener('input', function() {
|
||||
updateTextDisplay();
|
||||
generateQRCode();
|
||||
});
|
||||
wifiPasswordInput.addEventListener('input', function() {
|
||||
updateTextDisplay();
|
||||
generateQRCode();
|
||||
});
|
||||
|
||||
// Download QR code as image
|
||||
downloadBtn.addEventListener('click', downloadQRCode);
|
||||
|
||||
// Or check for URL parameters if present
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('text')) {
|
||||
const safeText = urlParams.get('text');
|
||||
// Nur erlaubte Zeichen (Buchstaben, Zahlen, gängige URL-Zeichen)
|
||||
if (/^[\w\-.:/?&=#%+@!;,]*$/i.test(safeText)) {
|
||||
textInput.value = safeText;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('ssid')) {
|
||||
const safeSsid = urlParams.get('ssid');
|
||||
if (/^[^<>"'`\\]*$/.test(safeSsid)) {
|
||||
wifiSsidInput.value = safeSsid;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('password')) {
|
||||
const safePassword = urlParams.get('password');
|
||||
if (/^[^<>"'`\\]*$/.test(safePassword)) {
|
||||
wifiPasswordInput.value = safePassword;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('size')) {
|
||||
const sizeValue = urlParams.get('size');
|
||||
if (["128", "256", "512", "1024"].includes(sizeValue)) {
|
||||
sizeSelect.value = sizeValue;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('errorCorrection')) {
|
||||
const ecValue = urlParams.get('errorCorrection').toUpperCase();
|
||||
if (["L", "M", "Q", "H"].includes(ecValue)) {
|
||||
errorCorrectionSelect.value = ecValue;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('foreground')) {
|
||||
const fgValue = urlParams.get('foreground');
|
||||
if (/^#[0-9A-F]{6}$/i.test(fgValue)) {
|
||||
foregroundColor.value = fgValue;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('background')) {
|
||||
const bgValue = urlParams.get('background');
|
||||
if (/^#[0-9A-F]{6}$/i.test(bgValue)) {
|
||||
backgroundColor.value = bgValue;
|
||||
}
|
||||
}
|
||||
generateQRCode();
|
||||
|
||||
function generateQRCode() {
|
||||
const text = textInput.value.trim();
|
||||
const wifiSsid = wifiSsidInput.value.trim();
|
||||
const wifiPassword = wifiPasswordInput.value.trim();
|
||||
const size = parseInt(sizeSelect.value);
|
||||
const errorCorrection = errorCorrectionSelect.value.toLowerCase();
|
||||
const fgColor = foregroundColor.value;
|
||||
const bgColor = backgroundColor.value;
|
||||
|
||||
// Update the gabe link color to match foreground color
|
||||
const gabeLink = document.querySelector('.credit a');
|
||||
if (gabeLink) {
|
||||
gabeLink.style.color = fgColor;
|
||||
}
|
||||
|
||||
// Clear previous error
|
||||
errorMessage.textContent = '';
|
||||
downloadBtn.style.display = 'none';
|
||||
|
||||
// Determine what to encode
|
||||
let qrText = text;
|
||||
|
||||
// If wifi credentials are provided, generate wifi QR code
|
||||
if (wifiSsid && wifiPassword) {
|
||||
// Wifi QR code format: WIFI:S:<SSID>;T:WPA;P:<password>;;
|
||||
qrText = `WIFI:S:${escapeSpecialChars(wifiSsid)};T:WPA;P:${escapeSpecialChars(wifiPassword)};;`;
|
||||
} else if (wifiSsid && !wifiPassword) {
|
||||
// SSID only (open network)
|
||||
qrText = `WIFI:S:${escapeSpecialChars(wifiSsid)};T:nopass;;`;
|
||||
} else if (!wifiSsid && wifiPassword) {
|
||||
// Password without SSID is invalid
|
||||
errorMessage.textContent = 'Bitte geben Sie eine SSID ein, wenn Sie ein Passwort angeben';
|
||||
qrcodeCanvas.style.display = 'none';
|
||||
qrcodeImg.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate input
|
||||
if (qrText === '') {
|
||||
errorMessage.textContent = 'Bitte geben Sie Text/URL oder Wifi-Daten ein';
|
||||
// Hide both canvas and image
|
||||
qrcodeCanvas.style.display = 'none';
|
||||
qrcodeImg.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new QR code on canvas
|
||||
try {
|
||||
if (!qr) {
|
||||
qr = new QRious({
|
||||
element: qrcodeCanvas,
|
||||
size: size,
|
||||
value: qrText,
|
||||
foreground: fgColor,
|
||||
background: bgColor,
|
||||
level: errorCorrection
|
||||
});
|
||||
} else {
|
||||
qr.set({
|
||||
size: size,
|
||||
value: qrText,
|
||||
foreground: fgColor,
|
||||
background: bgColor,
|
||||
level: errorCorrection
|
||||
});
|
||||
}
|
||||
|
||||
// Convert canvas to image
|
||||
const dataURL = qrcodeCanvas.toDataURL('image/png');
|
||||
qrcodeImg.src = dataURL;
|
||||
|
||||
// Show image (hide canvas) and download button
|
||||
qrcodeCanvas.style.display = 'none';
|
||||
qrcodeImg.style.display = 'block';
|
||||
downloadBtn.style.display = 'inline-block';
|
||||
} catch (err) {
|
||||
errorMessage.textContent = 'Error generating QR code: ' + err.message;
|
||||
qrcodeCanvas.style.display = 'none';
|
||||
qrcodeImg.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to escape special characters in wifi strings
|
||||
function escapeSpecialChars(str) {
|
||||
return str.replace(/[\\;:,]/g, '\\$&');
|
||||
}
|
||||
|
||||
function downloadQRCode() {
|
||||
// Use the image source for download
|
||||
const link = document.createElement('a');
|
||||
link.download = 'qrcode.png';
|
||||
link.href = qrcodeImg.src;
|
||||
|
||||
// Simulate click to trigger download
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
// Show success feedback
|
||||
const originalText = downloadBtn.textContent;
|
||||
downloadBtn.textContent = 'Downloaded!';
|
||||
|
||||
// Reset button after a short delay
|
||||
setTimeout(() => {
|
||||
downloadBtn.textContent = originalText;
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Function to update the text display with current QR code content
|
||||
function updateTextDisplay() {
|
||||
const wifiSsid = wifiSsidInput.value.trim();
|
||||
const wifiPassword = wifiPasswordInput.value.trim();
|
||||
|
||||
if (wifiSsid && wifiPassword) {
|
||||
// Show wifi QR code format
|
||||
textInput.value = `WIFI:S:${escapeSpecialChars(wifiSsid)};T:WPA;P:${escapeSpecialChars(wifiPassword)};;`;
|
||||
} else if (wifiSsid && !wifiPassword) {
|
||||
// Show open network format
|
||||
textInput.value = `WIFI:S:${escapeSpecialChars(wifiSsid)};T:nopass;;`;
|
||||
} else {
|
||||
// If no wifi data, keep original text input value
|
||||
// Don't change it here to avoid overwriting user input
|
||||
}
|
||||
|
||||
// Update clear button visibility
|
||||
toggleClearButton();
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user