diff --git a/README.md b/README.md index 903e55edba..69dc2e4a71 100644 --- a/README.md +++ b/README.md @@ -361,9 +361,8 @@ TODO this may not be applicable anymore since we've removed the `.sfdx` folder f ## Resetting Salesforce Org Keys -- Debug console -- Anon Apex -- maintenanceUtilities.resetServiceConnection(); +- Debug console > Debug > Open Execute Anonmous Window +- `maintenanceUtilities.resetServiceConnection();` or `QaStripeConnect.maintenanceUtilities.resetServiceConnection();` if in a packaged environment # Development diff --git a/app/controllers/api/configurations_controller.rb b/app/controllers/api/configurations_controller.rb index f31164fcec..d933cfd044 100644 --- a/app/controllers/api/configurations_controller.rb +++ b/app/controllers/api/configurations_controller.rb @@ -178,11 +178,14 @@ def update private def user_configuration_json { salesforce_account_id: @user.salesforce_account_id, + field_mappings: @user.field_mappings, field_defaults: @user.field_defaults, default_mappings: @user.default_mappings, required_mappings: @user.required_mappings, + feature_flags: @user.feature_flags, + connection_status: { # TODO use dynamic connection status salesforce: @user.salesforce_token.present?, @@ -191,7 +194,11 @@ def update last_synced: Time.now.to_i, stripe_account_id: @user.stripe_account_id, }, + settings: @user.connector_settings, + + enabled: @user.enabled, + configuration_hash: @user.configuration_hash, } end diff --git a/lib/stripe-force/db/user.rb b/lib/stripe-force/db/user.rb index 8ef1f26a2a..423b3b35c7 100644 --- a/lib/stripe-force/db/user.rb +++ b/lib/stripe-force/db/user.rb @@ -254,6 +254,22 @@ def stripe_credentials(forced_livemode: nil) } end + # this hash is used to prevent same-time editing via the SF UI + def configuration_hash + mappings_as_string = self.field_defaults.to_json + self.field_mappings.to_json + + # take into account all configuration options which are set via the UI + selective_configuration_json = self.connector_settings.slice(*DEFAULT_CONNECTOR_SETTINGS.keys).to_json + + Digest::SHA1.hexdigest(mappings_as_string + selective_configuration_json) + end + + # used for the idempotency key generation + def mapping_hash + mappings_as_string = self.field_defaults.to_json + self.field_mappings.to_json + Digest::SHA1.hexdigest(mappings_as_string) + end + protected def kms_encryption_context(field=nil) { # NOTE that the account is the SF organization instance ID diff --git a/lib/stripe-force/translate/utilities/stripe_util.rb b/lib/stripe-force/translate/utilities/stripe_util.rb index aaeec0cf0c..fd38b4e654 100644 --- a/lib/stripe-force/translate/utilities/stripe_util.rb +++ b/lib/stripe-force/translate/utilities/stripe_util.rb @@ -34,11 +34,8 @@ def self.billing_frequency_of_price_in_months(stripe_price) sig { params(user: StripeForce::User, sf_object: Restforce::SObject, action: T.nilable(Symbol)).returns(Hash) } def self.generate_idempotency_key_with_credentials(user, sf_object, action=nil) - mappings_as_string = user.field_defaults.to_json + user.field_mappings.to_json - mapping_uid = Digest::SHA1.hexdigest(mappings_as_string) - last_modified_as_timestamp = DateTime.parse(sf_object[SF_LAST_MODIFIED_DATE]).to_i - key = "#{mapping_uid}-#{sf_object[SF_ID]}-#{last_modified_as_timestamp}" + key = "#{user.mapping_hash}-#{sf_object[SF_ID]}-#{last_modified_as_timestamp}" if action key = "#{key}-#{action}" diff --git a/test/controllers/test_configurations_controller.rb b/test/controllers/test_configurations_controller.rb index 7f97f84146..fef4aa1007 100644 --- a/test/controllers/test_configurations_controller.rb +++ b/test/controllers/test_configurations_controller.rb @@ -196,6 +196,8 @@ class Critic::ConfigurationsControllerTest < ApplicationIntegrationTest assert_equal(10_000, result['settings']['sync_record_retention']) assert_equal('USD', result['settings']['default_currency']) assert_nil(result['settings']['sync_start_date']) + assert_equal(40, result['configuration_hash'].size) + assert(result['enabled']) refute_nil(result['settings']['filters']) assert_equal("Status = 'Activated'", result['settings']['filters'][SF_ORDER]) @@ -203,6 +205,32 @@ class Critic::ConfigurationsControllerTest < ApplicationIntegrationTest assert_nil(result['settings']['filters'][SF_PRODUCT]) end + it 'updates the configuration_hash when mappings change' do + get api_configuration_path, headers: authentication_headers + assert_response :success + result = parsed_json + + initial_hash = result['configuration_hash'] + + get api_configuration_path, headers: authentication_headers + assert_response :success + result = parsed_json + + # hash should remain the same when something doesn't change + assert_equal(initial_hash, result['configuration_hash']) + + @user.field_mappings['price'] = {'special' => 'mapping'} + @user.save + + get api_configuration_path, headers: authentication_headers + assert_response :success + result = parsed_json + + # if mappings change, hash should be different + refute_equal(initial_hash, result['configuration_hash']) + assert_equal(40, result['configuration_hash'].size) + end + it 'updates settings' do future_time = Time.now.to_i + 3600