mirror of
https://git.nadeko.net/Fijxu/invidious.git
synced 2025-12-21 10:28:50 +00:00
Add authentication API
This commit is contained in:
@@ -197,83 +197,6 @@ def create_user(sid, email, password)
|
||||
return user, sid
|
||||
end
|
||||
|
||||
def create_response(session, scopes, key, db, expire = 6.hours, use_nonce = false)
|
||||
expire = Time.now + expire
|
||||
|
||||
token = {
|
||||
"session" => session,
|
||||
"expire" => expire.to_unix,
|
||||
"scopes" => scopes,
|
||||
}
|
||||
|
||||
if use_nonce
|
||||
nonce = Random::Secure.hex(16)
|
||||
db.exec("INSERT INTO nonces VALUES ($1, $2) ON CONFLICT DO NOTHING", nonce, expire)
|
||||
token["nonce"] = nonce
|
||||
end
|
||||
|
||||
token["signature"] = sign_token(key, token)
|
||||
|
||||
return token.to_json
|
||||
end
|
||||
|
||||
def sign_token(key, hash)
|
||||
string_to_sign = [] of String
|
||||
|
||||
hash.each do |key, value|
|
||||
if key == "signature"
|
||||
next
|
||||
end
|
||||
|
||||
if value.is_a?(JSON::Any)
|
||||
case value
|
||||
when .as_a?
|
||||
value = value.as_a.map { |item| item.as_s }
|
||||
end
|
||||
end
|
||||
|
||||
case value
|
||||
when Array
|
||||
string_to_sign << "#{key}=#{value.sort.join(",")}"
|
||||
when Tuple
|
||||
string_to_sign << "#{key}=#{value.to_a.sort.join(",")}"
|
||||
else
|
||||
string_to_sign << "#{key}=#{value}"
|
||||
end
|
||||
end
|
||||
|
||||
string_to_sign = string_to_sign.sort.join("\n")
|
||||
return Base64.urlsafe_encode(OpenSSL::HMAC.digest(:sha256, key, string_to_sign)).strip
|
||||
end
|
||||
|
||||
def validate_response(token, session, scope, key, db, locale)
|
||||
if !token
|
||||
raise translate(locale, "Hidden field \"token\" is a required field")
|
||||
end
|
||||
|
||||
token = JSON.parse(URI.unescape(token)).as_h
|
||||
|
||||
if token["signature"]? != sign_token(key, token)
|
||||
raise translate(locale, "Invalid token")
|
||||
end
|
||||
|
||||
if token["nonce"]? && (nonce = db.query_one?("SELECT * FROM nonces WHERE nonce = $1", token["nonce"], as: {String, Time}))
|
||||
if nonce[1] > Time.now
|
||||
db.exec("UPDATE nonces SET expire = $1 WHERE nonce = $2", Time.new(1990, 1, 1), nonce[0])
|
||||
else
|
||||
raise translate(locale, "Invalid token")
|
||||
end
|
||||
end
|
||||
|
||||
if !token["scopes"].as_a.includes? scope.strip("/")
|
||||
raise translate(locale, "Invalid token")
|
||||
end
|
||||
|
||||
if token["expire"].as_i < Time.now.to_unix
|
||||
raise translate(locale, "Token is expired, please try again")
|
||||
end
|
||||
end
|
||||
|
||||
def generate_captcha(key, db)
|
||||
second = Random::Secure.rand(12)
|
||||
second_angle = second * 30
|
||||
@@ -326,7 +249,7 @@ def generate_captcha(key, db)
|
||||
|
||||
return {
|
||||
question: image,
|
||||
tokens: {create_response(answer, {"login"}, key, db, use_nonce: true)},
|
||||
tokens: {generate_response(answer, {":login"}, key, db, use_nonce: true)},
|
||||
}
|
||||
end
|
||||
|
||||
@@ -335,7 +258,7 @@ def generate_text_captcha(key, db)
|
||||
response = JSON.parse(response)
|
||||
|
||||
tokens = response["a"].as_a.map do |answer|
|
||||
create_response(answer.as_s, {"login"}, key, db, use_nonce: true)
|
||||
generate_response(answer.as_s, {":login"}, key, db, use_nonce: true)
|
||||
end
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user