diff --git a/plugins/enigma/enigma.js b/plugins/enigma/enigma.js
index 0d3e2390b8..da87e6cee0 100644
--- a/plugins/enigma/enigma.js
+++ b/plugins/enigma/enigma.js
@@ -63,6 +63,12 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
});
}
}
+
+ if ($('.enigma-bg-preview').length) {
+ rcmail.enigma_bg_post();
+ $('#rcmfd_enigma_bg_icon, #rcmfd_enigma_bg_scale, #rcmfd_enigma_bg_angle')
+ .on('change', function() { rcmail.enigma_bg_post(); });
+ }
}
else if (rcmail.env.task == 'mail') {
if (rcmail.env.action == 'compose') {
@@ -720,3 +726,20 @@ rcube_webmail.prototype.enigma_find_publickey = function(email)
}
);
};
+
+rcube_webmail.prototype.enigma_bg_post = function()
+{
+ var post = {};
+
+ $.each(['bg_icon', 'bg_scale', 'bg_angle'], function() {
+ post['_enigma_' + this] = $('#rcmfd_enigma_' + this).val();
+ });
+
+ rcmail.http_post('plugin.enigmabg', post);
+};
+
+rcube_webmail.prototype.enigma_bg_update = function(style)
+{
+ if (rcmail.env.task == 'settings')
+ $('.enigma-bg-preview').children().attr('style', style);
+};
diff --git a/plugins/enigma/enigma.php b/plugins/enigma/enigma.php
index fda9338ba3..8cbf6316e0 100644
--- a/plugins/enigma/enigma.php
+++ b/plugins/enigma/enigma.php
@@ -23,8 +23,9 @@ class enigma extends rcube_plugin
public $task = 'mail|settings|cli';
public $rc;
public $engine;
- public $ui;
+ private $ui;
+ private $settings_ui;
private $env_loaded = false;
@@ -42,7 +43,7 @@ function init()
$this->add_hook('message_body_prefix', array($this, 'status_message'));
$this->register_action('plugin.enigmaimport', array($this, 'import_file'));
- $this->register_action('plugin.enigmakeys', array($this, 'preferences_ui'));
+ $this->register_action('plugin.enigmakeys', array($this, 'keys_ui'));
// load the Enigma plugin configuration
$this->load_config();
@@ -76,16 +77,25 @@ function init()
$this->add_hook('preferences_save', array($this, 'preferences_save'));
$this->add_hook('identity_form', array($this, 'identity_form'));
+ // register handler for secure background style update
+ $this->register_action('plugin.enigmabg', array($this, 'background_style'));
+
// register handler for keys/certs management
- $this->register_action('plugin.enigmakeys', array($this, 'preferences_ui'));
-// $this->register_action('plugin.enigmacerts', array($this, 'preferences_ui'));
+ $this->register_action('plugin.enigmakeys', array($this, 'keys_ui'));
+// $this->register_action('plugin.enigmacerts', array($this, 'keys_ui'));
$this->load_ui();
- if (empty($_REQUEST['_framed']) || strpos($this->rc->action, 'plugin.enigma') === 0) {
+ if (empty($_REQUEST['_framed']) || strpos($this->rc->action, 'plugin.enigma') === 0
+ || $this->rc->action == 'edit-prefs' || $this->rc->action == 'save-prefs'
+ ) {
$this->ui->add_css();
}
+ if ($this->rc->action == 'edit-prefs' || $this->rc->action == 'save-prefs') {
+ $this->ui->add_js();
+ }
+
$this->password_handler();
}
else if ($this->rc->task == 'cli') {
@@ -137,6 +147,17 @@ function load_ui($all = false)
}
}
+ /**
+ * Plugin Settings UI initialization.
+ */
+ function load_settings_ui()
+ {
+ if (!$this->settings_ui) {
+ $this->load_ui();
+ $this->settings_ui = new enigma_settings($this);
+ }
+ }
+
/**
* Plugin engine initialization.
*/
@@ -182,6 +203,120 @@ function part_body($p)
return $this->engine->part_body($p);
}
+ /**
+ * Handler for keys/certs management UI template.
+ */
+ function keys_ui()
+ {
+ $this->load_ui();
+
+ $this->ui->init();
+ }
+
+ /**
+ * Handler for message_body_prefix hook.
+ * Called for every displayed (content) part of the message.
+ * Adds infobox about signature verification and/or decryption
+ * status above the body.
+ *
+ * @param array Original parameters
+ *
+ * @return array Modified parameters
+ */
+ function status_message($p)
+ {
+ $this->load_ui();
+
+ return $this->ui->status_message($p);
+ }
+
+ /**
+ * Handler for message_load hook.
+ * Check message bodies and attachments for keys/certs.
+ */
+ function message_load($p)
+ {
+ $this->load_ui();
+
+ return $this->ui->message_load($p);
+ }
+
+ /**
+ * Handler for template_object_messagebody hook.
+ * This callback function adds a box below the message content
+ * if there is a key/cert attachment available
+ */
+ function message_output($p)
+ {
+ $this->load_ui();
+
+ return $this->ui->message_output($p);
+ }
+
+ /**
+ * Handler for attached keys/certs import
+ */
+ function import_file()
+ {
+ $this->load_ui();
+
+ $this->ui->import_file();
+ }
+
+ /**
+ * Handle password submissions
+ */
+ function password_handler()
+ {
+ $this->load_engine();
+
+ $this->engine->password_handler();
+ }
+
+ /**
+ * Handle message_ready hook (encryption/signing)
+ */
+ function message_ready($p)
+ {
+ $this->load_ui();
+
+ return $this->ui->message_ready($p);
+ }
+
+ /**
+ * Handle message_compose_body hook
+ */
+ function message_compose($p)
+ {
+ $this->load_ui();
+
+ return $this->ui->message_compose($p);
+ }
+
+ /**
+ * Handler for refresh hook.
+ */
+ function refresh($p)
+ {
+ // calling enigma_engine constructor to remove passwords
+ // stored in session after expiration time
+ $this->load_engine();
+
+ return $p;
+ }
+
+ /**
+ * Handle delete_user_commit hook
+ */
+ function user_delete($p)
+ {
+ $this->load_engine();
+
+ $p['abort'] = $p['abort'] || !$this->engine->delete_user_data($p['username']);
+
+ return $p;
+ }
+
/**
* Handler for settings_actions hook.
* Adds Enigma settings section into preferences.
@@ -242,150 +377,11 @@ function preferences_sections_list($p)
*/
function preferences_list($p)
{
- if ($p['section'] != 'enigma') {
- return $p;
- }
-
- $no_override = array_flip((array)$this->rc->config->get('dont_override'));
-
- $p['blocks']['main']['name'] = $this->gettext('mainoptions');
-
- if (!isset($no_override['enigma_encryption'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_encryption';
- $input = new html_checkbox(array(
- 'name' => '_enigma_encryption',
- 'id' => $field_id,
- 'value' => 1,
- ));
-
- $p['blocks']['main']['options']['enigma_encryption'] = array(
- 'title' => html::label($field_id, $this->gettext('supportencryption')),
- 'content' => $input->show(intval($this->rc->config->get('enigma_encryption'))),
- );
- }
-
- if (!isset($no_override['enigma_signatures'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_signatures';
- $input = new html_checkbox(array(
- 'name' => '_enigma_signatures',
- 'id' => $field_id,
- 'value' => 1,
- ));
-
- $p['blocks']['main']['options']['enigma_signatures'] = array(
- 'title' => html::label($field_id, $this->gettext('supportsignatures')),
- 'content' => $input->show(intval($this->rc->config->get('enigma_signatures'))),
- );
- }
-
- if (!isset($no_override['enigma_decryption'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_decryption';
- $input = new html_checkbox(array(
- 'name' => '_enigma_decryption',
- 'id' => $field_id,
- 'value' => 1,
- ));
-
- $p['blocks']['main']['options']['enigma_decryption'] = array(
- 'title' => html::label($field_id, $this->gettext('supportdecryption')),
- 'content' => $input->show(intval($this->rc->config->get('enigma_decryption'))),
- );
- }
-
- if (!isset($no_override['enigma_sign_all'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_sign_all';
- $input = new html_checkbox(array(
- 'name' => '_enigma_sign_all',
- 'id' => $field_id,
- 'value' => 1,
- ));
-
- $p['blocks']['main']['options']['enigma_sign_all'] = array(
- 'title' => html::label($field_id, $this->gettext('signdefault')),
- 'content' => $input->show($this->rc->config->get('enigma_sign_all') ? 1 : 0),
- );
- }
-
- if (!isset($no_override['enigma_encrypt_all'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_encrypt_all';
- $input = new html_checkbox(array(
- 'name' => '_enigma_encrypt_all',
- 'id' => $field_id,
- 'value' => 1,
- ));
-
- $p['blocks']['main']['options']['enigma_encrypt_all'] = array(
- 'title' => html::label($field_id, $this->gettext('encryptdefault')),
- 'content' => $input->show($this->rc->config->get('enigma_encrypt_all') ? 1 : 0),
- );
- }
-
- if (!isset($no_override['enigma_attach_pubkey'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_attach_pubkey';
- $input = new html_checkbox(array(
- 'name' => '_enigma_attach_pubkey',
- 'id' => $field_id,
- 'value' => 1,
- ));
-
- $p['blocks']['main']['options']['enigma_attach_pubkey'] = array(
- 'title' => html::label($field_id, $this->gettext('attachpubkeydefault')),
- 'content' => $input->show($this->rc->config->get('enigma_attach_pubkey') ? 1 : 0),
- );
- }
-
- if (!isset($no_override['enigma_password_time'])) {
- if (!$p['current']) {
- $p['blocks']['main']['content'] = true;
- return $p;
- }
-
- $field_id = 'rcmfd_enigma_password_time';
- $select = new html_select(array('name' => '_enigma_password_time', 'id' => $field_id));
-
- foreach (array(1, 5, 10, 15, 30) as $m) {
- $label = $this->gettext(array('name' => 'nminutes', 'vars' => array('m' => $m)));
- $select->add($label, $m);
- }
- $select->add($this->gettext('wholesession'), 0);
+ if ($p['section'] == 'enigma') {
+ $this->load_settings_ui();
- $p['blocks']['main']['options']['enigma_password_time'] = array(
- 'title' => html::label($field_id, $this->gettext('passwordtime')),
- 'content' => $select->show(intval($this->rc->config->get('enigma_password_time'))),
- );
+ return $this->settings_ui->preferences_list($p);
}
-
- return $p;
}
/**
@@ -399,28 +395,21 @@ function preferences_list($p)
function preferences_save($p)
{
if ($p['section'] == 'enigma') {
- $p['prefs'] = array(
- 'enigma_signatures' => (bool) rcube_utils::get_input_value('_enigma_signatures', rcube_utils::INPUT_POST),
- 'enigma_decryption' => (bool) rcube_utils::get_input_value('_enigma_decryption', rcube_utils::INPUT_POST),
- 'enigma_encryption' => (bool) rcube_utils::get_input_value('_enigma_encryption', rcube_utils::INPUT_POST),
- 'enigma_sign_all' => (bool) rcube_utils::get_input_value('_enigma_sign_all', rcube_utils::INPUT_POST),
- 'enigma_encrypt_all' => (bool) rcube_utils::get_input_value('_enigma_encrypt_all', rcube_utils::INPUT_POST),
- 'enigma_attach_pubkey' => (bool) rcube_utils::get_input_value('_enigma_attach_pubkey', rcube_utils::INPUT_POST),
- 'enigma_password_time' => intval(rcube_utils::get_input_value('_enigma_password_time', rcube_utils::INPUT_POST)),
- );
- }
+ $this->load_settings_ui();
- return $p;
+ return $this->settings_ui->preferences_save($p);
+ }
}
/**
- * Handler for keys/certs management UI template.
+ * Handler for background testing action
*/
- function preferences_ui()
+ function background_style()
{
- $this->load_ui();
+ $this->load_env();
- $this->ui->init();
+ $this->rc->output->command('enigma_bg_update', enigma_settings::security_bg_style(true));
+ $this->rc->output->send();
}
/**
@@ -442,7 +431,7 @@ function identity_form($p)
if ($p['record']['email']) {
$listing = array();
$engine = $this->load_engine();
- $keys = (array)$engine->list_keys($p['record']['email']);
+ $keys = (array) $engine->list_keys($p['record']['email']);
foreach ($keys as $key) {
if ($key->get_type() === enigma_key::TYPE_KEYPAIR) {
@@ -456,7 +445,8 @@ function identity_form($p)
if (count($listing)) {
$content .= html::p(null, $this->gettext(array('name' => 'identitymatchingprivkeys', 'vars' => array('nr' => count($listing)))));
$content .= html::tag('ul', 'keylist', join('\n', $listing));
- } else {
+ }
+ else {
$content .= html::p(null, $this->gettext('identitynoprivkeys'));
}
}
@@ -477,108 +467,4 @@ function identity_form($p)
return $p;
}
-
- /**
- * Handler for message_body_prefix hook.
- * Called for every displayed (content) part of the message.
- * Adds infobox about signature verification and/or decryption
- * status above the body.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function status_message($p)
- {
- $this->load_ui();
-
- return $this->ui->status_message($p);
- }
-
- /**
- * Handler for message_load hook.
- * Check message bodies and attachments for keys/certs.
- */
- function message_load($p)
- {
- $this->load_ui();
-
- return $this->ui->message_load($p);
- }
-
- /**
- * Handler for template_object_messagebody hook.
- * This callback function adds a box below the message content
- * if there is a key/cert attachment available
- */
- function message_output($p)
- {
- $this->load_ui();
-
- return $this->ui->message_output($p);
- }
-
- /**
- * Handler for attached keys/certs import
- */
- function import_file()
- {
- $this->load_ui();
-
- $this->ui->import_file();
- }
-
- /**
- * Handle password submissions
- */
- function password_handler()
- {
- $this->load_engine();
-
- $this->engine->password_handler();
- }
-
- /**
- * Handle message_ready hook (encryption/signing)
- */
- function message_ready($p)
- {
- $this->load_ui();
-
- return $this->ui->message_ready($p);
- }
-
- /**
- * Handle message_compose_body hook
- */
- function message_compose($p)
- {
- $this->load_ui();
-
- return $this->ui->message_compose($p);
- }
-
- /**
- * Handler for refresh hook.
- */
- function refresh($p)
- {
- // calling enigma_engine constructor to remove passwords
- // stored in session after expiration time
- $this->load_engine();
-
- return $p;
- }
-
- /**
- * Handle delete_user_commit hook
- */
- function user_delete($p)
- {
- $this->load_engine();
-
- $p['abort'] = $p['abort'] || !$this->engine->delete_user_data($p['username']);
-
- return $p;
- }
}
diff --git a/plugins/enigma/lib/enigma_settings.php b/plugins/enigma/lib/enigma_settings.php
new file mode 100644
index 0000000000..51aa9f9ed6
--- /dev/null
+++ b/plugins/enigma/lib/enigma_settings.php
@@ -0,0 +1,345 @@
+ |
+ +-------------------------------------------------------------------------+
+*/
+
+class enigma_settings
+{
+ protected $plugin;
+ protected $rc;
+
+ // List of images (security background) - from FontAwesome
+ protected static $images = array(
+ 'lock' => '',
+ 'key' => '',
+ 'shield' => '',
+ 'envelope' => '',
+ 'user' => '',
+ );
+
+ // List of image scale options (security background)
+ protected static $scale_options = array(
+ 10, 15, 20, 25, 30, 35, 40
+ );
+
+ // List of image angle (rotation) options (security background)
+ protected static $angle_options = array(
+ 0, 45, 90, 135, 180, 225, 270, 315
+ );
+
+
+ public function __construct($plugin)
+ {
+ $this->plugin = $plugin;
+ $this->rc = rcube::get_instance();
+ }
+
+ /**
+ * Handler for preferences_list hook.
+ * Adds options blocks into Enigma settings sections in Preferences.
+ *
+ * @param array Original parameters
+ *
+ * @return array Modified parameters
+ */
+ public function preferences_list($p)
+ {
+ $no_override = array_flip((array)$this->rc->config->get('dont_override'));
+
+ $p['blocks']['main']['name'] = $this->plugin->gettext('mainoptions');
+ $p['blocks']['secbg']['name'] = $this->plugin->gettext('securitybg');
+
+ if (!isset($no_override['enigma_encryption'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_encryption';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_encryption',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_encryption'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('supportencryption')),
+ 'content' => $input->show(intval($this->rc->config->get('enigma_encryption'))),
+ );
+ }
+
+ if (!isset($no_override['enigma_signatures'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_signatures';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_signatures',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_signatures'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('supportsignatures')),
+ 'content' => $input->show(intval($this->rc->config->get('enigma_signatures'))),
+ );
+ }
+
+ if (!isset($no_override['enigma_decryption'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_decryption';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_decryption',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_decryption'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('supportdecryption')),
+ 'content' => $input->show(intval($this->rc->config->get('enigma_decryption'))),
+ );
+ }
+
+ if (!isset($no_override['enigma_sign_all'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_sign_all';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_sign_all',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_sign_all'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('signdefault')),
+ 'content' => $input->show($this->rc->config->get('enigma_sign_all') ? 1 : 0),
+ );
+ }
+
+ if (!isset($no_override['enigma_encrypt_all'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_encrypt_all';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_encrypt_all',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_encrypt_all'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('encryptdefault')),
+ 'content' => $input->show($this->rc->config->get('enigma_encrypt_all') ? 1 : 0),
+ );
+ }
+
+ if (!isset($no_override['enigma_attach_pubkey'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_attach_pubkey';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_attach_pubkey',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_attach_pubkey'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('attachpubkeydefault')),
+ 'content' => $input->show($this->rc->config->get('enigma_attach_pubkey') ? 1 : 0),
+ );
+ }
+
+ if (!isset($no_override['enigma_password_time'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_password_time';
+ $select = new html_select(array('name' => '_enigma_password_time', 'id' => $field_id));
+
+ foreach (array(1, 5, 10, 15, 30) as $m) {
+ $label = $this->plugin->gettext(array('name' => 'nminutes', 'vars' => array('m' => $m)));
+ $select->add($label, $m);
+ }
+ $select->add($this->plugin->gettext('wholesession'), 0);
+
+ $p['blocks']['main']['options']['enigma_password_time'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('passwordtime')),
+ 'content' => $select->show(intval($this->rc->config->get('enigma_password_time'))),
+ );
+ }
+
+ if (!$p['current']) {
+ $p['blocks']['secbg']['content'] = true;
+ return $p;
+ }
+
+ $prefs = self::security_bg_settings();
+
+ $field_id = 'rcmfd_enigma_bg_icon';
+ $select = new html_select(array('name' => '_enigma_bg_icon', 'id' => $field_id));
+
+ foreach (array_keys(self::$images) as $icon) {
+ $select->add($icon, $icon);
+ }
+
+ $p['blocks']['secbg']['options']['enigma_bg_icon'] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext('bgicon')),
+ 'content' => $select->show($prefs['enigma_bg_icon']),
+ );
+
+ foreach (array('bg_scale' => self::$scale_options, 'bg_angle' => self::$angle_options) as $item => $list) {
+ $opt_name = "enigma_$item";
+ $field_id = "rcmfd_$opt_name";
+ $range = new html_inputfield(array('type' => 'range', 'name' => "_$opt_name", 'id' => $field_id,
+ 'min' => 0, 'max' => count($list)-1, 'step' => 1));
+
+ $p['blocks']['secbg']['options'][$opt_name] = array(
+ 'title' => html::label($field_id, $this->plugin->gettext(str_replace('_', '', $item))),
+ 'content' => $range->show((int) $prefs[$opt_name]),
+ );
+ }
+
+ $p['blocks']['secbg']['options']['enigma_bg_preview'] = array(
+ 'class' => 'enigma-bg-preview',
+ 'title' => html::label(null, $this->plugin->gettext('bgpreview')),
+ 'content' => html::div(array('id' => 'enigma-message', 'class' => 'boxconfirmation enigmanotice encrypted'), $this->plugin->gettext('samplebox')),
+ );
+
+ return $p;
+ }
+
+ /**
+ * Handler for preferences_save hook.
+ * Executed on Enigma settings form submit.
+ *
+ * @param array Original parameters
+ *
+ * @return array Modified parameters
+ */
+ public function preferences_save($p)
+ {
+ if ($p['section'] == 'enigma') {
+ $p['prefs'] = array(
+ 'enigma_signatures' => (bool) rcube_utils::get_input_value('_enigma_signatures', rcube_utils::INPUT_POST),
+ 'enigma_decryption' => (bool) rcube_utils::get_input_value('_enigma_decryption', rcube_utils::INPUT_POST),
+ 'enigma_encryption' => (bool) rcube_utils::get_input_value('_enigma_encryption', rcube_utils::INPUT_POST),
+ 'enigma_sign_all' => (bool) rcube_utils::get_input_value('_enigma_sign_all', rcube_utils::INPUT_POST),
+ 'enigma_encrypt_all' => (bool) rcube_utils::get_input_value('_enigma_encrypt_all', rcube_utils::INPUT_POST),
+ 'enigma_attach_pubkey' => (bool) rcube_utils::get_input_value('_enigma_attach_pubkey', rcube_utils::INPUT_POST),
+ 'enigma_password_time' => (int) rcube_utils::get_input_value('_enigma_password_time', rcube_utils::INPUT_POST),
+ 'enigma_bg_icon' => rcube_utils::get_input_value('_enigma_bg_icon', rcube_utils::INPUT_POST),
+ 'enigma_bg_scale' => (int) rcube_utils::get_input_value('_enigma_bg_scale', rcube_utils::INPUT_POST),
+ 'enigma_bg_angle' => (int) rcube_utils::get_input_value('_enigma_bg_angle', rcube_utils::INPUT_POST),
+ );
+
+ if (!preg_match('/^[a-z]+$/', $p['prefs']['enigma_bg_icon'])) {
+ unset($p['prefs']['enigma_bg_icon']);
+ }
+ }
+
+ return $p;
+ }
+
+ /**
+ * Get the security background configuration. If there's no configuration
+ * we'll generate random values and save them as user preferences.
+ *
+ * @return array Configuration options
+ */
+ protected static function security_bg_settings()
+ {
+ $rcube = rcube::get_instance();
+
+ $prefs = array(
+ 'enigma_bg_icon' => $rcube->config->get('enigma_bg_icon'),
+ 'enigma_bg_scale' => $rcube->config->get('enigma_bg_scale'),
+ 'enigma_bg_angle' => $rcube->config->get('enigma_bg_angle'),
+ );
+
+ if (empty($prefs['enigma_bg_icon'])) {
+ $images = array_keys(self::$images);
+
+ $prefs['enigma_bg_icon'] = $images[mt_rand(0, count($images)-1)];
+ $prefs['enigma_bg_scale'] = mt_rand(0, count(self::$scale_options)-1);
+ $prefs['enigma_bg_angle'] = mt_rand(0, count(self::$angle_options)-1);
+
+ $rcube->user->save_prefs($prefs);
+ }
+
+ return $prefs;
+ }
+
+ /**
+ * Generate css rule with security background
+ *
+ * @param bool $post Replace user preferences with POST arguments
+ *
+ * @return string CSS rule
+ */
+ public static function security_bg_style($post = false)
+ {
+ // get user preferences
+ $prefs = self::security_bg_settings();
+
+ // use POSTed values (testing background in Preferences > Encryption)
+ if ($post) {
+ if (isset($_POST['_enigma_bg_icon'])) {
+ $prefs['enigma_bg_icon'] = rcube_utils::get_input_value('_enigma_bg_icon', rcube_utils::INPUT_POST);
+ }
+ if (isset($_POST['_enigma_bg_scale'])) {
+ $prefs['enigma_bg_scale'] = (int) rcube_utils::get_input_value('_enigma_bg_scale', rcube_utils::INPUT_POST);
+ }
+ if (isset($_POST['_enigma_bg_angle'])) {
+ $prefs['enigma_bg_angle'] = (int) rcube_utils::get_input_value('_enigma_bg_angle', rcube_utils::INPUT_POST);
+ }
+ }
+
+ $angle = self::$angle_options[$prefs['enigma_bg_angle']];
+ $scale = self::$scale_options[$prefs['enigma_bg_scale']] ?: 10;
+ $icon = self::$images[$prefs['enigma_bg_icon']] ?: self::$images['lock'];
+
+ // Get image viewport size for rotation arguments
+ $width = $height = 256;
+ if (preg_match('/viewbox="[0-9]+ [0-9]+ ([0-9]+) ([0-9]+)"/i', $icon, $m)) {
+ $width = intval($m[1] / 2);
+ $height = intval($m[2] / 2);
+ }
+
+ // Modify the background image:
+ // - apply angle (rotation)
+ // - scale the image to get a nice margin around it
+ // - apply semi-transparent color
+ $icon = str_replace('add('title', $option['title']);
- $table->add(null, $option['content']);
+ $table->add($option['class'], $option['content']);
}
else {
$table->add(array('colspan' => 2), $option['content']);
diff --git a/skins/elastic/ui.js b/skins/elastic/ui.js
index a13903b00a..b536b52afb 100644
--- a/skins/elastic/ui.js
+++ b/skins/elastic/ui.js
@@ -796,9 +796,10 @@ function rcube_elastic_ui()
}
// Forms
- var supported_controls = 'input:not(.button,.no-bs,[type=button],[type=radio],[type=checkbox]),textarea';
+ var supported_controls = 'input:not(.button,.no-bs,[type=button],[type=radio],[type=range],[type=checkbox]),textarea';
$(supported_controls, $('.propform', context)).addClass('form-control');
$('[type=checkbox]', $('.propform', context)).addClass('form-check-input');
+ $('[type=range]', $('.propform', context)).addClass('custom-range');
// Note: On selects we add form-control to get consistent focus
// and to not have to create separate rules for selects and inputs