Repository navigation
STF-1906: Add phone verification inputs #304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
65e00aa
0c6bdc9
31ae626
bb0ec16
7aef50f
e51b315
016038b
ac00483
e7a2ab4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ module Components | |
| # This is a parent class for the Billing and Shipping components. | ||
| class Addressable < Base | ||
| include Minfraud::Validates | ||
| include ::Minfraud::Enum | ||
|
|
||
| # The first name of the end user as provided in their billing / shipping | ||
| # information. | ||
|
|
@@ -74,20 +75,52 @@ class Addressable < Base | |
| # @return [String, nil] | ||
| attr_accessor :phone_country_code | ||
|
|
||
| # The most recent method used to verify the phone number. This must be | ||
| # one of +:delivered_code+, +:network+, or +:other+. | ||
| # +:delivered_code+ is a code delivered to the phone, such as by SMS, | ||
| # voice call, or messaging app. +:network+ is verification through the | ||
| # mobile network operator, such as silent network authentication. | ||
| # | ||
| # @!attribute phone_verification_method | ||
| # | ||
| # @return [Symbol, nil] | ||
| enum_accessor :phone_verification_method, %i[delivered_code network other] | ||
|
|
||
| # Whether the most recent verification of the phone number | ||
| # succeeded. Do not include this field if no verification was | ||
| # attempted. | ||
| # | ||
| # @return [Boolean, nil] | ||
| attr_accessor :phone_was_verification_successful | ||
|
|
||
| # The date and time of the most recent verification of the phone | ||
| # number. The string must be in the RFC 3339 date-time format, e.g., | ||
| # "2012-04-12T23:20:50.52Z". The time must not be before | ||
| # 1970-01-01T00:00:00Z or more than two days in the future. The web | ||
| # service ignores a time outside this range and returns a warning. | ||
| # | ||
| # @see https://datatracker.ietf.org/doc/html/rfc3339 | ||
| # | ||
| # @return [String, nil] | ||
| attr_accessor :phone_verification_time | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: The repo CLAUDE.md says "Validation happens in setters before assignment" and shows a 馃 Comment by Claude Opus 5.5.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We will leave this. The new fields follow the existing components, which also use Reply by Claude Opus 5.5 on Greg's behalf. |
||
|
|
||
| # @param params [Hash] Hash of parameters. Each key/value should | ||
| # correspond to one of the available attributes. | ||
| def initialize(params = {}) | ||
| @first_name = params[:first_name] | ||
| @last_name = params[:last_name] | ||
| @company = params[:company] | ||
| @address = params[:address] | ||
| @address_2 = params[:address_2] | ||
| @city = params[:city] | ||
| @region = params[:region] | ||
| @country = params[:country] | ||
| @postal = params[:postal] | ||
| @phone_number = params[:phone_number] | ||
| @phone_country_code = params[:phone_country_code] | ||
| @first_name = params[:first_name] | ||
| @last_name = params[:last_name] | ||
| @company = params[:company] | ||
| @address = params[:address] | ||
| @address_2 = params[:address_2] | ||
| @city = params[:city] | ||
| @region = params[:region] | ||
| @country = params[:country] | ||
| @postal = params[:postal] | ||
| @phone_number = params[:phone_number] | ||
| @phone_country_code = params[:phone_country_code] | ||
| self.phone_verification_method = params[:phone_verification_method] | ||
| @phone_was_verification_successful = params[:phone_was_verification_successful] | ||
| @phone_verification_time = params[:phone_verification_time] | ||
|
|
||
| validate | ||
| end | ||
|
|
@@ -108,6 +141,8 @@ def validate | |
| validate_string('postal', 255, @postal) | ||
| validate_string('phone_number', 255, @phone_number) | ||
| validate_telephone_country_code('phone_country_code', @phone_country_code) | ||
| validate_boolean('phone_was_verification_successful', @phone_was_verification_successful) | ||
| validate_rfc3339('phone_verification_time', @phone_verification_time) | ||
|
oschwald marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Low: This checks only the RFC 3339 format of With validation on, If the client should catch this, add a range check (compare in UTC, with the upper bound as now + 2 days). If the range is left to the server on purpose, as for 馃 Comment by Claude Opus 5.5.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No client checks this range, the same as for Reply by Claude Opus 5.5 on Greg's behalf. |
||
| end | ||
| end | ||
| end | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,14 +17,22 @@ def self.included(base) | |
| # types. | ||
| module ClassMethods | ||
| # Returns a hash in the following format: attribute_name => | ||
| # permitted_values | ||
| # permitted_values. It includes the attributes declared on parent | ||
| # classes. | ||
| # | ||
| # @return [Hash] | ||
| def mapping | ||
| # rubocop:disable ThreadSafety/ClassInstanceVariable | ||
| # This is a false positive - this is set during class definition and then only read | ||
| @mapping ||= {} | ||
| # This is a false positive - this only reads the mapping that | ||
| # enum_accessor sets during class definition | ||
| declared = @declared_mapping || {} | ||
| # rubocop:enable ThreadSafety/ClassInstanceVariable | ||
|
|
||
| if superclass.respond_to?(:mapping) | ||
| superclass.mapping.merge(declared) | ||
| else | ||
| declared.dup | ||
| end | ||
| end | ||
|
|
||
| # Create a set of methods for enum-like behavior of the attribute. | ||
|
|
@@ -35,23 +43,33 @@ def mapping | |
| # | ||
| # @return [nil] | ||
| def enum_accessor(attribute, assignable_values) | ||
| mapping[attribute] = assignable_values.map(&:intern) | ||
| values = assignable_values.map(&:intern).freeze | ||
| declared_mapping[attribute] = values | ||
|
|
||
| self.class.instance_eval do | ||
| define_method("#{attribute}_values") { mapping[attribute] } | ||
| end | ||
| define_singleton_method("#{attribute}_values") { values } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: 馃 Comment by Claude Opus 5.5.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in e51b315. Reply by Claude Opus 5.5 on Greg's behalf. |
||
|
|
||
| class_eval do | ||
| define_method(attribute.to_s) { instance_variable_get("@#{attribute}") } | ||
| define_method "#{attribute}=" do |value| | ||
| raise NotEnumValueError, 'Value is not permitted' if value && !self.class.mapping[attribute].include?(value.intern) | ||
| value = value.intern if value.is_a?(String) | ||
| raise NotEnumValueError, 'Value is not permitted' if !value.nil? && !values.include?(value) | ||
|
|
||
| instance_variable_set("@#{attribute}", value ? value.intern : nil) | ||
| instance_variable_set("@#{attribute}", value) | ||
| end | ||
| end | ||
|
|
||
| nil | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def declared_mapping | ||
| # rubocop:disable ThreadSafety/ClassInstanceVariable | ||
| # This is a false positive - only enum_accessor calls this, during class | ||
| # definition | ||
| @declared_mapping ||= {} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: The justification for the rubocop disable ("set during class definition and then only read") is no longer fully true. 馃 Comment by Claude Opus 5.5.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in e51b315. Reply by Claude Opus 5.5 on Greg's behalf. |
||
| # rubocop:enable ThreadSafety/ClassInstanceVariable | ||
| end | ||
| end | ||
| end | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.