]> git.wh0rd.org - tt-rss.git/commitdiff
Merge branch 'subscribe-idn-feed' into 'master'
authorAndrew Dolgov <cthulhoo@gmail.com>
Mon, 16 Jan 2017 08:36:00 +0000 (11:36 +0300)
committerAndrew Dolgov <cthulhoo@gmail.com>
Mon, 16 Jan 2017 08:36:00 +0000 (11:36 +0300)
Subscribe to feed with Internationalized Domain Name

Currently you cannot subscribe to feeds on hosts with internationalized domain names (IDNA) within tt-rss. You need to manually convert them to punycode to subscribe to them.

This patch adds code to detect IDNA and convert them to punycode in fix_url() if possible on the system. This requires PHP IDN functions (e.g. on Debian Jessie this needs php5-intl to be installed), so a notice is added to the installer sanity check.

See merge request !37

17 files changed:
classes/article.php
classes/feeds.php
classes/pluginhost.php
classes/pref/feeds.php
classes/ttrssmailer.php
config.php-dist
css/tt-rss.css
include/crypt.php
include/functions.php
include/rssfuncs.php
index.php
install/index.php
js/tt-rss.js
plugins/mail/init.php
plugins/toggle_sidebar/application_side_list.png [new file with mode: 0644]
plugins/toggle_sidebar/init.php [new file with mode: 0644]
update.php

index 9a7c687074c930a39a23533ce824a5886c2cbc38..46e9bb7977aea98ea6409893b48599d1d0f994d2 100644 (file)
@@ -209,7 +209,7 @@ class Article extends Handler_Protected {
                print "<table width='100%'><tr><td>";
 
                print "<textarea dojoType=\"dijit.form.SimpleTextarea\" rows='4'
-                       style='font-size : 12px; width : 98%' id=\"tags_str\"
+                       style='height : 100px; font-size : 12px; width : 98%' id=\"tags_str\"
                        name='tags_str'>$tags_str</textarea>
                <div class=\"autocomplete\" id=\"tags_choices\"
                                style=\"display:none\"></div>";
index afbeb249b3be25f4768505909aca751ead890b3b..8f101e5cb774e46c74f027fd9100665d1d2bb423 100755 (executable)
@@ -86,17 +86,23 @@ class Feeds extends Handler_Protected {
                $reply .= "<span class=\"main\">";
                $reply .= "<span id='selected_prompt'></span>";
 
-               $reply .= "<span class=\"sel_links\">
+               /*$reply .= "<span class=\"sel_links\">
                        <a href=\"#\" onclick=\"$sel_all_link\">".__('All')."</a>,
                        <a href=\"#\" onclick=\"$sel_unread_link\">".__('Unread')."</a>,
                        <a href=\"#\" onclick=\"$sel_inv_link\">".__('Invert')."</a>,
                        <a href=\"#\" onclick=\"$sel_none_link\">".__('None')."</a></li>";
 
-               $reply .= "</span> ";
+               $reply .= "</span> "; */
 
                $reply .= "<select dojoType=\"dijit.form.Select\"
                        onchange=\"headlineActionsChange(this)\">";
-               $reply .= "<option value=\"false\">".__('More...')."</option>";
+
+               $reply .= "<option value=\"0\" disabled='1'>".__('Select...')."</option>";
+
+               $reply .= "<option value=\"$sel_all_link\">".__('All')."</option>";
+               $reply .= "<option value=\"$sel_unread_link\">".__('Unread')."</option>";
+               $reply .= "<option value=\"$sel_inv_link\">".__('Invert')."</option>";
+               $reply .= "<option value=\"$sel_none_link\">".__('None')."</option>";
 
                $reply .= "<option value=\"0\" disabled=\"1\">".__('Selection toggle:')."</option>";
 
index 675e0af17152ad8fe7f00ca29e4924de8dca7078..82565257a94ef3bedbbd731b9d4131d5cc95e7b8 100644 (file)
@@ -50,6 +50,7 @@ class PluginHost {
        const HOOK_RENDER_ENCLOSURE = 29;
        const HOOK_ARTICLE_FILTER_ACTION = 30;
        const HOOK_ARTICLE_EXPORT_FEED = 31;
+       const HOOK_MAIN_TOOLBAR_BUTTON = 32;
 
        const KIND_ALL = 1;
        const KIND_SYSTEM = 2;
index 2803d68ecfd6537ed213aa83848d2bf71b99ec4c..6795236d5310b4b28063c92fd25e24687c8d8a34 100755 (executable)
@@ -646,7 +646,7 @@ class Pref_Feeds extends Handler_Protected {
 
                $auth_pass = $this->dbh->fetch_result($result, 0, "auth_pass");
 
-               if ($auth_pass_encrypted) {
+               if ($auth_pass_encrypted && function_exists("mcrypt_decrypt")) {
                        require_once "crypt.php";
                        $auth_pass = decrypt_string($auth_pass);
                }
@@ -983,14 +983,7 @@ class Pref_Feeds extends Handler_Protected {
 
                $feed_language = $this->dbh->escape_string(trim($_POST["feed_language"]));
 
-               if (strlen(FEED_CRYPT_KEY) > 0) {
-                       require_once "crypt.php";
-                       $auth_pass = substr(encrypt_string($auth_pass), 0, 250);
-                       $auth_pass_encrypted = 'true';
-               } else {
-                       $auth_pass_encrypted = 'false';
-               }
-
+               $auth_pass_encrypted = 'false';
                $auth_pass = $this->dbh->escape_string($auth_pass);
 
                if (get_pref('ENABLE_FEED_CATS')) {
@@ -1889,14 +1882,7 @@ class Pref_Feeds extends Handler_Protected {
                                        "SELECT id FROM ttrss_feeds
                                        WHERE feed_url = '$feed' AND owner_uid = ".$_SESSION["uid"]);
 
-                               if (strlen(FEED_CRYPT_KEY) > 0) {
-                                       require_once "crypt.php";
-                                       $pass = substr(encrypt_string($pass), 0, 250);
-                                       $auth_pass_encrypted = 'true';
-                               } else {
-                                       $auth_pass_encrypted = 'false';
-                               }
-
+                               $auth_pass_encrypted = 'false';
                                $pass = $this->dbh->escape_string($pass);
 
                                if ($this->dbh->num_rows($result) == 0) {
index 64e8a59a75784a554cae8d45a540e1f2a5eab347..4029bbbdb137b2abd2cb12beba9e6ef5c8ca5955 100644 (file)
@@ -7,6 +7,7 @@
 *\r
 */\r
 require_once 'lib/phpmailer/class.phpmailer.php';\r
+require_once 'lib/phpmailer/class.smtp.php';\r
 require_once "config.php";\r
 \r
 class ttrssMailer extends PHPMailer {\r
@@ -41,8 +42,8 @@ class ttrssMailer extends PHPMailer {
                        $this->Username = SMTP_LOGIN;\r
                        $this->Password = SMTP_PASSWORD;\r
                        }\r
-               if(SMTP_SECURE)
-                       $this->SMTPSecure = SMTP_SECURE;        
+               if(SMTP_SECURE)\r
+                       $this->SMTPSecure = SMTP_SECURE;        \r
        }\r
        /*      @brief a simple mail function to send email using the defaults\r
        *       This will send an HTML email using the configured defaults\r
index 2eaaab6173de0d68bb01243338346957399abf7f..c86af943be85da8c1b4be0f3fa75b2a88a0dd4c3 100644 (file)
        // including PUSH, bookmarklets and browser integration will not work properly.
 
        define('FEED_CRYPT_KEY', '');
+       // WARNING: mcrypt is deprecated in php 7.1. This directive exists for backwards
+       // compatibility with existing installs, new passwords are NOT going to be encrypted.
+       // Use update.php --decrypt-feeds to decrypt existing passwords in the database while
+       // mcrypt is still available.
+
        // Key used for encryption of passwords for password-protected feeds
        // in the database. A string of 24 random characters. If left blank, encryption
        // is not used. Requires mcrypt functions.
index e1dc64369936c7d40ed16ec6704a9e570569ab97..5003816b22edf68d6fb9ed1515e3b051c19ee18b 100644 (file)
@@ -419,6 +419,12 @@ div.prefHelp {
        margin-right : 4px;
 }
 
+@media (max-width: 992px) {
+       #main-toolbar #selected_prompt {
+               display : none;
+       }
+}
+
 span.contentPreview {
        color : #999;
        font-weight : normal;
index f06483ef118a963b0a074ea8009bc697158f0d08..217ad3b0fb5197447dca51a9b311256152bb4ee6 100644 (file)
 
                return false;
        }
-
-       function encrypt_string($str) {
-               $key = hash('SHA256', FEED_CRYPT_KEY, true);
-
-               $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,
-                       MCRYPT_MODE_CBC), MCRYPT_RAND);
-
-               $encstr = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str,
-                       MCRYPT_MODE_CBC, $iv);
-
-               $iv_base64 = base64_encode($iv);
-               $encstr_base64 = base64_encode($encstr);
-
-               return "$iv_base64:$encstr_base64";
-       }
 ?>
index f10c3a00b0015e650958f17c63d601b189064051..ce7627d5a77cd859600304b989c359a4b50e651e 100755 (executable)
                        "SELECT id FROM ttrss_feeds
                        WHERE feed_url = '$url' AND owner_uid = ".$_SESSION["uid"]);
 
-               if (strlen(FEED_CRYPT_KEY) > 0) {
-                       require_once "crypt.php";
-                       $auth_pass = substr(encrypt_string($auth_pass), 0, 250);
-                       $auth_pass_encrypted = 'true';
-               } else {
-                       $auth_pass_encrypted = 'false';
-               }
-
+               $auth_pass_encrypted = 'false';
                $auth_pass = db_escape_string($auth_pass);
 
                if (db_num_rows($result) == 0) {
index e667df41f99d2596ca594ca6f048a2e437d3c9f8..6c342971fc9b73bc93094cdeb3633d1f0be9649c 100644 (file)
                $auth_login = db_fetch_result($result, 0, "auth_login");
                $auth_pass = db_fetch_result($result, 0, "auth_pass");
 
-               if ($auth_pass_encrypted) {
+               if ($auth_pass_encrypted && function_exists("mcrypt_decrypt")) {
                        require_once "crypt.php";
                        $auth_pass = decrypt_string($auth_pass);
                }
                $auth_login = db_fetch_result($result, 0, "auth_login");
                $auth_pass = db_fetch_result($result, 0, "auth_pass");
 
-               if ($auth_pass_encrypted) {
+               if ($auth_pass_encrypted && function_exists("mcrypt_decrypt")) {
                        require_once "crypt.php";
                        $auth_pass = decrypt_string($auth_pass);
                }
index 6b27d90425e72fb9c4c9ebd1f0dc950140d5a812..220fe27c1693536d5147b7d69b3207dc151f44f2 100644 (file)
--- a/index.php
+++ b/index.php
 <div id="toolbar" dojoType="dijit.layout.ContentPane" region="top">
        <div id="main-toolbar" dojoType="dijit.Toolbar">
 
+               <?php
+               foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_MAIN_TOOLBAR_BUTTON) as $p) {
+                       echo $p->hook_main_toolbar_button();
+               }
+               ?>
+
                <form id="headlines-toolbar" action="" onsubmit='return false'>
 
                </form>
 
                <form id="main_toolbar_form" action="" onsubmit='return false'>
 
-               <button dojoType="dijit.form.Button" id="collapse_feeds_btn"
-                       onclick="collapse_feedlist()"
-                       title="<?php echo __('Collapse feedlist') ?>" style="display : none">
-                       &lt;&lt;</button>
-
                <select name="view_mode" title="<?php echo __('Show articles') ?>"
                        onchange="viewModeChanged()"
                        dojoType="dijit.form.Select">
index d9e370ea59b4b81fa36780fc073e12da66e4cca5..7da311ffb832c2bbf65d6406529ed395d3b86e12 100755 (executable)
 
                $finished = false;
 
-               if (function_exists("mcrypt_decrypt")) {
-                       $crypt_key = make_password(24);
-               } else {
-                       $crypt_key = "";
-               }
-
                foreach ($data as $line) {
                        if (preg_match("/define\('DB_TYPE'/", $line)) {
                                $rv .= "\tdefine('DB_TYPE', '$DB_TYPE');\n";
                                $rv .= "\tdefine('DB_PORT', '$DB_PORT');\n";
                        } else if (preg_match("/define\('SELF_URL_PATH'/", $line)) {
                                $rv .= "\tdefine('SELF_URL_PATH', '$SELF_URL_PATH');\n";
-                       } else if (preg_match("/define\('FEED_CRYPT_KEY'/", $line)) {
-                               $rv .= "\tdefine('FEED_CRYPT_KEY', '$crypt_key');\n";
                        } else if (!$finished) {
                                $rv .= "$line\n";
                        }
index 1b84025d112b879906c05c169038b4adb3e0d6a7..068ad0849634a44d297be06c0913002f02ba1616 100644 (file)
@@ -822,13 +822,7 @@ function parse_runtime_info(data) {
 function collapse_feedlist() {
        try {
 
-               if (!Element.visible('feeds-holder')) {
-                       Element.show('feeds-holder');
-                       $("collapse_feeds_btn").innerHTML = "&lt;&lt;";
-               } else {
-                       Element.hide('feeds-holder');
-                       $("collapse_feeds_btn").innerHTML = "&gt;&gt;";
-               }
+               Element.toggle("feeds-holder");
 
                dijit.byId("main").resize();
 
index eba4a5ce97df0214c3d22c1225b95293b1e4084b..acd89de4745f1240eaef68aab6ba17c148759383 100644 (file)
@@ -162,7 +162,8 @@ class Mail extends Plugin {
 
                print "</td></tr>";
 
-               print "<tr><td colspan='2'><textarea dojoType=\"dijit.form.SimpleTextarea\" style='font-size : 12px; width : 98%' rows=\"20\"
+               print "<tr><td colspan='2'><textarea dojoType=\"dijit.form.SimpleTextarea\" 
+                       style='height : 200px; font-size : 12px; width : 98%' rows=\"20\"
                        name='content'>$content</textarea>";
 
                print "</td></tr></table>";
diff --git a/plugins/toggle_sidebar/application_side_list.png b/plugins/toggle_sidebar/application_side_list.png
new file mode 100644 (file)
index 0000000..248eaf1
Binary files /dev/null and b/plugins/toggle_sidebar/application_side_list.png differ
diff --git a/plugins/toggle_sidebar/init.php b/plugins/toggle_sidebar/init.php
new file mode 100644 (file)
index 0000000..b2b0821
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+class Toggle_Sidebar extends Plugin {
+
+       private $host;
+
+       function about() {
+               return array(1.0,
+                       "Adds a main toolbar button to toggle sidebar",
+                       "fox");
+       }
+
+       function init($host) {
+               $this->host = $host;
+
+               $host->add_hook($host::HOOK_MAIN_TOOLBAR_BUTTON, $this);
+       }
+
+       function hook_main_toolbar_button() {
+               ?>
+
+               <button dojoType="dijit.form.Button" onclick="collapse_feedlist()">
+                       <img src="plugins/toggle_sidebar/application_side_list.png"
+                                title="<?php echo __('Collapse feedlist') ?>">
+               </button>
+
+               <?php
+       }
+
+       function api_version() {
+               return 2;
+       }
+
+}
+?>
index f174361853a9106269cdb01264ad28b339d224d9..821d25bce27c5262d65cdfddd62adea65b88e24c 100755 (executable)
@@ -38,6 +38,7 @@
                        "debug-feed:",
                        "force-refetch",
                        "force-rehash",
+                       "decrypt-feeds",
                        "help");
 
        foreach (PluginHost::getInstance()->get_commands() as $command => $data) {
@@ -91,6 +92,7 @@
                print "  --debug-feed N       - perform debug update of feed N\n";
                print "  --force-refetch      - debug update: force refetch feed data\n";
                print "  --force-rehash       - debug update: force rehash articles\n";
+               print "  --decrypt-feeds      - decrypt feed passwords\n";
                print "  --help               - show this help\n";
                print "Plugin options:\n";
 
                update_rss_feed($feed);
        }
 
+       if (isset($options["decrypt-feeds"])) {
+               $result = db_query("SELECT id, auth_pass FROM ttrss_feeds WHERE auth_pass_encrypted = true");
+
+               if (!function_exists("mcrypt_decrypt")) {
+                       _debug("mcrypt functions not available.");
+                       return;
+               }
+
+               require_once "crypt.php";
+
+               $total = 0;
+
+               db_query("BEGIN");
+
+               while ($line = db_fetch_assoc($result)) {
+                       _debug("processing feed id " . $line["id"]);
+
+                       $auth_pass = db_escape_string(decrypt_string($line["auth_pass"]));
+
+                       db_query("UPDATE ttrss_feeds SET auth_pass_encrypted = false, auth_pass = '$auth_pass' 
+                               WHERE id = " . $line["id"]);
+
+                       ++$total;
+               }
+
+               db_query("COMMIT");
+
+               _debug("$total feeds processed.");
+       }
+
        PluginHost::getInstance()->run_commands($options);
 
        if (file_exists(LOCK_DIRECTORY . "/$lock_filename"))
+               if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
+                       fclose($lock_handle);
                unlink(LOCK_DIRECTORY . "/$lock_filename");
 ?>