Files
conservatorio-tomadini/media/regularlabs/js/downloadkey.js
2024-12-17 17:34:10 +01:00

342 lines
12 KiB
JavaScript

/**
* @package Regular Labs Library
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
(function() {
'use strict';
window.RegularLabs = window.RegularLabs || {};
window.RegularLabs.DownloadKey = window.RegularLabs.DownloadKey || {
init: function() {
const downloadKeys = document.querySelectorAll('div.rl-download-key');
downloadKeys.forEach((container) => {
const spinner = container.querySelector('span.rl-spinner');
const inputField = container.querySelector('input.rl-code-field');
const editButton = container.querySelector('.button-edit');
const applyButton = container.querySelector('.button-apply');
const cancelButton = container.querySelector('.button-cancel');
const emptyError = container.querySelector('.key-error-empty');
const localError = container.querySelector('.key-error-local');
const modal = container.querySelector(`#downloadKeyModal_${inputField.id}`);
const extension = inputField.dataset['keyExtension'];
let key = '';
if (modal) {
// Move modal to end of body, to prevent it getting hidden if inside hidden tab
document.body.appendChild(modal);
modal.addEventListener('shown.bs.modal', () => {
const modalInputField = modal.querySelector('input.rl-download-key-field');
modalInputField.focus();
});
}
const getKey = async function() {
const url = 'index.php?option=com_ajax&plugin=regularlabs&format=raw&getDownloadKey=1';
const response = await RegularLabs.Scripts.loadUrl(url);
if (response.status !== 200) {
handleGetKeyFail();
return;
}
const responseText = response.responseText.trim();
handleGetKeySuccess(responseText);
};
const handleGetKeySuccess = async function(data) {
if ( ! data.match(/^[a-z0-9]*$/i)) {
handleGetKeyFail();
return;
}
key = data;
await checkDownloadKey();
reset();
addListeners();
};
const handleGetKeyFail = function() {
localError.classList.remove('hidden');
showModal();
};
const checkDownloadKey = async function() {
const result = await RegularLabs.DownloadKey.check(extension, key, container, false);
if (['empty', 'invalid'].indexOf(result.error) > -1) {
showModal();
}
};
const showModal = function() {
if ( ! modal) {
return;
}
RegularLabs.DownloadKey.check(extension, key, modal);
if (window.bootstrap && window.bootstrap.Modal && ! window.bootstrap.Modal.getInstance(modal)) {
Joomla.initialiseModal(modal, {
isJoomla: true
});
}
window.bootstrap.Modal.getInstance(modal).show();
};
const addListeners = function() {
inputField.addEventListener('focus', selectField);
inputField.addEventListener('keydown', handleKeyPressField);
document.addEventListener('mousedown', deselectField);
editButton.addEventListener('click', () => {
inputField.focus();
});
applyButton.addEventListener('click', clickSave);
cancelButton.addEventListener('click', clickCancel);
};
const selectField = function() {
inputField.value = '';
inputField.classList.remove('inactive');
editButton.classList.add('hidden');
applyButton.classList.remove('hidden');
cancelButton.classList.remove('hidden');
};
const handleKeyPressField = function(event) {
switch (event.keyCode) {
case 13: // ENTER
save();
break;
case 27: // ESC
cancel();
break;
default:
break;
}
};
const deselectField = function(event) {
if (event.target.closest('div.rl-download-key') === container) {
return;
}
if (inputField.classList.contains('inactive')) {
return;
}
cancel();
};
const clickSave = function(event) {
event.preventDefault();
save();
};
const clickCancel = function(event) {
event.preventDefault();
cancel();
};
const save = async function() {
const saved = await RegularLabs.DownloadKey.save(extension, inputField.value, container);
if ( ! saved) {
return;
}
key = inputField.value;
container.dataset.callback && eval(`(() => {
${container.dataset.callback}
})()`);
reset();
};
const cancel = async function() {
reset();
RegularLabs.DownloadKey.resetErrors(container);
RegularLabs.DownloadKey.check(extension, key, container);
};
const reset = function() {
inputField.value = cloak(key);
inputField.blur();
spinner.classList.add('hidden');
inputField.classList.remove('hidden');
inputField.classList.add('inactive');
editButton.classList.remove('hidden');
applyButton.classList.add('hidden');
cancelButton.classList.add('hidden');
};
const cloak = function(string) {
return RegularLabs.DownloadKey.cloak(string, inputField.dataset['keyCloakLength']);
};
getKey();
});
},
cloak: function(string, cloakLength = 4) {
if (string.length <= cloakLength) {
return string;
}
return "*".repeat(string.length - cloakLength) + string.substr(-cloakLength);
},
showError: function(type, element, focus = true) {
element.querySelector(`.key-error-${type}`) && element.querySelector(`.key-error-${type}`).classList.remove('hidden');
if (type === 'empty' || type === 'expired' || type === 'invalid') {
element.querySelector('div.rl-download-key-wrapper') && element.querySelector('div.rl-download-key-wrapper').classList.remove('hidden');
}
if ( ! focus) {
return;
}
const inputField = element.querySelector('input.rl-download-key-field');
inputField.classList.add('invalid');
inputField.click();
},
resetErrors: function(element) {
const inputField = element.querySelector('input.rl-download-key-field');
inputField.classList.remove('invalid');
element.querySelectorAll('[class*="key-error-"]').forEach((error) => {
error.classList.add('hidden');
});
},
save: function(extension, key, element) {
return new Promise(async (resolve) => {
const result = await RegularLabs.DownloadKey.check(extension, key, element);
if ( ! result.pass) {
resolve(false);
return;
}
await RegularLabs.DownloadKey.store(extension, key);
if (window.bootstrap.Modal && window.bootstrap.Modal.getInstance(element)) {
const mainId = element.id.replace('downloadKeyModal_', 'downloadKeyWrapper_');
const mainElement = document.querySelector(`#${mainId}`);
RegularLabs.DownloadKey.resetErrors(mainElement);
await RegularLabs.DownloadKey.check(extension, key, mainElement);
window.bootstrap.Modal.getInstance(element).hide();
} else {
RegularLabs.DownloadKey.resetErrors(element);
await RegularLabs.DownloadKey.check(extension, key, element);
}
resolve(true);
});
},
check: function(extension, key, element, focus = true) {
return new Promise(async (resolve) => {
const url = `index.php?option=com_ajax&plugin=regularlabs&format=raw&checkDownloadKey=1&extension=${extension}&key=${key}`;
const inputField = element.querySelector('input.rl-download-key-field');
RegularLabs.DownloadKey.resetErrors(element);
const result = {pass: false, error: ''};
if ( ! key) {
result.error = 'empty';
RegularLabs.DownloadKey.showError(result.error, element, focus);
inputField.value = RegularLabs.DownloadKey.cloak(key);
result.pass = true;
resolve(result);
return;
}
const response = await RegularLabs.Scripts.loadUrl(url);
if (response.status !== 200) {
result.error = 'local';
RegularLabs.DownloadKey.showError(result.error, element, false);
resolve(result);
return;
}
const responseText = response.responseText.trim();
if ( ! responseText || responseText.charAt(0) !== '{') {
result.error = 'external';
RegularLabs.DownloadKey.showError(result.error, element, false);
resolve(result);
return;
}
const data = JSON.parse(responseText);
if ( ! data.valid) {
result.error = 'invalid';
RegularLabs.DownloadKey.showError(result.error, element, focus);
resolve(result);
return;
}
const is_modal = element.id.indexOf('downloadKeyModal_') > -1;
if ( ! data.active && is_modal) {
result.error = 'expired';
RegularLabs.DownloadKey.showError(result.error, element, focus);
resolve(result);
return;
}
if ( ! data.active) {
RegularLabs.DownloadKey.showError('expired', element, false);
}
inputField.value = RegularLabs.DownloadKey.cloak(key);
result.pass = true;
resolve(result);
});
},
store: function(extension, key) {
const url = `index.php?option=com_ajax&plugin=regularlabs&format=raw&saveDownloadKey=1&key=${key}`;
return RegularLabs.Scripts.loadUrl(url);
},
};
RegularLabs.DownloadKey.init();
})();