Files
MokoSuiteBackup/source/packages/com_mokosuitebackup/sql/install.mysql.sql
T
Jonathan Miller d6b3e8cff0
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 23s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: PR Check / Secret Scan (pull_request) Successful in 9s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 13s
Universal: Build & Release / Promote to RC (pull_request) Failing after 11s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 34s
feat: SFTP key file upload, auth type dropdown, security hardening
SFTP UX improvements:
- SshKeyField: file upload button (FileReader → base64 → hidden field),
  key never displayed as readable text, __KEEP_EXISTING__ sentinel
  preserves DB value on re-save without re-uploading
- Auth type dropdown: password / key file / key file + passphrase
  with conditional field visibility via showon
- Required field markers on host, username, path, password
- Remove insecure FTP option from remote storage dropdown

Security:
- Private key stored base64-encoded in database
- SftpUploader decodes base64 before writing temp file
- ProfileTable::store() handles sentinel to prevent key leakage
- Key content never rendered in HTML form output
2026-06-23 08:51:49 -05:00

120 lines
7.4 KiB
SQL

CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_profiles` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL DEFAULT '',
`description` TEXT NOT NULL,
`backup_type` VARCHAR(20) NOT NULL DEFAULT 'full' COMMENT 'full, database, files',
`archive_format` VARCHAR(10) NOT NULL DEFAULT 'zip',
`compression_level` TINYINT(1) UNSIGNED NOT NULL DEFAULT 5 COMMENT '0=none, 9=max',
`split_size` INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '0=no split, otherwise MB per part',
`backup_dir` VARCHAR(512) NOT NULL DEFAULT '[DEFAULT_DIR]',
`archive_name_format` VARCHAR(512) NOT NULL DEFAULT '[host]_[datetime]_profile[profile_id]' COMMENT 'Filename format with placeholders',
`exclude_dirs` TEXT NOT NULL COMMENT 'Newline-separated directory paths to exclude',
`exclude_files` TEXT NOT NULL COMMENT 'Newline-separated filename patterns to exclude',
`exclude_tables` TEXT NOT NULL COMMENT 'Newline-separated table names to exclude',
`remote_storage` VARCHAR(20) NOT NULL DEFAULT 'none' COMMENT 'none, ftp, google_drive, s3',
`ftp_host` VARCHAR(255) NOT NULL DEFAULT '',
`ftp_port` INT(5) UNSIGNED NOT NULL DEFAULT 21,
`ftp_username` VARCHAR(255) NOT NULL DEFAULT '',
`ftp_password` VARCHAR(255) NOT NULL DEFAULT '',
`ftp_path` VARCHAR(512) NOT NULL DEFAULT '/backups',
`ftp_passive` TINYINT(1) NOT NULL DEFAULT 1,
`ftp_ssl` TINYINT(1) NOT NULL DEFAULT 0,
`sftp_host` VARCHAR(255) NOT NULL DEFAULT '',
`sftp_port` INT(5) UNSIGNED NOT NULL DEFAULT 22,
`sftp_username` VARCHAR(255) NOT NULL DEFAULT '',
`sftp_auth_type` VARCHAR(20) NOT NULL DEFAULT 'key',
`sftp_password` VARCHAR(255) NOT NULL DEFAULT '',
`sftp_key_data` MEDIUMTEXT,
`sftp_passphrase` VARCHAR(255) NOT NULL DEFAULT '',
`sftp_path` VARCHAR(512) NOT NULL DEFAULT '/backups',
`gdrive_client_id` VARCHAR(255) NOT NULL DEFAULT '',
`gdrive_client_secret` VARCHAR(255) NOT NULL DEFAULT '',
`gdrive_refresh_token` VARCHAR(512) NOT NULL DEFAULT '',
`gdrive_folder_id` VARCHAR(255) NOT NULL DEFAULT '',
`s3_endpoint` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'S3 endpoint URL (blank = AWS default)',
`s3_region` VARCHAR(50) NOT NULL DEFAULT 'us-east-1',
`s3_access_key` VARCHAR(255) NOT NULL DEFAULT '',
`s3_secret_key` VARCHAR(255) NOT NULL DEFAULT '',
`s3_bucket` VARCHAR(255) NOT NULL DEFAULT '',
`s3_path` VARCHAR(512) NOT NULL DEFAULT '/backups',
`remote_keep_local` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Keep local copy after upload',
`encryption_password` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'AES-256 archive encryption password (blank = no encryption)',
`include_mokorestore` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Include MokoRestore standalone restore script in archive',
`notify_email` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Comma-separated notification emails',
`notify_user_groups` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Comma-separated Joomla user group IDs',
`notify_on_success` TINYINT(1) NOT NULL DEFAULT 0,
`notify_on_failure` TINYINT(1) NOT NULL DEFAULT 1,
`retention_days` INT(11) NOT NULL DEFAULT 0 COMMENT '0 = use global default',
`retention_count` INT(11) NOT NULL DEFAULT 0 COMMENT '0 = use global default',
`ntfy_topic` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'ntfy topic name',
`ntfy_server` VARCHAR(512) NOT NULL DEFAULT 'https://ntfy.sh' COMMENT 'ntfy server URL',
`ntfy_token` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'ntfy access token (optional)',
`published` TINYINT(1) NOT NULL DEFAULT 1,
`ordering` INT(11) NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `idx_published` (`published`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
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',
`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 '',
`absolute_path` VARCHAR(1024) NOT NULL DEFAULT '',
`total_size` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`db_size` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`files_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`tables_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`multipart` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`tag` VARCHAR(50) NOT NULL DEFAULT '',
`backupstart` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`backupend` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`filesexist` TINYINT(1) NOT NULL DEFAULT 1,
`remote_filename` VARCHAR(512) NOT NULL DEFAULT '',
`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',
`log` MEDIUMTEXT DEFAULT NULL COMMENT 'Step-by-step backup log',
PRIMARY KEY (`id`),
KEY `idx_profile` (`profile_id`),
KEY `idx_status` (`status`),
KEY `idx_backupstart` (`backupstart`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_snapshots` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`description` VARCHAR(255) NOT NULL DEFAULT '',
`content_types` VARCHAR(255) NOT NULL DEFAULT '[]' COMMENT 'JSON array: ["articles","categories","modules"]',
`status` VARCHAR(20) NOT NULL DEFAULT 'complete' COMMENT 'complete, fail',
`articles_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`categories_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`modules_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`data_file` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Absolute path to JSON snapshot file',
`data_size` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Size of JSON file in bytes',
`log` MEDIUMTEXT DEFAULT NULL COMMENT 'Snapshot operation log',
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(11) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_created` (`created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Insert default backup profile (IGNORE prevents duplicate key error on update)
INSERT IGNORE INTO `#__mokosuitebackup_profiles` (
`id`, `title`, `description`, `backup_type`,
`archive_format`, `compression_level`, `split_size`, `backup_dir`,
`exclude_dirs`, `exclude_files`, `exclude_tables`,
`published`, `ordering`, `created`, `modified`
) VALUES (
1, 'Default Backup Profile', 'Full site backup with default settings', 'full',
'zip', 5, 0, '[DEFAULT_DIR]',
'administrator/components/com_mokosuitebackup/backups\ntmp\ncache\nlogs\nadministrator/logs',
'.gitignore\n.htaccess.bak',
'#__session',
1, 1, NOW(), NOW()
);