diff --git a/app/controllers/login/otp_controller.rb b/app/controllers/login/otp_controller.rb index 615067315f7..4d8d43433ca 100644 --- a/app/controllers/login/otp_controller.rb +++ b/app/controllers/login/otp_controller.rb @@ -78,7 +78,7 @@ class Login::OtpController < ApplicationController # of a maxed out bucket. increment_request_cost(150) - verification_code = params[:otp_login][:verification_code] + verification_code = params[:otp_login][:verification_code].delete(" ") if Canvas.redis_enabled? key = "otp_used:#{@current_user.global_id}:#{verification_code}" if Canvas.redis.get(key) diff --git a/spec/controllers/login/otp_controller_spec.rb b/spec/controllers/login/otp_controller_spec.rb index e115302f98f..417446372bf 100644 --- a/spec/controllers/login/otp_controller_spec.rb +++ b/spec/controllers/login/otp_controller_spec.rb @@ -175,6 +175,15 @@ describe Login::OtpController do expect(request.env.fetch("extra-request-cost").to_f >= 150).to be_truthy end + it "verifies a code entered with spaces" do + code = ROTP::TOTP.new(@user.otp_secret_key).now + post :create, params: { otp_login: { verification_code: "#{code[0..2]} #{code[3..]}" } } + expect(response).to redirect_to dashboard_url(login_success: 1) + expect(cookies["canvas_otp_remember_me"]).to be_nil + expect(Canvas.redis.get("otp_used:#{@user.global_id}:#{code}")).to eq "1" if Canvas.redis_enabled? + expect(request.env.fetch("extra-request-cost").to_f >= 150).to be_truthy + end + it "verifies a backup code" do code = @user.one_time_passwords.create!.code post :create, params: { otp_login: { verification_code: code } }