class Api { constructor(baseUrl) { this.baseUrl = baseUrl; } fetchUrl(url, body) { return fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(body), }).then(it => { if (it.status !== 200) { showError(it); } return it; }); } async uploadVideo(video, password) { const formData = new FormData(); formData.append('file', video); formData.append('password', await this.hashPassword(password)); return fetch(`${this.baseUrl}/upload-video.php`, { method: 'POST', body: formData }); } async deleteVideo(video, password) { return this.fetchUrl(`${this.baseUrl}/delete-video.php`, { password: await this.hashPassword(password), file: video }); } async fetchVideos(password) { return this.fetchUrl(`${this.baseUrl}/videos.php`, { password: await this.hashPassword(password) }); } async hashPassword(password) { // Encode the password as a Uint8Array const encoder = new TextEncoder(); const data = encoder.encode(password); // Hash the password using SHA-256 const hashBuffer = await crypto.subtle.digest('SHA-256', data); // Convert the hash to a hex string const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); return hashHex; } } async function showError(error) { const toaster = document.createElement('span'); toaster.classList.add('position-absolute'); toaster.classList.add('bg-danger'); toaster.classList.add('text-light'); toaster.classList.add('p-3'); toaster.classList.add('m-3'); toaster.style.top = 0; toaster.style.right = 0; if (error.status === 401) { toaster.innerHTML = 'Nesprávne heslo'; } else if (error.status === 404) { toaster.innerHTML = 'Súbor neexstuje'; } else { toaster.innerHTML = 'Chyba'; } document.body.appendChild(toaster); setTimeout(() => { document.body.removeChild(toaster); }, 6000); console.error(error, await error.json()); }