3396 Commits

Author SHA1 Message Date
Richard Lora
ed87890e85
Merge branch 'master' into optional-disable-api-features 2026-05-10 19:36:20 -04:00
Fijxu
9eda6e5bc4
chore: lint api/v1/channels.cr (#5693) 2026-04-25 16:57:45 -04:00
Fijxu
73c749f13f
Encapsulate helpers constants and functions inside it's own Helpers module (#5639)
It encapsulates all related code from helpers.cr into it's own module.
2026-04-25 16:57:33 -04:00
Fijxu
bc64cd9b67
Encapsulate translation constants and functions inside it's own module (#5637)
It encapsulates all related code from translation into it's own module.

Required for the migration to the crystal stdlib logger: https://github.com/iv-org/invidious/pull/5426
2026-04-25 16:55:55 -04:00
ChunkyProgrammer
606467c693
Playlists: fix parsing error when some videos are paid for in a course (#5207)
* Playlists: fix parsing error when some videos are paid for in a course

* Remove redundant casting to string

fix rebase error

Co-Authored-By: syeopite <70992037+syeopite@users.noreply.github.com>

* Fix rebase issues

---------

Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
2026-04-09 14:52:03 +02:00
NorkzYT
7ca2bbd768 fix(before_all): halt response after rendering disabled page error
The return from before_all did not stop the route handler from
executing. The trending/popular/hashtag routes still ran and
overwrote the 403 response. Now set a halted flag and use Kemal
halt in the before_all block to prevent route handler execution.

Error page now renders with the full Invidious theme (dark mode,
navbar, CSS) matching the rest of the UI.
2026-03-23 01:59:38 +00:00
NorkzYT
8cd5f0f652 fix(search_homepage): center subscription hint text under search bar 2026-03-23 00:16:45 +00:00
NorkzYT
58ced289d3 fix(playlists): prevent duplicate videos in the same playlist
Check if the video already exists in the playlist before inserting.
Uses the existing select_index() query. Returns 409 via the API and
silently redirects back on the web UI.

Applied to both the web route (playlist_ajax) and the API v1 route
(POST /api/v1/auth/playlists/:plid/videos).
2026-03-23 00:11:25 +00:00
NorkzYT
0eb941f498 feat(search): subscription-only search mode when YouTube search is disabled
When pages_enabled.search is false, instead of blocking search entirely,
the search bar now searches within the user's subscriptions and saved
playlists only. YouTube's search API is never called.

Changes:
- routes/search.cr: detect search_disabled, force subscription+playlist
  search for logged-in users, 403 for anonymous users
- search/processors.cr: new subscriptions_and_playlists() method that
  queries both the subscription materialized view and playlist_videos
  table, merges and deduplicates results
- before_all.cr: let /search through to the route handler (APIs still
  blocked), keep /hashtag/* blocked
- search_box.ecr: dynamic placeholder ("Search subscriptions & playlists")
- search_homepage.ecr: hint text when in subscription-only mode
- search.ecr: hide YouTube filters, show lock icon + notice, custom
  empty-results message
- template.ecr: always show search bar (subscription search needs it)
- en-US.json: 6 new locale strings for subscription-only search UX
2026-03-22 22:27:17 +00:00
NorkzYT
562389bc6d fix(pages_enabled): hide search UI and block all search routes when disabled
- Hide navbar search box when CONFIG.page_enabled?("search") is false
- Keep Invidious logo visible with proper width when search bar is hidden
- Hide search widget on search_homepage when search is disabled
- Block /results, /api/v1/search/suggestions in before_all guard
- Block /hashtag/* and /api/v1/hashtag/* when search is disabled
2026-03-22 21:42:11 +00:00
NorkzYT
ea36b2ba4b fix(preferences): unchecked pages_enabled checkboxes now persist correctly
HTML checkboxes send no value when unchecked, so the fallback
"|| \"on\"" always re-enabled popular/trending/search on save.
Changed default to "off" to match the pattern used by captcha_enabled,
login_enabled, and other checkbox toggles in the same handler.
2026-03-22 21:10:55 +00:00
Richard Lora
bd6dd9cb55 feat: add search_page_disabled locale + preferences page filtering + debug config route
- Fix kemal_static_file_handler directory_listing to use Path types (Crystal API compat)
- Add missing search_page_disabled translation key to en-US.json
- Filter preferences default_home options based on pages_enabled config
- Add admin-only /debug_config route for verifying configuration state
2026-02-28 19:01:35 -05:00
Richard Lora
2933c7e2f4
Merge branch 'master' into optional-disable-api-features 2026-02-28 18:48:26 -05:00
Ashley :3
21d0d1041a
Remove noreferrer since youtube now requires referrers on embeds (#5642)
* Remove noreferer since youtube now requires referers on embeds

* Update src/invidious/views/watch.ecr

---------

Co-authored-by: Fijxu <fijxu@nadeko.net>
2026-02-23 21:36:12 -03:00
Fijxu
fda8d1b528
Remove trailing whitespaces from codebase (#5634)
Removes trailing whitespaces found across the codebase using `find . -type f -exec grep -lE ' +$' {} +`

[skip ci]
2026-02-19 14:28:22 -03:00
Jeroen Boersma
e7f8b15b21
Add title listen button time updates (#5625)
When switching between Listen and Watching the timestamp in the url of
the listen of watch button is now updated automatically.

This means if you switch between listening and viewing you keep in sync
with time.
2026-02-16 16:39:44 -03:00
Fijxu
60c31e3069
Remove sort by rating and date in video search filters (#5629)
* Remove sort by rating and date in video search filters

Closes https://github.com/iv-org/invidious/issues/5626

* Remove check of protobug generation of rating and date sort filters in Invidious spec
2026-02-16 14:06:06 -03:00
Fijxu
29c29f7c8d Update src/invidious/routes/routes.cr
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-06 18:50:36 +01:00
Fijxu
067a426235 refactor: Move top level constants to it's own modules 2026-02-06 18:50:36 +01:00
Samantaz Fox
ffd9f4b112 pages/watch: HTML escape 'action' in download widget
Caught in the review of PR 5224, but forgot to click on "send review" in time.
I realized that too late, after the PR was already merged.
2026-02-06 18:44:37 +01:00
Fijxu
0ee92e3298 Update src/invidious/routes/before_all.cr
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-06 18:35:20 +01:00
Fijxu
a3a97ccf07 Only generate companion CSP one time to reuse it 2026-02-06 18:35:20 +01:00
ThatMatrix
ce9494133d fix(user/imports.cr): double header removal caused first video to be skipped 2026-02-06 18:33:58 +01:00
ThatMatrix
e4beb00413 fix(user/imports.cr): splitting error fixed 2026-02-06 18:33:58 +01:00
ThatMatrix
471857ce8b Fix(user/importers): Fixed typos 2026-02-06 18:33:58 +01:00
ThatMatrix
7be6fbd75c Fix(user/importers): Fixed youtube csv playlist importer 2026-02-06 18:33:58 +01:00
Cameron Radmore
84a699f7b7
Playlist API: return empty author url if ucid is empty (#5618) 2026-02-05 11:59:27 -03:00
Cameron Radmore
864893f4c7
Channels: parse pronouns and display them on channel page (#5617) 2026-02-05 11:58:52 -03:00
Cameron Radmore
ecbc21b067
playlist: parse playlist thumbnails for topic autogenerated playlists (#5616) 2026-02-04 12:57:16 -03:00
Fijxu
a9f812799c
fix: add missing embedded protobuf message in continuation token for channel videos (#5614)
* fix: add missing embedded protobuf message in continuation token for channel videos

* fix: add missing embedded protobuf message in continuation token for channel shorts

* fix: add missing embedded protobuf message in continuation token for channel livestreams
2026-02-03 16:18:15 -03:00
Fijxu
b521e3be6c
chore: Do not convert thin_mode preference to string to compare it (#5568) 2026-01-30 18:01:16 -03:00
Fijxu
abb0aa436c
Fix thin_mode preference for channel community page (#5567)
thin_mode only took in account the query param because
env.get("preferences").as(Preferences).thin_mode returned a boolean and
not a string to be able to compare it with the string `"true"`
2026-01-30 18:01:04 -03:00
Fijxu
344bc2d8e9
Strip unwanted headers from response headers in images and videoplayback (#5595)
Image responses contained the following unwanted headers that should not
be passed to the clients:

```
"Cross-Origin-Resource-Policy"
["cross-origin"]
"Cross-Origin-Opener-Policy-Report-Only"
["same-origin; report-to=\"youtube\""]
"Report-To"
["{\"group\":\"youtube\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube\"}]}"]
"Timing-Allow-Origin"
["*"]
```
2026-01-16 19:39:44 -03:00
Fijxu
5f84a5b353
Generate companion check id one time and add missing companion check id on captions (#5575)
* Only generate companion check id one time

* Add missing check id for companion captions
2025-12-22 17:14:59 +01:00
Fijxu
f7a31aa3de
fix lint 2025-12-21 00:50:37 -03:00
Jeroen Boersma
dbbaf51f1f
Allow downloading via companion (#5561)
* Allow downloading via companion

* post request where not proxied for the download companion which made
  it impossible to download with the companion enabled

* Re-apply Channel to Channels rename which was pulled in

* Update src/invidious/routes/companion.cr

* doc: better comments for each route

---------

Co-authored-by: Fijxu <fijxu@nadeko.net>
Co-authored-by: Émilien (perso) <4016501+unixfox@users.noreply.github.com>
2025-12-19 15:09:22 +01:00
Fijxu
bf17d53068
Replace deprecated blocking property of Socket (#5538)
* Replace deprecated `blocking` property of `Socket`

This replaces the deprecated argument `blocking` and uses
`Socket.set_blocking(fd, value)` instead.

Fixes a warning in the compiler

https://github.com/crystal-lang/crystal/pull/16033

* Upgrade to upstream

* chore: only Socket.set_blocking for > 1.18

---------

Co-authored-by: Emilien <4016501+unixfox@users.noreply.github.com>
2025-12-19 14:59:42 +01:00
syeopite
1f5685ef92 Reduce indent in StaticAssetsHandler#serve_file 2025-12-19 12:35:00 +01:00
syeopite
21049518d6 Improve cache size check to be more performant
Summing the sizes of each cached file every time is very inefficient.
Instead we can simply store the cache size in an constant and increase
it everytime a file is added into the cache.
2025-12-19 12:35:00 +01:00
syeopite
89a0761a19 Fix Ameba Lint/UselessAssign 2025-12-19 12:35:00 +01:00
syeopite
9e482b4807 Add specs for the new StaticAssetsHandler 2025-12-19 12:35:00 +01:00
syeopite
6fd1cb3585 Compare against 1.17.0-dev until full release 2025-12-19 12:35:00 +01:00
syeopite
ddfbed68f7 Simplify StaticAssetsHandler implementation
Overriding `#call` or patching out `serve_file_compressed` provides
only minimal benefits over the ease of maintenance granted by only
overriding what we need to for the caching behavior.
2025-12-19 12:35:00 +01:00
syeopite
d2be57a454 Replace Kemal::StaticFileHandler on Crystal < 1.17.0
Kemal's subclass of the stdlib `HTTP::StaticFileHandler` is not as
maintained as its parent, and so misses out on many enhancements and bug
fixes from upstream, which unfortunately also includes the patches for
security vulnerabilities...

Though this isn't necessarily Kemal's fault since the bulk of the stdlib
handler's logic was done in a single big method, making any changes hard
to maintain. This was fixed in Crystal 1.17.0 where the handler
was refactored into many private methods, making it easier for an
inheriting type to implement custom behaviors while still leveraging
much of the pre-existing code.

Since we don't actually use any of the Kemal specific features added by
`Kemal::StaticFileHandler`, there really isn't a reason to not just
create a new handler based upon the stdlib implementation instead which
will address the problems mentioned above.

This PR implements a new handler which inherits from the stdlib variant
and overrides the helper methods added in Crystal 1.17.0 to add the
caching behavior with minimal code changes. Since this new handler
depends on the code in Crystal 1.17.0, it will only be applied on
versions greater than or equal to 1.17.0. On older versions we'll
fallback to the current monkey patched `Kemal::StaticFileHandler`
2025-12-19 12:35:00 +01:00
Fijxu
aba31a8e20
Set Kemal max_request_line_size to 16384 for large channel continuation query parameters. (#5566)
* feat: Add configurable max_request_line_size to handle long URLs

This commit adds a new configuration option `max_request_line_size` that allows
users to increase the HTTP request line size limit. This is particularly useful
for handling very long continuation tokens that can cause 414 (URI Too Long) errors.

Changes:
- Add `max_request_line_size` property to Config class
- Configure Kemal server to use the custom limit if specified
- Document the option in config.example.yml with recommendations
- Add examples in docker-compose.yml for both YAML and env var configuration

The default behavior remains unchanged (8KB limit) unless explicitly configured.
This provides a solution for users experiencing 414 errors without affecting
existing installations.

* Hardcode max_request_line_size to 16384

---------

Co-authored-by: Sunghyun Kim <hello@sunghyun.me>
2025-12-15 08:21:55 +01:00
Sebastian Hädrich
994c25de2e
Add link to GitHub release/tag/commit in footer (#4702)
* Add link to GitHub release/tag/commit in footer

* Only show tag if there is one

Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>

---------

Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
2025-12-14 19:30:52 -03:00
Fijxu
65463333f3
Display "Erroneous CAPTCHA" for invalid captchas (#5508) 2025-12-11 17:28:20 -03:00
Fijxu
ef2290c1fd
Fix channel name overflow (#5553) 2025-12-06 20:20:42 -03:00
Fijxu
3944d2490c
Fix trending page by leaving livestream and gaming trending pages (#5555)
The livestream trending page is now the default.

Adds `content_container = special_category_container["gridRenderer"]?` in the `CategoryRendererParser`
needed for the gaming trending page. The JSON structure of the gaming
trending page looked like this:

```json
"contents": {
 "twoColumnBrowseResultsRenderer": {
  "tabs": [
   {
    "tabRenderer": {
     "selected": true,
     "content": {
      "sectionListRenderer": {
       "contents": [
        {
         "itemSectionRenderer": {
          "contents": [
           {
            "shelfRenderer": {
             "title": {
              "runs": [
               {
                "text": "Trending videos"
               }
              ]
             },
             "content": {
              "gridRenderer": { // <- This was added to the CategoryRendererParser
               "items": [
                {
                 "gridVideoRenderer": {
                  "videoId": "sTWztaLjD20",
                  // More video data
                  // ...
                 }
                }
               ]
              }
             }
            }
           }
          ]
         }
        }
       ]
      }
     }
    }
   }
  ]
 }
}
```

Thanks to
ae2755bf71/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeTrendingGamingVideosExtractor.java (L11-L13)
for the `browse_id` and `params` needed for the gaming trending page.
2025-12-06 20:19:38 -03:00
Fijxu
a7935bc378
fix: restore dmca_content functionality (#5228)
* fix: restore dmca_content functionality

This restores (or adds) the functionality of the `dmca_content` config
option that at this date, has been unused and makes no effect.

* only disable download widget for dmca video ids
2025-12-06 17:15:25 -03:00