Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/forms/webauthn_verification_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def extra_analytics_attributes
{
multi_factor_auth_method: auth_method,
webauthn_configuration_id: webauthn_configuration&.id,
}
frontend_error: webauthn_error.presence,
}.compact
end
end
3 changes: 3 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3123,6 +3123,7 @@ def logout_initiated(
# @param [String] area_code
# @param [String] country_code
# @param [String] phone_fingerprint the hmac fingerprint of the phone number formatted as e164
# @param [String] frontend_error Name of error that occurred in frontend during submission
# Multi-Factor Authentication
def multi_factor_auth(
success:,
Expand All @@ -3140,6 +3141,7 @@ def multi_factor_auth(
area_code: nil,
country_code: nil,
phone_fingerprint: nil,
frontend_error: nil,
**extra
)
track_event(
Expand All @@ -3159,6 +3161,7 @@ def multi_factor_auth(
area_code: area_code,
country_code: country_code,
phone_fingerprint: phone_fingerprint,
frontend_error:,
**extra,
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@
multi_factor_auth_method_created_at:
second_webauthn_platform_configuration.created_at.strftime('%s%L'),
webauthn_configuration_id: nil,
frontend_error: 'NotAllowedError',
Copy link
Copy Markdown
Contributor Author

@aduth aduth Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is being logged on the Multi-Factor Authentication event, it should probably be documented in the arguments for that method, and qualified as relating specifically to "WebAuthn".

Though maybe that extra friction is enough to warrant persuing the alternative instead.

)

patch :confirm, params: params
Expand Down
16 changes: 14 additions & 2 deletions spec/forms/webauthn_verification_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@
)
end
end

context 'with client-side webauthn error as blank string' do
let(:webauthn_error) { '' }

it 'returns successful result excluding frontend_error' do
expect(result.to_h).to eq(
success: true,
multi_factor_auth_method: 'webauthn',
webauthn_configuration_id: webauthn_configuration.id,
)
end
end
end

context 'when the input is invalid' do
Expand Down Expand Up @@ -136,20 +148,20 @@
success: false,
error_details: { webauthn_configuration: { blank: true } },
multi_factor_auth_method: 'webauthn',
webauthn_configuration_id: nil,
)
end
end

context 'when a client-side webauthn error is present' do
let(:webauthn_error) { 'Unexpected error!' }
let(:webauthn_error) { 'NotAllowedError' }

it 'returns unsuccessful result including client-side webauthn error text' do
expect(result.to_h).to eq(
success: false,
error_details: { webauthn_error: { webauthn_error: true } },
Copy link
Copy Markdown
Contributor Author

@aduth aduth Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "alternative" approach described in the original comment could look something like...

Suggested change
error_details: { webauthn_error: { webauthn_error: true } },
error_details: { webauthn_error: { NotAllowedError: true } },

Or:

Suggested change
error_details: { webauthn_error: { webauthn_error: true } },
error_details: { webauthn_error: { not_allowed_error: true } },

Or some extra processing to trim the redundant suffix:

Suggested change
error_details: { webauthn_error: { webauthn_error: true } },
error_details: { webauthn_error: { not_allowed: true } },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the third version leave the door open for other types of webauthn_errors? I'm not sure if that sort of scalability is likely but if it is I think that's a strong candidate. It seems pretty descriptive regardless.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think I like it as far as providing the actual detail relevant for the field, but my main concern is that it's not obvious the mapping between the original JavaScript-derived error name and the resulting logged key name, which would I expect would be derived by some opaque logic like javascript_error_name.underscore.tr('_error', ''). And the "Error" suffix of JavaScript error names is only a standard convention, not strictly mandatory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually thinking I might go a different direction with this and use ActiveRecord's built-in absence validator for this, which seems like a nice compromise between the challenges above and trying to avoid having a redundant webauthn_error subproperty.

I'll plan tackle that in a quick follow-on pull request.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll plan tackle that in a quick follow-on pull request.

See #9614

multi_factor_auth_method: 'webauthn',
webauthn_configuration_id: webauthn_configuration.id,
frontend_error: webauthn_error,
)
end
end
Expand Down