342 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			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();
 | |
| })();
 |