__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2024 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

/**
 * Akeeba Web Push integration.
 *
 * Window events being dispatched:
 *
 * * onAkeebaBackupWebPushNotSubscribed when the user is not subscribed to push notifications or just unsubscribed.
 * * onAkeebaBackupWebPushSubscribed when the user is already subscribed to push notifications or just subscribed.
 */
((document, window, navigator) => {
	class AkeebaBackupWebPushIntegration
	{
		options = {};

		/**
		 * Public constructor
		 *
		 * @param {Object} options The configuration options
		 */
		constructor(options)
		{
			this.options = options;
		}

		/**
		 * Convert a Base64Url-encoded string to a byte array
		 *
		 * @param   {string} base64String The string to convert
		 * @returns {Uint8Array} The resulting array
		 * @since   9.3.1
		 * @internal
		 */
		#urlBase64ToUint8Array(base64String)
		{
			var padding = '='.repeat((4 - base64String.length % 4) % 4);
			var base64  = (base64String + padding)
				.replace(/-/g, '+')
				.replace(/_/g, '/');

			var rawData     = window.atob(base64);
			var outputArray = new Uint8Array(rawData.length);

			for (var i = 0; i < rawData.length; ++i)
			{
				outputArray[i] = rawData.charCodeAt(i);
			}
			return outputArray;
		}

		/**
		 * Disable the Web Push subscription interface.
		 *
		 * Used when the browser does not support Service Workers or the Web Push Manager object.
		 *
		 * @since  9.3.1
		 */
		disableInterface()
		{
			document.querySelector(this.options.subscribeButton).classList.add('d-none', 'disabled');
			document.querySelector(this.options.unsubscribeButton).classList.add('d-none', 'disabled');
			document.querySelector(this.options.unavailableInfo).classList.remove('d-none');
			document.getElementById('webPushDetails').classList.add('d-none');
		}

		/**
		 * Registers a Service Worker to listen to our Web Push messages.
		 *
		 * @returns {null|Promise<ServiceWorkerRegistration>}
		 * @since   9.3.1
		 */
		registerServiceWorker()
		{
			console.debug('[Web Push] Preparing to register a Service Worker.');

			const workerUri = this.options.workerUri;

			if (!workerUri)
			{
				console.error('[Web Push] The backend provided no Service Worker URI. Cannot proceed.');

				return null;
			}

			return navigator.serviceWorker
				.register(workerUri)
				.then((registration) => {
					console.log('[Web Push] Service worker successfully registered.');

					return registration;
				})
				.catch((err) => {
					console.error('[Web Push] Unable to register Service Worker.', err);

					return null;
				})
		}

		/**
		 * Ask for permission to send Web Push notifications
		 *
		 * @returns {Promise<unknown>}
		 * @since   9.3.1
		 */
		askPermission()
		{
			return new Promise((resolve, reject) => {
				console.debug('[Web Push] Requesting permission.');

				const permissionResult = Notification
					.requestPermission((result) => {
						resolve(result);
					});

				if (permissionResult)
				{
					permissionResult.then(resolve, reject);
				}
			}).then((permissionResult) => {
				if (permissionResult !== 'granted')
				{
					console.error('[Web Push] Permission for push notifications was NOT granted.');

					throw new Error("We were not granted permission.");
				}

				console.log('[Web Push] Permission for push notifications was granted.');

				return true;
			});
		}

		/**
		 * Gets the user Web Push registration and returns the subscription record.
		 *
		 * @returns {Promise<PushSubscription>|null}
		 * @since   9.3.1
		 */
		subscribeUserToPush()
		{
			console.debug('[Web Push] Preparing to subscribe the user.');

			const workerUri = this.options.workerUri;
			const publicKey = this.options.vapidKeys?.publicKey;

			if (!workerUri)
			{
				console.error('[Web Push] The backend provided no Service Worker URI. Cannot proceed.');

				return null;
			}

			if (!publicKey)
			{
				console.error('[Web Push] The backend provided no VAPID public Key. Cannot proceed.')
			}

			return navigator.serviceWorker
				.register(workerUri)
				.then((registration) => {
					const subscriberOptions = {
						userVisibleOnly:      true,
						applicationServerKey: this.#urlBase64ToUint8Array(publicKey)
					};

					return registration.pushManager.subscribe(subscriberOptions);
				})
				.then((pushSubscription) => {
					console.log('[Web Push] Received PushSubscription');
					console.debug(JSON.stringify(pushSubscription));

					return pushSubscription;
				});
		}

		/**
		 * Sends the user's Web Push subscription record to the server
		 *
		 * @param   pushSubscription
		 * @returns {null|Promise<any>}
		 * @since   9.3.1
		 */
		saveUserSubscription(pushSubscription)
		{
			console.log('[Web Push] About to send the user subscription information to the backend.');

			const subscribeUri = this.options.subscribeUri;

			if (!subscribeUri)
			{
				console.error('[Web Push] The backend provided no subscription registration URL. Cannot proceed.');

				return null;
			}

			const body = new FormData();
			body.append('subscription', JSON.stringify(pushSubscription));

			return fetch(subscribeUri, {
				method:  'POST', headers: {
					'X-CSRF-Token': Joomla.getOptions('csrf.token')
				}, body: body
			})
				.then((response) => {
					if (!response.ok)
					{
						console.error(`[Web Push] Server returned HTTP error ${response.status}. Cannot proceed.`);

						throw new Error(`Server returned HTTP error ${response.status}.`);
					}

					return response.json();
				})
				.then((responseData) => {
					if (!responseData || !responseData.success)
					{
						console.error(`[Web Push] Server returned invalid data: ${responseData}. Cannot proceed.`);

						const additionalMessage = responseData?.error ?? '';

						throw new Error('Bad response from server. ' + additionalMessage);
					}
				});
		}

		isUserSubscribed(serviceWorkerRegistration)
		{
			serviceWorkerRegistration.pushManager.getSubscription()
				.then((subscription) => {
					let myEvent;

					if (!subscription)
					{
						myEvent = new CustomEvent('onAkeebaBackupWebPushNotSubscribed');
					}
					else
					{
						myEvent = new CustomEvent('onAkeebaBackupWebPushSubscribed', {
							detail: {
								subscription
							}
						});
					}

					window.dispatchEvent(myEvent);
				})
				.catch((err) => {
					if (navigator.appVersion.includes('Safari'))
					{
						console.error(
							'[Web Push] Safari does not yet support Web Push (even if it is enabled as an experimental feature)');

						this.disableInterface();

						return;
					}

					console.error('[Web Push] Cannot get push subscription status', err);
				});
		}

		onSubscribeClick(e)
		{
			e.target.classList.add('disabled');
			var theSubscription;

			this.askPermission()
				.then((junk) => {
					return this.subscribeUserToPush();
				})
				.then((pushSubscription) => {
					if (pushSubscription === null)
					{
						return null;
					}

					theSubscription = pushSubscription;

					return this.saveUserSubscription(pushSubscription);
				})
				.then(() => {
					e.target.classList.remove('disabled');

					const myEvent = new CustomEvent('onAkeebaBackupWebPushSubscribed', {
						detail: {
							subscription: theSubscription
						}
					});

					window.dispatchEvent(myEvent);

				})
				.catch((err) => {
					e.target.classList.remove('disabled');

					Joomla.renderMessages({error: [err.message]});
				});
		}

		onUnsubscribeClick(e)
		{
			const that     = this;
			const elButton = e.target;

			function removeFromServer(subscription)
			{
				console.log('[Web Push] About to send the user unsubscription information to the backend.');

				const unsubscribeUri = that.options.unsubscribeUri;

				if (!unsubscribeUri)
				{
					console.log(that.options);
					console.error(
						'[Web Push] The backend provided no unsubscription registration URL. Cannot proceed.');

					return null;
				}

				const json = JSON.stringify(subscription);
				const body = new FormData();
				body.append('subscription', json);

				return fetch(unsubscribeUri, {
					method:  'POST', headers: {
						'X-CSRF-Token': Joomla.getOptions('csrf.token')
					}, body: body
				})
					.then((response) => {
						if (!response.ok)
						{
							console.error(`[Web Push] Server returned HTTP error ${response.status}. Cannot proceed.`);

							throw new Error(`Server returned HTTP error ${response.status}.`);
						}

						return response.json();
					})
					.then((responseData) => {
						if (!responseData || !responseData.success)
						{
							console.error(`[Web Push] Server returned invalid data: ${responseData}. Cannot proceed.`);

							throw new Error('Bad response from server.');
						}

						elButton.classList.remove('disabled');

						// Send custom event
						const myEvent = new CustomEvent('onAkeebaBackupWebPushNotSubscribed', {
							detail: {
								subscription: subscription
							}
						});

						window.dispatchEvent(myEvent);
					})
					.catch((err) => {
						elButton.classList.remove('disabled');

						Joomla.renderMessages({error: [err.message]});
					});
			}

			this.registerServiceWorker().then((reg) => {
				elButton.classList.add('disabled');

				reg.pushManager.getSubscription().then((subscription) => {
					subscription.unsubscribe().then((successful) => {
						if (!successful)
						{
							elButton.classList.remove('disabled');

							return subscription;
						}

						removeFromServer(subscription);
					})
				}).catch((err) => {
					elButton.classList.remove('disabled');

					Joomla.renderMessages({error: [err.message]});
				})
			})
		}

		/**
		 * Initialise the Web Push integration
		 *
		 * @since  9.3.1
		 */
		init()
		{
			console.debug('[Web Push] Initialising');

			if (!this.options.subscribeButton)
			{
				console.warn(
					'[Web Push] The backend provided no element to trigger the user subscription process. Abort.');
			}

			const elSubscribeButton = document.querySelector(this.options.subscribeButton);

			if (!elSubscribeButton)
			{
				console.info('[Web Push] The element to trigger the user subscription process does not exist.')

				return;
			}

			if (!('serviceWorker' in navigator) || !('PushManager' in window))
			{
				console.warn('[Web Push] The browser is incompatible with the Web Push standard.');

				this.disableInterface();

				return;
			}

			// What to do if the user is already subscribed
			window.addEventListener('onAkeebaBackupWebPushSubscribed', (e) => {
				console.debug('[Web Push] The user is already subscribed.');

				const elUnsubscribeButton = document.querySelector(this.options.unsubscribeButton);

				if (elSubscribeButton)
				{
					elSubscribeButton.classList.add('d-none', 'disabled');
				}

				if (elUnsubscribeButton)
				{
					elUnsubscribeButton.classList.remove('d-none', 'disabled');

					elUnsubscribeButton.addEventListener('click', (e) => {
						this.onUnsubscribeClick(e);
					});
				}
			});

			window.addEventListener('onAkeebaBackupWebPushNotSubscribed', (e) => {
				console.debug('[Web Push] The user is not yet subscribed.');

				const elUnsubscribeButton = document.querySelector(this.options.unsubscribeButton);

				if (elUnsubscribeButton)
				{
					elUnsubscribeButton.classList.add('d-none', 'disabled');
				}

				if (elSubscribeButton)
				{
					elSubscribeButton.classList.remove('d-none', 'disabled');

					elSubscribeButton.addEventListener('click', (e) => {
						this.onSubscribeClick(e);
					});
				}
			});


			// Register the service worker, then check the user's subscription
			this.registerServiceWorker()
				.then((serviceWorkerRegistration) => {
					this.isUserSubscribed(serviceWorkerRegistration);
				});

			return this;
		}
	}

	if (Joomla.getOptions('akeeba.webPush') ?? {})
	{
		const akeebaWebPush = new AkeebaBackupWebPushIntegration(Joomla.getOptions('com_akeebabackup.webPush') ?? {});
		akeebaWebPush.init();
	}
})(document, window, navigator);

Filemanager

Name Type Size Permission Actions
Backup.js File 18.73 KB 0664
Backup.min.js File 10.27 KB 0664
Browser.js File 1018 B 0664
Browser.min.js File 647 B 0664
Configuration.js File 75.16 KB 0664
Configuration.min.js File 33.87 KB 0664
ConfigurationWizard.js File 13.3 KB 0664
ConfigurationWizard.min.js File 7.78 KB 0664
ControlPanel.js File 2.92 KB 0664
ControlPanel.min.js File 1.51 KB 0664
DatabaseFilters.js File 16.6 KB 0664
DatabaseFilters.min.js File 7.96 KB 0664
Discover.js File 614 B 0664
Discover.min.js File 326 B 0664
FileFilters.js File 31.18 KB 0664
FileFilters.min.js File 14.23 KB 0664
IncludeFolders.js File 13.03 KB 0664
IncludeFolders.min.js File 6.27 KB 0664
Log.js File 1.06 KB 0664
Log.min.js File 702 B 0664
Manage.js File 5.55 KB 0664
Manage.min.js File 3.39 KB 0664
MultipleDatabases.js File 16.75 KB 0664
MultipleDatabases.min.js File 8.19 KB 0664
RegExDatabaseFilters.js File 10.87 KB 0664
RegExDatabaseFilters.min.js File 5.49 KB 0664
RegExFileFilters.js File 11.11 KB 0664
RegExFileFilters.min.js File 5.67 KB 0664
RemoteFiles.js File 1.75 KB 0664
RemoteFiles.min.js File 876 B 0664
Restore.js File 14.35 KB 0664
Restore.min.js File 6.28 KB 0664
S3Import.js File 2.9 KB 0664
S3Import.min.js File 1.69 KB 0664
System.js File 43.92 KB 0664
System.min.js File 11.09 KB 0664
Transfer.js File 18.97 KB 0664
Transfer.min.js File 12.98 KB 0664
Upload.js File 1.11 KB 0664
Upload.min.js File 567 B 0664
WebPush.js File 11.81 KB 0664
WebPush.min.js File 7.77 KB 0664
WebPushWorker.js File 479 B 0664
WebPushWorker.min.js File 256 B 0664
Filemanager