Commit Graph

910 Commits

Author SHA1 Message Date
Alexandre Alapetite
7e72033859 Filter on last user modified (#8093)
Example: `userdate:PT1H` to select only articles modified by user during the last hour
Fix https://github.com/FreshRSS/FreshRSS/issues/4280#issuecomment-3393078024

Useful for instance to bulk mark as unread recently marked articles by error:
1. Click on the toggle button to show the read articles (making sure the toggle for the unread articles is off)
2. Sort by *User modified 9→1*
3. Filter by *user modified date*, for instance to the last 3 hours by typing `userdate:PT3H`
4. Click in the drop-down menu *Mark selection as unread*

P.S.: I have added at the same time a bunch of unit tests for date-related logic
2025-10-15 00:12:19 +02:00
Alexandre Alapetite
e070c3ed2b Implement search form (#8103)
* Add UI for advanced search
To help users with the seach operators.
Obviously not as powerful as a manually-written search query.
Lack in particular negation and logical *and* for now, but I might try to do something about it.

<img width="939" height="1438" alt="image" src="https://github.com/user-attachments/assets/0bcad39b-eff3-4f44-876b-a2552af2af00" />

* Consistency: allow multiple user queries like S:1,2

* Fix user query and add tests
2025-10-15 00:08:40 +02:00
Alexandre Alapetite
20ecbeb09c Fix drag&drop of user query losing information (#8113)
* Fix drag&drop of user query losing information
Information about RSS sharing was lost after a drag&drop

* Fix related type cast
2025-10-14 11:01:23 +02:00
Alexandre Alapetite
57e1a375cb Strengthen some crypto (#8061)
For login, tokens, nonces
2025-10-04 14:32:18 +02:00
Alexis Degrugillier
032316155c Add a new hook in the UI (#8054)
* Add a new hook in the UI

The new hook allows extension to add their own tool bar to navigate between
entries. For instance, if the user wants less or more buttons that what's
available by default.

See #7912
See #7913

* add link data to ease navigation
2025-10-02 15:33:53 +02:00
Alexandre Alapetite
e27ca6d9dd SimplePie: apply HTTPS policy also on GUIDs and permalinks (#8037)
* SimplePie: apply HTTPS policy also on GUIDs and permalinks
Fix WordPress duplicates HTTP vs. HTTPS
fix https://github.com/FreshRSS/FreshRSS/issues/5151

* Move code upstream
* https://github.com/simplepie/simplepie/pull/951
* https://github.com/FreshRSS/simplepie/pull/59
2025-10-01 23:13:23 +02:00
Alexandre Alapetite
49c96fe3ec Fix SimplePie support of HTTP trailer headers (#7983)
* Fix SimplePie support of HTTP trailer headers
fix https://github.com/FreshRSS/FreshRSS/discussions/7981
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Trailer
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Server-Timing
We need to use content-length to know where the body stops, but content-length is wrong is any compression was used.
So let cURL perform the separation of HTTP headers and body instead of using the SimplePie parser.

* Minor whitespace

* Same change for lib_rss

* Move changes to SimplePie repo
https://github.com/FreshRSS/simplepie/pull/55
https://github.com/FreshRSS/simplepie/pull/57
2025-10-01 23:07:38 +02:00
dependabot[bot]
8e57e28a9a Update phpmailer/phpmailer requirement from 6.10.0 to 6.11.1 in /lib (#8048)
* Update phpmailer/phpmailer requirement from 6.10.0 to 6.11.1 in /lib

Updates the requirements on [phpmailer/phpmailer](https://github.com/PHPMailer/PHPMailer) to permit the latest version.
- [Release notes](https://github.com/PHPMailer/PHPMailer/releases)
- [Changelog](https://github.com/PHPMailer/PHPMailer/blob/master/changelog.md)
- [Commits](https://github.com/PHPMailer/PHPMailer/compare/v6.10.0...v6.11.1)

---
updated-dependencies:
- dependency-name: phpmailer/phpmailer
  dependency-version: 6.11.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* composer update --no-autoloader

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-10-01 21:03:22 +02:00
Alexis Degrugillier
dac275ce3a Add support for extension priority (#8038)
Extension can now define their hook priority. This will allow to define the order in which hooks are triggered.

See #7110

Closes #7110

Changes proposed in this pull request:

- Add support for extension priority

How to test the feature manually:

1. Create an extension with 2 hooks on the same hook type but different priority
2. The hooks must be prepending the title with different values
3. Validate that changing the hook priority changes the final title accordingly.
2025-10-01 11:01:31 +02:00
maTh
2bcc090622 configurable notification timeout (#7942)
Ref #7931
Ref #5466
Ref #6409

added configuration in "Display"
<img width="636" height="167" alt="grafik" src="https://github.com/user-attachments/assets/7bbc9f26-d91b-4dd2-b715-1d3f9b7a9ad3" />

* i18n: fr

* Update app/i18n/pl/conf.php

Co-authored-by: Inverle <inverle@proton.me>

* make fix-all

* max()

* Minor whitespace
(I am not a fan of excessive vertical indenting)

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Inverle <inverle@proton.me>
2025-10-01 10:48:07 +02:00
Alexis Degrugillier
72884813e1 Add hook enums (#8036)
- add an enum to handle hook types (enum are available since PHP 8.1)
- change hook calls from string value to enum value
2025-09-30 22:59:41 +02:00
Inverle
9dd30f03ec Improve restriction of curl params (#8009)
Rework #7979 
Forgot to change `httpGet()`, which is used in multiple places
2025-09-25 22:50:21 +02:00
Inverle
067479a9f1 Lazy-load <track src> (#7997)
Follow-up of #7636

I found it's the only missing element that needs to be lazy loaded by putting HTML of https://github.com/cure53/HTTPLeaks/blob/main/leak.html into a feed
2025-09-23 22:12:44 +02:00
Alexandre Alapetite
92a73a2c4f Minor forgotten str_starts_with (#7991)
A couple of places, which have been forgotten when we moved to using `str_starts_with()` instead of `strpos()`.
2025-09-21 19:06:06 +02:00
Alexandre Alapetite
bc3e4c8fa4 Add option for CSP frame-ancestors (#7857)
* Add option for CSP frame-ancestors
https://github.com/FreshRSS/FreshRSS/discussions/7856

* Revert contentSelectorPreviewAction

* Same for f.php and api

* Fix double init in f.php

* No sandbox for API page
2025-09-21 13:29:58 +02:00
KleinMann
d670bf1e72 Add entry_before_update and entry_before_add hooks (#7977)
Discussion: https://github.com/FreshRSS/FreshRSS/discussions/7973

Changes proposed in this pull request:

- Add new extension hook "entry_before_add"
- Add new extension hook "entry_before_update"

How to test the feature manually:

1. Create extension that uses the hooks and confirm they are invoked correctly.

Extension to use for testing
https://github.com/rnkln/freshrss-xExtension-Discord/pull/2
2025-09-18 23:44:17 +02:00
Inverle
055342118f Restrict allowed curl parameters (#7979)
For additional safety, also making sure in this PR that [`CURLOPT_COOKIEFILE`](https://curl.se/libcurl/c/CURLOPT_COOKIEFILE.html) is only allowed as an empty string during import.
2025-09-18 23:43:04 +02:00
Alexandre Alapetite
bb56f59fcf SimplePie merge upstream (#7967)
* https://github.com/simplepie/simplepie/pull/936 (Normalize encoding uppercase)
2025-09-15 13:40:14 +02:00
Alexandre Alapetite
b04104fd95 Bump SimplePie to 1.9.0 (#7955)
Main change is https://github.com/simplepie/simplepie/pull/937 (PHP 8.5: Conditionally call deprecated functions)

P.S. a sync with SimplePie upstream was already done recently, hence the limited changes:
* https://github.com/FreshRSS/FreshRSS/pull/7775
2025-09-13 00:19:31 +02:00
Alexis Degrugillier
6ad625812a Add a default language constant (#7933)
This replace the use of `en` through out the code.
2025-09-09 22:01:04 +02:00
Alexis Degrugillier
23ba48c71f Change how files are included (#7916)
1. `include`, `include_once`, `require` and `require_once` are expressions not functions, parentheses are not necessary.
2. to move up the directory tree, it's better to use the `dirname` function instead of relying on `/..`.
2025-09-05 15:56:46 +02:00
Inverle
c44bb029c0 Fix log CRLF injection (#7883)
* Fix log CRLF injection

* empty -> space

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-08-31 20:05:30 +02:00
Inverle
200eafb352 Regenerate session ID on login (#7829)
Follow-up to #7762

* Regenerate session ID on login
* Send only one cookie
* Improvements
* Delete old session file
* Simplify
* Make function consistent with others
2025-08-30 21:40:00 +02:00
Inverle
379a387dde Disallow setting non-existent language (#7878)
The set language is used inside paths and can lead to issues by including PHP files from other locations
2025-08-30 16:26:24 +02:00
Inverle
43248b461d Fix curl response parsing (#7866)
* Fix curl response parsing

* Specify redirect count with `\SimplePie\HTTP\Parser::prepareHeaders()` instead

Simply notify SimplePie of the redirect count before parsing

* Better error check

* Simplify
2025-08-30 15:13:10 +02:00
Alexandre Alapetite
ade9ba8817 Call cleanCache when refreshing feeds (#7827)
Otherwise, it is only called when calling `httpGet()` which can be rare for users not using Web Scraping.
https://github.com/FreshRSS/FreshRSS/discussions/7784#discussioncomment-14109207
2025-08-15 09:37:00 +02:00
Alexandre Alapetite
ddb9e91bf2 Fix some PHP 8.5 deprecations (#7826)
https://github.com/php/php-src/blob/php-8.5.0beta1/NEWS
https://php.net/function.curl-close
> This function has no effect. Prior to PHP 8.0.0, this function was used to close the resource.
2025-08-15 09:36:45 +02:00
Alexandre Alapetite
531b9286d9 Fix regression on_http_response (#7824)
Fix regression (bad merge) from https://github.com/FreshRSS/FreshRSS/pull/7775
* https://github.com/FreshRSS/simplepie/pull/50
2025-08-14 09:35:30 +02:00
Alexandre Alapetite
eaf69f591f SimplePie Fix regex backtrack limit in clean_hash() (#7813)
https://github.com/FreshRSS/simplepie/pull/48
and merge upstream https://github.com/FreshRSS/simplepie/pull/49
fix https://github.com/FreshRSS/FreshRSS/issues/7807
We had a risk of hitting `Backtrack limit was exhausted` in case of open XML comment `<!--` not closed and followed by a very long document.
Fixed by:
* Limiting the max length of the comment
* Stopping at an apparent end of CDATA section `]]>` as it is likely an error

It does not matter much if there are rare cases when the regex does not work perfectly, as it is only used for a cache hint.
2025-08-11 00:52:09 +02:00
Inverle
2b85a50ed7 Show warning when unsafe CSP policy is in use (#7804)
* Show warning when unsafe CSP policy is in use

* Fix bare markdown URL

* i18n: fr

* Minor i18n: fr

* Add target="_blank" to i18n strings

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-08-09 21:47:39 +02:00
Inverle
d9197d7e32 New JS attribute: data-auto-leave-validation (#7785)
Instead of a repeating pattern like: `<input type="text" value="something" data-leave-validation="something">`, you can now put a `data-auto-leave-validation="1"` attribute on a `<form>` for example, and it will automatically set the `data-leave-validation` attributes inside the form elements.

`data_auto_leave_validation(parent)`  from `extra.js` is called on slider open and page load.

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2025-08-08 17:39:38 +02:00
Alexandre Alapetite
62f32ccadf PHPStan: finalise strictArrayFilter (#7794)
As well as reportPossiblyNonexistentConstantArrayOffset.
And disable PHPStan-next from GitHub Action, since the work is completed for now.
2025-08-07 22:19:45 +02:00
Alexandre Alapetite
b817598f57 Bump SimplePie with PHPStan Level 8 (#7775)
* Bump SimplePie with PHPStan Level 8
* https://github.com/FreshRSS/simplepie/pull/45
SimplePie increased to PHPStan Level 8:
* https://github.com/simplepie/simplepie/pull/857

* Merge upstream
Including my two PRs:
* https://github.com/simplepie/simplepie/pull/932
* https://github.com/simplepie/simplepie/pull/933

* Resolve upstream sync of Expose HTTP status
* https://github.com/FreshRSS/simplepie/pull/47
Finalise merge, following:
* https://github.com/simplepie/simplepie/pull/905#issuecomment-3007605779
* https://github.com/simplepie/simplepie/pull/909
* https://github.com/FreshRSS/FreshRSS/issues/7038
2025-08-01 23:27:35 +02:00
Alexandre Alapetite
536c476f0d composer update + corresponding PHPStan fixes (#7781)
Replacing failing Dependabot PRs:
* https://github.com/FreshRSS/FreshRSS/pull/7779
* https://github.com/FreshRSS/FreshRSS/pull/7780
* https://github.com/FreshRSS/FreshRSS/pull/7778
2025-08-01 21:36:25 +02:00
Alexandre Alapetite
e915ebe46e Rework fetch favicons (#7767)
* Use main function `httpGet()` instead of local one;
* Use HTTP cache, also between users;
* Do not default to feed URL when there is no website URL

TODO for later: consider supporting Atom's `<icon>` and RSS 2.0's `<image>` https://github.com/FreshRSS/FreshRSS/issues/7774
2025-08-01 08:30:49 +02:00
Inverle
c952256564 Strip more unsafe attributes e.g. referrerpolicy (#7770) 2025-07-31 17:04:47 +02:00
Inverle
3ce64d271b Implement sudo mode / reauthentication (#7753)
* Implement sudo mode / reauthentication

* i18n: fr

* generate flags

* Improvements

* Remove HMAC check
* Don't require reauth to access logs when signed in as admin
* Notify user of bad login via notification instead

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-07-31 13:53:14 +02:00
Alexandre Alapetite
97f1bd2dcb Fix regression Minz_Configuration (#7765)
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/7761
Partially avoid calls to deprecated functions.
Avoid warnings:
```
[warning] --- old_entries does not exist in configuration
[warning] --- keep_history_default does not exist in configuration
```
2025-07-31 09:53:21 +02:00
Alexandre Alapetite
7a0c423357 Implement support for HTTP 429 Too Many Requests (#7760)
* Implement support for HTTP 429 Too Many Requests
Will obey the corresponding HTTP `Retry-After` header at domain level.

* Implement 503 Service Unavailable

* Sanitize Retry-After

* Reduce default value when Retry-After is absent
And make configuration parameter

* Retry-After also for favicons
2025-07-31 09:17:42 +02:00
Inverle
e33ef74af9 before_login_btn hook + system conf attributes (#7761)
* `before_login_btn` hook + system conf attributes

* phpstan fix

* Refactoring

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-07-30 08:03:04 +02:00
Sam Edwards
5bbd299c7e Call DOMNode::insertBefore() on the parent of it's $child (#7741)
Follow-up to https://github.com/FreshRSS/FreshRSS/pull/7654#discussion_r2208901108

Changes proposed in this pull request:

- `DOMNode::insertBefore()` needs to be called on an element that is the parent of the `$child` param being passed
- Update code to call this on `$doc->documentElement` instead of directly on the `$doc` (`DOMDocument`)

How to test the feature manually:

1. Set up an HTML + XPath feed for a URL that contains partial HTML content (eg. https://victoria.citified.ca/modules/blog/news.php?n=7&c=8)
1. Observe that the feed is processed successfully without error, and that the `<base>` is still inserted
2025-07-17 01:44:10 +02:00
Alexandre Alapetite
8b73573a32 SimplePie: sync upstream (#7706)
https://github.com/FreshRSS/simplepie/pull/43
2025-07-03 08:45:52 +02:00
Inverle
7915abd833 Implement custom feed favicons (#7646)
Closes #3789, #6503

Icon setting when no custom icon is set yet:

![image](https://github.com/user-attachments/assets/28b07dd0-7dac-4c76-b1d7-77035f91a87a)

- `Change...` button opens a file dialog, and after selecting a file shows the chosen icon in the preview on the left. `Submit` must be clicked after selecting the icon.
- `Reset to default` changes the preview icon to the default one, and also requires `Submit` to be clicked to apply the changes.

Full list of changes:
- CSP now includes `blob:` in `img-src` for
   - `indexAction()` and `feedAction()` in `subscriptionController.php`
   - all of the view actions in `indexController.php`
- Introduce new attribute `customFavicon (boolean)` for feeds that indicates if the feed has a custom favicon
   - `hashFavicon()` in `Feed.php` is dependent on this attribute
      - `hashFavicon()` has a new parameter called `skipCache (boolean)` that allows the reset of the favicon hash for the Feed object
      - `resetFaviconHash()` just calls `hashFavicon(skipCache: true)`
- `f.php` URLs now have the format of `/f.php?h=XXXXX&t=cachebuster`, where the `t` parameter is only used for serving custom favicons
   - if `t` parameter is set, `f.php` returns a `Cache-Control: immutable` header
- `stripos` and `strpos` were changed to `str_contains` in various places (refactor)
- JS for handling the custom favicon configuration logic is in `extra.js` inside `init_update_feed()` which is called when feed configuration is opened from the aside or when the subscription management page with the feed is loaded
   - Server-side code for uploading the icon in `subscriptionController.php` under `feedAction()`
   - Errors that may occur during the setting of a custom favicon:
      - Unsupported image file type (handled only server-side with `isImgMime()`)
      - When the file is bigger than 1 MiB (default), handled both client-side and server-side
      - Standard feed error when `updateFeed()` fails
- JS vars `javascript_vars.phtml` are no longer escaped with `htmlspecialchars()`, instead with json encoding,
- CSS for disabled buttons was added
- Max favicon file size is configurable with the `max_favicon_upload_size` option in `config.php` (not exposed via UI)
- Custom favicons are currently deleted only when they are either reset to the default icon, or the feed gets deleted. They do not get deleted when the user deletes their account without removing their feeds first.
- ` faviconPrepare()` and `faviconRebuild()` are not allowed to be called when the `customFavicon` attribute is `true`
- New i18n strings:
   - `'sub.feed.icon' => 'Icon'`
   - `'sub.feed.change_favicon' => 'Change…'`
   - `'sub.feed.reset_favicon' => 'Reset to default'`
   - `'sub.feed.favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.'`
   - `'feedback.sub.feed.favicon.too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.'`
   - `'feedback.sub.feed.favicon.unsupported_format' => 'Unsupported image file format!'`
- Extension hook `custom_favicon_hash`
   - `setCustomFavicon()` method
   - `resetCustomFavicon()` method
   - `customFaviconExt` and `customFaviconDisallowDel` attributes
   - example of usage: https://github.com/FreshRSS/Extensions/pull/337
- Extension hook `custom_favicon_btn_url`
   - Allows extensions to implement a button for setting a custom favicon for individual feeds by providing an URL. The URL will be sent a POST request with the `extAction` field set to either `query_icon_info` or `update_icon`, along with an `id` field which describes the feed's ID.
2025-06-30 12:01:56 +02:00
Inverle
7d9fc0ce0c Fix multiple auth headers bug (#7703)
Fix https://github.com/FreshRSS/FreshRSS/issues/7699
2025-06-30 09:51:31 +02:00
Alexandre Alapetite
7c57f38008 Fix feeds encoded in UTF-16LE (#7691)
* Fix feeds encoded in UTF-16LE
Fix https://github.com/FreshRSS/FreshRSS/issues/7690
https://github.com/FreshRSS/simplepie/pull/40
The final character `>` of a feed is encoded as `3E00` in UTF-16LE, so calling `trim()` was removing the `\x00`, breaking the multibyte encoding and making the feed invalid.

Upstream PR https://github.com/simplepie/simplepie/pull/916

* Trim body for all paths
https://github.com/FreshRSS/simplepie/pull/42
https://github.com/simplepie/simplepie/pull/917
Slight refactor of https://github.com/simplepie/simplepie/pull/916 (https://github.com/FreshRSS/simplepie/pull/40) to cover all paths.
Missing paths included the fsock method without gzip (e.g. deflate or plain).
2025-06-25 16:37:41 +02:00
Alexandre Alapetite
42aeecb5ed Fix support for XML feeds with HTML entities (#7689)
fix https://github.com/FreshRSS/FreshRSS/issues/7687

https://github.com/FreshRSS/simplepie/pull/37
Upstream: https://github.com/simplepie/simplepie/pull/915

Partial revert of https://github.com/FreshRSS/FreshRSS/pull/7515

HTML entities are normally only allowed in XML when there is a DTD declaring them. SimplePie is even allowing Atom documents with undeclared HTML entities - which I am not sure is on purpose.
2025-06-24 10:37:33 +02:00
Stefan
51298cd6bc Exposed the reading modes for extensions through Minz (#7668)
* + Exposed the reading modes for extensions through Minz. Now extensions can add a custom view mode. Graceful fallback to normal view in case the extension was disabled without resetting the view_mode through the uninstall method. In that case the user will be informed via Minz_Request::setBadNotification that the view has been reset to normal.
+ Added translation strings for de, en and en-us for the notification

* + Added missing, generated translations

* Simplify indexAction, performance

* Minor settings htmlspecialchars

* i18n: fr

* Minor wording

* Doc

* Fix i18n

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-06-22 00:36:32 +02:00
Inverle
18b5c8ec6d Handle redirects when scraping feed from HTML (#7654)
* Handle redirects when scraping feed from HTML

* pass codesniffer

* pass PHPStan

* Optimize

* Another approach relying on HTML base
Standard way to save an HTML document with relative references

* Fix case of existing HTML base
which should not be overriden

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-06-22 00:09:18 +02:00
Inverle
a6948218fb frame-ancestors CSP (#7677) 2025-06-18 22:20:17 +02:00
Alexandre Alapetite
b418b83bd4 SimplePie: Fix propagation of HTTP error codes (#7670)
* SimplePie: Fix propagation of HTTP error codes
fix https://github.com/FreshRSS/FreshRSS/issues/7038
https://github.com/FreshRSS/simplepie/pull/36
upstream https://github.com/simplepie/simplepie/pull/905

Co-authored-by: Edgar Alvarado <15692727+pe1uca@users.noreply.github.com>
2025-06-15 21:25:03 +02:00