require "openssl/hmac" struct Invidious::User module Captcha extend self def generate_image(key) second = Random::Secure.rand(12) second_angle = second * 30 second = second * 5 minute = Random::Secure.rand(12) minute_angle = minute * 30 minute = minute * 5 hour = Random::Secure.rand(12) hour_angle = hour * 30 + minute_angle.to_f / 12 if hour == 0 hour = 12 end clock_svg = <<-END_SVG 1 2 3 4 5 6 7 8 9 10 11 12 END_SVG image = "data:image/png;base64," image += Process.run(%(rsvg-convert -w 400 -h 400 -b none -f png), shell: true, input: IO::Memory.new(clock_svg), output: Process::Redirect::Pipe ) do |proc| Base64.strict_encode(proc.output.gets_to_end) end answer = "#{hour}:#{minute.to_s.rjust(2, '0')}:#{second.to_s.rjust(2, '0')}" answer = OpenSSL::HMAC.hexdigest(:sha256, key, answer) return { question: image, tokens: {generate_response(answer, {":login"}, key, use_nonce: true)}, } end end end