Files
Wallos/scripts/profile.js

381 lines
12 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function () {
document.getElementById("userForm").addEventListener("submit", function (event) {
event.preventDefault();
const submitButton = document.getElementById("userSubmit");
submitButton.disabled = true;
const formData = new FormData(event.target);
formData.append("action", "save");
fetch("endpoints/user/save_user.php", {
method: "POST",
headers: {
"X-CSRF-Token": window.csrfToken,
},
body: formData,
})
.then(response => response.json())
.then(data => {
if (data.success) {
document.getElementById("avatar").src = document.getElementById("avatarImg").src;
const newUsername = document.getElementById("username").value;
document.getElementById("user").textContent = newUsername;
showSuccessMessage(data.message);
if (data.reload) {
location.reload();
}
} else {
showErrorMessage(data.message || translate("failed_save_user"));
}
})
.catch(error => {
console.error(error);
showErrorMessage(translate("unknown_error"));
})
.finally(() => {
submitButton.disabled = false;
});
});
});
function toggleAvatarSelect() {
var avatarSelect = document.getElementById("avatarSelect");
if (avatarSelect.classList.contains("is-open")) {
avatarSelect.classList.remove("is-open");
} else {
avatarSelect.classList.add("is-open");
}
}
function closeAvatarSelect() {
var avatarSelect = document.getElementById("avatarSelect");
avatarSelect.classList.remove("is-open");
}
document.querySelectorAll('.avatar-option').forEach((avatar) => {
avatar.addEventListener("click", () => {
changeAvatar(avatar.src);
document.getElementById('avatarUser').value = avatar.getAttribute('data-src');
closeAvatarSelect();
})
});
function changeAvatar(src) {
document.getElementById("avatarImg").src = src;
}
function successfulUpload(field, msg) {
var reader = new FileReader();
if (field.files.length === 0) {
return;
}
if (!['image/jpeg', 'image/png', 'image/gif', 'image/jtif', 'image/webp'].includes(field.files[0]['type'])) {
showErrorMessage(msg);
return;
}
reader.onload = function () {
changeAvatar(reader.result);
};
reader.readAsDataURL(field.files[0]);
closeAvatarSelect();
}
function deleteAvatar(path) {
fetch('endpoints/user/delete_avatar.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-CSRF-Token": window.csrfToken,
},
body: JSON.stringify({ avatar: path }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
var avatarContainer = document.querySelector(`.avatar-container[data-src="${path}"]`);
if (avatarContainer) {
avatarContainer.remove();
}
showSuccessMessage();
} else {
showErrorMessage(data.message || "");
}
})
.catch((error) => {
console.error('Error:', error);
});
}
function enableTotp() {
const totpSecret = document.querySelector("#totp-secret");
const totpSecretCode = document.querySelector("#totp-secret-code");
const qrCode = document.getElementById("totp-qr-code");
totpSecret.value = "";
totpSecretCode.textContent = "";
qrCode.innerHTML = "";
fetch("endpoints/user/enable_totp.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": window.csrfToken,
},
body: JSON.stringify({ action: "generate" }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
totpSecret.value = data.secret;
totpSecretCode.textContent = data.secret;
new QRCode(qrCode, data.qrCodeUrl);
openTotpPopup();
} else {
showErrorMessage(data.message);
}
})
.catch(error => {
console.error(error);
showErrorMessage(translate("unknown_error"));
});
}
function openTotpPopup() {
const enableTotpButton = document.getElementById('enableTotp');
enableTotpButton.disabled = true;
const totpPopup = document.getElementById('totp-popup');
totpPopup.classList.add('is-open');
}
function closeTotpPopup() {
const enableTotpButton = document.getElementById('enableTotp');
enableTotpButton.disabled = false;
const totpPopup = document.getElementById('totp-popup');
totpPopup.classList.remove('is-open');
const totpBackupCodes = document.getElementById('totp-backup-codes');
if (!totpBackupCodes.classList.contains('hide')) {
location.reload();
}
}
function submitTotp() {
const totpCode = document.getElementById('totp').value;
const totpSecret = document.getElementById('totp-secret').value;
fetch('endpoints/user/enable_totp.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-CSRF-Token": window.csrfToken,
},
body: JSON.stringify({ totpCode: totpCode, totpSecret: totpSecret, action: 'verify' }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
const backupCodes = data.backupCodes;
const backupCodesList = document.getElementById('backup-codes');
backupCodesList.innerHTML = '';
backupCodes.forEach(code => {
const li = document.createElement('li');
li.textContent = code;
backupCodesList.appendChild(li);
});
const totpSetup = document.getElementById('totp-setup');
const totpBackupCodes = document.getElementById('totp-backup-codes');
totpSetup.classList.add('hide');
totpBackupCodes.classList.remove('hide');
} else {
showErrorMessage(data.message);
}
})
.catch(error => {
showErrorMessage(error);
console.log(error);
});
}
function copyBackupCodes() {
const backupCodes = document.querySelectorAll('#backup-codes li');
const codes = Array.from(backupCodes).map(code => code.textContent).join('\n');
navigator.clipboard.writeText(codes)
.then(() => {
showSuccessMessage(translate('copied_to_clipboard'));
})
.catch(() => {
showErrorMessage(translate('unknown_error'));
});
}
function downloadBackupCodes() {
const backupCodes = document.querySelectorAll('#backup-codes li');
const codes = Array.from(backupCodes).map(code => code.textContent).join('\n');
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(codes));
element.setAttribute('download', 'wallos-backup-codes.txt');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function closeTotpDisablePopup() {
const totpPopup = document.getElementById('totp-disable-popup');
totpPopup.classList.remove('is-open');
}
function disableTotp() {
const totpPopup = document.getElementById('totp-disable-popup');
totpPopup.classList.add('is-open');
}
function submitDisableTotp() {
const totpCode = document.getElementById('totp-disable').value;
fetch('endpoints/user/disable_totp.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-CSRF-Token": window.csrfToken,
},
body: JSON.stringify({ totpCode: totpCode }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
if (data.reload) {
location.reload();
}
} else {
showErrorMessage(data.message);
}
})
.catch(error => {
showErrorMessage(error);
});
}
function regenerateApiKey() {
const regenerateButton = document.getElementById("regenerateApiKey");
regenerateButton.disabled = true;
fetch("endpoints/user/regenerateapikey.php", {
method: "POST",
headers: {
"X-CSRF-Token": window.csrfToken,
},
})
.then(response => response.json())
.then(data => {
regenerateButton.disabled = false;
if (data.success) {
const newApiKey = data.apiKey;
document.getElementById("apikey").value = newApiKey;
showSuccessMessage(data.message);
} else {
showErrorMessage(data.message || translate("failed_regenerate_api_key"));
}
})
.catch(error => {
console.error(error);
regenerateButton.disabled = false;
showErrorMessage(translate("unknown_error"));
});
}
function exportAsJson() {
fetch("endpoints/subscriptions/export.php")
.then(response => response.json())
.then(data => {
if (data.success) {
const subscriptions = JSON.stringify(data.subscriptions);
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(subscriptions));
element.setAttribute('download', 'subscriptions.json');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
} else {
showErrorMessage(data.message);
}
})
.catch(error => {
console.log(error);
showErrorMessage(translate('unknown_error'));
});
}
function exportAsCsv() {
fetch("endpoints/subscriptions/export.php")
.then(response => response.json())
.then(data => {
if (data.success) {
const subscriptions = data.subscriptions;
const header = Object.keys(subscriptions[0]).join(',');
const csv = subscriptions.map(subscription => Object.values(subscription).join(',')).join('\n');
const csvWithHeader = header + '\n' + csv;
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(csvWithHeader));
element.setAttribute('download', 'subscriptions.csv');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
} else {
showErrorMessage(data.message);
}
})
.catch(error => {
showErrorMessage(translate('unknown_error'));
});
}
function deleteAccount(userId) {
if (!confirm(translate('delete_account_confirmation'))) {
return;
}
if (!confirm(translate('this_will_delete_all_data'))) {
return;
}
fetch('endpoints/settings/deleteaccount.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-CSRF-Token": window.csrfToken,
},
body: JSON.stringify({ userId: userId }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
window.location.href = 'logout.php';
} else {
showErrorMessage(data.message);
}
})
.catch((error) => {
showErrorMessage(translate('unknown_error'));
});
}