mirror of
https://git.nadeko.net/Fijxu/invidious.git
synced 2025-12-15 01:25:08 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -91,7 +91,7 @@ module Invidious::Database::Playlists
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Salect
|
||||
# Select
|
||||
# -------------------
|
||||
|
||||
def select(*, id : String) : InvidiousPlaylist?
|
||||
@@ -113,7 +113,7 @@ module Invidious::Database::Playlists
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Salect (filtered)
|
||||
# Select (filtered)
|
||||
# -------------------
|
||||
|
||||
def select_like_iv(email : String) : Array(InvidiousPlaylist)
|
||||
@@ -213,7 +213,7 @@ module Invidious::Database::PlaylistVideos
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Salect
|
||||
# Select
|
||||
# -------------------
|
||||
|
||||
def select(plid : String, index : VideoIndex, offset, limit = 100) : Array(PlaylistVideo)
|
||||
|
||||
@@ -262,7 +262,7 @@ def get_referer(env, fallback = "/", unroll = true)
|
||||
end
|
||||
|
||||
referer = referer.request_target
|
||||
referer = "/" + referer.gsub(/[^\/?@&%=\-_.:,*0-9a-zA-Z]/, "").lstrip("/\\")
|
||||
referer = "/" + referer.gsub(/[^\/?@&%=\-_.:,*0-9a-zA-Z+]/, "").lstrip("/\\")
|
||||
|
||||
if referer == env.request.path
|
||||
referer = fallback
|
||||
|
||||
@@ -97,7 +97,7 @@ module Invidious::Routes::BeforeAll
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self'" + extra_connect_csp,
|
||||
"manifest-src 'self'",
|
||||
"media-src 'self' blob:" + extra_media_csp,
|
||||
"media-src 'self' blob:",
|
||||
"child-src 'self' blob:",
|
||||
"frame-src 'self'",
|
||||
"frame-ancestors " + frame_ancestors,
|
||||
@@ -162,6 +162,21 @@ module Invidious::Routes::BeforeAll
|
||||
preferences.locale = locale
|
||||
env.set "preferences", preferences
|
||||
|
||||
# Allow media resources to be loaded from google servers
|
||||
# TODO: check if *.youtube.com can be removed
|
||||
#
|
||||
# `!preferences.local` has to be checked after setting and
|
||||
# reading `preferences` from the "PREFS" cookie and
|
||||
# saved user preferences from the database, otherwise
|
||||
# `https://*.googlevideo.com:443 https://*.youtube.com:443`
|
||||
# will not be set in the CSP header if
|
||||
# `default_user_preferences.local` is set to true on the
|
||||
# configuration file, causing preference “Proxy Videos”
|
||||
# not to work while having it disabled and using medium quality.
|
||||
if CONFIG.disabled?("local") || !preferences.local
|
||||
env.response.headers["Content-Security-Policy"] = env.response.headers["Content-Security-Policy"].gsub("media-src", "media-src https://*.googlevideo.com:443 https://*.youtube.com:443")
|
||||
end
|
||||
|
||||
current_page = env.request.path
|
||||
if env.request.query
|
||||
query = HTTP::Params.parse(env.request.query.not_nil!)
|
||||
|
||||
@@ -21,9 +21,6 @@ module Invidious::Routes::Login
|
||||
account_type = env.params.query["type"]?
|
||||
account_type ||= "invidious"
|
||||
|
||||
captcha_type = env.params.query["captcha"]?
|
||||
captcha_type ||= "image"
|
||||
|
||||
templated "user/login"
|
||||
end
|
||||
|
||||
@@ -88,34 +85,14 @@ module Invidious::Routes::Login
|
||||
password = password.byte_slice(0, 55)
|
||||
|
||||
if CONFIG.captcha_enabled
|
||||
captcha_type = env.params.body["captcha_type"]?
|
||||
answer = env.params.body["answer"]?
|
||||
change_type = env.params.body["change_type"]?
|
||||
|
||||
if !captcha_type || change_type
|
||||
if change_type
|
||||
captcha_type = change_type
|
||||
end
|
||||
captcha_type ||= "image"
|
||||
|
||||
account_type = "invidious"
|
||||
|
||||
if captcha_type == "image"
|
||||
captcha = Invidious::User::Captcha.generate_image(HMAC_KEY)
|
||||
else
|
||||
captcha = Invidious::User::Captcha.generate_text(HMAC_KEY)
|
||||
end
|
||||
|
||||
return templated "user/login"
|
||||
end
|
||||
account_type = "invidious"
|
||||
captcha = Invidious::User::Captcha.generate_image(HMAC_KEY)
|
||||
|
||||
tokens = env.params.body.select { |k, _| k.match(/^token\[\d+\]$/) }.map { |_, v| v }
|
||||
|
||||
answer ||= ""
|
||||
captcha_type ||= "image"
|
||||
|
||||
case captcha_type
|
||||
when "image"
|
||||
if answer
|
||||
answer = answer.lstrip('0')
|
||||
answer = OpenSSL::HMAC.hexdigest(:sha256, HMAC_KEY, answer)
|
||||
|
||||
@@ -124,27 +101,8 @@ module Invidious::Routes::Login
|
||||
rescue ex
|
||||
return error_template(400, ex)
|
||||
end
|
||||
else # "text"
|
||||
answer = Digest::MD5.hexdigest(answer.downcase.strip)
|
||||
|
||||
if tokens.empty?
|
||||
return error_template(500, "Erroneous CAPTCHA")
|
||||
end
|
||||
|
||||
found_valid_captcha = false
|
||||
error_exception = Exception.new
|
||||
tokens.each do |tok|
|
||||
begin
|
||||
validate_request(tok, answer, env.request, HMAC_KEY, locale)
|
||||
found_valid_captcha = true
|
||||
rescue ex
|
||||
error_exception = ex
|
||||
end
|
||||
end
|
||||
|
||||
if !found_valid_captcha
|
||||
return error_template(500, error_exception)
|
||||
end
|
||||
else
|
||||
return templated "user/login"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -58,7 +58,11 @@ module Invidious::Routes::Search
|
||||
end
|
||||
|
||||
begin
|
||||
items = query.process
|
||||
if user
|
||||
items = query.process(user.as(User))
|
||||
else
|
||||
items = query.process
|
||||
end
|
||||
rescue ex : ChannelSearchException
|
||||
return error_template(404, "Unable to find channel with id of '#{HTML.escape(ex.channel)}'. Are you sure that's an actual channel id? It should look like 'UC4QobU6STFB0P71PMvOGN5A'.")
|
||||
rescue ex
|
||||
|
||||
@@ -4,8 +4,6 @@ struct Invidious::User
|
||||
module Captcha
|
||||
extend self
|
||||
|
||||
private TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com")
|
||||
|
||||
def generate_image(key)
|
||||
second = Random::Secure.rand(12)
|
||||
second_angle = second * 30
|
||||
@@ -60,19 +58,5 @@ struct Invidious::User
|
||||
tokens: {generate_response(answer, {":login"}, key, use_nonce: true)},
|
||||
}
|
||||
end
|
||||
|
||||
def generate_text(key)
|
||||
response = make_client(TEXTCAPTCHA_URL, &.get("/github.com/iv.org/invidious.json").body)
|
||||
response = JSON.parse(response)
|
||||
|
||||
tokens = response["a"].as_a.map do |answer|
|
||||
generate_response(answer.as_s, {":login"}, key, use_nonce: true)
|
||||
end
|
||||
|
||||
return {
|
||||
question: response["q"].as_s,
|
||||
tokens: tokens,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,91 +11,7 @@
|
||||
<table id="jslicense-labels1">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/_helpers.js?v=<%= ASSET_COMMIT %>">_helpers.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/_helpers.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/handlers.js?v=<%= ASSET_COMMIT %>">handlers.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/handlers.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/community.js?v=<%= ASSET_COMMIT %>">community.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/community.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/embed.js?v=<%= ASSET_COMMIT %>">embed.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/embed.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/notifications.js?v=<%= ASSET_COMMIT %>">notifications.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/notifications.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/player.js?v=<%= ASSET_COMMIT %>">player.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/player.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/silvermine-videojs-quality-selector.min.js?v=<%= ASSET_COMMIT %>">silvermine-videojs-quality-selector.min.js</a>
|
||||
<a href="/js/silvermine-videojs-quality-selector.min.js?v=<%= ASSET_COMMIT %>">silvermine-videojs-quality-selector.min.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@@ -121,34 +37,6 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/subscribe_widget.js?v=<%= ASSET_COMMIT %>">subscribe_widget.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/subscribe_widget.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/themes.js?v=<%= ASSET_COMMIT %>">themes.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/themes.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/videojs/videojs-contrib-quality-levels/videojs-contrib-quality-levels.js?v=<%= ASSET_COMMIT %>">videojs-contrib-quality-levels.js</a>
|
||||
@@ -289,19 +177,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/watch.js?v=<%= ASSET_COMMIT %>">watch.js</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="/<%= JS_PATH %>/watch.js?v=<%= ASSET_COMMIT %>"><%= translate(locale, "source") %></a>
|
||||
</td>
|
||||
</tr>
|
||||
<%- {% for row in run("../../../scripts/generate_js_licenses.cr").stringify.split('\n') %} %>
|
||||
<%-= {{row.id}} -%>
|
||||
<% {% end %} -%>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -25,44 +25,17 @@
|
||||
<% end %>
|
||||
|
||||
<% if captcha %>
|
||||
<% case captcha_type when %>
|
||||
<% when "image" %>
|
||||
<% captcha = captcha.not_nil! %>
|
||||
<img style="width:50%" src='<%= captcha[:question] %>'/>
|
||||
<% captcha[:tokens].each_with_index do |token, i| %>
|
||||
<input type="hidden" name="token[<%= i %>]" value="<%= HTML.escape(token) %>">
|
||||
<% end %>
|
||||
<input type="hidden" name="captcha_type" value="image">
|
||||
<label for="answer"><%= translate(locale, "Time (h:mm:ss):") %></label>
|
||||
<input type="text" name="answer" type="text" placeholder="h:mm:ss">
|
||||
<% else # "text" %>
|
||||
<% captcha = captcha.not_nil! %>
|
||||
<% captcha[:tokens].each_with_index do |token, i| %>
|
||||
<input type="hidden" name="token[<%= i %>]" value="<%= HTML.escape(token) %>">
|
||||
<% end %>
|
||||
<input type="hidden" name="captcha_type" value="text">
|
||||
<label for="answer"><%= captcha[:question] %></label>
|
||||
<input type="text" name="answer" type="text" placeholder="<%= translate(locale, "Answer") %>">
|
||||
<% captcha = captcha.not_nil! %>
|
||||
<img style="width:50%" src='<%= captcha[:question] %>'/>
|
||||
<% captcha[:tokens].each_with_index do |token, i| %>
|
||||
<input type="hidden" name="token[<%= i %>]" value="<%= HTML.escape(token) %>">
|
||||
<% end %>
|
||||
<label for="answer"><%= translate(locale, "Time (h:mm:ss):") %></label>
|
||||
<input type="text" name="answer" type="text" placeholder="h:mm:ss">
|
||||
|
||||
<button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
|
||||
<%= translate(locale, "Register") %>
|
||||
</button>
|
||||
|
||||
<% case captcha_type when %>
|
||||
<% when "image" %>
|
||||
<label>
|
||||
<button type="submit" name="change_type" class="pure-button pure-button-primary" value="text">
|
||||
<%= translate(locale, "Text CAPTCHA") %>
|
||||
</button>
|
||||
</label>
|
||||
<% else # "text" %>
|
||||
<label>
|
||||
<button type="submit" name="change_type" class="pure-button pure-button-primary" value="image">
|
||||
<%= translate(locale, "Image CAPTCHA") %>
|
||||
</button>
|
||||
</label>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
|
||||
<%= translate(locale, "Sign In") %>/<%= translate(locale, "Register") %>
|
||||
|
||||
@@ -132,7 +132,7 @@ private module Parsers
|
||||
badges = VideoBadges::None
|
||||
item_contents["badges"]?.try &.as_a.each do |badge|
|
||||
b = badge["metadataBadgeRenderer"]
|
||||
case b["label"].as_s
|
||||
case b["label"]?.try &.as_s
|
||||
when "LIVE"
|
||||
badges |= VideoBadges::LiveNow
|
||||
when "New"
|
||||
|
||||
Reference in New Issue
Block a user