diff --git a/app/controllers/devise_overrides/sessions_controller.rb b/app/controllers/devise_overrides/sessions_controller.rb
index bf3a7f221..974fb05e4 100644
--- a/app/controllers/devise_overrides/sessions_controller.rb
+++ b/app/controllers/devise_overrides/sessions_controller.rb
@@ -12,9 +12,11 @@ class DeviseOverrides::SessionsController < DeviseTokenAuth::SessionsController
return handle_mfa_verification if mfa_verification_request?
return handle_sso_authentication if sso_authentication_request?
- super do |resource|
- return handle_mfa_required(resource) if resource&.mfa_enabled?
- end
+ user = find_user_for_authentication
+ return handle_mfa_required(user) if user&.mfa_enabled?
+
+ # Only proceed with standard authentication if no MFA is required
+ super
end
def render_create_success
@@ -23,6 +25,17 @@ class DeviseOverrides::SessionsController < DeviseTokenAuth::SessionsController
private
+ def find_user_for_authentication
+ return nil unless params[:email].present? && params[:password].present?
+
+ normalized_email = params[:email].strip.downcase
+ user = User.from_email(normalized_email)
+ return nil unless user&.valid_password?(params[:password])
+ return nil unless user.active_for_authentication?
+
+ user
+ end
+
def mfa_verification_request?
params[:mfa_token].present?
end
@@ -59,10 +72,10 @@ class DeviseOverrides::SessionsController < DeviseTokenAuth::SessionsController
@resource = user if user&.valid_sso_auth_token?(params[:sso_auth_token])
end
- def handle_mfa_required(resource)
+ def handle_mfa_required(user)
render json: {
mfa_required: true,
- mfa_token: Mfa::TokenService.new(user: resource).generate_token
+ mfa_token: Mfa::TokenService.new(user: user).generate_token
}, status: :partial_content
end
diff --git a/app/controllers/super_admin/users_controller.rb b/app/controllers/super_admin/users_controller.rb
index ff242030a..e98e61c95 100644
--- a/app/controllers/super_admin/users_controller.rb
+++ b/app/controllers/super_admin/users_controller.rb
@@ -13,11 +13,11 @@ class SuperAdmin::UsersController < SuperAdmin::ApplicationController
redirect_to new_super_admin_user_path, notice: notice
end
end
- #
- # def update
- # super
- # send_foo_updated_email(requested_resource)
- # end
+
+ def update
+ requested_resource.skip_reconfirmation! if resource_params[:confirmed_at].present?
+ super
+ end
# Override this method to specify custom lookup behavior.
# This will be used to set the resource for the `show`, `edit`, and `update`
diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb
index 8abdefd1a..753b617ef 100644
--- a/app/dashboards/user_dashboard.rb
+++ b/app/dashboards/user_dashboard.rb
@@ -59,11 +59,11 @@ class UserDashboard < Administrate::BaseDashboard
SHOW_PAGE_ATTRIBUTES = %i[
id
avatar_url
- unconfirmed_email
name
type
display_name
email
+ unconfirmed_email
created_at
updated_at
confirmed_at
diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json
index a7db8480f..21e8dd1b2 100644
--- a/app/javascript/dashboard/i18n/locale/en/contact.json
+++ b/app/javascript/dashboard/i18n/locale/en/contact.json
@@ -555,10 +555,12 @@
"WROTE": "wrote",
"YOU": "You",
"SAVE": "Save note",
+ "ADD_NOTE": "Add contact note",
"EXPAND": "Expand",
"COLLAPSE": "Collapse",
"NO_NOTES": "No notes, you can add notes from the contact details page.",
- "EMPTY_STATE": "There are no notes associated to this contact. You can add a note by typing in the box above."
+ "EMPTY_STATE": "There are no notes associated to this contact. You can add a note by typing in the box above.",
+ "CONVERSATION_EMPTY_STATE": "There are no notes yet. Use the Add note button to create one."
}
},
"EMPTY_STATE": {
diff --git a/app/javascript/dashboard/i18n/locale/en/login.json b/app/javascript/dashboard/i18n/locale/en/login.json
index ec5658db2..864c76359 100644
--- a/app/javascript/dashboard/i18n/locale/en/login.json
+++ b/app/javascript/dashboard/i18n/locale/en/login.json
@@ -22,6 +22,20 @@
},
"FORGOT_PASSWORD": "Forgot your password?",
"CREATE_NEW_ACCOUNT": "Create a new account",
- "SUBMIT": "Login"
+ "SUBMIT": "Login",
+ "SAML": {
+ "LABEL": "Log in via SSO",
+ "TITLE": "Initiate Single Sign-on (SSO)",
+ "SUBTITLE": "Enter your work email to access your organization",
+ "BACK_TO_LOGIN": "Login via Password",
+ "WORK_EMAIL": {
+ "LABEL": "Work Email",
+ "PLACEHOLDER": "Enter your work email"
+ },
+ "SUBMIT": "Continue with SSO",
+ "API": {
+ "ERROR_MESSAGE": "SSO authentication failed"
+ }
+ }
}
}
diff --git a/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactNotes.vue b/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactNotes.vue
index 66b6876b1..c828c60ef 100644
--- a/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactNotes.vue
+++ b/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactNotes.vue
@@ -1,21 +1,34 @@
-