diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | CONTRIBUTING.md | 2 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | application/LinkDB.php | 2 | ||||
-rw-r--r-- | application/config/ConfigManager.php | 6 | ||||
-rw-r--r-- | composer.json | 2 | ||||
-rw-r--r-- | doc/md/Plugin-System.md | 4 | ||||
-rw-r--r-- | doc/md/Plugins.md | 2 | ||||
-rw-r--r-- | doc/md/Release-Shaarli.md | 6 | ||||
-rw-r--r-- | doc/md/Security.md | 3 | ||||
-rw-r--r-- | doc/md/Shaarli-configuration.md | 5 | ||||
-rw-r--r-- | doc/md/index.md | 2 | ||||
-rw-r--r-- | index.php | 174 | ||||
-rw-r--r-- | plugins/playvideos/README.md | 2 | ||||
-rw-r--r-- | tpl/default/js/shaarli.js | 6 | ||||
-rw-r--r-- | tpl/default/loginform.html | 3 | ||||
-rw-r--r-- | tpl/default/tools.html | 2 | ||||
-rw-r--r-- | tpl/vintage/loginform.html | 4 |
18 files changed, 129 insertions, 112 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b018cb4..60262d56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -61,7 +61,7 @@ The documentation has been migrated to ReadTheDocs: | |||
61 | This release introduces the REST API, and requires updating HTTP server | 61 | This release introduces the REST API, and requires updating HTTP server |
62 | configuration to enable URL rewriting, see: | 62 | configuration to enable URL rewriting, see: |
63 | - https://shaarli.github.io/api-documentation/ | 63 | - https://shaarli.github.io/api-documentation/ |
64 | - https://github.com/shaarli/Shaarli/wiki/Server-configuration | 64 | - https://shaarli.readthedocs.io/en/master/Server-configuration/ |
65 | 65 | ||
66 | **WARNING**: Shaarli now requires PHP 5.5+. | 66 | **WARNING**: Shaarli now requires PHP 5.5+. |
67 | 67 | ||
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bb82951d..03564fd2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md | |||
@@ -54,7 +54,7 @@ Please report any problem you might find. | |||
54 | * starting from branch ` master`, switch to a new branch (eg. `git checkout -b my-awesome-feature`) | 54 | * starting from branch ` master`, switch to a new branch (eg. `git checkout -b my-awesome-feature`) |
55 | * edit the required files (from the Github web interface or your text editor) | 55 | * edit the required files (from the Github web interface or your text editor) |
56 | * add and commit your changes with a meaningful commit message (eg `Cool new feature, fixes issue #1001`) | 56 | * add and commit your changes with a meaningful commit message (eg `Cool new feature, fixes issue #1001`) |
57 | * run unit tests against your patched version, see [Running unit tests](https://github.com/shaarli/Shaarli/wiki/Running-unit-tests) | 57 | * run unit tests against your patched version, see [Running unit tests](https://shaarli.readthedocs.io/en/master/Unit-tests/#run-unit-tests) |
58 | * Open your fork in the Github web interface and click the "Compare and Pull Request" button, enter required info and submit your Pull Request. | 58 | * Open your fork in the Github web interface and click the "Compare and Pull Request" button, enter required info and submit your Pull Request. |
59 | 59 | ||
60 | All changes you will do on the `my-awesome-feature` in the future will be added to your Pull Request. Don't work directly on the master branch, don't do unrelated work on your `my-awesome-feature` branch. | 60 | All changes you will do on the `my-awesome-feature` in the future will be added to your Pull Request. Don't work directly on the master branch, don't do unrelated work on your `my-awesome-feature` branch. |
@@ -159,14 +159,14 @@ composer_dependencies: clean | |||
159 | find vendor/ -name ".git" -type d -exec rm -rf {} + | 159 | find vendor/ -name ".git" -type d -exec rm -rf {} + |
160 | 160 | ||
161 | ### generate a release tarball and include 3rd-party dependencies | 161 | ### generate a release tarball and include 3rd-party dependencies |
162 | release_tar: composer_dependencies doc_html | 162 | release_tar: composer_dependencies htmldoc |
163 | git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).tar HEAD | 163 | git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).tar HEAD |
164 | tar rvf $(ARCHIVE_VERSION).tar --transform "s|^vendor|$(ARCHIVE_PREFIX)vendor|" vendor/ | 164 | tar rvf $(ARCHIVE_VERSION).tar --transform "s|^vendor|$(ARCHIVE_PREFIX)vendor|" vendor/ |
165 | tar rvf $(ARCHIVE_VERSION).tar --transform "s|^doc/html|$(ARCHIVE_PREFIX)doc/html|" doc/html/ | 165 | tar rvf $(ARCHIVE_VERSION).tar --transform "s|^doc/html|$(ARCHIVE_PREFIX)doc/html|" doc/html/ |
166 | gzip $(ARCHIVE_VERSION).tar | 166 | gzip $(ARCHIVE_VERSION).tar |
167 | 167 | ||
168 | ### generate a release zip and include 3rd-party dependencies | 168 | ### generate a release zip and include 3rd-party dependencies |
169 | release_zip: composer_dependencies doc_html | 169 | release_zip: composer_dependencies htmldoc |
170 | git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).zip -9 HEAD | 170 | git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).zip -9 HEAD |
171 | mkdir -p $(ARCHIVE_PREFIX)/{doc,vendor} | 171 | mkdir -p $(ARCHIVE_PREFIX)/{doc,vendor} |
172 | rsync -a doc/html/ $(ARCHIVE_PREFIX)doc/html/ | 172 | rsync -a doc/html/ $(ARCHIVE_PREFIX)doc/html/ |
@@ -195,17 +195,11 @@ doxygen: clean | |||
195 | @rm -rf doxygen | 195 | @rm -rf doxygen |
196 | @( cat Doxyfile ; echo "PROJECT_NUMBER=`git describe`" ) | doxygen - | 196 | @( cat Doxyfile ; echo "PROJECT_NUMBER=`git describe`" ) | doxygen - |
197 | 197 | ||
198 | ### Convert local markdown documentation to HTML | 198 | ### generate HTML documentation from Markdown pages with MkDocs |
199 | # | 199 | htmldoc: |
200 | # For all pages: | ||
201 | # - convert GitHub-flavoured relative links to standard Markdown | ||
202 | # - generate html documentation with mkdocs | ||
203 | htmlpages: | ||
204 | python3 -m venv venv/ | 200 | python3 -m venv venv/ |
205 | bash -c 'source venv/bin/activate; \ | 201 | bash -c 'source venv/bin/activate; \ |
206 | pip install mkdocs; \ | 202 | pip install mkdocs; \ |
207 | mkdocs build' | 203 | mkdocs build' |
208 | find doc/html/ -type f -exec chmod a-x '{}' \; | 204 | find doc/html/ -type f -exec chmod a-x '{}' \; |
209 | rm -r venv | 205 | rm -r venv |
210 | |||
211 | doc_html: authors htmlpages | ||
diff --git a/application/LinkDB.php b/application/LinkDB.php index 9308164a..22c1f0ab 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php | |||
@@ -249,7 +249,7 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
249 | $link = array( | 249 | $link = array( |
250 | 'id' => 1, | 250 | 'id' => 1, |
251 | 'title'=>' Shaarli: the personal, minimalist, super-fast, no-database delicious clone', | 251 | 'title'=>' Shaarli: the personal, minimalist, super-fast, no-database delicious clone', |
252 | 'url'=>'https://github.com/shaarli/Shaarli/wiki', | 252 | 'url'=>'https://shaarli.readthedocs.io', |
253 | 'description'=>'Welcome to Shaarli! This is your first public bookmark. To edit or delete me, you must first login. | 253 | 'description'=>'Welcome to Shaarli! This is your first public bookmark. To edit or delete me, you must first login. |
254 | 254 | ||
255 | To learn how to use Shaarli, consult the link "Help/documentation" at the bottom of this page. | 255 | To learn how to use Shaarli, consult the link "Help/documentation" at the bottom of this page. |
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index 8eab26f1..fdd5b3d7 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php | |||
@@ -9,8 +9,8 @@ use Shaarli\Config\Exception\UnauthorizedConfigException; | |||
9 | * | 9 | * |
10 | * Manages all Shaarli's settings. | 10 | * Manages all Shaarli's settings. |
11 | * See the documentation for more information on settings: | 11 | * See the documentation for more information on settings: |
12 | * - doc/Shaarli-configuration.html | 12 | * - doc/md/Shaarli-configuration.md |
13 | * - https://github.com/shaarli/Shaarli/wiki/Shaarli-configuration | 13 | * - https://shaarli.readthedocs.io/en/master/Shaarli-configuration/#configuration |
14 | */ | 14 | */ |
15 | class ConfigManager | 15 | class ConfigManager |
16 | { | 16 | { |
@@ -328,6 +328,8 @@ class ConfigManager | |||
328 | $this->setEmpty('privacy.default_private_links', false); | 328 | $this->setEmpty('privacy.default_private_links', false); |
329 | $this->setEmpty('privacy.hide_public_links', false); | 329 | $this->setEmpty('privacy.hide_public_links', false); |
330 | $this->setEmpty('privacy.hide_timestamps', false); | 330 | $this->setEmpty('privacy.hide_timestamps', false); |
331 | // default state of the 'remember me' checkbox of the login form | ||
332 | $this->setEmpty('privacy.remember_user_default', true); | ||
331 | 333 | ||
332 | $this->setEmpty('thumbnail.enable_thumbnails', true); | 334 | $this->setEmpty('thumbnail.enable_thumbnails', true); |
333 | $this->setEmpty('thumbnail.enable_localcache', true); | 335 | $this->setEmpty('thumbnail.enable_localcache', true); |
diff --git a/composer.json b/composer.json index 756ea588..afb8aca4 100644 --- a/composer.json +++ b/composer.json | |||
@@ -6,7 +6,7 @@ | |||
6 | "homepage": "https://github.com/shaarli/Shaarli", | 6 | "homepage": "https://github.com/shaarli/Shaarli", |
7 | "support": { | 7 | "support": { |
8 | "issues": "https://github.com/shaarli/Shaarli/issues", | 8 | "issues": "https://github.com/shaarli/Shaarli/issues", |
9 | "wiki": "https://github.com/shaarli/Shaarli/wiki" | 9 | "wiki": "https://shaarli.readthedocs.io" |
10 | }, | 10 | }, |
11 | "keywords": ["bookmark", "link", "share", "web"], | 11 | "keywords": ["bookmark", "link", "share", "web"], |
12 | "config": { | 12 | "config": { |
diff --git a/doc/md/Plugin-System.md b/doc/md/Plugin-System.md index 30f0ae74..cbec04c0 100644 --- a/doc/md/Plugin-System.md +++ b/doc/md/Plugin-System.md | |||
@@ -49,10 +49,10 @@ hook_<plugin_name>_<hook_name>($data, $conf) | |||
49 | 49 | ||
50 | Parameters: | 50 | Parameters: |
51 | 51 | ||
52 | - data: see [$data section](https://github.com/shaarli/Shaarli/wiki/Plugin-System#plugins-data) | 52 | - data: see [$data section](https://shaarli.readthedocs.io/en/master/Plugin-System/#plugins-data) |
53 | - conf: the `ConfigManager` instance. | 53 | - conf: the `ConfigManager` instance. |
54 | 54 | ||
55 | For exemple, if my plugin want to add data to the header, this function is needed: | 55 | For example, if my plugin want to add data to the header, this function is needed: |
56 | 56 | ||
57 | hook_demo_plugin_render_header | 57 | hook_demo_plugin_render_header |
58 | 58 | ||
diff --git a/doc/md/Plugins.md b/doc/md/Plugins.md index 7d40637f..463dae17 100644 --- a/doc/md/Plugins.md +++ b/doc/md/Plugins.md | |||
@@ -72,4 +72,4 @@ Usage of each plugin is documented in it's README file: | |||
72 | 72 | ||
73 | #### Third party plugins | 73 | #### Third party plugins |
74 | 74 | ||
75 | See [Community & related software](https://github.com/shaarli/Shaarli/wiki/Community-%26-Related-software#third-party-plugins) | 75 | See [Community & related software](https://shaarli.readthedocs.io/en/master/Community-&-Related-software/) |
diff --git a/doc/md/Release-Shaarli.md b/doc/md/Release-Shaarli.md index 974a7438..e22eabc9 100644 --- a/doc/md/Release-Shaarli.md +++ b/doc/md/Release-Shaarli.md | |||
@@ -46,6 +46,12 @@ TBA | |||
46 | 46 | ||
47 | 47 | ||
48 | ## Increment the version code, update docs, create and push a signed tag | 48 | ## Increment the version code, update docs, create and push a signed tag |
49 | ### Update the list of Git contributors | ||
50 | ```bash | ||
51 | $ make authors | ||
52 | $ git commit -s -m "Update AUTHORS" | ||
53 | ``` | ||
54 | |||
49 | ### Create and merge a Pull Request | 55 | ### Create and merge a Pull Request |
50 | This one is pretty straightforward ;-) | 56 | This one is pretty straightforward ;-) |
51 | 57 | ||
diff --git a/doc/md/Security.md b/doc/md/Security.md index 36f629af..65db4225 100644 --- a/doc/md/Security.md +++ b/doc/md/Security.md | |||
@@ -1,9 +1,6 @@ | |||
1 | ## Client browser | 1 | ## Client browser |
2 | - Shaarli relies on `HTTP_REFERER` for some functions (like redirects and clicking on tags). If you have disabled or masqueraded `HTTP_REFERER` in your browser, some features of Shaarli may not work | 2 | - Shaarli relies on `HTTP_REFERER` for some functions (like redirects and clicking on tags). If you have disabled or masqueraded `HTTP_REFERER` in your browser, some features of Shaarli may not work |
3 | 3 | ||
4 | ## PHP | ||
5 | - `magic_quotes` is an horrible option of PHP which is often activated on servers. No serious developer should rely on this horror to secure their code against SQL injections. You should disable it (and Shaarli expects this option to be disabled). Nevertheless, I have added code to cope with `magic_quotes` on, so you should not be bothered even on crappy hosts. | ||
6 | |||
7 | ## Server and sessions | 4 | ## Server and sessions |
8 | - Directories are protected using `.htaccess` files | 5 | - Directories are protected using `.htaccess` files |
9 | - Forms are protected against XSRF (Cross-site requests forgery): | 6 | - Forms are protected against XSRF (Cross-site requests forgery): |
diff --git a/doc/md/Shaarli-configuration.md b/doc/md/Shaarli-configuration.md index 188a3c09..d90e95eb 100644 --- a/doc/md/Shaarli-configuration.md +++ b/doc/md/Shaarli-configuration.md | |||
@@ -91,6 +91,8 @@ _These settings should not be edited_ | |||
91 | - **default_private_links**: Check the private checkbox by default for every new link. | 91 | - **default_private_links**: Check the private checkbox by default for every new link. |
92 | - **hide_public_links**: All links are hidden while logged out. | 92 | - **hide_public_links**: All links are hidden while logged out. |
93 | - **hide_timestamps**: Timestamps are hidden. | 93 | - **hide_timestamps**: Timestamps are hidden. |
94 | - **remember_user_default**: Default state of the login page's *remember me* checkbox | ||
95 | - `true`: checked by default, `false`: unchecked by default | ||
94 | 96 | ||
95 | ### Feed | 97 | ### Feed |
96 | 98 | ||
@@ -192,7 +194,8 @@ _These settings should not be edited_ | |||
192 | "privacy": { | 194 | "privacy": { |
193 | "default_private_links": true, | 195 | "default_private_links": true, |
194 | "hide_public_links": false, | 196 | "hide_public_links": false, |
195 | "hide_timestamps": false | 197 | "hide_timestamps": false, |
198 | "remember_user_default": true | ||
196 | }, | 199 | }, |
197 | "thumbnail": { | 200 | "thumbnail": { |
198 | "enable_thumbnails": true, | 201 | "enable_thumbnails": true, |
diff --git a/doc/md/index.md b/doc/md/index.md index b10e3cf4..24ada6c7 100644 --- a/doc/md/index.md +++ b/doc/md/index.md | |||
@@ -37,7 +37,7 @@ Login: `demo`; Password: `demo` | |||
37 | - daily RSS feed | 37 | - daily RSS feed |
38 | - permalinks for easy reference | 38 | - permalinks for easy reference |
39 | - links can be public or private | 39 | - links can be public or private |
40 | - extensible through [plugins](https://github.com/shaarli/Shaarli/wiki/Plugins#plugin-usage) | 40 | - extensible through [plugins](https://shaarli.readthedocs.io/en/master/Plugins/#plugin-usage) |
41 | 41 | ||
42 | ### Tag, view and search your links! | 42 | ### Tag, view and search your links! |
43 | - add a custom title and description to archived links | 43 | - add a custom title and description to archived links |
@@ -48,8 +48,8 @@ if (! file_exists(__DIR__ . '/vendor/autoload.php')) { | |||
48 | ."If you installed Shaarli through Git or using the development branch,\n" | 48 | ."If you installed Shaarli through Git or using the development branch,\n" |
49 | ."please refer to the installation documentation to install PHP" | 49 | ."please refer to the installation documentation to install PHP" |
50 | ." dependencies using Composer:\n" | 50 | ." dependencies using Composer:\n" |
51 | ."- https://github.com/shaarli/Shaarli/wiki/Server-requirements\n" | 51 | ."- https://shaarli.readthedocs.io/en/master/Server-requirements/\n" |
52 | ."- https://github.com/shaarli/Shaarli/wiki/Download-and-Installation"; | 52 | ."- https://shaarli.readthedocs.io/en/master/Download-and-Installation/"; |
53 | exit; | 53 | exit; |
54 | } | 54 | } |
55 | require_once 'inc/rain.tpl.class.php'; | 55 | require_once 'inc/rain.tpl.class.php'; |
@@ -133,15 +133,6 @@ date_default_timezone_set($conf->get('general.timezone', 'UTC')); | |||
133 | 133 | ||
134 | ob_start(); // Output buffering for the page cache. | 134 | ob_start(); // Output buffering for the page cache. |
135 | 135 | ||
136 | // In case stupid admin has left magic_quotes enabled in php.ini: | ||
137 | if (get_magic_quotes_gpc()) | ||
138 | { | ||
139 | function stripslashes_deep($value) { $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value); return $value; } | ||
140 | $_POST = array_map('stripslashes_deep', $_POST); | ||
141 | $_GET = array_map('stripslashes_deep', $_GET); | ||
142 | $_COOKIE = array_map('stripslashes_deep', $_COOKIE); | ||
143 | } | ||
144 | |||
145 | // Prevent caching on client side or proxy: (yes, it's ugly) | 136 | // Prevent caching on client side or proxy: (yes, it's ugly) |
146 | header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | 137 | header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); |
147 | header("Cache-Control: no-store, no-cache, must-revalidate"); | 138 | header("Cache-Control: no-store, no-cache, must-revalidate"); |
@@ -186,42 +177,42 @@ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { | |||
186 | */ | 177 | */ |
187 | function setup_login_state($conf) | 178 | function setup_login_state($conf) |
188 | { | 179 | { |
189 | if ($conf->get('security.open_shaarli')) { | 180 | if ($conf->get('security.open_shaarli')) { |
190 | return true; | 181 | return true; |
191 | } | 182 | } |
192 | $userIsLoggedIn = false; // By default, we do not consider the user as logged in; | 183 | $userIsLoggedIn = false; // By default, we do not consider the user as logged in; |
193 | $loginFailure = false; // If set to true, every attempt to authenticate the user will fail. This indicates that an important condition isn't met. | 184 | $loginFailure = false; // If set to true, every attempt to authenticate the user will fail. This indicates that an important condition isn't met. |
194 | if (! $conf->exists('credentials.login')) { | 185 | if (! $conf->exists('credentials.login')) { |
195 | $userIsLoggedIn = false; // Shaarli is not configured yet. | 186 | $userIsLoggedIn = false; // Shaarli is not configured yet. |
196 | $loginFailure = true; | 187 | $loginFailure = true; |
197 | } | 188 | } |
198 | if (isset($_COOKIE['shaarli_staySignedIn']) && | 189 | if (isset($_COOKIE['shaarli_staySignedIn']) && |
199 | $_COOKIE['shaarli_staySignedIn']===STAY_SIGNED_IN_TOKEN && | 190 | $_COOKIE['shaarli_staySignedIn']===STAY_SIGNED_IN_TOKEN && |
200 | !$loginFailure) | 191 | !$loginFailure) |
201 | { | 192 | { |
202 | fillSessionInfo($conf); | 193 | fillSessionInfo($conf); |
203 | $userIsLoggedIn = true; | 194 | $userIsLoggedIn = true; |
204 | } | 195 | } |
205 | // If session does not exist on server side, or IP address has changed, or session has expired, logout. | 196 | // If session does not exist on server side, or IP address has changed, or session has expired, logout. |
206 | if (empty($_SESSION['uid']) | 197 | if (empty($_SESSION['uid']) |
207 | || ($conf->get('security.session_protection_disabled') === false && $_SESSION['ip'] != allIPs()) | 198 | || ($conf->get('security.session_protection_disabled') === false && $_SESSION['ip'] != allIPs()) |
208 | || time() >= $_SESSION['expires_on']) | 199 | || time() >= $_SESSION['expires_on']) |
209 | { | 200 | { |
210 | logout(); | 201 | logout(); |
211 | $userIsLoggedIn = false; | 202 | $userIsLoggedIn = false; |
212 | $loginFailure = true; | 203 | $loginFailure = true; |
213 | } | 204 | } |
214 | if (!empty($_SESSION['longlastingsession'])) { | 205 | if (!empty($_SESSION['longlastingsession'])) { |
215 | $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // In case of "Stay signed in" checked. | 206 | $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // In case of "Stay signed in" checked. |
216 | } | 207 | } |
217 | else { | 208 | else { |
218 | $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Standard session expiration date. | 209 | $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Standard session expiration date. |
219 | } | 210 | } |
220 | if (!$loginFailure) { | 211 | if (!$loginFailure) { |
221 | $userIsLoggedIn = true; | 212 | $userIsLoggedIn = true; |
222 | } | 213 | } |
223 | 214 | ||
224 | return $userIsLoggedIn; | 215 | return $userIsLoggedIn; |
225 | } | 216 | } |
226 | $userIsLoggedIn = setup_login_state($conf); | 217 | $userIsLoggedIn = setup_login_state($conf); |
227 | 218 | ||
@@ -245,10 +236,10 @@ function allIPs() | |||
245 | */ | 236 | */ |
246 | function fillSessionInfo($conf) | 237 | function fillSessionInfo($conf) |
247 | { | 238 | { |
248 | $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // Generate unique random number (different than phpsessionid) | 239 | $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // Generate unique random number (different than phpsessionid) |
249 | $_SESSION['ip']=allIPs(); // We store IP address(es) of the client to make sure session is not hijacked. | 240 | $_SESSION['ip']=allIPs(); // We store IP address(es) of the client to make sure session is not hijacked. |
250 | $_SESSION['username']= $conf->get('credentials.login'); | 241 | $_SESSION['username']= $conf->get('credentials.login'); |
251 | $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. | 242 | $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. |
252 | } | 243 | } |
253 | 244 | ||
254 | /** | 245 | /** |
@@ -265,7 +256,7 @@ function check_auth($login, $password, $conf) | |||
265 | $hash = sha1($password . $login . $conf->get('credentials.salt')); | 256 | $hash = sha1($password . $login . $conf->get('credentials.salt')); |
266 | if ($login == $conf->get('credentials.login') && $hash == $conf->get('credentials.hash')) | 257 | if ($login == $conf->get('credentials.login') && $hash == $conf->get('credentials.hash')) |
267 | { // Login/password is correct. | 258 | { // Login/password is correct. |
268 | fillSessionInfo($conf); | 259 | fillSessionInfo($conf); |
269 | logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Login successful'); | 260 | logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Login successful'); |
270 | return true; | 261 | return true; |
271 | } | 262 | } |
@@ -394,9 +385,10 @@ if (isset($_POST['login'])) | |||
394 | // If user wants to keep the session cookie even after the browser closes: | 385 | // If user wants to keep the session cookie even after the browser closes: |
395 | if (!empty($_POST['longlastingsession'])) | 386 | if (!empty($_POST['longlastingsession'])) |
396 | { | 387 | { |
397 | setcookie('shaarli_staySignedIn', STAY_SIGNED_IN_TOKEN, time()+31536000, WEB_PATH); | 388 | $_SESSION['longlastingsession'] = 31536000; // (31536000 seconds = 1 year) |
398 | $_SESSION['longlastingsession']=31536000; // (31536000 seconds = 1 year) | 389 | $expiration = time() + $_SESSION['longlastingsession']; // calculate relative cookie expiration (1 year from now) |
399 | $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // Set session expiration on server-side. | 390 | setcookie('shaarli_staySignedIn', STAY_SIGNED_IN_TOKEN, $expiration, WEB_PATH); |
391 | $_SESSION['expires_on'] = $expiration; // Set session expiration on server-side. | ||
400 | 392 | ||
401 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; | 393 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; |
402 | session_set_cookie_params($_SESSION['longlastingsession'],$cookiedir,$_SERVER['SERVER_NAME']); // Set session cookie expiration on client side | 394 | session_set_cookie_params($_SESSION['longlastingsession'],$cookiedir,$_SERVER['SERVER_NAME']); // Set session cookie expiration on client side |
@@ -591,20 +583,29 @@ function showDailyRSS($conf) { | |||
591 | */ | 583 | */ |
592 | function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) | 584 | function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) |
593 | { | 585 | { |
594 | $day=date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. | 586 | $day = date('Ymd', strtotime('-1 day')); // Yesterday, in format YYYYMMDD. |
595 | if (isset($_GET['day'])) $day=$_GET['day']; | 587 | if (isset($_GET['day'])) { |
588 | $day = $_GET['day']; | ||
589 | } | ||
596 | 590 | ||
597 | $days = $LINKSDB->days(); | 591 | $days = $LINKSDB->days(); |
598 | $i = array_search($day,$days); | 592 | $i = array_search($day, $days); |
599 | if ($i===false) { $i=count($days)-1; $day=$days[$i]; } | 593 | if ($i === false && count($days)) { |
600 | $previousday=''; | 594 | // no links for day, but at least one day with links |
601 | $nextday=''; | 595 | $i = count($days) - 1; |
602 | if ($i!==false) | 596 | $day = $days[$i]; |
603 | { | ||
604 | if ($i>=1) $previousday=$days[$i-1]; | ||
605 | if ($i<count($days)-1) $nextday=$days[$i+1]; | ||
606 | } | 597 | } |
598 | $previousday = ''; | ||
599 | $nextday = ''; | ||
607 | 600 | ||
601 | if ($i !== false) { | ||
602 | if ($i >= 1) { | ||
603 | $previousday=$days[$i - 1]; | ||
604 | } | ||
605 | if ($i < count($days) - 1) { | ||
606 | $nextday = $days[$i + 1]; | ||
607 | } | ||
608 | } | ||
608 | try { | 609 | try { |
609 | $linksToDisplay = $LINKSDB->filterDay($day); | 610 | $linksToDisplay = $LINKSDB->filterDay($day); |
610 | } catch (Exception $exc) { | 611 | } catch (Exception $exc) { |
@@ -613,9 +614,7 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) | |||
613 | } | 614 | } |
614 | 615 | ||
615 | // We pre-format some fields for proper output. | 616 | // We pre-format some fields for proper output. |
616 | foreach($linksToDisplay as $key=>$link) | 617 | foreach($linksToDisplay as $key => $link) { |
617 | { | ||
618 | |||
619 | $taglist = explode(' ',$link['tags']); | 618 | $taglist = explode(' ',$link['tags']); |
620 | uasort($taglist, 'strcasecmp'); | 619 | uasort($taglist, 'strcasecmp'); |
621 | $linksToDisplay[$key]['taglist']=$taglist; | 620 | $linksToDisplay[$key]['taglist']=$taglist; |
@@ -629,21 +628,22 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) | |||
629 | so I manually spread entries with a simple method: I roughly evaluate the | 628 | so I manually spread entries with a simple method: I roughly evaluate the |
630 | height of a div according to title and description length. | 629 | height of a div according to title and description length. |
631 | */ | 630 | */ |
632 | $columns=array(array(),array(),array()); // Entries to display, for each column. | 631 | $columns = array(array(), array(), array()); // Entries to display, for each column. |
633 | $fill=array(0,0,0); // Rough estimate of columns fill. | 632 | $fill = array(0, 0, 0); // Rough estimate of columns fill. |
634 | foreach($linksToDisplay as $key=>$link) | 633 | foreach($linksToDisplay as $key => $link) { |
635 | { | ||
636 | // Roughly estimate length of entry (by counting characters) | 634 | // Roughly estimate length of entry (by counting characters) |
637 | // Title: 30 chars = 1 line. 1 line is 30 pixels height. | 635 | // Title: 30 chars = 1 line. 1 line is 30 pixels height. |
638 | // Description: 836 characters gives roughly 342 pixel height. | 636 | // Description: 836 characters gives roughly 342 pixel height. |
639 | // This is not perfect, but it's usually OK. | 637 | // This is not perfect, but it's usually OK. |
640 | $length=strlen($link['title'])+(342*strlen($link['description']))/836; | 638 | $length = strlen($link['title']) + (342 * strlen($link['description'])) / 836; |
641 | if ($link['thumbnail']) $length +=100; // 1 thumbnails roughly takes 100 pixels height. | 639 | if ($link['thumbnail']) { |
640 | $length += 100; // 1 thumbnails roughly takes 100 pixels height. | ||
641 | } | ||
642 | // Then put in column which is the less filled: | 642 | // Then put in column which is the less filled: |
643 | $smallest=min($fill); // find smallest value in array. | 643 | $smallest = min($fill); // find smallest value in array. |
644 | $index=array_search($smallest,$fill); // find index of this smallest value. | 644 | $index = array_search($smallest, $fill); // find index of this smallest value. |
645 | array_push($columns[$index],$link); // Put entry in this column. | 645 | array_push($columns[$index], $link); // Put entry in this column. |
646 | $fill[$index]+=$length; | 646 | $fill[$index] += $length; |
647 | } | 647 | } |
648 | 648 | ||
649 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); | 649 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); |
@@ -745,6 +745,8 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
745 | $PAGE->assign('username', escape($_GET['username'])); | 745 | $PAGE->assign('username', escape($_GET['username'])); |
746 | } | 746 | } |
747 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); | 747 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); |
748 | // add default state of the 'remember me' checkbox | ||
749 | $PAGE->assign('remember_user_default', $conf->get('privacy.remember_user_default')); | ||
748 | $PAGE->renderPage('loginform'); | 750 | $PAGE->renderPage('loginform'); |
749 | exit; | 751 | exit; |
750 | } | 752 | } |
@@ -803,7 +805,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
803 | $maxcount = max($maxcount, $value); | 805 | $maxcount = max($maxcount, $value); |
804 | } | 806 | } |
805 | 807 | ||
806 | alphabetical_sort($tags, true, true); | 808 | alphabetical_sort($tags, false, true); |
807 | 809 | ||
808 | $tagList = array(); | 810 | $tagList = array(); |
809 | foreach($tags as $key => $value) { | 811 | foreach($tags as $key => $value) { |
@@ -1233,7 +1235,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1233 | // Linkdate is kept here to: | 1235 | // Linkdate is kept here to: |
1234 | // - use the same permalink for notes as they're displayed when creating them | 1236 | // - use the same permalink for notes as they're displayed when creating them |
1235 | // - let users hack creation date of their posts | 1237 | // - let users hack creation date of their posts |
1236 | // See: https://github.com/shaarli/Shaarli/wiki/Datastore-hacks#changing-the-timestamp-for-a-link | 1238 | // See: https://shaarli.readthedocs.io/en/master/Various-hacks/#changing-the-timestamp-for-a-shaare |
1237 | $linkdate = escape($_POST['lf_linkdate']); | 1239 | $linkdate = escape($_POST['lf_linkdate']); |
1238 | if (isset($LINKSDB[$id])) { | 1240 | if (isset($LINKSDB[$id])) { |
1239 | // Edit | 1241 | // Edit |
@@ -1256,6 +1258,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1256 | // Remove duplicates. | 1258 | // Remove duplicates. |
1257 | $tags = implode(' ', array_unique(explode(' ', $tags))); | 1259 | $tags = implode(' ', array_unique(explode(' ', $tags))); |
1258 | 1260 | ||
1261 | if (empty(trim($_POST['lf_url']))) { | ||
1262 | $_POST['lf_url'] = '?' . smallHash($linkdate . $id); | ||
1263 | } | ||
1259 | $url = whitelist_protocols(trim($_POST['lf_url']), $conf->get('security.allowed_protocols')); | 1264 | $url = whitelist_protocols(trim($_POST['lf_url']), $conf->get('security.allowed_protocols')); |
1260 | 1265 | ||
1261 | $link = array( | 1266 | $link = array( |
@@ -1325,10 +1330,17 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1325 | die('Wrong token.'); | 1330 | die('Wrong token.'); |
1326 | } | 1331 | } |
1327 | 1332 | ||
1328 | if (strpos($_GET['lf_linkdate'], ' ') !== false) { | 1333 | $ids = trim($_GET['lf_linkdate']); |
1329 | $ids = array_values(array_filter(preg_split('/\s+/', escape($_GET['lf_linkdate'])))); | 1334 | if (strpos($ids, ' ') !== false) { |
1335 | // multiple, space-separated ids provided | ||
1336 | $ids = array_values(array_filter(preg_split('/\s+/', escape($ids)))); | ||
1330 | } else { | 1337 | } else { |
1331 | $ids = [$_GET['lf_linkdate']]; | 1338 | // only a single id provided |
1339 | $ids = [$ids]; | ||
1340 | } | ||
1341 | // assert at least one id is given | ||
1342 | if(!count($ids)){ | ||
1343 | die('no id provided'); | ||
1332 | } | 1344 | } |
1333 | foreach ($ids as $id) { | 1345 | foreach ($ids as $id) { |
1334 | $id = (int) escape($id); | 1346 | $id = (int) escape($id); |
diff --git a/plugins/playvideos/README.md b/plugins/playvideos/README.md index b1698470..ab4be22a 100644 --- a/plugins/playvideos/README.md +++ b/plugins/playvideos/README.md | |||
@@ -8,7 +8,7 @@ This uses code from https://zaius.github.io/youtube_playlist/ and is currently o | |||
8 | 8 | ||
9 | #### Installation and setup | 9 | #### Installation and setup |
10 | 10 | ||
11 | This is a default Shaarli plugin, you just have to enable it. See https://github.com/shaarli/Shaarli/wiki/Shaarli-configuration/ | 11 | This is a default Shaarli plugin, you just have to enable it. See https://shaarli.readthedocs.io/en/master/Shaarli-configuration/ |
12 | 12 | ||
13 | 13 | ||
14 | #### Troubleshooting | 14 | #### Troubleshooting |
diff --git a/tpl/default/js/shaarli.js b/tpl/default/js/shaarli.js index e0b4c752..1c66ebbd 100644 --- a/tpl/default/js/shaarli.js +++ b/tpl/default/js/shaarli.js | |||
@@ -401,14 +401,14 @@ window.onload = function () { | |||
401 | 401 | ||
402 | var message = 'Are you sure you want to delete '+ links.length +' links?\n'; | 402 | var message = 'Are you sure you want to delete '+ links.length +' links?\n'; |
403 | message += 'This action is IRREVERSIBLE!\n\nTitles:\n'; | 403 | message += 'This action is IRREVERSIBLE!\n\nTitles:\n'; |
404 | var ids = ''; | 404 | var ids = []; |
405 | links.forEach(function(item) { | 405 | links.forEach(function(item) { |
406 | message += ' - '+ item['title'] +'\n'; | 406 | message += ' - '+ item['title'] +'\n'; |
407 | ids += item['id'] +'+'; | 407 | ids.push(item['id']); |
408 | }); | 408 | }); |
409 | 409 | ||
410 | if (window.confirm(message)) { | 410 | if (window.confirm(message)) { |
411 | window.location = '?delete_link&lf_linkdate='+ ids +'&token='+ token.value; | 411 | window.location = '?delete_link&lf_linkdate='+ ids.join('+') +'&token='+ token.value; |
412 | } | 412 | } |
413 | }); | 413 | }); |
414 | } | 414 | } |
diff --git a/tpl/default/loginform.html b/tpl/default/loginform.html index eb6d8378..5777a218 100644 --- a/tpl/default/loginform.html +++ b/tpl/default/loginform.html | |||
@@ -30,7 +30,8 @@ | |||
30 | </div> | 30 | </div> |
31 | <div class="remember-me"> | 31 | <div class="remember-me"> |
32 | <input type="checkbox" name="longlastingsession" id="longlastingsessionform" | 32 | <input type="checkbox" name="longlastingsession" id="longlastingsessionform" |
33 | checked="checked" tabindex="22"> | 33 | {if="$remember_user_default"}checked="checked"{/if} |
34 | tabindex="22"> | ||
34 | <label for="longlastingsessionform">{'Remember me'|t}</label> | 35 | <label for="longlastingsessionform">{'Remember me'|t}</label> |
35 | </div> | 36 | </div> |
36 | <div> | 37 | <div> |
diff --git a/tpl/default/tools.html b/tpl/default/tools.html index 35173d17..72fd58af 100644 --- a/tpl/default/tools.html +++ b/tpl/default/tools.html | |||
@@ -97,7 +97,7 @@ | |||
97 | var%20desc=document.getSelection().toString(); | 97 | var%20desc=document.getSelection().toString(); |
98 | if(desc.length>4000){ | 98 | if(desc.length>4000){ |
99 | desc=desc.substr(0,4000)+'...'; | 99 | desc=desc.substr(0,4000)+'...'; |
100 | alert("{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}"); | 100 | alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}'); |
101 | } | 101 | } |
102 | window.open( | 102 | window.open( |
103 | '{$pageabsaddr}?private=1&post='+ | 103 | '{$pageabsaddr}?private=1&post='+ |
diff --git a/tpl/vintage/loginform.html b/tpl/vintage/loginform.html index 84176385..1becd44f 100644 --- a/tpl/vintage/loginform.html +++ b/tpl/vintage/loginform.html | |||
@@ -24,7 +24,9 @@ | |||
24 | </label> | 24 | </label> |
25 | <input type="submit" value="Login" class="bigbutton" tabindex="4"> | 25 | <input type="submit" value="Login" class="bigbutton" tabindex="4"> |
26 | <label for="longlastingsession"> | 26 | <label for="longlastingsession"> |
27 | <input type="checkbox" name="longlastingsession" id="longlastingsession" tabindex="3"> | 27 | <input type="checkbox" name="longlastingsession" |
28 | id="longlastingsession" tabindex="3" | ||
29 | {if="$remember_user_default"}checked="checked"{/if}> | ||
28 | Stay signed in (Do not check on public computers)</label> | 30 | Stay signed in (Do not check on public computers)</label> |
29 | <input type="hidden" name="token" value="{$token}"> | 31 | <input type="hidden" name="token" value="{$token}"> |
30 | {if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if} | 32 | {if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if} |