|
|
|
@ -21,6 +21,16 @@ module Invidious::Routes::Login
|
|
|
|
|
account_type = env.params.query["type"]?
|
|
|
|
|
account_type ||= "invidious"
|
|
|
|
|
|
|
|
|
|
if CONFIG.auth_type.find(&.== account_type).nil?
|
|
|
|
|
if CONFIG.auth_type.size == 0
|
|
|
|
|
account_type = "invidious"
|
|
|
|
|
else
|
|
|
|
|
account_type = CONFIG.auth_type[0]
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
oauth = CONFIG.auth_type.find(&.== "oauth") && (CONFIG.oauth.size > 0)
|
|
|
|
|
|
|
|
|
|
captcha_type = env.params.query["captcha"]?
|
|
|
|
|
captcha_type ||= "image"
|
|
|
|
|
|
|
|
|
@ -30,6 +40,35 @@ module Invidious::Routes::Login
|
|
|
|
|
templated "user/login"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.login_oauth(env)
|
|
|
|
|
locale = env.get("preferences").as(Preferences).locale
|
|
|
|
|
|
|
|
|
|
referer = get_referer(env, "/feed/subscriptions")
|
|
|
|
|
|
|
|
|
|
authorization_code = env.params.query["code"]?
|
|
|
|
|
provider_k = env.params.url["provider"]
|
|
|
|
|
if authorization_code
|
|
|
|
|
begin
|
|
|
|
|
token = OAuthHelper.auth(provider_k, authorization_code)
|
|
|
|
|
info = JSON.parse(OAuthHelper.info(provider_k, token))
|
|
|
|
|
|
|
|
|
|
email = info["email"].as_s
|
|
|
|
|
user = Invidious::Database::Users.select(email: email)
|
|
|
|
|
|
|
|
|
|
if user
|
|
|
|
|
user_flow_existing(env,email)
|
|
|
|
|
else
|
|
|
|
|
user_flow_new(env,email,nil);
|
|
|
|
|
end
|
|
|
|
|
rescue
|
|
|
|
|
return error_template(403, "Invalid Authorization Code")
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
return error_template(403, "Missing Authorization Code")
|
|
|
|
|
end
|
|
|
|
|
env.redirect referer
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.login(env)
|
|
|
|
|
locale = env.get("preferences").as(Preferences).locale
|
|
|
|
|
|
|
|
|
@ -42,10 +81,19 @@ module Invidious::Routes::Login
|
|
|
|
|
# https://stackoverflow.com/a/574698
|
|
|
|
|
email = env.params.body["email"]?.try &.downcase.byte_slice(0, 254)
|
|
|
|
|
password = env.params.body["password"]?
|
|
|
|
|
oauth = CONFIG.auth_type.find(&.== "oauth") && (CONFIG.oauth.size > 0)
|
|
|
|
|
|
|
|
|
|
account_type = env.params.query["type"]?
|
|
|
|
|
account_type ||= "invidious"
|
|
|
|
|
|
|
|
|
|
if CONFIG.auth_type.size == 0
|
|
|
|
|
return error_template(401, "No authentication backend enabled.")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if CONFIG.auth_type.find(&.== account_type).nil?
|
|
|
|
|
account_type = CONFIG.auth_type[0]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
case account_type
|
|
|
|
|
when "google"
|
|
|
|
|
tfa_code = env.params.body["tfa"]?.try &.lchop("G-")
|
|
|
|
@ -308,6 +356,13 @@ module Invidious::Routes::Login
|
|
|
|
|
error_message = %(#{ex.message}<br/>Traceback:<br/><div style="padding-left:2em" id="traceback">#{traceback.gets_to_end}</div>)
|
|
|
|
|
return error_template(500, error_message)
|
|
|
|
|
end
|
|
|
|
|
when "oauth"
|
|
|
|
|
provider_k = env.params.body["provider"]
|
|
|
|
|
env.redirect OAuthHelper.get(provider_k).get_authorize_uri("openid email profile")
|
|
|
|
|
when "saml"
|
|
|
|
|
return error_template(501, "Not implemented")
|
|
|
|
|
when "ldap"
|
|
|
|
|
return error_template(501, "Not implemented")
|
|
|
|
|
when "invidious"
|
|
|
|
|
if !email
|
|
|
|
|
return error_template(401, "User ID is a required field")
|
|
|
|
@ -324,21 +379,10 @@ module Invidious::Routes::Login
|
|
|
|
|
return error_template(400, "Please sign in using 'Log in with Google'")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if Crypto::Bcrypt::Password.new(user.password.not_nil!).verify(password.byte_slice(0, 55))
|
|
|
|
|
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
|
|
|
|
|
Invidious::Database::SessionIDs.insert(sid, email)
|
|
|
|
|
|
|
|
|
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
|
|
|
|
else
|
|
|
|
|
if !Crypto::Bcrypt::Password.new(user.password.not_nil!).verify(password.byte_slice(0, 55))
|
|
|
|
|
return error_template(401, "Wrong username or password")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Since this user has already registered, we don't want to overwrite their preferences
|
|
|
|
|
if env.request.cookies["PREFS"]?
|
|
|
|
|
cookie = env.request.cookies["PREFS"]
|
|
|
|
|
cookie.expires = Time.utc(1990, 1, 1)
|
|
|
|
|
env.response.cookies << cookie
|
|
|
|
|
end
|
|
|
|
|
user_flow_existing(env, email)
|
|
|
|
|
else
|
|
|
|
|
if !CONFIG.registration_enabled
|
|
|
|
|
return error_template(400, "Registration has been disabled by administrator.")
|
|
|
|
@ -417,32 +461,7 @@ module Invidious::Routes::Login
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
|
|
|
|
|
user, sid = create_user(sid, email, password)
|
|
|
|
|
|
|
|
|
|
if language_header = env.request.headers["Accept-Language"]?
|
|
|
|
|
if language = ANG.language_negotiator.best(language_header, LOCALES.keys)
|
|
|
|
|
user.preferences.locale = language.header
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Invidious::Database::Users.insert(user)
|
|
|
|
|
Invidious::Database::SessionIDs.insert(sid, email)
|
|
|
|
|
|
|
|
|
|
view_name = "subscriptions_#{sha256(user.email)}"
|
|
|
|
|
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
|
|
|
|
|
|
|
|
|
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
|
|
|
|
|
|
|
|
|
if env.request.cookies["PREFS"]?
|
|
|
|
|
user.preferences = env.get("preferences").as(Preferences)
|
|
|
|
|
Invidious::Database::Users.update_preferences(user)
|
|
|
|
|
|
|
|
|
|
cookie = env.request.cookies["PREFS"]
|
|
|
|
|
cookie.expires = Time.utc(1990, 1, 1)
|
|
|
|
|
env.response.cookies << cookie
|
|
|
|
|
end
|
|
|
|
|
user_flow_new(env, email, password);
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
env.redirect referer
|
|
|
|
@ -488,4 +507,49 @@ module Invidious::Routes::Login
|
|
|
|
|
env.response.headers["Content-Type"] = response.headers["Content-Type"]
|
|
|
|
|
response.body
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.user_flow_existing(env, email)
|
|
|
|
|
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
|
|
|
|
|
Invidious::Database::SessionIDs.insert(sid, email)
|
|
|
|
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
|
|
|
|
|
|
|
|
|
# Since this user has already registered, we don't want to overwrite their preferences
|
|
|
|
|
if env.request.cookies["PREFS"]?
|
|
|
|
|
cookie = env.request.cookies["PREFS"]
|
|
|
|
|
cookie.expires = Time.utc(1990, 1, 1)
|
|
|
|
|
env.response.cookies << cookie
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.user_flow_new(env, email, password)
|
|
|
|
|
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
|
|
|
|
|
if password
|
|
|
|
|
user, sid = create_user(sid, email, password)
|
|
|
|
|
else
|
|
|
|
|
user, sid = create_user(sid, email)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if language_header = env.request.headers["Accept-Language"]?
|
|
|
|
|
if language = ANG.language_negotiator.best(language_header, LOCALES.keys)
|
|
|
|
|
user.preferences.locale = language.header
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Invidious::Database::Users.insert(user)
|
|
|
|
|
Invidious::Database::SessionIDs.insert(sid, email)
|
|
|
|
|
|
|
|
|
|
view_name = "subscriptions_#{sha256(user.email)}"
|
|
|
|
|
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
|
|
|
|
|
|
|
|
|
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
|
|
|
|
|
|
|
|
|
if env.request.cookies["PREFS"]?
|
|
|
|
|
user.preferences = env.get("preferences").as(Preferences)
|
|
|
|
|
Invidious::Database::Users.update_preferences(user)
|
|
|
|
|
|
|
|
|
|
cookie = env.request.cookies["PREFS"]
|
|
|
|
|
cookie.expires = Time.utc(1990, 1, 1)
|
|
|
|
|
env.response.cookies << cookie
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|