kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.3 KiB
139 lines
5.3 KiB
require_relative '../spec_helper'
|
|
|
|
describe 'My Account 2FA configuration', type: :feature,
|
|
with_config: {:'2fa' => {active_strategies: [:developer, :totp]}},
|
|
js: true do
|
|
let(:dialog) { ::Components::PasswordConfirmationDialog.new }
|
|
let(:user_password) {'bob!' * 4}
|
|
let(:user) do
|
|
FactoryGirl.create(:user,
|
|
login: 'bob',
|
|
password: user_password,
|
|
password_confirmation: user_password,
|
|
)
|
|
end
|
|
|
|
before do
|
|
login_as user
|
|
end
|
|
|
|
it 'allows 2FA device management' do
|
|
|
|
# Visit empty index
|
|
visit my_2fa_devices_path
|
|
expect(page).to have_selector('.generic-table--empty-row', text: I18n.t('two_factor_authentication.devices.not_existing'))
|
|
expect(page).to have_selector('.on-off-status.-disabled')
|
|
|
|
# Visit inline create
|
|
find('.wp-inline-create--add-link').click
|
|
expect(page).to have_selector('h2', text: I18n.t('two_factor_authentication.devices.add_new'))
|
|
expect(current_path).to eq new_my_2fa_device_path
|
|
|
|
# Select SMS
|
|
find('.mobile-otp-new-device-sms .button').click
|
|
|
|
# Try to save with invalid phone number
|
|
fill_in 'device_phone_number', with: 'invalid!'
|
|
click_button I18n.t(:button_continue)
|
|
|
|
# Enter valid phone number
|
|
expect(page).to have_selector('#errorExplanation', text: 'Phone number must be of format +XX XXXXXXXXX')
|
|
fill_in 'device_phone_number', with: '+49 123456789'
|
|
click_button I18n.t(:button_continue)
|
|
|
|
# Fill in wrong token
|
|
fill_in 'otp', with: 'whatever'
|
|
|
|
# Log token for next access
|
|
sms_token = nil
|
|
allow_any_instance_of(::OpenProject::TwoFactorAuthentication::TokenStrategy::Developer)
|
|
.to receive(:create_mobile_otp).and_wrap_original do |m|
|
|
sms_token = m.call
|
|
end
|
|
|
|
click_button I18n.t(:button_continue)
|
|
|
|
expect(page).to have_selector('h2', text: I18n.t('two_factor_authentication.devices.confirm_device'))
|
|
expect(page).to have_selector('input#otp')
|
|
expect(page).to have_selector('.flash.error', text: I18n.t('two_factor_authentication.devices.registration_failed_token_invalid'))
|
|
|
|
# Fill in correct token
|
|
fill_in 'otp', with: sms_token
|
|
click_button I18n.t(:button_continue)
|
|
|
|
# Assert that it exists and is default
|
|
expect(page).to have_selector('.mobile-otp--two-factor-device-row td', text: 'Mobile phone (bob) (+49 123456789)')
|
|
expect(page).to have_selector('.mobile-otp--two-factor-device-row td .icon-yes', count: 2)
|
|
expect(page).to have_selector('.on-off-status.-enabled')
|
|
|
|
# Create another one as totp
|
|
# Visit create button
|
|
visit my_2fa_devices_path
|
|
find('.toolbar-item .button', text: '2FA device').click
|
|
expect(page).to have_selector('h2', text: I18n.t('two_factor_authentication.devices.add_new'))
|
|
expect(current_path).to eq new_my_2fa_device_path
|
|
|
|
# Select totp
|
|
find('.mobile-otp-new-device-totp .button').click
|
|
|
|
# Change identifier
|
|
fill_in 'device_identifier', with: 'custom identifier'
|
|
click_button I18n.t(:button_continue)
|
|
|
|
# Confirm token
|
|
expect(page).to have_selector('h2', text: I18n.t('two_factor_authentication.devices.confirm_device'))
|
|
expect(page).to have_selector('input#otp')
|
|
|
|
device = user.otp_devices.order(:id).last
|
|
expect(device.identifier).to eq 'custom identifier'
|
|
expect(device.default).to be_falsey
|
|
expect(device.active).to be_falsey
|
|
|
|
fill_in 'otp', with: device.totp.now
|
|
click_button I18n.t(:button_continue)
|
|
|
|
expect(page).to have_selector('.mobile-otp--two-factor-device-row', count: 2)
|
|
rows = page.all('.mobile-otp--two-factor-device-row')
|
|
expect(rows[0]).to have_selector('.mobile-otp--two-factor-device-row td .icon-yes', count: 2)
|
|
expect(rows[1]).to have_selector('.mobile-otp--two-factor-device-row td', text: 'custom identifier')
|
|
expect(rows[1]).to have_selector('.mobile-otp--two-factor-device-row td .icon-yes', count: 1)
|
|
|
|
device.reload
|
|
expect(device.active).to be_truthy
|
|
expect(device.default).to be_falsey
|
|
|
|
# Make the second one the default
|
|
# Confirm the password wrongly
|
|
find('.two-factor--mark-default-button').click
|
|
dialog.confirm_flow_with 'wrong_password', should_fail: true
|
|
|
|
# Confirm again
|
|
find('.two-factor--mark-default-button').click
|
|
dialog.confirm_flow_with user_password, should_fail: false
|
|
|
|
expect(page).to have_selector('.mobile-otp--two-factor-device-row', count: 2)
|
|
rows = page.all('.mobile-otp--two-factor-device-row')
|
|
expect(rows[0]).to have_selector('.mobile-otp--two-factor-device-row td .icon-yes', count: 1)
|
|
expect(rows[1]).to have_selector('.mobile-otp--two-factor-device-row td .icon-yes', count: 2)
|
|
|
|
device.reload
|
|
expect(device.default).to be_truthy
|
|
|
|
# Delete the sms device
|
|
rows[0].find('.two-factor--delete-button').click
|
|
dialog.confirm_flow_with user_password, should_fail: false
|
|
|
|
expect(page).to have_selector('.mobile-otp--two-factor-device-row', count: 1)
|
|
expect(page).to have_selector('.on-off-status.-enabled')
|
|
expect(user.otp_devices.count).to eq 1
|
|
|
|
# Delete the totp device
|
|
find('.two-factor--delete-button').click
|
|
dialog.confirm_flow_with user_password, should_fail: false
|
|
|
|
expect(page).to have_selector('.generic-table--empty-row', text: I18n.t('two_factor_authentication.devices.not_existing'))
|
|
expect(page).to have_selector('.on-off-status.-disabled')
|
|
expect(user.otp_devices.count).to eq 0
|
|
end
|
|
end
|
|
|
|
|