724 lines
26 KiB
JavaScript
724 lines
26 KiB
JavaScript
// Bug Report System - JavaScript rész
|
|
(function() {
|
|
const logs = [];
|
|
|
|
const origLog = console.log;
|
|
const origError = console.error;
|
|
const origWarn = console.warn;
|
|
|
|
console.log = function(...args) {
|
|
logs.push('[LOG] ' + args.join(' '));
|
|
origLog.apply(console, args);
|
|
};
|
|
console.error = function(...args) {
|
|
logs.push('[ERROR] ' + args.join(' '));
|
|
origError.apply(console, args);
|
|
};
|
|
console.warn = function(...args) {
|
|
logs.push('[WARN] ' + args.join(' '));
|
|
origWarn.apply(console, args);
|
|
};
|
|
|
|
const origXHROpen = XMLHttpRequest.prototype.open;
|
|
const origXHRSend = XMLHttpRequest.prototype.send;
|
|
|
|
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
|
|
this._method = method;
|
|
this._url = url;
|
|
return origXHROpen.apply(this, arguments);
|
|
};
|
|
XMLHttpRequest.prototype.send = function(data) {
|
|
const startTime = Date.now();
|
|
this._sendData = data;
|
|
|
|
this.addEventListener('load', function() {
|
|
const duration = Date.now() - startTime;
|
|
logs.push(`[NETWORK] ${this._method} ${this._url} - Status: ${this.status} (${duration}ms)`);
|
|
});
|
|
|
|
this.addEventListener('error', function() {
|
|
const duration = Date.now() - startTime;
|
|
let errorLog = `[NET ERROR] ${this._method} ${this._url} - Failed (${duration}ms)`;
|
|
if (this._sendData && (this._method === 'POST' || this._method === 'PUT' || this._method === 'PATCH')) {
|
|
let postData = 'Unknown';
|
|
try {
|
|
if (typeof this._sendData === 'string') {
|
|
postData = this._sendData;
|
|
} else if (this._sendData instanceof FormData) {
|
|
postData = 'FormData';
|
|
const formDataEntries = [];
|
|
for (let [key, value] of this._sendData.entries()) {
|
|
formDataEntries.push(`${key}=${value}`);
|
|
}
|
|
if (formDataEntries.length > 0) {
|
|
postData = formDataEntries.join('&');
|
|
}
|
|
} else {
|
|
postData = JSON.stringify(this._sendData);
|
|
}
|
|
} catch (e) {
|
|
postData = '[Cannot serialize data]';
|
|
}
|
|
errorLog += ` - POST Data: ${postData}`;
|
|
}
|
|
logs.push(errorLog);
|
|
});
|
|
|
|
this.addEventListener('timeout', function() {
|
|
const duration = Date.now() - startTime;
|
|
let timeoutLog = `[NET ERROR] ${this._method} ${this._url} - Timeout (${duration}ms)`;
|
|
if (this._sendData && (this._method === 'POST' || this._method === 'PUT' || this._method === 'PATCH')) {
|
|
let postData = 'Unknown';
|
|
try {
|
|
if (typeof this._sendData === 'string') {
|
|
postData = this._sendData;
|
|
} else if (this._sendData instanceof FormData) {
|
|
postData = 'FormData';
|
|
const formDataEntries = [];
|
|
for (let [key, value] of this._sendData.entries()) {
|
|
formDataEntries.push(`${key}=${value}`);
|
|
}
|
|
if (formDataEntries.length > 0) {
|
|
postData = formDataEntries.join('&');
|
|
}
|
|
} else {
|
|
postData = JSON.stringify(this._sendData);
|
|
}
|
|
} catch (e) {
|
|
postData = '[Cannot serialize data]';
|
|
}
|
|
timeoutLog += ` - POST Data: ${postData}`;
|
|
}
|
|
logs.push(timeoutLog);
|
|
});
|
|
|
|
return origXHRSend.apply(this, arguments);
|
|
};
|
|
|
|
window.addEventListener('unhandledrejection', event => {
|
|
logs.push('[UNHANDLED PROMISE REJECTION] ' + (event.reason?.message || event.reason));
|
|
});
|
|
|
|
window.onerror = function(message, source, lineno, colno, error) {
|
|
logs.push(`[GLOBAL ERROR] ${message} at ${source}:${lineno}:${colno}`);
|
|
};
|
|
|
|
window.addEventListener('error', event => {
|
|
if (event.target && (event.target.src || event.target.href)) {
|
|
logs.push(`[RESOURCE LOAD ERROR] ${event.target.tagName} on ${event.target.src || event.target.href}`);
|
|
}
|
|
}, true);
|
|
window.addEventListener('online', () => {
|
|
logs.push('[NETWORK STATUS] Back online');
|
|
});
|
|
window.addEventListener('offline', () => {
|
|
logs.push('[NETWORK STATUS] Offline');
|
|
});
|
|
|
|
const origFetch = window.fetch;
|
|
window.fetch = function(input, init) {
|
|
const startTime = Date.now();
|
|
const url = typeof input === 'string' ? input : input.url;
|
|
const method = (init && init.method) || 'GET';
|
|
const requestBody = init && init.body;
|
|
|
|
return origFetch.apply(this, arguments)
|
|
.then(response => {
|
|
const duration = Date.now() - startTime;
|
|
logs.push(`[NETWORK] ${method} ${url} - Status: ${response.status} (${duration}ms)`);
|
|
return response;
|
|
})
|
|
.catch(error => {
|
|
const duration = Date.now() - startTime;
|
|
let errorLog = `[NET ERROR] ${method} ${url} - ${error.message} (${duration}ms)`;
|
|
if (requestBody && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
|
|
let postData = 'Unknown';
|
|
try {
|
|
if (typeof requestBody === 'string') {
|
|
postData = requestBody;
|
|
} else if (requestBody instanceof FormData) {
|
|
postData = 'FormData';
|
|
const formDataEntries = [];
|
|
for (let [key, value] of requestBody.entries()) {
|
|
formDataEntries.push(`${key}=${value}`);
|
|
}
|
|
if (formDataEntries.length > 0) {
|
|
postData = formDataEntries.join('&');
|
|
}
|
|
} else {
|
|
postData = JSON.stringify(requestBody);
|
|
}
|
|
} catch (e) {
|
|
postData = '[Cannot serialize data]';
|
|
}
|
|
errorLog += ` - POST Data: ${postData}`;
|
|
}
|
|
logs.push(errorLog);
|
|
throw error;
|
|
});
|
|
};
|
|
|
|
const bugBtn = document.createElement('button');
|
|
bugBtn.innerHTML = 'Hibabejelentés 🐛';
|
|
Object.assign(bugBtn.style, {
|
|
position: 'fixed',
|
|
bottom: '30px',
|
|
left: '-97px',
|
|
zIndex: '99999',
|
|
backgroundColor: '#e74c3c',
|
|
color: 'white',
|
|
border: 'none',
|
|
borderRadius: '0px 8px 8px 0px',
|
|
cursor: 'pointer',
|
|
fontSize: '12px',
|
|
fontWeight: 'bold',
|
|
transition: 'all 0.3s ease',
|
|
width: '130px',
|
|
padding: '5px 10px',
|
|
overflow: 'hidden',
|
|
opacity: '1'
|
|
});
|
|
|
|
bugBtn.onmouseenter = () => {
|
|
bugBtn.style.left = '0px';
|
|
};
|
|
bugBtn.onmouseleave = () => {
|
|
bugBtn.style.left = '-97px';
|
|
};
|
|
document.body.appendChild(bugBtn);
|
|
|
|
bugBtn.onclick = async () => {
|
|
bugBtn.textContent = 'Küldés...';
|
|
bugBtn.disabled = true;
|
|
try {
|
|
let screenshotData = null;
|
|
let screenshotDataFull = null;
|
|
|
|
if (typeof html2canvas !== 'undefined') {
|
|
try {
|
|
|
|
const links = document.querySelectorAll('link[rel="stylesheet"]');
|
|
const filterPromises = Array.from(links).map(link => {
|
|
const href = link.href;
|
|
return fetch(href)
|
|
.then(r => r.text())
|
|
.then(css => {
|
|
css = css.replace(/color\s*\([^)]*\)/gi, '#000000');
|
|
css = css.replace(/color-mix\s*\([^()]*(?:\([^()]*\)[^()]*)*\)/gi, '#808080');
|
|
return css;
|
|
})
|
|
.catch(() => null);
|
|
});
|
|
|
|
const cssArrays = await Promise.all(filterPromises);
|
|
const combinedCss = cssArrays.filter(c => c).join('\n');
|
|
|
|
const filterUnsupported = (clonedDoc) => {
|
|
const clonedLinks = clonedDoc.querySelectorAll('link[rel="stylesheet"]');
|
|
clonedLinks.forEach(link => link.remove());
|
|
|
|
if (combinedCss) {
|
|
const style = clonedDoc.createElement('style');
|
|
style.textContent = combinedCss;
|
|
clonedDoc.head.appendChild(style);
|
|
}
|
|
|
|
clonedDoc.querySelectorAll('[style]').forEach(el => {
|
|
const style = el.getAttribute('style');
|
|
let newStyle = style;
|
|
newStyle = newStyle.replace(/color\s*\([^)]*\)/gi, '#000000');
|
|
newStyle = newStyle.replace(/color-mix\s*\([^()]*(?:\([^()]*\)[^()]*)*\)/gi, '#808080');
|
|
el.setAttribute('style', newStyle);
|
|
});
|
|
|
|
clonedDoc.querySelectorAll('style').forEach(styleEl => {
|
|
let css = styleEl.textContent;
|
|
css = css.replace(/color\s*\([^)]*\)/gi, '#000000');
|
|
css = css.replace(/color-mix\s*\([^()]*(?:\([^()]*\)[^()]*)*\)/gi, '#808080');
|
|
styleEl.textContent = css;
|
|
});
|
|
};
|
|
|
|
const canvas = await html2canvas(document.body, {
|
|
scale: window.devicePixelRatio || 1,
|
|
onclone: filterUnsupported
|
|
});
|
|
|
|
const canvasFull = await html2canvas(document.body, {
|
|
scrollX: 0,
|
|
scrollY: 0,
|
|
width: document.documentElement.scrollWidth,
|
|
height: document.documentElement.scrollHeight,
|
|
scale: window.devicePixelRatio || 1,
|
|
onclone: filterUnsupported
|
|
});
|
|
|
|
screenshotData = canvas.toDataURL('image/png');
|
|
screenshotDataFull = canvasFull.toDataURL('image/png');
|
|
} catch (e) {
|
|
console.error('Screenshot hiba:', e);
|
|
}
|
|
}
|
|
SendReport(screenshotData, screenshotDataFull);
|
|
} catch (error) {
|
|
console.error('Bug report küldési hiba:', error);
|
|
GenerateAlerts('error', 'Hiba történt a bejelentés küldése során.');
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
let currentImageMode = 'viewport';
|
|
let drawMode = 'pen';
|
|
let isDrawing = false;
|
|
let lastX = 0;
|
|
let lastY = 0;
|
|
let startX = 0;
|
|
let startY = 0;
|
|
let paintCanvas, paintCtx;
|
|
let baseImageViewport = new Image();
|
|
let baseImageFull = new Image();
|
|
let currentScreenshotData, currentScreenshotDataFull, currentText;
|
|
let savedImageData = null;
|
|
|
|
window.switchImage = function() {
|
|
currentImageMode = document.getElementById('BUGREPORT_imageSelector').value;
|
|
setupCanvas();
|
|
};
|
|
window.setDrawMode = function(mode) {
|
|
drawMode = mode;
|
|
document.getElementById('BUGREPORT_penBtn').style.background = mode === 'pen' ? '#c0392b' : '#e74c3c';
|
|
document.getElementById('BUGREPORT_rectBtn').style.background = mode === 'rect' ? '#2980b9' : '#3498db';
|
|
document.getElementById('BUGREPORT_textBtn').style.background = mode === 'text' ? '#d68910' : '#f39c12';
|
|
|
|
if (mode === 'text') {
|
|
paintCanvas.style.cursor = 'text';
|
|
} else {
|
|
paintCanvas.style.cursor = 'crosshair';
|
|
}
|
|
};
|
|
window.clearCanvas = function() {
|
|
setupCanvas();
|
|
};
|
|
window.skipPainting = function() {
|
|
const alertElement = document.querySelector('.custom-alert');
|
|
if (alertElement) {
|
|
alertElement.remove();
|
|
}
|
|
SendReport(currentScreenshotData, currentScreenshotDataFull, currentText, 'skipped');
|
|
};
|
|
window.savePaintedImage = function() {
|
|
const paintedImageData = paintCanvas.toDataURL('image/png');
|
|
const alertElement = document.querySelector('.custom-alert');
|
|
if (alertElement) {
|
|
alertElement.remove();
|
|
}
|
|
SendReport(currentScreenshotData, currentScreenshotDataFull, currentText, paintedImageData);
|
|
};
|
|
|
|
function setupCanvas() {
|
|
const img = currentImageMode === 'viewport' ? baseImageViewport : baseImageFull;
|
|
const maxWidth = window.innerWidth * 0.8;
|
|
const maxHeight = window.innerHeight * 0.6;
|
|
|
|
let displayWidth = img.naturalWidth;
|
|
let displayHeight = img.naturalHeight;
|
|
|
|
if (displayWidth > maxWidth) {
|
|
displayHeight = (displayHeight * maxWidth) / displayWidth;
|
|
displayWidth = maxWidth;
|
|
}
|
|
|
|
if (displayHeight > maxHeight) {
|
|
displayWidth = (displayWidth * maxHeight) / displayHeight;
|
|
displayHeight = maxHeight;
|
|
}
|
|
|
|
paintCanvas.width = displayWidth;
|
|
paintCanvas.height = displayHeight;
|
|
|
|
paintCtx.clearRect(0, 0, paintCanvas.width, paintCanvas.height);
|
|
paintCtx.drawImage(img, 0, 0, paintCanvas.width, paintCanvas.height);
|
|
}
|
|
|
|
function GetMouseX(e, canvas) {
|
|
const rect = paintCanvas.getBoundingClientRect();
|
|
return ((e.clientX - rect.left) * canvas.width) / rect.width;
|
|
}
|
|
function GetMouseY(e, canvas) {
|
|
const rect = paintCanvas.getBoundingClientRect();
|
|
return ((e.clientY - rect.top) * canvas.height) / rect.height;
|
|
}
|
|
|
|
function startDraw(e) {
|
|
if (drawMode === 'text') return;
|
|
|
|
isDrawing = true;
|
|
lastX = startX = GetMouseX(e, paintCanvas);
|
|
lastY = startY = GetMouseY(e, paintCanvas);
|
|
}
|
|
function draw(e) {
|
|
if (!isDrawing || drawMode === 'text') return;
|
|
|
|
const currentX = GetMouseX(e, paintCanvas);
|
|
const currentY = GetMouseY(e, paintCanvas);
|
|
|
|
paintCtx.strokeStyle = '#e74c3c';
|
|
paintCtx.lineWidth = 3;
|
|
paintCtx.lineCap = 'round';
|
|
|
|
if (drawMode === 'pen') {
|
|
paintCtx.beginPath();
|
|
paintCtx.moveTo(lastX, lastY);
|
|
paintCtx.lineTo(currentX, currentY);
|
|
paintCtx.stroke();
|
|
|
|
lastX = currentX;
|
|
lastY = currentY;
|
|
}
|
|
}
|
|
function stopDraw(e) {
|
|
if (!isDrawing) return;
|
|
isDrawing = false;
|
|
|
|
if (drawMode === 'rect') {
|
|
const endX = GetMouseX(e, paintCanvas);
|
|
const endY = GetMouseY(e, paintCanvas);
|
|
|
|
paintCtx.strokeStyle = '#e74c3c';
|
|
paintCtx.lineWidth = 3;
|
|
paintCtx.strokeRect(startX, startY, endX - startX, endY - startY);
|
|
}
|
|
}
|
|
function handleClick(e) {
|
|
if (drawMode !== 'text') return;
|
|
|
|
const x = GetMouseX(e, paintCanvas);
|
|
const y = GetMouseY(e, paintCanvas);
|
|
|
|
const text = prompt('Írja be a szöveget:');
|
|
if (text) {
|
|
paintCtx.fillStyle = '#e74c3c';
|
|
paintCtx.font = '16px Arial';
|
|
paintCtx.fillText(text, x, y);
|
|
}
|
|
}
|
|
function initializePaintCanvas() {
|
|
paintCanvas = document.getElementById('BUGREPORT_paintCanvas');
|
|
paintCtx = paintCanvas.getContext('2d');
|
|
|
|
paintCanvas.addEventListener('mousedown', startDraw);
|
|
paintCanvas.addEventListener('mousemove', draw);
|
|
paintCanvas.addEventListener('mouseup', stopDraw);
|
|
paintCanvas.addEventListener('click', handleClick);
|
|
|
|
baseImageViewport.onload = () => {
|
|
setupCanvas();
|
|
};
|
|
|
|
if (baseImageFull.complete || baseImageFull.naturalWidth > 0) {
|
|
setupCanvas();
|
|
} else {
|
|
baseImageFull.onload = () => {
|
|
if (currentImageMode === 'full') {
|
|
setupCanvas();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
function BrowserData() {
|
|
const data = [];
|
|
|
|
// Document
|
|
[
|
|
{ k: 'URL', v: () => document.URL },
|
|
{ k: 'referrer', v: () => document.referrer },
|
|
{ k: 'characterSet', v: () => document.characterSet },
|
|
{ k: 'contentType', v: () => document.contentType },
|
|
{ k: 'visibilityState', v: () => document.visibilityState },
|
|
{ k: 'title', v: () => document.title },
|
|
{ k: 'domain', v: () => document.domain },
|
|
{ k: 'lastModified', v: () => document.lastModified },
|
|
{ k: 'readyState', v: () => document.readyState },
|
|
{ k: 'compatMode', v: () => document.compatMode },
|
|
{ k: 'dir', v: () => document.dir },
|
|
{ k: 'fullscreenEnabled', v: () => document.fullscreenEnabled },
|
|
{ k: 'hidden', v: () => document.hidden },
|
|
{ k: 'documentElement.lang', v: () => document.documentElement.lang }
|
|
].forEach(o => data.push(`document.${o.k} paraméter értéke: ${o.v()}`));
|
|
|
|
// Location
|
|
[
|
|
'href','protocol','host','hostname','port','pathname','search','hash','origin'
|
|
].forEach(p => data.push(`location.${p} paraméter értéke: ${location[p]}`));
|
|
if (location.ancestorOrigins) data.push(`location.ancestorOrigins paraméter értéke: ${[...location.ancestorOrigins].join(', ')}`);
|
|
|
|
// Navigator alap és kiterjesztett
|
|
[
|
|
'userAgent','platform','language','languages','onLine','maxTouchPoints','hardwareConcurrency','deviceMemory',
|
|
'cookieEnabled','doNotTrack','appCodeName','appName','appVersion','product','productSub','vendor','vendorSub',
|
|
'buildID','oscpu','appMinorVersion','pdfViewerEnabled','webdriver'
|
|
].forEach(p => {
|
|
const v = navigator[p];
|
|
if (v!==undefined) data.push(`navigator.${p} paraméter értéke: ${Array.isArray(v)?v.join(', '):v}`);
|
|
});
|
|
if (navigator.javaEnabled) data.push(`navigator.javaEnabled() paraméter értéke: ${navigator.javaEnabled()}`);
|
|
|
|
// Navigator.connection
|
|
if (navigator.connection) {
|
|
['type','downlink','rtt','effectiveType','saveData']
|
|
.forEach(k => data.push(`connection.${k} paraméter értéke: ${navigator.connection[k]}`));
|
|
}
|
|
|
|
// Navigator.userAgentData (Chrome)
|
|
if (navigator.userAgentData) {
|
|
data.push(`userAgentData.mobile paraméter értéke: ${navigator.userAgentData.mobile}`);
|
|
data.push(`userAgentData.brands paraméter értéke: ${navigator.userAgentData.brands.map(b=>b.brand+'('+b.version+')').join(', ')}`);
|
|
}
|
|
|
|
// Plugins & mimeTypes
|
|
if (navigator.plugins) data.push(`plugins paraméter értéke: ${Array.from(navigator.plugins).map(p=>p.name).join(', ')}`);
|
|
if (navigator.mimeTypes) data.push(`mimeTypes paraméter értéke: ${Array.from(navigator.mimeTypes).map(m=>m.type).join(', ')}`);
|
|
|
|
// Window & screen
|
|
[
|
|
'innerWidth','innerHeight','outerWidth','outerHeight','devicePixelRatio',
|
|
'scrollX','scrollY','name','length','screenLeft','screenTop'
|
|
].forEach(p => data.push(`window.${p} paraméter értéke: ${window[p]}`));
|
|
[
|
|
'width','height','availWidth','availHeight','colorDepth','pixelDepth',
|
|
'availLeft','availTop','isExtended'
|
|
].forEach(p => data.push(`screen.${p} paraméter értéke: ${screen[p]}`));
|
|
if (screen.orientation) {
|
|
data.push(`screen.orientation.type paraméter értéke: ${screen.orientation.type}`);
|
|
data.push(`screen.orientation.angle paraméter értéke: ${screen.orientation.angle}`);
|
|
}
|
|
|
|
// History
|
|
data.push(`history.length paraméter értéke: ${history.length}`);
|
|
data.push(`history.state paraméter értéke: ${JSON.stringify(history.state)}`);
|
|
|
|
// Timezone & Intl
|
|
try {
|
|
const intl = Intl.DateTimeFormat().resolvedOptions();
|
|
data.push(`timezone paraméter értéke: ${intl.timeZone}`);
|
|
data.push(`Intl.locale paraméter értéke: ${intl.locale}`);
|
|
data.push(`Intl.calendar paraméter értéke: ${intl.calendar}`);
|
|
data.push(`Intl.numberingSystem paraméter értéke: ${intl.numberingSystem}`);
|
|
} catch {}
|
|
|
|
// Performance
|
|
if (performance) {
|
|
['timeOrigin'].forEach(p => data.push(`performance.${p} paraméter értéke: ${performance[p]}`));
|
|
if (performance.navigation) ['type','redirectCount'].forEach(p=>data.push(`performance.navigation.${p} paraméter értéke: ${performance.navigation[p]}`));
|
|
if (performance.memory) ['totalJSHeapSize','usedJSHeapSize','jsHeapSizeLimit'].forEach(p=>data.push(`performance.memory.${p} paraméter értéke: ${performance.memory[p]}`));
|
|
data.push(`performance.getEntries().length paraméter értéke: ${performance.getEntries().length}`);
|
|
if (performance.timing) {
|
|
data.push(`performance.timing.loadEventEnd paraméter értéke: ${performance.timing.loadEventEnd}`);
|
|
data.push(`performance.timing.domContentLoadedEventEnd paraméter értéke: ${performance.timing.domContentLoadedEventEnd}`);
|
|
}
|
|
data.push(`performance.now() paraméter értéke: ${performance.now()}`);
|
|
}
|
|
|
|
// Storage & cookies
|
|
data.push(`document.cookie.length paraméter értéke: ${document.cookie.length}`);
|
|
try { data.push(`localStorage.length paraméter értéke: ${localStorage.length}`); } catch {}
|
|
try { data.push(`sessionStorage.length paraméter értéke: ${sessionStorage.length}`); } catch {}
|
|
data.push(`indexedDB elérhető: ${'indexedDB' in window}`);
|
|
data.push(`caches elérhető: ${'caches' in window}`);
|
|
|
|
// Battery
|
|
if (navigator.getBattery) {
|
|
navigator.getBattery().then(b=>{
|
|
['charging','level','chargingTime','dischargingTime']
|
|
.forEach(p=>data.push(`battery.${p} paraméter értéke: ${b[p]}`));
|
|
});
|
|
}
|
|
|
|
// Crypto
|
|
data.push(`crypto elérhető: ${'crypto' in window}`);
|
|
data.push(`crypto.subtle elérhető: ${!!(crypto && crypto.subtle)}`);
|
|
data.push(`crypto.randomUUID elérhető: ${typeof crypto.randomUUID === 'function'}`);
|
|
data.push(`crypto.getRandomValues elérhető: ${typeof crypto.getRandomValues === 'function'}`);
|
|
|
|
// Geolocation, clipboard, permissions, mediaDevices, usb, serial, bluetooth, xr, serviceWorker, sendBeacon, vibrate
|
|
[
|
|
'geolocation','clipboard','permissions','mediaDevices','usb','serial','bluetooth','xr','serviceWorker','sendBeacon','vibrate','keyboard','mediaCapabilities'
|
|
].forEach(api => data.push(`${api} elérhető: ${api in navigator || api in window}`));
|
|
|
|
// Permissions lekérés (state)
|
|
if (navigator.permissions) {
|
|
['geolocation','notifications','microphone','camera','clipboard-read','clipboard-write'].forEach(name => {
|
|
navigator.permissions.query({name}).then(res => {
|
|
data.push(`permissions.${name} paraméter értéke: ${res.state}`);
|
|
}).catch(()=>{});
|
|
});
|
|
}
|
|
|
|
// CSS / vizuális adatok
|
|
try {
|
|
data.push(`getComputedStyle(document.body).fontFamily paraméter értéke: ${getComputedStyle(document.body).fontFamily}`);
|
|
} catch {}
|
|
data.push(`matchMedia("(prefers-color-scheme: dark)").matches paraméter értéke: ${matchMedia("(prefers-color-scheme: dark)").matches}`);
|
|
|
|
// Dátum/idő
|
|
data.push(`Date.now() paraméter értéke: ${Date.now()}`);
|
|
data.push(`new Date().getTimezoneOffset() paraméter értéke: ${new Date().getTimezoneOffset()}`);
|
|
|
|
// Feature detect / Events
|
|
data.push(`draggable támogatás: ${'draggable' in document.createElement('span')}`);
|
|
data.push(`pointerEvents támogatás: ${'onpointerdown' in window}`);
|
|
data.push(`touchEvent támogatás: ${'ontouchstart' in window}`);
|
|
data.push(`fullscreen API: ${'fullscreenEnabled' in document}`);
|
|
data.push(`visibility API: ${typeof document.hidden !== 'undefined'}`);
|
|
|
|
return data;
|
|
}
|
|
|
|
function SendReport(screenshotData, screenshotDataFull, text = "%DefaultText%", paintedImage = null) {
|
|
if (text == "%DefaultText%") {
|
|
var html = `
|
|
<p><strong>Kérjük, írja le a hibát amit tapasztal minél pontosabban.</strong></p>
|
|
<textarea id="BUGREPORT_bugDescription" style="width: calc(100% - 20px); height: 150px; margin: 10px 0; padding: 10px; border: 1px solid #ccc; border-radius: 4px;" placeholder="Írja le itt a problémát..."></textarea>
|
|
<br clear="all"><br>
|
|
<button id="BUGREPORT_AlertBtnNo" style="float: right; margin-left: 15px; width: 80;">Mégsem</button>
|
|
<button id="BUGREPORT_AlertBtnYes" style="float: right; width: 60px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Tovább</button>
|
|
`;
|
|
|
|
|
|
const overlay = CreateAlertBox('Hibabejelentés', html, false);
|
|
document.getElementById('BUGREPORT_AlertBtnYes').onclick = function () {
|
|
var reporttext = document.getElementById("BUGREPORT_bugDescription").value;
|
|
if (reporttext == "") {
|
|
html = `<p><b>Kérjük írja le mi történt!</b></p>`;
|
|
CreateAlertBox("Figyelem", html);
|
|
return;
|
|
}
|
|
SendReport(screenshotData, screenshotDataFull, reporttext);
|
|
CloseAlertBox(overlay);
|
|
};
|
|
document.getElementById('BUGREPORT_AlertBtnNo').onclick = function () {
|
|
CloseAlertBox(overlay);
|
|
bugBtn.textContent = 'Hibabejelentés 🐛';
|
|
bugBtn.disabled = false;
|
|
};
|
|
|
|
} else if (paintedImage === null && screenshotData != null) {
|
|
currentScreenshotData = screenshotData;
|
|
currentScreenshotDataFull = screenshotDataFull;
|
|
currentText = text;
|
|
|
|
baseImageViewport.src = screenshotData;
|
|
baseImageFull.src = screenshotDataFull;
|
|
|
|
var paintHtml = `
|
|
<p>Jelölje be a problémás területeket a képernyőn.</p>
|
|
|
|
<div style="margin: 10px 0;">
|
|
<label>Kép választása:</label>
|
|
<select id="BUGREPORT_imageSelector" onchange="switchImage()" style="margin-left: 10px; padding: 5px;">
|
|
<option value="viewport">Jelenlegi nézet</option>
|
|
<option value="full">Teljes oldal</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div style="margin: 10px 0;">
|
|
<button onclick="setDrawMode('pen')" id="BUGREPORT_penBtn" style="padding: 8px 15px; margin: 5px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer;">Ceruza</button>
|
|
<button onclick="setDrawMode('rect')" id="BUGREPORT_rectBtn" style="padding: 8px 15px; margin: 5px; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer;">Négyzet</button>
|
|
<button onclick="setDrawMode('text')" id="BUGREPORT_textBtn" style="padding: 8px 15px; margin: 5px; background: #f39c12; color: white; border: none; border-radius: 4px; cursor: pointer;">Szöveg</button>
|
|
<button onclick="clearCanvas()" style="padding: 8px 15px; margin: 5px; background: #95a5a6; color: white; border: none; border-radius: 4px; cursor: pointer;">Törlés</button>
|
|
</div>
|
|
|
|
<div style="border: 1px solid #ccc; margin: 10px 0; position: relative; overflow: auto; max-height: 60vh;">
|
|
<canvas id="BUGREPORT_paintCanvas" style="cursor: crosshair; display: block; max-width: 100%;"></canvas>
|
|
</div>
|
|
|
|
<br clear="all"><br>
|
|
<button id="BUGREPORT_AlertBtnNoPaint" style="float: right; margin-left: 15px; width: 80;">Kihagyás</button>
|
|
<button id="BUGREPORT_AlertBtnYesPaint" style="float: right; width: 60px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Mentés</button>
|
|
<br clear="all">
|
|
`;
|
|
|
|
const overlay = CreateAlertBox('Hiba megjelölése (opcionális)', paintHtml, false);
|
|
document.getElementById('BUGREPORT_AlertBtnYesPaint').onclick = function () {
|
|
savePaintedImage();
|
|
CloseAlertBox(overlay);
|
|
bugBtn.textContent = 'Hibabejelentés 🐛';
|
|
bugBtn.disabled = false;
|
|
};
|
|
document.getElementById('BUGREPORT_AlertBtnNoPaint').onclick = function () {
|
|
skipPainting();
|
|
CloseAlertBox(overlay);
|
|
bugBtn.textContent = 'Hibabejelentés 🐛';
|
|
bugBtn.disabled = false;
|
|
};
|
|
|
|
setTimeout(() => {
|
|
initializePaintCanvas();
|
|
}, 100);
|
|
|
|
} else {
|
|
bugBtn.textContent = 'Küldés...';
|
|
bugBtn.disabled = true;
|
|
|
|
const reportData = {
|
|
userAgent: navigator.userAgent,
|
|
url: window.location.href,
|
|
timestamp: new Date().toISOString(),
|
|
viewport: {
|
|
width: window.innerWidth,
|
|
height: window.innerHeight
|
|
},
|
|
screen: {
|
|
width: screen.width,
|
|
height: screen.height
|
|
},
|
|
logs: logs,
|
|
description: text,
|
|
browserData: BrowserData(),
|
|
screenshot: screenshotData,
|
|
screenshotFull: screenshotDataFull,
|
|
screenshotPainted: paintedImage !== 'skipped' ? paintedImage : null
|
|
};
|
|
|
|
fetch('/managers/bug_report_handler.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(reportData)
|
|
})
|
|
.then(response => response.json())
|
|
.then(result => {
|
|
if (result.success) {
|
|
GenerateAlerts('success', 'Hibabejelentés sikeresen elküldve! Köszönjük a visszajelzést.');
|
|
} else {
|
|
GenerateAlerts('error', 'Hiba történt a küldés során: ' + (result.error || 'Ismeretlen hiba'));
|
|
}
|
|
|
|
})
|
|
.catch(error => {
|
|
console.error('Bug report küldési hiba:', error);
|
|
GenerateAlerts('error', 'Hiba történt a bejelentés küldése során.');
|
|
})
|
|
.finally(() => {
|
|
bugBtn.textContent = 'Hibabejelentés 🐛';
|
|
bugBtn.disabled = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
})();
|
|
|
|
|
|
function loadScript(url, callback) {
|
|
const script = document.createElement('script');
|
|
script.src = url;
|
|
script.onload = () => callback && callback();
|
|
document.head.appendChild(script);
|
|
}
|
|
|
|
loadScript('https://szaturnusz.szatuna.hu/js/html2canvas.min.js', () => {});
|