// Backup with restic. System > Configuration > Backup (admins): status, actions, settings, jobs and snapshots. // E-Mail > Restore (admins, domain admins): snapshot, a tree of its domains and mailboxes (also deleted ones), the // restore modal, the restores. Both pages share the job details modal. Texts from lang.backup. Loaded via $js_minifier. var mailcowBackup = (function($) { 'use strict'; var POLL_MS = 5000; var COMPONENTS = ['mails', 'imap_acl', 'aliases', 'groups', 'sender_acl', 'mail_policies', 'retention_rules', 'filters', 'sieve_activate', 'spam', 'bcc', 'syncjobs', 'app_passwords', 'tfa', 'sogo', 'settings', 'password']; // unchecked for existing targets, preselected when everything to restore was deleted var RISKY = ['tfa', 'app_passwords', 'retention_rules', 'sieve_activate']; // overwrite current values; for deleted targets SOGo is a normal item and settings/password are not sent var OVERWRITE = ['sogo', 'settings', 'password']; // existing targets: only the mails by default var EXISTING_DEFAULT = ['mails']; // items that need the mails, not in snapshots without them (RESTIC_BACKUP_MODE=config, as JobService::MAIL_COMPONENTS) var MAIL_COMPONENTS = ['mails', 'imap_acl', 'sogo', 'sieve_activate']; var BACKUP_MODES = ['all', 'data', 'config']; // domain admin ACL an item needs (as JobService::COMPONENT_ACL) var COMPONENT_ACL = {groups: 'mailbox_groups', mail_policies: 'mail_policies', retention_rules: 'retention', filters: 'filters', sieve_activate: 'filters', spam: 'spam_policy', bcc: 'bcc_maps', syncjobs: 'syncjobs', app_passwords: 'app_passwds'}; // the restore of the dovecot container (mails, IMAP ACLs, Sieve) cannot be cancelled while it runs var DOVECOT_STEPS = ['mails', 'mails_running']; var SECRETS = ['password', 's3_secret_key', 'rest_password']; // value of a password field while its secret is stored: shown as dots, never sent var SECRET_MASK = '************'; var JOB_TYPES = ['backup', 'check', 'prune', 'init']; var STATE_CLASS = {queued: 'bg-secondary', running: 'bg-info text-black', done: 'bg-success', failed: 'bg-danger', cancelled: 'bg-warning text-black'}; var RESULT_COUNTS = ['added', 'skipped', 'errors']; // a scheduled backup is overdue this long after the longest gap of the schedule (26 hours for one backup a day) var STALE_MARGIN = 2 * 3600; // entries of the schedule (as SettingsService::MAX_SCHEDULE) var MAX_SCHEDULE = 24; // weekdays in the order of the form, 0 = Sunday var WEEKDAYS = [1, 2, 3, 4, 5, 6, 0]; // errors of a job that could not open the repository var REPO_ERROR = /unable to open|wrong (repository )?password|does not exist|host key|connection refused|no such host|could not resolve|timed? ?out|permission denied|repository/i; // lang.backup of the page, '' if missing function L(key) { var src = (typeof lang !== 'undefined' && lang && lang.backup) ? lang.backup : {}; return (src[key] !== undefined && src[key] !== null) ? src[key] : ''; } function esc(s) { return escapeHtml(s === null || s === undefined ? '' : String(s)); } // replaces %s (and %1$s) one after the other, like vsprintf in the PHP alert box function fill(text) { var args = Array.prototype.slice.call(arguments, 1), next = 0; return String(text).replace(/%(?:(\d+)\$)?s/g, function(match, pos) { var value = pos ? args[pos - 1] : args[next++]; return (value === undefined || value === null) ? '' : String(value); }); } function pad(n) { return (n < 10 ? '0' : '') + n; } function now() { return Math.floor(Date.now() / 1000); } function pageLang() { return document.documentElement.lang || undefined; } // the time zone of mailcow (TZ in mailcow.conf), so times match the schedule and the "Restored