Browse Source

Fixes #5327 - Password validation errors containing %s are not interpolated

Mantas Masalskis 6 months ago
parent
commit
88ed68a134

+ 1 - 2
app/assets/javascripts/app/controllers/_profile/password.coffee

@@ -128,8 +128,7 @@ class ProfilePassword extends App.ControllerSubContent
   error: (xhr, status, error) =>
     return if xhr.status != 422
 
-    data = xhr.responseJSON
-
+    data    = xhr.responseJSON
     message = if data.notice
                 App.i18n.translateContent( data.notice[0], data.notice[1] )
               else

+ 7 - 1
app/assets/javascripts/app/controllers/getting_started/admin.coffee

@@ -101,7 +101,13 @@ class GettingStartedAdmin extends App.ControllerWizardFullScreen
 
       fail: (settings, details) =>
         @formEnable(e)
-        @form.showAlert(details.error_human || details.error || __('User could not be created.'))
+
+        message = if _.isArray(details.notice)
+                    App.i18n.translateContent(details.notice[0], details.notice[1])
+                  else
+                    details.error_human || details.error || __('User could not be created.')
+
+        @form.showAlert(message)
     )
 
   relogin: (data, status, xhr) =>

+ 7 - 1
app/assets/javascripts/app/controllers/signup.coffee

@@ -95,7 +95,13 @@ class Signup extends App.ControllerFullPage
         ))
       fail: (settings, details) =>
         @formEnable(e)
-        @form.showAlert(details.error_human || details.error || __('User could not be created.'))
+
+        message = if _.isArray(details.notice)
+                    App.i18n.translateContent(details.notice[0], details.notice[1])
+                  else
+                    details.error_human || details.error || __('User could not be created.')
+
+        @form.showAlert(message)
     )
 
   resend: (e) =>

+ 4 - 4
app/controllers/users_controller.rb

@@ -554,7 +554,7 @@ curl http://localhost/api/v1/users/password_reset_verify -v -u #{login}:#{passwo
       render json: { message: 'failed' }, status: :ok
       return
     rescue PasswordPolicy::Error => e
-      render json: { message: 'failed', notice: [e] }, status: :ok
+      render json: { message: 'failed', notice: e.metadata }, status: :ok
       return
     end
 
@@ -602,7 +602,7 @@ curl http://localhost/api/v1/users/password_change -v -u #{login}:#{password} -H
         new_password:     params[:password_new]
       ).execute
     rescue PasswordPolicy::Error => e
-      render json: { message: 'failed', notice: [e.message] }, status: :unprocessable_entity
+      render json: { message: 'failed', notice: e.metadata }, status: :unprocessable_entity
       return
     rescue PasswordHash::Error
       render json: { message: 'failed', notice: [__('The current password you provided is incorrect.')] }, status: :unprocessable_entity
@@ -997,7 +997,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
     begin
       signup.execute
     rescue PasswordPolicy::Error => e
-      render json: { error: e.message }, status: :unprocessable_entity
+      render json: { message: 'failed', notice: e.metadata }, status: :unprocessable_entity
       return
     rescue Service::CheckFeatureEnabled::FeatureDisabledError => e
       raise Exceptions::UnprocessableEntity, e.message
@@ -1020,7 +1020,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
     )
     render json: { message: 'ok' }, status: :created
   rescue PasswordPolicy::Error => e
-    render json: { error: e.message }, status: :unprocessable_entity
+    render json: { message: 'failed', notice: e.metadata }, status: :unprocessable_entity
   rescue Exceptions::MissingAttribute, Service::System::CheckSetup::SystemSetupError => e
     raise Exceptions::UnprocessableEntity, e.message
   end

+ 11 - 11
i18n/zammad.pot

@@ -3337,7 +3337,7 @@ msgstr ""
 msgid "Could not parse any sender attribute from the email. Checked fields:"
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/signup.coffee:133
+#: app/assets/javascripts/app/controllers/signup.coffee:139
 msgid "Could not process your request"
 msgstr ""
 
@@ -3349,7 +3349,7 @@ msgstr ""
 msgid "Could not remove the two-factor authentication method for this user."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:198
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:197
 msgid "Could not remove two-factor authentication method"
 msgstr ""
 
@@ -3358,7 +3358,7 @@ msgstr ""
 msgid "Could not remove two-factor authentication method."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:228
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:227
 #: app/frontend/apps/desktop/pages/personal-setting/views/PersonalSettingTwoFactorAuth.vue:77
 msgid "Could not set two-factor authentication method as default"
 msgstr ""
@@ -5460,7 +5460,7 @@ msgstr ""
 msgid "Email sent to \"%s\". Please let the user verify their email account."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/signup.coffee:118
+#: app/assets/javascripts/app/controllers/signup.coffee:124
 #: app/frontend/apps/desktop/pages/authentication/views/Signup.vue:91
 msgid "Email sent to \"%s\". Please verify your email account."
 msgstr ""
@@ -6555,7 +6555,7 @@ msgstr ""
 msgid "Generate Token"
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:241
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:240
 #: app/assets/javascripts/app/views/profile/password.jst.eco:113
 msgid "Generate recovery codes"
 msgstr ""
@@ -11544,7 +11544,7 @@ msgstr ""
 msgid "Remove selected values"
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:177
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:176
 msgid "Remove two-factor authentication"
 msgstr ""
 
@@ -14299,7 +14299,7 @@ msgstr ""
 msgid "The parameter 'mentionable_type' is invalid."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:136
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:135
 #: app/assets/javascripts/app/controllers/password_reset_verify.coffee:143
 msgid "The password could not be set. Please contact your administrator."
 msgstr ""
@@ -16177,13 +16177,13 @@ msgstr ""
 msgid "Two-factor authentication method could not be initiated."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:191
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:190
 #: app/frontend/apps/desktop/components/TwoFactor/TwoFactorConfiguration/TwoFactorConfigurationSecurityKeys.vue:156
 #: app/frontend/apps/desktop/pages/personal-setting/views/PersonalSettingTwoFactorAuth.vue:126
 msgid "Two-factor authentication method was removed."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/_profile/password.coffee:221
+#: app/assets/javascripts/app/controllers/_profile/password.coffee:220
 #: app/frontend/apps/desktop/pages/personal-setting/views/PersonalSettingTwoFactorAuth.vue:98
 msgid "Two-factor authentication method was set as default."
 msgstr ""
@@ -16653,8 +16653,8 @@ msgstr ""
 msgid "User authorization failed."
 msgstr ""
 
-#: app/assets/javascripts/app/controllers/getting_started/admin.coffee:104
-#: app/assets/javascripts/app/controllers/signup.coffee:98
+#: app/assets/javascripts/app/controllers/getting_started/admin.coffee:108
+#: app/assets/javascripts/app/controllers/signup.coffee:102
 #: app/frontend/apps/mobile/entities/user/composables/useUserCreate.ts:55
 msgid "User could not be created."
 msgstr ""

+ 10 - 2
lib/password_policy.rb

@@ -4,7 +4,15 @@
 class PasswordPolicy
   include ::Mixin::HasBackends
 
-  class PasswordPolicy::Error < StandardError; end
+  class PasswordPolicy::Error < StandardError
+    attr_reader :metadata
+
+    def initialize(metadata)
+      @metadata = metadata
+
+      super(metadata.try(:first))
+    end
+  end
 
   attr_reader :password
 
@@ -16,7 +24,7 @@ class PasswordPolicy
   def valid!
     return if valid?
 
-    raise PasswordPolicy::Error, error.first
+    raise PasswordPolicy::Error, error
   end
 
   def valid?

+ 1 - 1
spec/requests/user/password_reset_verify_spec.rb

@@ -52,7 +52,7 @@ RSpec.describe 'User password reset verify endpoint', authenticated_as: false, t
 
     it 'returns failure with notice', if: notice do
       send_request
-      expect(json_response).to include({ 'message' => 'failed', 'notice' => [include(notice)] })
+      expect(json_response).to include({ 'message' => 'failed', 'notice' => include(start_with(notice)) })
     end
   end
 

+ 2 - 2
spec/requests/user_spec.rb

@@ -106,7 +106,7 @@ RSpec.describe 'User', performs_jobs: true, type: :request do
       params = { email: 'some_new_customer@example.com', signup: true }
       post '/api/v1/users', params: params, headers: headers, as: :json
       expect(response).to have_http_status(:unprocessable_entity)
-      expect(json_response['error']).to be_truthy
+      expect(json_response['message']).to eq('failed')
 
       # already existing user with enabled feature, pretend signup is successful
       params = { email: 'rest-customer1@example.com', password: 'asd1ASDasd!', signup: true }
@@ -212,7 +212,7 @@ RSpec.describe 'User', performs_jobs: true, type: :request do
         params = { email: 'some_new_customer@example.com', password: 'asdasdasdasd', signup: true }
         post '/api/v1/users', params: params, headers: headers, as: :json
         expect(response).to have_http_status(:unprocessable_entity)
-        expect(json_response['error']).to include('Invalid password')
+        expect(json_response['notice']).to include(include('Invalid password'))
       end
 
       it 'verified with no current user', authenticated_as: :admin do