identity-vault/spec/requests/step_up_spec.rb
2026-01-01 17:47:36 -05:00

96 lines
3.6 KiB
Ruby

require "rails_helper"
RSpec.describe "StepUp", type: :request do
let(:identity) { create(:identity) }
let(:session) do
identity.sessions.create!(
session_token: SecureRandom.hex(32),
expires_at: 1.week.from_now
)
end
before do
allow_any_instance_of(ApplicationController).to receive(:current_identity).and_return(identity)
allow_any_instance_of(ApplicationController).to receive(:current_session).and_return(session)
allow_any_instance_of(ApplicationController).to receive(:identity_signed_in?).and_return(true)
end
describe "email step-up method blocked for email_change action" do
describe "POST /step_up/send_email_code" do
it "rejects email code request for email_change action" do
post "/step_up/send_email_code", params: { action_type: "email_change", return_to: "/email_changes/new" }
expect(response).to redirect_to(new_step_up_path(action_type: "email_change", return_to: "/email_changes/new"))
expect(flash[:error]).to eq("Email verification is not available for this action")
end
it "allows email code request for other actions" do
post "/step_up/send_email_code", params: { action_type: "remove_totp", return_to: "/security" }
expect(response).to redirect_to(new_step_up_path(action_type: "remove_totp", method: :email, return_to: "/security", code_sent: true))
expect(flash[:notice]).to include("verification code has been sent")
end
end
describe "POST /step_up/verify" do
let!(:totp) do
t = identity.totps.create!
t.mark_verified!
t
end
it "rejects email method verification for email_change action" do
login_code = identity.v2_login_codes.create!
post "/step_up/verify", params: {
action_type: "email_change",
method: "email",
code: login_code.code,
return_to: "/email_changes/new"
}
expect(response).to redirect_to(new_step_up_path(action_type: "email_change", return_to: "/email_changes/new"))
expect(flash[:error]).to eq("Email verification is not available for this action")
end
it "allows TOTP verification for email_change action" do
code = ROTP::TOTP.new(totp.secret).now
post "/step_up/verify", params: {
action_type: "email_change",
method: "totp",
code: code,
return_to: "/email_changes/new"
}
expect(response).to redirect_to("/email_changes/new")
expect(session.reload.last_step_up_at).to be_within(5.seconds).of(Time.current)
expect(session.reload.last_step_up_action).to eq("email_change")
end
it "binds step-up to specific action type" do
code = ROTP::TOTP.new(totp.secret).now
post "/step_up/verify", params: {
action_type: "oidc_reauth",
method: "totp",
code: code,
return_to: "/oauth/authorize"
}
expect(session.reload.last_step_up_action).to eq("oidc_reauth")
expect(session.recently_stepped_up?(for_action: "oidc_reauth")).to be true
expect(session.recently_stepped_up?(for_action: "email_change")).to be false
end
end
describe "POST /step_up/resend_email" do
it "rejects resend for email_change action" do
post "/step_up/resend_email", params: { action_type: "email_change", return_to: "/email_changes/new" }
expect(response).to redirect_to(new_step_up_path(action_type: "email_change", return_to: "/email_changes/new"))
expect(flash[:error]).to eq("Email verification is not available for this action")
end
end
end
end