From b360f707e8b9749bb3825bdcf4408a92dd3e5548 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 12 May 2014 14:36:09 +0200 Subject: Small code improvement --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'index.php') diff --git a/index.php b/index.php index 239dc004f..3674db1d7 100644 --- a/index.php +++ b/index.php @@ -211,7 +211,7 @@ if (empty($RCMAIL->user->ID)) { $OUTPUT->show_message('sessionerror', 'error', null, true, -1); } - if ($OUTPUT->ajax_call || !empty($_REQUEST['_framed'])) { + if ($OUTPUT->ajax_call || $OUTPUT->framed) { $OUTPUT->command('session_error', $RCMAIL->url(array('_err' => 'session'))); $OUTPUT->send('iframe'); } -- cgit v1.2.3 From ba5c53e5c3894bcbbc33dfd3271583e44c35de25 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 9 Jun 2014 14:16:35 +0200 Subject: Send X-UA-Compatible as HTTP header instead of meta tag --- index.php | 1 + program/lib/Roundcube/rcube_output.php | 36 ++++++++++++++++++---------------- skins/classic/includes/links.html | 1 - skins/larry/includes/links.html | 1 - 4 files changed, 20 insertions(+), 19 deletions(-) (limited to 'index.php') diff --git a/index.php b/index.php index 3674db1d7..ae5df4000 100644 --- a/index.php +++ b/index.php @@ -44,6 +44,7 @@ $RCMAIL = rcmail::get_instance($GLOBALS['env']); // Make the whole PHP output non-cacheable (#1487797) $RCMAIL->output->nocacheing_headers(); +$RCMAIL->output->common_headers(); // turn on output buffering ob_start(); diff --git a/program/lib/Roundcube/rcube_output.php b/program/lib/Roundcube/rcube_output.php index 1907645b0..55a38b240 100644 --- a/program/lib/Roundcube/rcube_output.php +++ b/program/lib/Roundcube/rcube_output.php @@ -44,7 +44,6 @@ abstract class rcube_output $this->browser = new rcube_browser(); } - /** * Magic getter */ @@ -60,7 +59,6 @@ abstract class rcube_output return null; } - /** * Setter for output charset. * To be specified in a meta tag and sent as http-header @@ -72,7 +70,6 @@ abstract class rcube_output $this->charset = $charset; } - /** * Getter for output charset * @@ -83,7 +80,6 @@ abstract class rcube_output return $this->charset; } - /** * Set environment variable * @@ -95,7 +91,6 @@ abstract class rcube_output $this->env[$name] = $value; } - /** * Environment variable getter. * @@ -108,7 +103,6 @@ abstract class rcube_output return $this->env[$name]; } - /** * Delete all stored env variables and commands */ @@ -117,7 +111,6 @@ abstract class rcube_output $this->env = array(); } - /** * Invoke display_message command * @@ -129,7 +122,6 @@ abstract class rcube_output */ abstract function show_message($message, $type = 'notice', $vars = null, $override = true, $timeout = 0); - /** * Redirect to a certain url. * @@ -138,13 +130,11 @@ abstract class rcube_output */ abstract function redirect($p = array(), $delay = 1); - /** * Send output to the client. */ abstract function send(); - /** * Send HTTP headers to prevent caching a page */ @@ -157,9 +147,6 @@ abstract class rcube_output header("Expires: ".gmdate("D, d M Y H:i:s")." GMT"); header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - // Request browser to disable DNS prefetching (CVE-2010-0464) - header("X-DNS-Prefetch-Control: off"); - // We need to set the following headers to make downloads work using IE in HTTPS mode. if ($this->browser->ie && rcube_utils::https_check()) { header('Pragma: private'); @@ -178,14 +165,32 @@ abstract class rcube_output */ public function future_expire_header($offset = 2600000) { - if (headers_sent()) + if (headers_sent()) { return; + } header("Expires: " . gmdate("D, d M Y H:i:s", time()+$offset) . " GMT"); header("Cache-Control: max-age=$offset"); header("Pragma: "); } + /** + * Send browser compatibility/security/etc. headers + */ + public function common_headers() + { + if (headers_sent()) { + return; + } + + // Unlock IE compatibility mode + if ($this->browser->ie) { + header('X-UA-Compatible: IE=edge'); + } + + // Request browser to disable DNS prefetching (CVE-2010-0464) + header("X-DNS-Prefetch-Control: off"); + } /** * Show error page and terminate script execution @@ -200,7 +205,6 @@ abstract class rcube_output exit(-1); } - /** * Create an edit field for inclusion on a form * @@ -253,7 +257,6 @@ abstract class rcube_output return $out; } - /** * Convert a variable into a javascript object notation * @@ -269,5 +272,4 @@ abstract class rcube_output // that's why we have @ here return @json_encode($input); } - } diff --git a/skins/classic/includes/links.html b/skins/classic/includes/links.html index 2f6ef0119..8ff57c229 100644 --- a/skins/classic/includes/links.html +++ b/skins/classic/includes/links.html @@ -1,4 +1,3 @@ - diff --git a/skins/larry/includes/links.html b/skins/larry/includes/links.html index ce9863a6c..a49e58826 100644 --- a/skins/larry/includes/links.html +++ b/skins/larry/includes/links.html @@ -1,4 +1,3 @@ - -- cgit v1.2.3 From d19a9b35cc3fa0f25467107d55fbbd0ed4578cc4 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 8 Jul 2014 11:53:52 +0200 Subject: Remove obsolete code that disables session check on 'send' action --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'index.php') diff --git a/index.php b/index.php index ae5df4000..0b9e0bada 100644 --- a/index.php +++ b/index.php @@ -189,7 +189,7 @@ else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id']) } // check session and auth cookie -else if ($RCMAIL->task != 'login' && $_SESSION['user_id'] && $RCMAIL->action != 'send') { +else if ($RCMAIL->task != 'login' && $_SESSION['user_id']) { if (!$RCMAIL->session->check_auth()) { $RCMAIL->kill_session(); $session_error = true; -- cgit v1.2.3 From 7e7e451b66a30d2798c3194330bdf42cd74561fe Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Wed, 9 Jul 2014 10:55:25 +0200 Subject: Warn for unsent/unsaved message when closing compose window; remove localStorage copy if page was left intentionally but not on session errors (#1489818) --- index.php | 2 +- program/js/app.js | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'index.php') diff --git a/index.php b/index.php index 0b9e0bada..e0aaf77f8 100644 --- a/index.php +++ b/index.php @@ -212,7 +212,7 @@ if (empty($RCMAIL->user->ID)) { $OUTPUT->show_message('sessionerror', 'error', null, true, -1); } - if ($OUTPUT->ajax_call || $OUTPUT->framed) { + if ($OUTPUT->ajax_call || $OUTPUT->get_env('framed')) { $OUTPUT->command('session_error', $RCMAIL->url(array('_err' => 'session'))); $OUTPUT->send('iframe'); } diff --git a/program/js/app.js b/program/js/app.js index 31c23dd0e..a47d971d6 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -658,6 +658,7 @@ function rcube_webmail() // remove copy from local storage if compose screen is left intentionally this.remove_compose_data(this.env.compose_id); + this.compose_skip_unsavedcheck = true; } this.last_command = command; @@ -719,6 +720,7 @@ function rcube_webmail() if (win) { this.save_compose_form_local(); + this.compose_skip_unsavedcheck = true; $("input[name='_action']", form).val('compose'); form.action = this.url('mail/compose', { _id: this.env.compose_id, _extwin: 1 }); form.target = win.name; @@ -1402,7 +1404,7 @@ function rcube_webmail() if (task == 'mail') url += '&_mbox=INBOX'; - else if (task == 'logout') + else if (task == 'logout' && !this.env.server_error) this.clear_compose_data(); this.redirect(url); @@ -3474,6 +3476,7 @@ function rcube_webmail() form._draft.value = draft ? '1' : ''; form.action = this.add_url(form.action, '_unlock', msgid); form.action = this.add_url(form.action, '_lang', lang); + form.action = this.add_url(form.action, '_framed', 1); // register timer to notify about connection timeout this.submit_timer = setTimeout(function(){ @@ -3779,6 +3782,7 @@ function rcube_webmail() // always remove local copy upon saving as draft this.remove_compose_data(this.env.compose_id); + this.compose_skip_unsavedcheck = false; }; this.auto_save_start = function() @@ -3803,6 +3807,21 @@ function rcube_webmail() ref.compose_type_activity_last = ref.compose_type_activity; } }, 5000); + + $(window).unload(function() { + // remove copy from local storage if compose screen is left after warning + if (!ref.env.server_error) + ref.remove_compose_data(ref.env.compose_id); + }); + } + + // check for unsaved changes before leaving the compose page + if (!window.onbeforeunload) { + window.onbeforeunload = function() { + if (!ref.compose_skip_unsavedcheck && ref.cmp_hash != ref.compose_field_hash()) { + return ref.get_label('notsentwarning'); + } + }; } // Unlock interface now that saving is complete @@ -4306,6 +4325,7 @@ function rcube_webmail() this.sent_successfully = function(type, msg, folders) { this.display_message(msg, type); + this.compose_skip_unsavedcheck = true; if (this.env.extwin) { this.lock_form(this.gui_objects.messageform); @@ -7380,6 +7400,7 @@ function rcube_webmail() // save message in local storage and do not redirect if (this.env.action == 'compose') { this.save_compose_form_local(); + this.compose_skip_unsavedcheck = true; } else if (redirect_url) { setTimeout(function(){ ref.redirect(redirect_url, true); }, 2000); -- cgit v1.2.3 From d01f9fc7f5a369284fbfd92c6e804d84147e42a1 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 4 Aug 2014 19:03:27 +0200 Subject: Add option (disabled_actions) to disable UI elements/actions (#1489638) --- CHANGELOG | 1 + config/defaults.inc.php | 3 +++ index.php | 8 ++++++++ program/include/rcmail_output_html.php | 30 ++++++++++++++++++++++++++--- program/steps/mail/func.inc | 1 + skins/classic/includes/messagetoolbar.html | 30 ++++++++++++++--------------- skins/classic/templates/compose.html | 4 ++-- skins/classic/templates/messagepreview.html | 4 ++-- skins/larry/includes/mailtoolbar.html | 30 ++++++++++++++--------------- skins/larry/templates/addressbook.html | 16 +++++++-------- skins/larry/templates/compose.html | 4 ++-- skins/larry/templates/folders.html | 4 ++-- skins/larry/templates/mail.html | 30 ++++++++++++++--------------- skins/larry/templates/message.html | 4 ++-- skins/larry/templates/messagepreview.html | 4 ++-- 15 files changed, 105 insertions(+), 68 deletions(-) (limited to 'index.php') diff --git a/CHANGELOG b/CHANGELOG index f2bbe353d..4b799ca62 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Add option (disabled_actions) to disable UI elements/actions (#1489638) - Support password encryption using openssl extension (#1489989) - Create/rename groups in UI dialogs (#1489951) - Added 'contact_search_name' option to define autocompletion entry format diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 18171b75f..625d4ea80 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -285,6 +285,9 @@ $config['enable_installer'] = false; // don't allow these settings to be overriden by the user $config['dont_override'] = array(); +// List of disabled UI elements/actions +$config['disabled_actions'] = array(); + // define which settings should be listed under the 'advanced' block // which is hidden by default $config['advanced_prefs'] = array(); diff --git a/index.php b/index.php index e0aaf77f8..3154daf68 100644 --- a/index.php +++ b/index.php @@ -260,6 +260,14 @@ else { 'message' => "Referer check failed"), true, true); } } + + // check access to disabled actions + $disabled_actions = (array) $RCMAIL->config->get('disabled_actions'); + if (in_array($RCMAIL->task . '.' . ($RCMAIL->action ?: 'index'), $disabled_actions)) { + rcube::raise_error(array( + 'code' => 403, 'type' => 'php', + 'message' => "Action disabled"), true, true); + } } // we're ready, user is authenticated and the request is safe diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 705a72ece..a84824648 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -1139,7 +1139,8 @@ EOF; */ public function button($attrib) { - static $s_button_count = 100; + static $s_button_count = 100; + static $disabled_actions = null; // these commands can be called directly via url $a_static_commands = array('compose', 'list', 'preferences', 'folders', 'identities'); @@ -1148,9 +1149,14 @@ EOF; return ''; } + // try to find out the button type if ($attrib['type']) { $attrib['type'] = strtolower($attrib['type']); + if ($pos = strpos($attrib['type'], '-menuitem')) { + $attrib['type'] = substr($attrib['type'], 0, -9); + $menuitem = true; + } } else { $attrib['type'] = ($attrib['image'] || $attrib['imagepas'] || $attrib['imageact']) ? 'image' : 'link'; @@ -1158,8 +1164,21 @@ EOF; $command = $attrib['command']; - if ($attrib['task']) - $command = $attrib['task'] . '.' . $command; + if ($attrib['task']) { + $element = $command = $attrib['task'] . '.' . $command; + } + else { + $element = ($this->env['task'] ? $this->env['task'] . '.' : '') . $command; + } + + if ($disabled_actions === null) { + $disabled_actions = (array) $this->config->get('disabled_actions'); + } + + // remove buttons for disabled actions + if (in_array($element, $disabled_actions)) { + return ''; + } if (!$attrib['image']) { $attrib['image'] = $attrib['imagepas'] ? $attrib['imagepas'] : $attrib['imageact']; @@ -1292,6 +1311,11 @@ EOF; $out = html::tag($attrib['wrapper'], null, $out); } + if ($menuitem) { + $class = $attrib['menuitem-class'] ? ' class="' . $attrib['menuitem-class'] . '"' : ''; + $out = '
  • ' . $out . '
  • '; + } + return $out; } diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 103d79d73..c6c0b95e6 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -2075,6 +2075,7 @@ function rcmail_message_import_form($attrib = array()) )); $content = html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) + . html::tag('input', array('type' => 'hidden', 'name' => '_framed', 'value' => '1')) . html::div(null, $fileinput->show()) . html::div('hint', $RCMAIL->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))); diff --git a/skins/classic/includes/messagetoolbar.html b/skins/classic/includes/messagetoolbar.html index 9d067fb8d..7cf7d477c 100644 --- a/skins/classic/includes/messagetoolbar.html +++ b/skins/classic/includes/messagetoolbar.html @@ -28,39 +28,39 @@
      -
    • -
    • + +
      -
    • -
    • + +
      -
    • -
    • -
    • -
    • -
    • - -
    • + + + + + + +
      -
    • -
    • -
    • -
    • + + + +
    diff --git a/skins/classic/templates/compose.html b/skins/classic/templates/compose.html index 19b22bc69..1515eeb06 100644 --- a/skins/classic/templates/compose.html +++ b/skins/classic/templates/compose.html @@ -202,8 +202,8 @@
  • -
  • -
  • + + diff --git a/skins/classic/templates/messagepreview.html b/skins/classic/templates/messagepreview.html index 82414c420..869f03f65 100644 --- a/skins/classic/templates/messagepreview.html +++ b/skins/classic/templates/messagepreview.html @@ -28,8 +28,8 @@
      -
    • -
    • + +
    diff --git a/skins/larry/includes/mailtoolbar.html b/skins/larry/includes/mailtoolbar.html index 7485a93bd..9d66763cd 100644 --- a/skins/larry/includes/mailtoolbar.html +++ b/skins/larry/includes/mailtoolbar.html @@ -21,8 +21,8 @@ @@ -30,8 +30,8 @@ @@ -39,13 +39,13 @@ @@ -53,10 +53,10 @@ diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html index 424e96597..62bca3c84 100644 --- a/skins/larry/templates/addressbook.html +++ b/skins/larry/templates/addressbook.html @@ -29,8 +29,8 @@ @@ -76,10 +76,10 @@ @@ -132,8 +132,8 @@ diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html index 7fa21650e..04a987f89 100644 --- a/skins/larry/templates/compose.html +++ b/skins/larry/templates/compose.html @@ -212,8 +212,8 @@ -
  • -
  • + + diff --git a/skins/larry/templates/folders.html b/skins/larry/templates/folders.html index 034f35ab3..f48169cd4 100644 --- a/skins/larry/templates/folders.html +++ b/skins/larry/templates/folders.html @@ -32,8 +32,8 @@ diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html index 6da2cf6f6..2c4e0f2c5 100644 --- a/skins/larry/templates/mail.html +++ b/skins/larry/templates/mail.html @@ -157,18 +157,18 @@ @@ -176,21 +176,21 @@ diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html index a6b4cf5d8..dde15acfb 100644 --- a/skins/larry/templates/message.html +++ b/skins/larry/templates/message.html @@ -100,8 +100,8 @@ diff --git a/skins/larry/templates/messagepreview.html b/skins/larry/templates/messagepreview.html index 03fc91505..2e3b5efd1 100644 --- a/skins/larry/templates/messagepreview.html +++ b/skins/larry/templates/messagepreview.html @@ -68,8 +68,8 @@ -- cgit v1.2.3 From a873d934f56c3173fae671440094f71ee8eaf91d Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Wed, 27 Aug 2014 14:37:10 +0200 Subject: Give precedence to plugin.* actions over custom tasks registered by plugins --- index.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'index.php') diff --git a/index.php b/index.php index 3154daf68..9c87f9a40 100644 --- a/index.php +++ b/index.php @@ -295,13 +295,14 @@ if (is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/func.inc' $redirects = 0; $incstep = null; while ($redirects < 5) { // execute a plugin action - if ($RCMAIL->plugins->is_plugin_task($RCMAIL->task)) { - if (!$RCMAIL->action) $RCMAIL->action = 'index'; - $RCMAIL->plugins->exec_action($RCMAIL->task.'.'.$RCMAIL->action); + if (preg_match('/^plugin\./', $RCMAIL->action)) { + $RCMAIL->plugins->exec_action($RCMAIL->action); break; } - else if (preg_match('/^plugin\./', $RCMAIL->action)) { - $RCMAIL->plugins->exec_action($RCMAIL->action); + // execute action registered to a plugin task + else if ($RCMAIL->plugins->is_plugin_task($RCMAIL->task)) { + if (!$RCMAIL->action) $RCMAIL->action = 'index'; + $RCMAIL->plugins->exec_action($RCMAIL->task.'.'.$RCMAIL->action); break; } // try to include the step file -- cgit v1.2.3