�PNG  IHDR22?�� pHYs  �� OiCCPPhotoshop ICC profilexڝSgTS�=���BK���KoR RB���&*! J�!��Q�EEȠ�����Q, � ��!���������{�kּ������>���� �H3Q5� �B�������.@� $p�d!s�#�~<<+"��x� �M��0���B�\���t�8K�@z�B�@F���&S�`�cb�P-`'������{[�!�� e�Dh;��V�EX0fK�9�-0IWfH���� � 0Q��){`�##x��F�W<�+��*x��<�$9E�[-qWW.(�I+6aa�@.�y�2�4���������x����6��_-��"bb���ϫp@�t~��,/��;�m��%�h^ �u��f�@����W�p�~<�5�j>{�-�]c�K'Xt����o��(�h���w��?�G�%�fI�q^D$.Tʳ?�D��*�A��,���� �`6�B$��BB d�r`)��B(�Ͱ*`/�@4�Qh��p.�U�=p�a��(�� A�a!ڈb�X#����!�H�$ ɈQ"K�5H1R�T UH�=r9�\F��;�2����G1���Q=� �C��7�F� �dt1�����r�=�6��Ыhڏ>C�0��3�l0.��B�8, �c˱"� ���V����cϱw�E� 6wB aAHXLXN�H� $4� 7 �Q�'"��K�&���b21�XH,#��/{�C�7$�C2'��I��T��F�nR#�,��4H#���dk�9�, +ȅ����3��!�[ �b@q��S�(R�jJ��4�e�2AU��Rݨ�T5�ZB���R�Q��4u�9̓IK�����hh�i��t�ݕN��W���G���w ��Ljg(�gw��L�Ӌ�T071���oUX*�*|�� �J�&�*/T����ު U�U�T��^S}�FU3S� Ԗ�U��P�SSg�;���g�oT?�~Y��Y�L�OC�Q��_�� c�x,!k ��u�5�&���|v*�����=���9C3J3W�R�f?�q��tN �(���~���)�)�4L�1e\k����X�H�Q�G�6������E�Y��A�J'\'Gg����S�Sݧ �M=:��.�k���Dw�n��^��Lo��y���}/�T�m���G X� $� �<�5qo</���QC]�@C�a�a�ᄑ��<��F�F�i�\�$�m�mƣ&&!&KM�M�RM��)�;L;L���͢�֙5�=1�2��כ߷`ZxZ,����eI��Z�Yn�Z9Y�XUZ]�F���%ֻ�����N�N���gð�ɶ�����ۮ�m�}agbg�Ů��}�}��= ���Z~s�r:V:ޚΜ�?}����/gX���3��)�i�S��Ggg�s�󈋉K��.�>.���Ƚ�Jt�q]�z���������ۯ�6�i�ܟ�4�)�Y3s���C�Q��? ��0k߬~OCO�g��#/c/�W�װ��w��a�>�>r��>�<7�2�Y_�7��ȷ�O�o�_��C#�d�z����%g��A�[��z|!��?:�e����A���AA�������!h�쐭!��Α�i�P~���a�a��~ '���W�?�p�X�1�5w��Cs�D�D�Dޛg1O9�-J5*>�.j<�7�4�?�.fY��X�XIlK9.*�6nl������� �{�/�]py�����.,:�@L�N8��A*��%�w%� y��g"/�6ш�C\*N�H*Mz�쑼5y$�3�,幄'���L Lݛ:��v m2=:�1����qB�!M��g�g�fvˬe����n��/��k���Y- �B��TZ(�*�geWf�͉�9���+��̳�ې7�����ᒶ��KW-X潬j9�������(�x��oʿ�ܔ���Ĺd�f�f���-�[����n �ڴ �V����E�/��(ۻ��C���<��e����;?T�T�T�T6��ݵa��n��{��4���[���>ɾ�UUM�f�e�I���?�������m]�Nmq����#�׹���=TR��+�G�����w- 6 U����#pDy��� �� :�v�{���vg/jB��F�S��[b[�O�>����z�G��499�?r����C�d�&����ˮ/~�����јѡ�򗓿m|������������x31^�V���w�w��O�| (�h���SЧ��������c3-� cHRMz%������u0�`:�o�_�F5IDATx��ytUս�?�;���fN$$��@B�!�k��� -*�gE���j�O�kQ�ʠ`U�B_ �AÐ0%�Ȕ�@r3ޛ;߳��$�@��v����^�s����������$��ߢ !�W��5�̱'-٘������4�>�Rƫ$�G��0U�H}�_ _� #��k�MJ/=�9Du *ڲ�k�PQ;0��j|�*�$�^컂脛y���>�z×� B��� ��(�:$�ʔ_�6��C!B����MVx��a��ζyY����j��ƋY2�9�F�{r��r�딟F��Q��hY6��� x��[l��RC��������nt@��;P��3��� F�w��7��:�P���ɋ'���mj���Bƪ�$�Q�L��y��߷g��\���z����v5�p�v$�v櫻�`6~K �Y�X����,�:��"�o�e0II"(��,������l_�C���/4�+f�E�!q��:����u����c��樼.UE�@� �]K�W���$-�h]�JG���Dz)�`��.�A/ ���mᏣc�3jK� �!�>���$�Q�!�_�? \�C2(E �M$Z I{�U���s�ǣ���=��@Բe ޻��W�����@ �w����}�9v,)��.}*|"�s��di���,���G�]W�AC�������|<����[��ߕ������K�*�G nߴ!��‹��J�!��6(L�a)��Am��������;adf��:�xm��nh�;֦I��(���o�C~ډa?�=��s����h��E������xp����)���_���t��W�����´;8���`dz=(��@@�+,�;�`�fhl��XȌ�3,uI�~z(J����� �ZX�A����H'�À�㜦�82|��a�n�z2��I���� ���EY�h�ε<�0�q�{��C��v�˅��?"@��χ�x�WS+��N�~�KQ�J�8ل�� _.W��� !TU{�����,��"�� �;�������HI S� ��))�o�1�H�D� ���� (� ;����"Ҕ��,���� �F=���O��&�Ph>�`���y��߲ &S��P�<��'��1s�1cĂ�N����2)����@�u��tv��<�+�-&�����h��[!FSG���' � z z0��<����8d&�����E0�,��<��"!P�b4��� �{S�����X����.�囤���T��hEF��X�q0"-<����h���]�Py*����F⩍��@v�˂�Y08�� .q��a��s����(!<̫1�3�L�H��7sYW�`��qtu�\7��?�@�Y�� %Ka�x�GZ�*W�P��y�����N0r9��Z�c�%���q,��k�����!!,��>���IB��� �x1�Xu�Y���v-���ֺ��N������JP��a�2`�e5��w��u;�6�i���̃��(K���ťa��(l51��JL��O'%���]���ٖ뿉!��{*�p+f ���i8��D�ȑ���ܩ�M��V��ӟz��x�7Z�1i}�^͜���6e����x��)u�d�ˏ�V�eG�\�X1�����=n�U'�~Y����L�\,�(d!x ,�:�TW8� M`r���@��r+v�Q0��>^;˴�VbF��('����� �*O��i��j�Ӆ����^�S3&� ���{������.ی�� N;��NU%d0�Ce\r"�C�b��&t7N�7��� �ȪD�[%l�۪�$��'m?�A9tI�9>��NVL ��� 6v~M�����ъ�B���0����9$&=ώm��W�0���L���&��E���f�f��'+�9��hv��7,���M��6�D�&�^� �����8 D֮�����o��k^z��O��hP�8q�5d*��YVq3�{��������#LX4�?��jP=3�~�؅c�ݰ�̱�ұ��8̲��2�G�����j��έ�9��w7���U�X�w�85C��?!I&���o&����L���I#�^�eV�,�^t5�k� �xs˛\��U�8��."���{���ǵ�l4��ݼ�;��r"���G�/~���gJV�N糦��ZZ^k+NN�D��I$�=OE�z����|*�*{��%k���G��>�`9��b;�s���8,�qs��c��.b��q�%�>r��n�R�Ƨ�%�,�A��le#�8���}; 21�0�b�&�QX�f���q�00����$>�h�N�'�a3��A���/�r ��L5�8�GԲ'�����w;��c#�q1���h$*��V^�k��QĽ�b:i������� ����H F#�_���,��]g����Ը����`RUU���� ��"�qD���>-��ϤI�~��3�̴�����NZ[[555�eeek7�m����YF#[��Đ��R��i��L�H�r ��@��J-�Pŝ��_|�-��6y��ks�V�U~��6���w.����(��0A� 4��f��� /���C�xŊ�ٳ����z=6�����rg���mKo��o�/����a�g���?'9%9��P��斓��~���L{�� �H��{AW��B��$����v�1b�&Mb�ر��ر#�0`�`xMBp! )Z�Nmo�mZ�g�}�eذaWTVV ���'99��C5��&�&+5�bT>|8��PUUETT����&���t��~TE%��'������b�tEGG;RSS�S�N�v��ѯ��t����u1@�ޚ"f��͈���r'L�Ph��m��ƌ�74o��`�x�q�P���NRSS�X,�����l&&&��MFFA!-��`��ҷ�n��Yuu�����x<I�LB%����KԒ50�!�3�bz�����ʸKL���;---�l6[��`��������Ȏ;�����egg4��!D�T��jWujyZ��������K����%����p�^���X,6��sV=�ܖ����6�3�X ���4ҿ��A2�&����_k�;d�� �VfOIEND�B`� 0x0x
PHP 8.1.31
Preview: updraft-onboarding.js Size: 24.34 KB
/var/www/weelorum_com_usr/data/www/weelorum.com/wp-content/plugins/updraftplus/includes/updraft-onboarding.js
/**
 * Initialize global object for onboarding actions if it doesn't exist
 */
if (!window.pluginOnboardingActions) {
	window.pluginOnboardingActions = {};
}

/**
 * Initialize global object for filters if it doesn't exist
 */
if (!window.updraftOnboardingFilters) {
	window.updraftOnboardingFilters = {};
}

/**
 * Adds a filter function to a specific tag.
 *
 * @param {string} tag The name of the filter.
 * @param {function} callback The function to be called when the filter is applied.
 */
window.pluginOnboardingActions.addFilter = function(tag, callback) {
	if (!window.updraftOnboardingFilters[tag]) {
		window.updraftOnboardingFilters[tag] = [];
	}
	window.updraftOnboardingFilters[tag].push(callback);
};

/**
 * Applies all filter functions registered for a specific tag to a value.
 *
 * @param {string} tag The name of the filter.
 * @param {any} value The value to filter.
 * @returns {any} The filtered value.
 */
window.pluginOnboardingActions.applyFilters = function(tag, value) {
	const args = Array.prototype.slice.call(arguments, 2);

	if (window.updraftOnboardingFilters[tag]) {
		window.updraftOnboardingFilters[tag].forEach(function(callback) {
			value = callback.apply(null, [value].concat(args));
		});
	}

	return value;
};

/**
 * Helper function to get a setting value from the settings array.
 *
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {string} id The ID of the setting to retrieve.
 * @param {any} defaultValue The default value if the setting is not found.
 * @returns {any} The value of the setting or the default value.
 */
const updraftGetSettingValue = function(settings, id, defaultValue) {
	if (typeof defaultValue === 'undefined') {
		defaultValue = '';
	}

	const found = settings.find(function(s) {
		return s.id === id;
	});

	if (found && typeof found.value !== 'undefined') {
		return found.value;
	}

	return defaultValue;
};

/**
 * Simple email validation function.
 *
 * @param {string} email The email string to validate.
 * @returns {boolean} True if the email is valid, false otherwise.
 */
const updraftIsValidEmail = function(email) {
	const trimmed = (email || "").trim();
	return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed);
};

/**
 * Creates callback objects (success and error) for storage connection testing.
 * This helps keep the code DRY when there are many connection testing functions.
 *
 * @param {object} options Options to configure the callbacks.
 * @param {string} options.groupId The group ID (e.g., 'backblaze', 'azure').
 * @param {string} options.methodLabel A user-friendly label for the storage method (e.g., 'Backblaze', 'Azure').
 * @param {function} options.setAlertState Function to update connection status in Zustand store.
 * @param {function} options.setValue Function to update a field's value in Zustand for completion status.
 * @returns {{successCallback: Function, errorCallback: Function}} An object containing the callback functions.
 */
window.pluginOnboardingActions.createTestConnectionCallbacks = function({groupId, methodLabel, setAlertState, setValue}) {
	const successCallback = function(response, status) {
		if (response && response.data && response.data.success) {
			let message = wp.i18n.sprintf(updraftplus_onboarding.connected, updraftplus_onboarding.remote_storages[methodLabel]);

			setAlertState(groupId, {
				responseMessage: message,
				responseSuccess: true,
				responseCode: 'success',
				isUpdating: false,
			});
			if (setValue) {
				setValue(`${groupId}_completed`, true);
				console.log(`[${methodLabel}] Calling setValue for ${groupId}_completed to true`);
			}
		} else {
			response.output = response.output.replaceAll('&quot;', '"');
			setAlertState(groupId, {
				responseMessage: wp.i18n.sprintf(updraftlion.settings_test_result, updraftplus_onboarding.remote_storages[methodLabel]) + ' ' + response.output,
				responseSuccess: false,
				responseCode: 'danger',
				isUpdating: false,
			});
			if (setValue) {
				setValue(`${groupId}_completed`, false);
				console.log(`[${methodLabel}] Calling setValue for ${groupId}_completed to false (failure)`);
			}
		}
	};

	const errorCallback = function(response, status, error_code, resp) {
		let errorMessage = wp.i18n.sprintf(updraftlion.settings_test_result, updraftplus_onboarding.remote_storages[methodLabel]);

		if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
			errorMessage = resp.fatal_error_message;
			console.error(resp.fatal_error_message);
		} else if (response && response.output) {
			errorMessage = response.output.replaceAll('&quot;', '"');
		} else {
			errorMessage = `updraft_send_command: error: ${status} (${error_code})`;
			console.log(errorMessage);
		}
		setAlertState(groupId, {
			responseMessage: errorMessage,
			responseSuccess: false,
			responseCode: 'danger',
			isUpdating: false,
		});
		if (setValue) {
			setValue(`${groupId}_completed`, false);
			console.log(`[${methodLabel}] Calling setValue for ${groupId}_completed to false (error)`);
		}
	};

	return { successCallback, errorCallback };
};

/**
 * Generic function to test connections to various remote storage destinations.
 *
 * @param {object} field The definition object of the clicked button field.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {string} methodLabel A user-friendly label for the storage method (e.g., 'Backblaze', 'Azure').
 * @param {object} dataPayload The complete data payload to send to the backend.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 */
window.pluginOnboardingActions.testRemoteStorageConnection = async function(
	field,
	setAlertState,
	methodLabel,
	dataPayload,
	setValue
) {
	console.log(`[${methodLabel}] Initiating remote storage connection test...`);

	// Use field.group_id if available, otherwise fallback to field.id
	const groupId = field.group_id || field.id;
	const message = wp.i18n.sprintf(updraftplus_onboarding.testing_remote_storage, updraftplus_onboarding.remote_storages[methodLabel]);
	setAlertState(groupId, {
		isUpdating: true,
		responseSuccess: false,
		responseCode: 'loading',
		responseMessage: message,
	});

	// Use the utility function to create callbacks
	const { successCallback, errorCallback } = window.pluginOnboardingActions.createTestConnectionCallbacks({
		groupId,
		methodLabel: methodLabel,
		setAlertState,
		setValue
	});

	window.updraft_send_command(
		'test_storage_settings',
		dataPayload,
		successCallback,
		{ error_callback: errorCallback }
	);
};

/**
 * Function to transform data for Backblaze connection.
 * Splits the full backup path into bucket name and backup path.
 *
 * @param {object} data The raw form data for Backblaze.
 * @returns {object} The transformed data.
 */
function updraftDataForBackblaze(data) {
	const fullPathValue = data.bucket_name || ''; // Ensure it's a string to prevent indexOf error

	let bucketName = '';
	let backupPath = '';

	const firstSlashIndex = fullPathValue.indexOf('/');
	if (firstSlashIndex !== -1) {
		bucketName = fullPathValue.substring(0, firstSlashIndex);
		backupPath = fullPathValue.substring(firstSlashIndex + 1);
	} else {
		bucketName = fullPathValue;
		backupPath = '';
	}

	data.bucket_name = bucketName;
	data.backup_path = backupPath;

	return data;
}

// Register dataForBackblaze as a filter
window.pluginOnboardingActions.addFilter('dataForBackblaze', updraftDataForBackblaze);

/**
 * Function to transform data for FTP connection.
 * Converts the boolean 'passive' value to an integer (1 or 0).
 *
 * @param {object} data The raw form data for FTP.
 * @returns {object} The transformed data.
 */
function updraftDataForFtp(data) {
	if (typeof data.passive === 'boolean') {
		data.passive = data.passive ? 1 : 0;
	}
	return data;
}

// Register dataForFtp as a filter
window.pluginOnboardingActions.addFilter('dataForFtp', updraftDataForFtp);

/**
 * Function to transform data for WebDAV connection.
 * Combines individual fields into a single 'url' parameter.
 *
 * @param {object} data The raw form data for WebDAV.
 * @returns {object} The transformed data with a single 'url' field.
 */
function updraftDataForWebdav(data) {
	const protocol = data.protocol || 'webdav://';
	const user = data.user || '';
	const pass = data.pass || '';
	const host = data.host || '';
	const port = data.port; // Can be 0, empty string, or a number
	const path = data.path || '';
	data.enable_chunk = data.enable_chunk ? 1 : 0;
	data.webdav = protocol;

	let credentials = '';
	if (user && pass) {
		credentials = `${user}:${pass}@`;
	} else if (user) {
		credentials = `${user}@`;
	}

	let portString = '';
	if (port) {
		const defaultWebdavPort = (protocol === 'webdavs://') ? 443 : 80;
		if (parseInt(port, 10) !== defaultWebdavPort) {
			portString = `:${port}`;
		}
	}

	// Ensure path starts with a slash if it's not empty
	const formattedPath = path.startsWith('/') || !path ? path : `/${path}`;

	data.url = `${protocol}${credentials}${host}${portString}${formattedPath}`;

	// Return an object with the constructed URL and other relevant fields
	return data;
}

// Register dataForWebdav as a filter
window.pluginOnboardingActions.addFilter('dataForWebdav', updraftDataForWebdav);

/**
 * Generic function to test connections to various remote storage destinations.
 * Gathers data dynamically and then calls the generic `testRemoteStorageConnection` function.
 *
 * @param {object} field The definition object of the clicked button field.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 */
window.pluginOnboardingActions.testConnection = async function(
	field,
	settings,
	setAlertState,
	setValue
) {
	// Use field.group_id if available, otherwise fallback to field.id
	const groupId = field.group_id || field.id;
	const methodLabel = field.method_label || groupId;

	let formData = {};
	// Collect relevant settings for the current destination
	settings.forEach(function(setting) {
		if (setting.id.indexOf(groupId + '_') === 0) {
			const key = setting.id.substring((groupId + '_').length);
			formData[key] = (setting && typeof setting.value !== 'undefined') ? setting.value : '';
		}
	});

	// Apply specific data transformations based on groupId using filters
	const filterTag = `dataFor${groupId.charAt(0).toUpperCase() + groupId.slice(1)}`;
	formData = window.pluginOnboardingActions.applyFilters(filterTag, formData);

	// Prepare payload
	const dataForUpdraftCommand = Object.assign({}, formData, {
		useservercerts: 0,
		disableverify: 0,
		nossl: 0,
		method: groupId
	});

	await window.pluginOnboardingActions.testRemoteStorageConnection(
		field,
		setAlertState,
		methodLabel,
		dataForUpdraftCommand,
		setValue
	);
};

/**
 * Function to handle OAuth connections for remote storage.
 * This will trigger a click on the existing authentication button for the specified destination.
 *
 * @param {object} field The definition object of the clicked button field.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand.
 */
window.pluginOnboardingActions.oauth = async function(
	field,
	settings,
	setAlertState,
	setValue
) {
	// Use field.group_id if available, otherwise fallback to field.id
	const groupId = field.group_id || field.id;
	const methodLabel = field.method_label || groupId;
	let message = wp.i18n.sprintf(updraftplus_onboarding.oauth_pre_connection, updraftplus_onboarding.remote_storages[methodLabel]);

	setAlertState(groupId, {
		isUpdating: true,
		responseSuccess: true, // Optimistic, will be updated
		responseCode: 'loading',
		responseMessage: message,
	});

	let authSuccessReceived = false;

	// Promise to wait for the 'auth_success' message from the popup
	const waitForAuthSuccess = new Promise(function(resolve, reject) {
		const messageHandler = function(event) {
			if (event.origin !== window.location.origin && !event.origin.includes('updraftplus.com')) {
				return;
			}

			if (event.data && event.data.type === 'auth_success') {
				authSuccessReceived = true;
				window.removeEventListener('message', messageHandler);
				resolve();
			}
		};
		window.addEventListener('message', messageHandler);

		// Also handle popup closure as a potential failure if auth_success isn't received
		const popupClosedHandler = function() {
			window.removeEventListener('updraftAuthPopupClosed', popupClosedHandler);
			if (!authSuccessReceived) {
				window.removeEventListener('message', messageHandler); // Clean up message listener too
				reject(new Error('OAuth popup closed without successful authentication.'));
			}
		};
		window.addEventListener('updraftAuthPopupClosed', popupClosedHandler);
	});

	// Trigger a click on the authentication button for the specific destination
	jQuery(`.updraftplusmethod.${groupId} .updraft_authlink[data-remote_method="${groupId}"]`)?.trigger('click', {
		is_requesting_popup_auth: true
	});

	try {
		await waitForAuthSuccess; // Wait for the auth_success message

		// If we reach here, auth_success was received
		setAlertState(groupId, {
			isUpdating: false,
			responseSuccess: true,
			responseCode: 'success',
			responseMessage: wp.i18n.sprintf(updraftplus_onboarding.connected, updraftplus_onboarding.remote_storages[methodLabel]),
		});
		setValue(`${groupId}_completed`, true);
	} catch (error) {
		// If we reach here, the popup was closed without auth_success
		console.error(`OAuth failed for ${methodLabel}:`, error.message);
		setAlertState(groupId, {
			isUpdating: false,
			responseSuccess: false,
			responseCode: 'danger',
			responseMessage: wp.i18n.sprintf(updraftplus_onboarding.remote_storage_not_connected, updraftplus_onboarding.remote_storages[methodLabel]),
		});
		setValue(`${groupId}_completed`, false);
	}
};

/**
 * Handles the 'Save and continue' action for remote storage settings.
 * This function will iterate through selected groups and trigger their connection tests.
 *
 * @param {object} currentStep The current step object.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 * @returns {Promise<{success: boolean, message: string}>} Result of the operation.
 */
window.pluginOnboardingActions.saveAndContinueRemoteStorage = async function(
	currentStep,
	settings,
	setAlertState,
	setValue
) {
	const completedGroups = {};
	let foundCompletedGroup = false;

	// Get selected destinations from settings
	let selectedDestinations = updraftGetSettingValue(settings, 'selected_destinations', []);

	// If selected_destinations is empty, try to get from single_group
	if (!Array.isArray(selectedDestinations)) {
		selectedDestinations = [selectedDestinations];
	}

	if (selectedDestinations.length === 0) {
		console.error('No selected remote storage group found. Returning error.');
		return { success: false };
	}

	for (const groupId of selectedDestinations) {
		const completionFieldId = `${groupId}_completed`;
		const isCompleted = updraftGetSettingValue(settings, completionFieldId, false);

		if (isCompleted) {
			foundCompletedGroup = true;
			let groupSettings = {};
			settings.forEach(function(setting) {
				if (setting.id.indexOf(groupId + '_') === 0 && setting.id !== completionFieldId) {
					const key = setting.id.substring((groupId + '_').length);
					groupSettings[key] = (setting && typeof setting.value !== 'undefined') ? setting.value : '';
				}
			});


			// Apply specific data transformations based on groupId using filters
			const filterTag = `dataFor${groupId.charAt(0).toUpperCase() + groupId.slice(1)}`;
			groupSettings = window.pluginOnboardingActions.applyFilters(filterTag, groupSettings);
			console.log(`Collected settings for ${groupId} after filter ${filterTag}:`, groupSettings);

			completedGroups[groupId] = groupSettings;
		}
	}

	if (!foundCompletedGroup) {
		console.error('No completed remote storage group found. Returning error.');
		return { success: false };
	}

	window.updraft_send_command(
		'update_backup_and_storage_settings',
		{ current_step: currentStep.id, remote_storages: completedGroups },
		null
	);

	return { success: true };
};

/**
 * Handles the 'Save and continue' action for backup settings.
 *
 * @param {object} currentStep The current step object.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 * @returns {Promise<{success: boolean, message: string}>} Result of the operation.
 */
window.pluginOnboardingActions.saveAndContinueBackupSettings = async function(
	currentStep,
	settings,
	setAlertState,
	setValue
) {
	const backupFrequency = updraftGetSettingValue(settings, 'backup_frequency');
	const keepLastBackups = updraftGetSettingValue(settings, 'keep_last_backups');

	const backupSettings = {
		backup_frequency: backupFrequency,
		keep_last_backups: keepLastBackups,
	};

	console.log('Backup Settings:', backupSettings);

	window.updraft_send_command(
		'update_backup_and_storage_settings',
		{ current_step: currentStep.id, backup_settings: backupSettings },
		null
	);

	return { success: true };
};

/**
 * Promise-based wrapper for window.updraft_send_command.
 *
 * @param {string} command - The command name sent to Updraft.
 * @param {Object} payload - The payload data sent with the command.
 * @returns {Promise<{
 *   success: boolean,
 *   response?: Object,
 *   status?: string,
 *   error_code?: string
 * }>} The command execution result.
 */
const updraftSendCommandWithPromise = async function(command, payload) {
	return new Promise(function (resolve) {
		window.updraft_send_command(
			command,
			payload,
			function (response) {
				resolve({ success: true, response });
			},
			{
				error_callback: function (response, status, error_code) {
					resolve({
						success: false,
						response,
						status,
						error_code,
					});
				},
			}
		);
	});
}

/**
 * Handles UpdraftVault connection or quota refresh,
 * including UI state updates, form value updates, and onboarding global state.
 *
 * @param {string} command - The command name sent to Updraft.
 * @param {Object} payload - The payload data for the command.
 * @param {string} groupId - Alert/state group ID to be updated.
 * @param {string} methodLabel - The method label (e.g., "UpdraftVault").
 * @param {Function} setAlertState - Setter for the alert UI state.
 * @param {Function} setValue - Setter for form values.
 * @param {boolean} isConnect - Indicates whether this is an initial connection or a quota refresh.
 * @returns {Promise<{
 *   success: boolean,
 *   message: string
 * }>} The final status of the process.
 */
async function handleUpdraftVaultConnection(
	command,
	payload,
	groupId,
	methodLabel,
	setAlertState,
	setValue,
	isConnect
) {
	let message = isConnect ? updraftplus_onboarding.connecting : updraftplus_onboarding.refreshing;
	message = wp.i18n.sprintf(message, 'UpdraftVault');

	if (typeof setAlertState === 'function') {
		setAlertState(groupId, {
			isUpdating: true,
			responseSuccess: false,
			responseCode: 'loading',
			responseMessage: message,
		});
	}

	const result = await updraftSendCommandWithPromise(command, payload);

	if (result.success && result.response && result.response.connected) {
		const response = result.response;
		let emailDisplay = '';
		let quotaDisplay = '';

		if (response && typeof response === 'object') {
			emailDisplay = payload.email;
			if (response.quota) {
				quotaDisplay = response.quota;
			}
		}

		if (emailDisplay) {
			setValue('updraftvault_email_display', emailDisplay);
		}
		if (quotaDisplay) {
			setValue('updraftvault_quota_display', quotaDisplay);
		}
		if (isConnect) {
			setValue('updraftvault_completed', true);
		}

		if (typeof setAlertState === 'function') {
			setAlertState(groupId, {
				isUpdating: false,
				responseSuccess: true,
				responseCode: false,
				responseMessage: '',
			});
		}

		return { success: true, message: '' };
	}

	if (result.success) {
		if (isConnect) {
			message = updraftplus_onboarding.remote_storage_not_connected;
		} else {
			message = updraftplus_onboarding.cannot_refresh_updraftvault;
		}
	} else {
		if (isConnect) {
			message = updraftplus_onboarding.connection_error;
		} else {
			message = updraftplus_onboarding.refresh_error;
		}

		message += result.status + ' (' + result.error_code + ')';
	}

	message = wp.i18n.sprintf(message, 'UpdraftVault');

	if (typeof setAlertState === 'function') {
		setAlertState(groupId, {
			isUpdating: false,
			responseSuccess: false,
			responseCode: 'danger',
			responseMessage: message,
		});
	}

	if (isConnect) {
		setValue('updraftvault_completed', false);
	}

	return { success: false };
}

/**
 * Handles the connect to UpdraftVault from an onboarding step.
 *
 * @param {object} field The current step object.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 * @returns {Promise<{success: boolean, message: string}>} Result of the operation.
 */
window.pluginOnboardingActions.connectUpdraftVault = async function(
	field,
	settings,
	setAlertState,
	setValue
) {
	const groupId = field.group_id || field.id || 'updraftvault';
	const methodLabel = field.method_label || 'UpdraftVault';

	const email = updraftGetSettingValue(settings, 'updraftvault_email', '');
	const password = updraftGetSettingValue(settings, 'updraftvault_password', '');

	if (!email || !updraftIsValidEmail(email)) {
		setAlertState(groupId, {
			isUpdating: false,
			responseSuccess: false,
			responseCode: 'danger',
			responseMessage: updraftplus_onboarding.email_not_valid,
		});
		setValue('updraftvault_completed', false);
		return { success: false };
	}

	if (!password) {
		setAlertState(groupId, {
			isUpdating: false,
			responseSuccess: false,
			responseCode: 'danger',
			responseMessage: updraftplus_onboarding.password_cannot_empty,
		});
		setValue('updraftvault_completed', false);
		return { success: false };
	}

	return handleUpdraftVaultConnection(
		'vault_connect',
		{
			email: email,
			pass: password,
			return_data_only: true
		},
		groupId,
		methodLabel,
		setAlertState,
		setValue,
		true
	);
};

/**
 * Handles the recount quota for UpdraftVault from an onboarding step.
 *
 * @param {object} field The current step object.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 * @returns {Promise<{success: boolean, message: string}>} Result of the operation.
 */
window.pluginOnboardingActions.recountQuotaUpdraftVault = async function(
	field,
	settings,
	setAlertState,
	setValue
) {
	const groupId = 'updraftvault_connected';
	const methodLabel = field.method_label || 'UpdraftVault';

	return handleUpdraftVaultConnection(
		'vault_recountquota',
		{
			return_data_only: true
		},
		groupId,
		methodLabel,
		setAlertState,
		setValue,
		false
	);
};

/**
 * Handles the disconnect to UpdraftVault from an onboarding step.
 *
 * @param {object} field The current step object.
 * @param {Array<object>} settings The entire form settings array from Zustand.
 * @param {function} setAlertState Function to update connection status in Zustand store.
 * @param {function} setValue Function to update a field's value in Zustand for completion status.
 * @returns {Promise<{success: boolean, message: string}>} Result of the operation.
 */
window.pluginOnboardingActions.disconnectUpdraftVault = function(
	field,
	settings,
	setAlertState,
	setValue
) {
	const groupId = 'updraftvault_connected';
	const methodLabel = field.method_label || 'UpdraftVault';

	try {
		setValue('updraftvault_completed', false);
		return handleUpdraftVaultConnection(
			'vault_disconnect',
			{
				return_data_only: true
			},
			groupId,
			methodLabel,
			setAlertState,
			setValue,
			false
		);
	} catch (e) {
		console.error('Error in disconnectUpdraftVault:', e);
		return { success: false };
	}
};

Directory Contents

Dirs: 16 × Files: 45
Name Size Perms Modified Actions
blockui DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
Dropbox2 DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
Google DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
images DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
jstree DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
labelauty DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
pcloud DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
select2 DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
tether DIR
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
- drwxr-xr-x 2026-07-28 01:49:19
Edit Download
237 B lr-xr-xr-x 2026-07-28 01:49:19
Edit Download
216.28 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
40.33 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
57.53 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
40.28 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
52.70 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
11.40 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
10.30 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
21.31 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
8.42 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
33.97 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
21.07 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
8.34 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
18.96 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
8.17 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
8.51 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
1.81 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
4.38 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
14.87 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
42.27 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
19.06 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
6.92 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
408 B lrw-r--r-- 2026-06-07 20:02:59
Edit Download
9.27 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
37.84 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
57.01 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
42.18 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
39.55 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
59.41 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
44.03 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
57.83 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
79.42 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
32.05 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
166.70 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
279.49 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
9.15 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
24.34 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
452 B lrw-r--r-- 2026-06-07 20:02:59
Edit Download
1.68 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
3.38 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
7.07 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
4.40 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
18.48 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
13.81 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
1.99 KB lrw-r--r-- 2026-06-07 20:02:59
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).
© 2026 0xNothings — Secure File Manager. All rights reserved. Built with ❤️ & Tailwind x Dark UI
Upload
Kotlin Archives - Weelorum https://weelorum.com/technology/kotlin/ Full Cycle Mobile App Development Services For Startups Sun, 01 Mar 2026 20:04:38 +0000 en-US hourly 1 https://wordpress.org/?v=7.0 PayFlow https://weelorum.com/portfolio-projects/payflow/ Sun, 01 Mar 2026 20:04:38 +0000 https://weelorum.com/success-stories/payflow/ PayFlow is a fintech application that simplifies international money transfers and currency exchange. Users can hold multiple currencies, send money globally with competitive rates, and receive instant notifications. The app features biometric authentication and real-time transaction tracking.

Сообщение PayFlow появились сначала на Weelorum.

]]>
PayFlow is a fintech application that simplifies international money transfers and currency exchange. Users can hold multiple currencies, send money globally with competitive rates, and receive instant notifications. The app features biometric authentication and real-time transaction tracking.

Сообщение PayFlow появились сначала на Weelorum.

]]>
Knock Knock https://weelorum.com/portfolio-projects/knock-knock/ Sun, 01 Mar 2026 20:04:37 +0000 https://weelorum.com/success-stories/knock-knock/ Knock Knock is a real-time restaurant discovery app. It shows users what’s happening inside venues, how crowded they are, and offers live previews via photos and video. The app uses geolocation to help people choose where to eat or socialize based on current ambiance.

Сообщение Knock Knock появились сначала на Weelorum.

]]>
Knock Knock is a real-time restaurant discovery app. It shows users what’s happening inside venues, how crowded they are, and offers live previews via photos and video. The app uses geolocation to help people choose where to eat or socialize based on current ambiance.

Сообщение Knock Knock появились сначала на Weelorum.

]]>