summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOmar Roth <omarroth@hotmail.com>2019-02-16 09:57:09 -0600
committerGitHub <noreply@github.com>2019-02-16 09:57:09 -0600
commit6a8a49d8efec065d7d2745d6bc66a4319546798e (patch)
treebcc1806159e28ba6d7ddd8fdd8ecf492a39d11e4 /src
parent7e2954c325d7ee0303de3197cdfebd616bf0a9d5 (diff)
parent27663b10a256cd3ddb31b3b5e013daeaf577155f (diff)
downloadinvidious-6a8a49d8efec065d7d2745d6bc66a4319546798e.tar.gz
invidious-6a8a49d8efec065d7d2745d6bc66a4319546798e.tar.bz2
invidious-6a8a49d8efec065d7d2745d6bc66a4319546798e.zip
Merge branch 'master' into 347-screenshots
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr58
-rw-r--r--src/invidious/channels.cr128
-rw-r--r--src/invidious/helpers/helpers.cr113
-rw-r--r--src/invidious/mixes.cr5
-rw-r--r--src/invidious/playlists.cr111
-rw-r--r--src/invidious/users.cr33
-rw-r--r--src/invidious/views/components/subscribe_widget_script.ecr4
7 files changed, 282 insertions, 170 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 72ac8caf..222b82ae 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -163,9 +163,10 @@ before_all do |env|
# Invidious users only have SID
if !env.request.cookies.has_key? "SSID"
- user = PG_DB.query_one?("SELECT * FROM users WHERE $1 = ANY(id)", sid, as: User)
+ email = PG_DB.query_one?("SELECT email FROM session_ids WHERE id = $1", sid, as: String)
- if user
+ if email
+ user = PG_DB.query_one("SELECT * FROM users WHERE email = $1", email, as: User)
challenge, token = create_response(user.email, "sign_out", HMAC_KEY, PG_DB, 1.week)
env.set "challenge", challenge
@@ -177,7 +178,7 @@ before_all do |env|
end
else
begin
- user = get_user(sid, headers, PG_DB, false)
+ user, sid = get_user(sid, headers, PG_DB, false)
challenge, token = create_response(user.email, "sign_out", HMAC_KEY, PG_DB, 1.week)
env.set "challenge", challenge
@@ -312,7 +313,7 @@ get "/watch" do |env|
end
if watched && !watched.includes? id
- PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE $2 = id", [id], user.as(User).id)
+ PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.as(User).email)
end
if nojs
@@ -818,7 +819,7 @@ post "/login" do |env|
# Prefer Authenticator app and SMS over unsupported protocols
if challenge_results[0][-1][0][0][8] != 6 && challenge_results[0][-1][0][0][8] != 9
tfa = challenge_results[0][-1][0].as_a.select { |auth_type| auth_type[8] == 6 || auth_type[8] == 9 }[0]
- select_challenge = "[#{challenge_results[0][-1][0].as_a.index(tfa).not_nil!}]"
+ select_challenge = "[2,null,null,null,[#{tfa[8]}]]"
tl = challenge_results[1][2]
@@ -880,7 +881,7 @@ post "/login" do |env|
sid = login.cookies["SID"].value
- user = get_user(sid, headers, PG_DB)
+ user, sid = get_user(sid, headers, PG_DB)
# We are now logged in
@@ -986,7 +987,7 @@ post "/login" do |env|
if Crypto::Bcrypt::Password.new(user.password.not_nil!) == password
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- PG_DB.exec("UPDATE users SET id = id || $1 WHERE LOWER(email) = LOWER($2)", [sid], email)
+ PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", sid, email, Time.now)
if Kemal.config.ssl || CONFIG.https_only
secure = true
@@ -1024,13 +1025,14 @@ post "/login" do |env|
end
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = create_user(sid, email, password)
+ user, sid = create_user(sid, email, password)
user_array = user.to_a
- user_array[5] = user_array[5].to_json
+ user_array[4] = user_array[4].to_json
args = arg_array(user_array)
PG_DB.exec("INSERT INTO users VALUES (#{args})", user_array)
+ PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", sid, email, Time.now)
view_name = "subscriptions_#{sha256(user.email)[0..7]}"
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS \
@@ -1078,7 +1080,7 @@ get "/signout" do |env|
user = env.get("user").as(User)
sid = env.get("sid").as(String)
- PG_DB.exec("UPDATE users SET id = array_remove(id, $1) WHERE email = $2", sid, user.email)
+ PG_DB.exec("DELETE FROM session_ids * WHERE id = $1", sid)
env.request.cookies.each do |cookie|
cookie.expires = Time.new(1990, 1, 1)
@@ -1252,7 +1254,7 @@ get "/mark_watched" do |env|
if user
user = user.as(User)
if !user.watched.includes? id
- PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE $2 = id", [id], user.id)
+ PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.email)
end
end
@@ -1347,9 +1349,10 @@ get "/subscription_manager" do |env|
locale = LOCALES[env.get("locale").as(String)]?
user = env.get? "user"
+ sid = env.get? "sid"
referer = get_referer(env, "/")
- if !user
+ if !user && !sid
next env.redirect referer
end
@@ -1360,7 +1363,7 @@ get "/subscription_manager" do |env|
headers = HTTP::Headers.new
headers["Cookie"] = env.request.headers["Cookie"]
- user = get_user(user.id[0], headers, PG_DB)
+ user, sid = get_user(sid, headers, PG_DB)
end
action_takeout = env.params.query["action_takeout"]?.try &.to_i?
@@ -1370,14 +1373,7 @@ get "/subscription_manager" do |env|
format = env.params.query["format"]?
format ||= "rss"
- subscriptions = [] of InvidiousChannel
- user.subscriptions.each do |ucid|
- begin
- subscriptions << get_channel(ucid, PG_DB, false, false)
- rescue ex
- next
- end
- end
+ subscriptions = PG_DB.query_all("SELECT * FROM channels WHERE id = ANY('{#{user.subscriptions.join(",")}}')", as: InvidiousChannel)
subscriptions.sort_by! { |channel| channel.author.downcase }
if action_takeout
@@ -1756,10 +1752,12 @@ get "/feed/subscriptions" do |env|
locale = LOCALES[env.get("locale").as(String)]?
user = env.get? "user"
+ sid = env.get? "sid"
referer = get_referer(env)
if user
user = user.as(User)
+ sid = sid.as(String)
preferences = user.preferences
if preferences.unseen_only
@@ -1771,7 +1769,7 @@ get "/feed/subscriptions" do |env|
headers["Cookie"] = env.request.headers["Cookie"]
if !user.password
- user = get_user(user.id[0], headers, PG_DB)
+ user, sid = get_user(sid, headers, PG_DB)
end
max_results = preferences.max_results
@@ -3033,7 +3031,8 @@ end
ucid = env.params.url["ucid"]
page = env.params.query["page"]?.try &.to_i?
page ||= 1
- sort_by = env.params.query["sort_by"]?.try &.downcase
+ sort_by = env.params.query["sort"]?.try &.downcase
+ sort_by ||= env.params.query["sort_by"]?.try &.downcase
sort_by ||= "newest"
begin
@@ -3438,7 +3437,7 @@ get "/api/v1/mixes/:rdid" do |env|
rdid = env.params.url["rdid"]
continuation = env.params.query["continuation"]?
- continuation ||= rdid.lchop("RD")
+ continuation ||= rdid.lchop("RD")[0, 11]
format = env.params.query["format"]?
format ||= "json"
@@ -3662,6 +3661,8 @@ get "/latest_version" do |env|
id = env.params.query["id"]?
itag = env.params.query["itag"]?
+ region = env.params.query["region"]?
+
local = env.params.query["local"]?
local ||= "false"
local = local == "true"
@@ -3670,7 +3671,7 @@ get "/latest_version" do |env|
halt env, status_code: 400
end
- video = get_video(id, PG_DB, proxies)
+ video = get_video(id, PG_DB, proxies, region: region)
fmt_stream = video.fmt_stream(decrypt_function)
adaptive_fmts = video.adaptive_fmts(decrypt_function)
@@ -3943,14 +3944,13 @@ end
error 500 do |env|
error_message = <<-END_HTML
- Looks like you've found a bug in Invidious. Feel free to open a new issue
- <a href="https://github.com/omarroth/invidious/issues/github.com/omarroth/invidious">
+ Looks like you've found a bug in Invidious. Feel free to open a new issue
+ <a href="https://github.com/omarroth/invidious/issues">
here
</a>
or send an email to
<a href="mailto:omarroth@protonmail.com">
- omarroth@protonmail.com
- </a>.
+ omarroth@protonmail.com</a>.
END_HTML
templated "error"
end
diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr
index ccaf2487..b6692919 100644
--- a/src/invidious/channels.cr
+++ b/src/invidious/channels.cr
@@ -260,6 +260,132 @@ def produce_channel_videos_url(ucid, page = 1, auto_generated = nil, sort_by = "
return url
end
+def produce_channel_playlists_url(ucid, cursor, sort = "newest", auto_generated = false)
+ if !auto_generated
+ cursor = Base64.urlsafe_encode(cursor, false)
+ end
+
+ meta = IO::Memory.new
+
+ if auto_generated
+ meta.write(Bytes[0x08, 0x0a])
+ end
+
+ meta.write(Bytes[0x12, 0x09])
+ meta.print("playlists")
+
+ if auto_generated
+ meta.write(Bytes[0x20, 0x32])
+ else
+ # TODO: Look at 0x01, 0x00
+ case sort
+ when "oldest", "oldest_created"
+ meta.write(Bytes[0x18, 0x02])
+ when "newest", "newest_created"
+ meta.write(Bytes[0x18, 0x03])
+ when "last", "last_added"
+ meta.write(Bytes[0x18, 0x04])
+ end
+
+ meta.write(Bytes[0x20, 0x01])
+ end
+
+ meta.write(Bytes[0x30, 0x02])
+ meta.write(Bytes[0x38, 0x01])
+ meta.write(Bytes[0x60, 0x01])
+ meta.write(Bytes[0x6a, 0x00])
+
+ meta.write(Bytes[0x7a, cursor.size])
+ meta.print(cursor)
+
+ meta.write(Bytes[0xb8, 0x01, 0x00])
+
+ meta.rewind
+ meta = Base64.urlsafe_encode(meta.to_slice)
+ meta = URI.escape(meta)
+
+ continuation = IO::Memory.new
+ continuation.write(Bytes[0x12, ucid.size])
+ continuation.print(ucid)
+
+ continuation.write(Bytes[0x1a])
+ continuation.write(write_var_int(meta.size))
+ continuation.print(meta)
+
+ continuation.rewind
+ continuation = continuation.gets_to_end
+
+ wrapper = IO::Memory.new
+ wrapper.write(Bytes[0xe2, 0xa9, 0x85, 0xb2, 0x02])
+ wrapper.write(write_var_int(continuation.size))
+ wrapper.print(continuation)
+ wrapper.rewind
+
+ wrapper = Base64.urlsafe_encode(wrapper.to_slice)
+ wrapper = URI.escape(wrapper)
+
+ url = "/browse_ajax?continuation=#{wrapper}&gl=US&hl=en"
+
+ return url
+end
+
+def extract_channel_playlists_cursor(url, auto_generated)
+ wrapper = HTTP::Params.parse(URI.parse(url).query.not_nil!)["continuation"]
+
+ wrapper = URI.unescape(wrapper)
+ wrapper = Base64.decode(wrapper)
+
+ # 0xe2 0xa9 0x85 0xb2 0x02
+ wrapper += 5
+
+ continuation_size = read_var_int(wrapper[0, 4])
+ wrapper += write_var_int(continuation_size).size
+ continuation = wrapper[0, continuation_size]
+
+ # 0x12
+ continuation += 1
+ ucid_size = continuation[0]
+ continuation += 1
+ ucid = continuation[0, ucid_size]
+ continuation += ucid_size
+
+ # 0x1a
+ continuation += 1
+ meta_size = read_var_int(continuation[0, 4])
+ continuation += write_var_int(meta_size).size
+ meta = continuation[0, meta_size]
+ continuation += meta_size
+
+ meta = String.new(meta)
+ meta = URI.unescape(meta)
+ meta = Base64.decode(meta)
+
+ # 0x12 0x09 playlists
+ meta += 11
+
+ until meta[0] == 0x7a
+ tag = read_var_int(meta[0, 4])
+ meta += write_var_int(tag).size
+ value = meta[0]
+ meta += 1
+ end
+
+ # 0x7a
+ meta += 1
+ cursor_size = meta[0]
+ meta += 1
+ cursor = meta[0, cursor_size]
+
+ cursor = String.new(cursor)
+
+ if !auto_generated
+ cursor = URI.unescape(cursor)
+ cursor = Base64.decode_string(cursor)
+ end
+
+ return cursor
+end
+
def get_about_info(ucid, locale)
client = make_client(YT_URL)
@@ -290,7 +416,7 @@ def get_about_info(ucid, locale)
sub_count ||= 0
author = about.xpath_node(%q(//span[contains(@class,"qualified-channel-title-text")]/a)).not_nil!.content
- ucid = about.xpath_node(%q(//link[@rel="canonical"])).not_nil!["href"].split("/")[-1]
+ ucid = about.xpath_node(%q(//meta[@itemprop="channelId"])).not_nil!["content"]
# Auto-generated channels
# https://support.google.com/youtube/answer/2579942
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 942757c3..45ebc4dd 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -166,35 +166,33 @@ def extract_videos(nodeset, ucid = nil)
videos.map { |video| video.as(SearchVideo) }
end
-def extract_items(nodeset, ucid = nil)
+def extract_items(nodeset, ucid = nil, author_name = nil)
# TODO: Make this a 'common', so it makes more sense to be used here
items = [] of SearchItem
nodeset.each do |node|
- anchor = node.xpath_node(%q(.//h3[contains(@class,"yt-lockup-title")]/a))
+ anchor = node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
if !anchor
next
end
+ title = anchor.content.strip
+ id = anchor["href"]
if anchor["href"].starts_with? "https://www.googleadservices.com"
next
end
anchor = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-byline")]/a))
- if !anchor
- author = ""
- author_id = ""
- else
+ if anchor
author = anchor.content.strip
author_id = anchor["href"].split("/")[-1]
end
- anchor = node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
- if !anchor
- next
- end
- title = anchor.content.strip
- id = anchor["href"]
+ author ||= author_name
+ author_id ||= ucid
+
+ author ||= ""
+ author_id ||= ""
description_html = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-description")]))
description_html, description = html_to_content(description_html)
@@ -354,3 +352,94 @@ def extract_items(nodeset, ucid = nil)
return items
end
+
+def extract_shelf_items(nodeset, ucid = nil, author_name = nil)
+ items = [] of SearchPlaylist
+
+ nodeset.each do |shelf|
+ shelf_anchor = shelf.xpath_node(%q(.//h2[contains(@class, "branded-page-module-title")]))
+
+ if !shelf_anchor
+ next
+ end
+
+ title = shelf_anchor.xpath_node(%q(.//span[contains(@class, "branded-page-module-title-text")]))
+ if title
+ title = title.content.strip
+ end
+ title ||= ""
+
+ id = shelf_anchor.xpath_node(%q(.//a)).try &.["href"]
+ if !id
+ next
+ end
+
+ is_playlist = false
+ videos = [] of SearchPlaylistVideo
+
+ shelf.xpath_nodes(%q(.//ul[contains(@class, "yt-uix-shelfslider-list")]/li)).each do |child_node|
+ type = child_node.xpath_node(%q(./div))
+ if !type
+ next
+ end
+
+ case type["class"]
+ when .includes? "yt-lockup-video"
+ is_playlist = true
+
+ anchor = child_node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
+ if anchor
+ video_title = anchor.content.strip
+ video_id = HTTP::Params.parse(URI.parse(anchor["href"]).query.not_nil!)["v"]
+ end
+ video_title ||= ""
+ video_id ||= ""
+
+ anchor = child_node.xpath_node(%q(.//span[@class="video-time"]))
+ if anchor
+ length_seconds = decode_length_seconds(anchor.content)
+ end
+ length_seconds ||= 0
+
+ videos << SearchPlaylistVideo.new(
+ video_title,
+ video_id,
+ length_seconds
+ )
+ when .includes? "yt-lockup-playlist"
+ anchor = child_node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
+ if anchor
+ playlist_title = anchor.content.strip
+ params = HTTP::Params.parse(URI.parse(anchor["href"]).query.not_nil!)
+ plid = params["list"]
+ end
+ playlist_title ||= ""
+ plid ||= ""
+
+ items << SearchPlaylist.new(
+ playlist_title,
+ plid,
+ author_name,
+ ucid,
+ 50,
+ Array(SearchPlaylistVideo).new
+ )
+ end
+ end
+
+ if is_playlist
+ plid = HTTP::Params.parse(URI.parse(id).query.not_nil!)["list"]
+
+ items << SearchPlaylist.new(
+ title,
+ plid,
+ author_name,
+ ucid,
+ videos.size,
+ videos
+ )
+ end
+ end
+
+ return items
+end
diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr
index a56f468a..a3ada869 100644
--- a/src/invidious/mixes.cr
+++ b/src/invidious/mixes.cr
@@ -52,7 +52,10 @@ def fetch_mix(rdid, video_id, cookies = nil, locale = nil)
item = item["playlistPanelVideoRenderer"]
id = item["videoId"].as_s
- title = item["title"]["simpleText"].as_s
+ title = item["title"]?.try &.["simpleText"].as_s
+ if !title
+ next
+ end
author = item["longBylineText"]["runs"][0]["text"].as_s
ucid = item["longBylineText"]["runs"][0]["navigationEndpoint"]["browseEndpoint"]["browseId"].as_s
length_seconds = decode_length_seconds(item["lengthText"]["simpleText"].as_s)
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index 220a0ef7..28f2e4ce 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -161,117 +161,6 @@ def produce_playlist_url(id, index)
return url
end
-def produce_channel_playlists_url(ucid, cursor, sort = "newest")
- cursor = Base64.urlsafe_encode(cursor, false)
-
- meta = IO::Memory.new
- meta.write(Bytes[0x12, 0x09])
- meta.print("playlists")
-
- # TODO: Look at 0x01, 0x00
- case sort
- when "oldest", "oldest_created"
- meta.write(Bytes[0x18, 0x02])
- when "newest", "newest_created"
- meta.write(Bytes[0x18, 0x03])
- when "last", "last_added"
- meta.write(Bytes[0x18, 0x04])
- end
-
- meta.write(Bytes[0x20, 0x01])
- meta.write(Bytes[0x30, 0x02])
- meta.write(Bytes[0x38, 0x01])
- meta.write(Bytes[0x60, 0x01])
- meta.write(Bytes[0x6a, 0x00])
-
- meta.write(Bytes[0x7a, cursor.size])
- meta.print(cursor)
-
- meta.write(Bytes[0xb8, 0x01, 0x00])
-
- meta.rewind
- meta = Base64.urlsafe_encode(meta.to_slice)
- meta = URI.escape(meta)
-
- continuation = IO::Memory.new
- continuation.write(Bytes[0x12, ucid.size])
- continuation.print(ucid)
-
- continuation.write(Bytes[0x1a])
- continuation.write(write_var_int(meta.size))
- continuation.print(meta)
-
- continuation.rewind
- continuation = continuation.gets_to_end
-
- wrapper = IO::Memory.new
- wrapper.write(Bytes[0xe2, 0xa9, 0x85, 0xb2, 0x02])
- wrapper.write(write_var_int(continuation.size))
- wrapper.print(continuation)
- wrapper.rewind
-
- wrapper = Base64.urlsafe_encode(wrapper.to_slice)
- wrapper = URI.escape(wrapper)
-
- url = "/browse_ajax?continuation=#{wrapper}&gl=US&hl=en"
-
- return url
-end
-
-def extract_channel_playlists_cursor(url)
- wrapper = HTTP::Params.parse(URI.parse(url).query.not_nil!)["continuation"]
-
- wrapper = URI.unescape(wrapper)
- wrapper = Base64.decode(wrapper)
-
- # 0xe2 0xa9 0x85 0xb2 0x02
- wrapper += 5
-
- continuation_size = read_var_int(wrapper[0, 4])
- wrapper += write_var_int(continuation_size).size
- continuation = wrapper[0, continuation_size]
-
- # 0x12
- continuation += 1
- ucid_size = continuation[0]
- continuation += 1
- ucid = continuation[0, ucid_size]
- continuation += ucid_size
-
- # 0x1a
- continuation += 1
- meta_size = read_var_int(continuation[0, 4])
- continuation += write_var_int(meta_size).size
- meta = continuation[0, meta_size]
- continuation += meta_size
-
- meta = String.new(meta)
- meta = URI.unescape(meta)
- meta = Base64.decode(meta)
-
- # 0x12 0x09 playlists
- meta += 11
-
- until meta[0] == 0x7a
- tag = read_var_int(meta[0, 4])
- meta += write_var_int(tag).size
- value = meta[0]
- meta += 1
- end
-
- # 0x7a
- meta += 1
- cursor_size = meta[0]
- meta += 1
- cursor = meta[0, cursor_size]
-
- cursor = String.new(cursor)
- cursor = URI.unescape(cursor)
- cursor = Base64.decode_string(cursor)
-
- return cursor
-end
-
def fetch_playlist(plid, locale)
client = make_client(YT_URL)
diff --git a/src/invidious/users.cr b/src/invidious/users.cr
index d45c5af4..072638ba 100644
--- a/src/invidious/users.cr
+++ b/src/invidious/users.cr
@@ -12,7 +12,6 @@ class User
end
add_mapping({
- id: Array(String),
updated: Time,
notifications: Array(String),
subscriptions: Array(String),
@@ -126,18 +125,21 @@ class Preferences
end
def get_user(sid, headers, db, refresh = true)
- if db.query_one?("SELECT EXISTS (SELECT true FROM users WHERE $1 = ANY(id))", sid, as: Bool)
- user = db.query_one("SELECT * FROM users WHERE $1 = ANY(id)", sid, as: User)
+ if email = db.query_one?("SELECT email FROM session_ids WHERE id = $1", sid, as: String)
+ user = db.query_one("SELECT * FROM users WHERE email = $1", email, as: User)
if refresh && Time.now - user.updated > 1.minute
- user = fetch_user(sid, headers, db)
+ user, sid = fetch_user(sid, headers, db)
user_array = user.to_a
- user_array[5] = user_array[5].to_json
+ user_array[4] = user_array[4].to_json
args = arg_array(user_array)
db.exec("INSERT INTO users VALUES (#{args}) \
- ON CONFLICT (email) DO UPDATE SET id = users.id || $1, updated = $2, subscriptions = $4", user_array)
+ ON CONFLICT (email) DO UPDATE SET updated = $1, subscriptions = $3", user_array)
+
+ db.exec("INSERT INTO session_ids VALUES ($1,$2,$3) \
+ ON CONFLICT (id) DO NOTHING", sid, user.email, Time.now)
begin
view_name = "subscriptions_#{sha256(user.email)[0..7]}"
@@ -149,14 +151,17 @@ def get_user(sid, headers, db, refresh = true)
end
end
else
- user = fetch_user(sid, headers, db)
+ user, sid = fetch_user(sid, headers, db)
user_array = user.to_a
- user_array[5] = user_array[5].to_json
+ user_array[4] = user_array[4].to_json
args = arg_array(user.to_a)
db.exec("INSERT INTO users VALUES (#{args}) \
- ON CONFLICT (email) DO UPDATE SET id = users.id || $1, updated = $2, subscriptions = $4", user_array)
+ ON CONFLICT (email) DO UPDATE SET updated = $1, subscriptions = $3", user_array)
+
+ db.exec("INSERT INTO session_ids VALUES ($1,$2,$3) \
+ ON CONFLICT (id) DO NOTHING", sid, user.email, Time.now)
begin
view_name = "subscriptions_#{sha256(user.email)[0..7]}"
@@ -168,7 +173,7 @@ def get_user(sid, headers, db, refresh = true)
end
end
- return user
+ return user, sid
end
def fetch_user(sid, headers, db)
@@ -196,17 +201,17 @@ def fetch_user(sid, headers, db)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = User.new([sid], Time.now, [] of String, channels, email, DEFAULT_USER_PREFERENCES, nil, token, [] of String)
- return user
+ user = User.new(Time.now, [] of String, channels, email, DEFAULT_USER_PREFERENCES, nil, token, [] of String)
+ return user, sid
end
def create_user(sid, email, password)
password = Crypto::Bcrypt::Password.create(password, cost: 10)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = User.new([sid], Time.now, [] of String, [] of String, email, DEFAULT_USER_PREFERENCES, password.to_s, token, [] of String)
+ user = User.new(Time.now, [] of String, [] of String, email, DEFAULT_USER_PREFERENCES, password.to_s, token, [] of String)
- return user
+ return user, sid
end
def create_response(user_id, operation, key, db, expire = 6.hours)
diff --git a/src/invidious/views/components/subscribe_widget_script.ecr b/src/invidious/views/components/subscribe_widget_script.ecr
index c5e36b79..e2994c86 100644
--- a/src/invidious/views/components/subscribe_widget_script.ecr
+++ b/src/invidious/views/components/subscribe_widget_script.ecr
@@ -20,7 +20,7 @@ function subscribe(timeouts = 0) {
var fallback = subscribe_button.innerHTML;
subscribe_button.onclick = unsubscribe;
- subscribe_button.innerHTML = '<b><%= translate(locale, "Unsubscribe") %> | <%= sub_count_text %></b>'
+ subscribe_button.innerHTML = '<b><%= translate(locale, "Unsubscribe").gsub("'", "\\'") %> | <%= sub_count_text %></b>'
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
@@ -55,7 +55,7 @@ function unsubscribe(timeouts = 0) {
var fallback = subscribe_button.innerHTML;
subscribe_button.onclick = subscribe;
- subscribe_button.innerHTML = '<b><%= translate(locale, "Subscribe") %> | <%= sub_count_text %></b>'
+ subscribe_button.innerHTML = '<b><%= translate(locale, "Subscribe").gsub("'", "\\'") %> | <%= sub_count_text %></b>'
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {