From 1f387039a030a346199858af14a12f8198326088 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Mon, 29 Jun 2026 09:34:53 -0500 Subject: [PATCH 1/2] fix: mark backup as warning when remote upload fails, show failure reason - Add 'warning' status for backups where the archive was created successfully but remote upload failed (SFTP, FTP, S3, GDrive) - Add status_message column to records table storing the specific failure reason without needing to read the full log - Display warning badge (yellow) with failure details in backup list and detail views - Include warning-status backups in dashboard stats, retention cleanup, and archive browser/download actions - Add filter option for warning status in backups list - Add uploadErrors tracking to SteppedSession for multi-step backups Claude-Session: https://claude.ai/code/session_01MbEjBtsSjPuTWhqqrMS2wG --- .../forms/filter_backups.xml | 1 + .../language/en-GB/com_mokosuitebackup.ini | 1 + .../com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../com_mokosuitebackup/sql/install.mysql.sql | 3 +- .../sql/updates/mysql/01.45.01.sql | 1 + .../src/Engine/BackupEngine.php | 21 ++++++++++-- .../src/Engine/SteppedBackupEngine.php | 34 ++++++++++++++----- .../src/Engine/SteppedSession.php | 1 + .../src/Model/DashboardModel.php | 6 ++-- .../tmpl/backup/default.php | 17 ++++++++-- .../tmpl/backups/default.php | 13 ++++++- .../src/Extension/MokoSuiteBackup.php | 10 +++--- source/pkg_mokosuitebackup.xml | 2 +- 13 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.01.sql diff --git a/source/packages/com_mokosuitebackup/forms/filter_backups.xml b/source/packages/com_mokosuitebackup/forms/filter_backups.xml index a44abd5..fa78e99 100644 --- a/source/packages/com_mokosuitebackup/forms/filter_backups.xml +++ b/source/packages/com_mokosuitebackup/forms/filter_backups.xml @@ -15,6 +15,7 @@ > + diff --git a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini index 8547103..8d8e64f 100644 --- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini @@ -207,6 +207,7 @@ COM_MOKOJOOMBACKUP_TYPE_DIFFERENTIAL="Differential (changed files + full DB)" ; Status labels COM_MOKOJOOMBACKUP_STATUS_COMPLETE="Complete" +COM_MOKOJOOMBACKUP_STATUS_WARNING="Warning" COM_MOKOJOOMBACKUP_STATUS_RUNNING="Running" COM_MOKOJOOMBACKUP_STATUS_FAIL="Failed" COM_MOKOJOOMBACKUP_STATUS_PENDING="Pending" diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index 1bba702..2f38405 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 01.45.00 + 01.45.01 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitebackup/sql/install.mysql.sql b/source/packages/com_mokosuitebackup/sql/install.mysql.sql index 984ff45..9d52cc4 100644 --- a/source/packages/com_mokosuitebackup/sql/install.mysql.sql +++ b/source/packages/com_mokosuitebackup/sql/install.mysql.sql @@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_records` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `profile_id` INT(11) UNSIGNED NOT NULL DEFAULT 1, `description` VARCHAR(255) NOT NULL DEFAULT '', - `status` VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending, running, complete, fail', + `status` VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending, running, complete, warning, fail', `origin` VARCHAR(20) NOT NULL DEFAULT 'backend' COMMENT 'backend, cli, api, scheduled', `backup_type` VARCHAR(20) NOT NULL DEFAULT 'full' COMMENT 'full, database, files', `archivename` VARCHAR(512) NOT NULL DEFAULT '', @@ -83,6 +83,7 @@ CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_records` ( `checksum` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'SHA-256 hash of archive', `base_record_id` INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Base full backup ID for differential', `manifest` LONGTEXT DEFAULT NULL COMMENT 'JSON file manifest for differential comparison', + `status_message` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Short user-facing status detail (e.g. upload failure reason)', `log` MEDIUMTEXT DEFAULT NULL COMMENT 'Step-by-step backup log', PRIMARY KEY (`id`), KEY `idx_profile` (`profile_id`), diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.01.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.01.sql new file mode 100644 index 0000000..4a14283 --- /dev/null +++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.01.sql @@ -0,0 +1 @@ +ALTER TABLE `#__mokosuitebackup_records` ADD COLUMN `status_message` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Short user-facing status detail (e.g. upload failure reason)' AFTER `log`; diff --git a/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php b/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php index 5eb994c..05a7825 100644 --- a/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php +++ b/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php @@ -285,8 +285,9 @@ class BackupEngine $this->log('Standalone ' . $restoreScriptName . ' generated (' . number_format(filesize($restoreScriptPath)) . ' bytes)'); } - $remoteFilename = ''; - $uploadFailed = false; + $remoteFilename = ''; + $uploadFailed = false; + $uploadErrors = []; /* Step 3: Remote upload — iterate all enabled destinations */ $remotes = $this->loadRemoteDestinations($db, $profileId); @@ -308,10 +309,12 @@ class BackupEngine } } else { $uploadFailed = true; + $uploadErrors[] = ($remote->title ?? $remote->type) . ': ' . $result['message']; $this->log(' WARNING: Upload failed: ' . $result['message']); } } catch (\Throwable $e) { $uploadFailed = true; + $uploadErrors[] = ($remote->title ?? $remote->type) . ': ' . $e->getMessage(); $this->log(' WARNING: Upload exception: ' . $e->getMessage()); } } @@ -354,11 +357,13 @@ class BackupEngine } } else { $uploadFailed = true; + $uploadErrors[] = $remoteStorage . ': ' . $uploadResult['message']; $this->log('WARNING: Remote upload failed: ' . $uploadResult['message']); $this->log('Local backup is preserved.'); } } catch (\Throwable $e) { $uploadFailed = true; + $uploadErrors[] = $remoteStorage . ': ' . $e->getMessage(); $this->log('WARNING: Remote upload threw an exception: ' . $e->getMessage()); $this->log('Local backup is preserved.'); } @@ -372,10 +377,20 @@ class BackupEngine error_log('MokoSuiteBackup: Could not write log file: ' . $logPath); } + $statusMessage = ''; + + if ($uploadFailed) { + $statusMessage = 'Remote upload failed: ' . implode('; ', $uploadErrors); + if (strlen($statusMessage) > 512) { + $statusMessage = substr($statusMessage, 0, 509) . '...'; + } + } + // Final record update (includes fields needed by NotificationSender) $update = (object) [ 'id' => $recordId, - 'status' => 'complete', + 'status' => $uploadFailed ? 'warning' : 'complete', + 'status_message' => $statusMessage, 'description' => $description, 'backup_type' => $profile->backup_type, 'archivename' => $archiveName, diff --git a/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php b/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php index 9e18d04..3cdb86d 100644 --- a/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php +++ b/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php @@ -451,6 +451,7 @@ class SteppedBackupEngine $db = Factory::getDbo(); $remoteFilename = ''; $uploadFailed = false; + $uploadErrors = $session->uploadErrors ?? []; if (!empty($session->remoteDestinations)) { // ── Multi-remote path ────────────────────────────────── @@ -485,13 +486,16 @@ class SteppedBackupEngine } } else { $uploadFailed = true; + $uploadErrors[] = ($title) . ': ' . $result['message']; $session->log(' WARNING: Upload failed: ' . $result['message']); } } catch (\Throwable $e) { $uploadFailed = true; + $uploadErrors[] = ($title ?? $type) . ': ' . $e->getMessage(); $session->log(' WARNING: Upload exception: ' . $e->getMessage()); } + $session->uploadErrors = $uploadErrors; $session->remoteIndex++; $session->currentStep++; @@ -517,7 +521,7 @@ class SteppedBackupEngine $session->statusMessage = $uploadFailed ? 'Backup complete (some remote uploads failed — local archive preserved)' : 'Backup complete'; - $this->completeRecord($session, $uploadFailed); + $this->completeRecord($session, $uploadFailed, $uploadErrors); } } else { // ── Legacy single-remote fallback ────────────────────── @@ -557,11 +561,13 @@ class SteppedBackupEngine } } else { $uploadFailed = true; + $uploadErrors[] = $session->remoteStorage . ': ' . $result['message']; $session->log('WARNING: Remote upload failed: ' . $result['message']); $session->log('Local backup is preserved.'); } } catch (\Throwable $e) { $uploadFailed = true; + $uploadErrors[] = $session->remoteStorage . ': ' . $e->getMessage(); $session->log('WARNING: Remote upload threw an exception: ' . $e->getMessage()); $session->log('Local backup is preserved.'); } @@ -580,7 +586,7 @@ class SteppedBackupEngine $session->statusMessage = $uploadFailed ? 'Backup complete (remote upload failed — local archive preserved)' : 'Backup complete'; - $this->completeRecord($session, $uploadFailed); + $this->completeRecord($session, $uploadFailed, $uploadErrors); } } @@ -631,7 +637,7 @@ class SteppedBackupEngine /** * Mark the backup record as complete. */ - private function completeRecord(SteppedSession $session, bool $uploadFailed = false): void + private function completeRecord(SteppedSession $session, bool $uploadFailed = false, array $uploadErrors = []): void { $db = Factory::getDbo(); $logContent = implode("\n", $session->log); @@ -645,13 +651,23 @@ class SteppedBackupEngine $totalSize = is_file($session->archivePath) ? filesize($session->archivePath) : 0; $checksum = is_file($session->archivePath) ? hash_file('sha256', $session->archivePath) : ''; + $statusMessage = ''; + + if ($uploadFailed && !empty($uploadErrors)) { + $statusMessage = 'Remote upload failed: ' . implode('; ', $uploadErrors); + if (strlen($statusMessage) > 512) { + $statusMessage = substr($statusMessage, 0, 509) . '...'; + } + } + $update = (object) [ - 'id' => $session->recordId, - 'status' => 'complete', - 'backupend' => date('Y-m-d H:i:s'), - 'total_size' => $totalSize, - 'checksum' => $checksum, - 'log' => $logContent, + 'id' => $session->recordId, + 'status' => $uploadFailed ? 'warning' : 'complete', + 'status_message' => $statusMessage, + 'backupend' => date('Y-m-d H:i:s'), + 'total_size' => $totalSize, + 'checksum' => $checksum, + 'log' => $logContent, ]; $db->updateObject('#__mokosuitebackup_records', $update, 'id'); diff --git a/source/packages/com_mokosuitebackup/src/Engine/SteppedSession.php b/source/packages/com_mokosuitebackup/src/Engine/SteppedSession.php index c153c52..31238ae 100644 --- a/source/packages/com_mokosuitebackup/src/Engine/SteppedSession.php +++ b/source/packages/com_mokosuitebackup/src/Engine/SteppedSession.php @@ -60,6 +60,7 @@ class SteppedSession // Multi-remote destinations (loaded from #__mokosuitebackup_remotes) public array $remoteDestinations = []; public int $remoteIndex = 0; + public array $uploadErrors = []; // Progress public int $totalSteps = 0; diff --git a/source/packages/com_mokosuitebackup/src/Model/DashboardModel.php b/source/packages/com_mokosuitebackup/src/Model/DashboardModel.php index ae85d6e..f3c08d5 100644 --- a/source/packages/com_mokosuitebackup/src/Model/DashboardModel.php +++ b/source/packages/com_mokosuitebackup/src/Model/DashboardModel.php @@ -30,7 +30,7 @@ class DashboardModel extends BaseDatabaseModel ->select('r.*, p.title AS profile_title') ->from($db->quoteName('#__mokosuitebackup_records', 'r')) ->join('LEFT', $db->quoteName('#__mokosuitebackup_profiles', 'p') . ' ON p.id = r.profile_id') - ->where($db->quoteName('r.status') . ' = ' . $db->quote('complete')) + ->where($db->quoteName('r.status') . ' IN (' . $db->quote('complete') . ', ' . $db->quote('warning') . ')') ->order($db->quoteName('r.backupend') . ' DESC'); $db->setQuery($query, 0, 1); @@ -75,7 +75,7 @@ class DashboardModel extends BaseDatabaseModel ->select('COUNT(*) AS total_count') ->select('COALESCE(SUM(' . $db->quoteName('total_size') . '), 0) AS total_size') ->from($db->quoteName('#__mokosuitebackup_records')) - ->where($db->quoteName('status') . ' = ' . $db->quote('complete')); + ->where($db->quoteName('status') . ' IN (' . $db->quote('complete') . ', ' . $db->quote('warning') . ')'); $db->setQuery($query); $stats = $db->loadObject(); @@ -274,7 +274,7 @@ class DashboardModel extends BaseDatabaseModel ->select('COALESCE(SUM(r.total_size), 0) AS total_size') ->from($db->quoteName('#__mokosuitebackup_records', 'r')) ->join('LEFT', $db->quoteName('#__mokosuitebackup_profiles', 'p') . ' ON p.id = r.profile_id') - ->where($db->quoteName('r.status') . ' = ' . $db->quote('complete')) + ->where($db->quoteName('r.status') . ' IN (' . $db->quote('complete') . ', ' . $db->quote('warning') . ')') ->group($db->quoteName('r.profile_id')) ->order('total_size DESC'); $db->setQuery($query); diff --git a/source/packages/com_mokosuitebackup/tmpl/backup/default.php b/source/packages/com_mokosuitebackup/tmpl/backup/default.php index bcaf51f..27cc6ea 100644 --- a/source/packages/com_mokosuitebackup/tmpl/backup/default.php +++ b/source/packages/com_mokosuitebackup/tmpl/backup/default.php @@ -30,12 +30,23 @@ $ajaxUrl = Route::_('index.php?option=com_mokosuitebackup&format=json', false) item->status) { 'complete' => 'badge bg-success', + 'warning' => 'badge bg-warning text-dark', 'running' => 'badge bg-info', 'fail' => 'badge bg-danger', default => 'badge bg-secondary', }; + $statusLabel = match ($this->item->status) { + 'complete' => Text::_('COM_MOKOJOOMBACKUP_STATUS_COMPLETE'), + 'warning' => Text::_('COM_MOKOJOOMBACKUP_STATUS_WARNING'), + 'running' => Text::_('COM_MOKOJOOMBACKUP_STATUS_RUNNING'), + 'fail' => Text::_('COM_MOKOJOOMBACKUP_STATUS_FAIL'), + default => $this->escape($this->item->status), + }; ?> - escape($this->item->status); ?> + + item->status_message)) : ?> +
escape($this->item->status_message); ?>
+ @@ -94,7 +105,7 @@ $ajaxUrl = Route::_('index.php?option=com_mokosuitebackup&format=json', false) - item->status === 'complete' && !empty($this->item->filesexist)) : ?> + item->status, ['complete', 'warning']) && !empty($this->item->filesexist)) : ?>

@@ -153,7 +164,7 @@ $ajaxUrl = Route::_('index.php?option=com_mokosuitebackup&format=json', false) document.getElementById('mb-detail-log-body').textContent = 'Error: ' + err.message; }); - item->status === 'complete' && !empty($this->item->filesexist)) : ?> + item->status, ['complete', 'warning']) && !empty($this->item->filesexist)) : ?> // Load archive contents function formatFileSize(bytes) { if (bytes === 0) return '0 B'; diff --git a/source/packages/com_mokosuitebackup/tmpl/backups/default.php b/source/packages/com_mokosuitebackup/tmpl/backups/default.php index f5e664a..2e3495c 100644 --- a/source/packages/com_mokosuitebackup/tmpl/backups/default.php +++ b/source/packages/com_mokosuitebackup/tmpl/backups/default.php @@ -92,12 +92,23 @@ $listDirn = $this->escape($this->state->get('list.direction')); status) { 'complete' => 'badge bg-success', + 'warning' => 'badge bg-warning text-dark', 'running' => 'badge bg-info', 'fail' => 'badge bg-danger', default => 'badge bg-secondary', }; + $statusLabel = match ($item->status) { + 'complete' => Text::_('COM_MOKOJOOMBACKUP_STATUS_COMPLETE'), + 'warning' => Text::_('COM_MOKOJOOMBACKUP_STATUS_WARNING'), + 'running' => Text::_('COM_MOKOJOOMBACKUP_STATUS_RUNNING'), + 'fail' => Text::_('COM_MOKOJOOMBACKUP_STATUS_FAIL'), + default => $this->escape($item->status), + }; ?> - escape($item->status); ?> + + status_message)) : ?> +
escape($item->status_message); ?> + escape($item->backup_type); ?> diff --git a/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php b/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php index 1e7406a..74b39df 100644 --- a/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php +++ b/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php @@ -259,6 +259,8 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface $maxCount = (int) $profile->retention_count > 0 ? (int) $profile->retention_count : $globalMaxCount; $pid = (int) $profile->id; + $completedStatuses = '(' . $db->quote('complete') . ', ' . $db->quote('warning') . ')'; + // Delete by age for this profile $cutoff = date('Y-m-d H:i:s', strtotime("-{$maxAge} days")); $query = $db->getQuery(true) @@ -266,7 +268,7 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface ->from($db->quoteName('#__mokosuitebackup_records')) ->where($db->quoteName('profile_id') . ' = ' . $pid) ->where($db->quoteName('backupstart') . ' < ' . $db->quote($cutoff)) - ->where($db->quoteName('status') . ' = ' . $db->quote('complete')); + ->where($db->quoteName('status') . ' IN ' . $completedStatuses); $db->setQuery($query); $expired = $db->loadObjectList(); @@ -279,7 +281,7 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface ->select('COUNT(*)') ->from($db->quoteName('#__mokosuitebackup_records')) ->where($db->quoteName('profile_id') . ' = ' . $pid) - ->where($db->quoteName('status') . ' = ' . $db->quote('complete')); + ->where($db->quoteName('status') . ' IN ' . $completedStatuses); $db->setQuery($query); $totalCount = (int) $db->loadResult(); @@ -289,7 +291,7 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface ->select('id, absolute_path') ->from($db->quoteName('#__mokosuitebackup_records')) ->where($db->quoteName('profile_id') . ' = ' . $pid) - ->where($db->quoteName('status') . ' = ' . $db->quote('complete')) + ->where($db->quoteName('status') . ' IN ' . $completedStatuses) ->order($db->quoteName('backupstart') . ' ASC'); $db->setQuery($query, 0, $excess); $oldest = $db->loadObjectList(); @@ -306,7 +308,7 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface ->from($db->quoteName('#__mokosuitebackup_records', 'r')) ->join('LEFT', $db->quoteName('#__mokosuitebackup_profiles', 'p') . ' ON p.id = r.profile_id') ->where('p.id IS NULL') - ->where($db->quoteName('r.status') . ' = ' . $db->quote('complete')); + ->where($db->quoteName('r.status') . ' IN (' . $db->quote('complete') . ', ' . $db->quote('warning') . ')'); $db->setQuery($query); $orphans = $db->loadObjectList(); diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index a88829b..6038c05 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 01.45.00 + 01.45.01 2026-06-02 Moko Consulting hello@mokoconsulting.tech -- 2.52.0 From 4a3826314fa4c90b3694e20b08bc38bf47dd23c0 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Mon, 29 Jun 2026 14:35:43 +0000 Subject: [PATCH 2/2] chore(version): pre-release bump to 01.45.04-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- SECURITY.md | 2 +- source/packages/MokoSuiteClient | 2 +- source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/com_mokosuitebackup/sql/updates/mysql/01.45.04.sql | 1 + .../mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml | 2 +- .../packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_webservices_mokosuitebackup/mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 14 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.04.sql diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 11958bd..1e3816e 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.00.00 +# VERSION: 01.45.04 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/SECURITY.md b/SECURITY.md index 2286acd..b9cde7a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla PATH: /SECURITY.md -VERSION: 01.45.00 +VERSION: 01.45.04 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/source/packages/MokoSuiteClient b/source/packages/MokoSuiteClient index 9df6bea..ff1ee76 160000 --- a/source/packages/MokoSuiteClient +++ b/source/packages/MokoSuiteClient @@ -1 +1 @@ -Subproject commit 9df6bea4b7480b2e443898ad84a279070ba4a7f6 +Subproject commit ff1ee76d71bd058b4316ce38a6670d648d392470 diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index 2f38405..7252f77 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 01.45.01 + 01.45.04 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.04.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.04.sql new file mode 100644 index 0000000..43ab0ec --- /dev/null +++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/01.45.04.sql @@ -0,0 +1 @@ +/* 01.45.04 — no schema changes */ diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index e6eb337..af326e4 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> mod_mokosuitebackup_cpanel - 01.45.00 + 01.45.04 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index 22bb14b..7d2d339 100644 --- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Action Log - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml index 5b1fe35..ecf879e 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml index 44f4a47..44679e6 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml index 345b8bd..c1a549e 100644 --- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml @@ -1,7 +1,7 @@ Quick Icon - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml index 9d0f954..e8acb7a 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml index d9a104f..0b479d1 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml index cb64b0d..87aa35d 100644 --- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Web Services - MokoSuiteBackup - 01.45.00 + 01.45.04 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index 6038c05..78e3372 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 01.45.01 + 01.45.04 2026-06-02 Moko Consulting hello@mokoconsulting.tech -- 2.52.0