From 385bea56f7ac77f0c992a8d87339b339351ea55c Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz <40526225+ArcaEge@users.noreply.github.com> Date: Tue, 9 Dec 2025 23:22:44 +0000 Subject: [PATCH] add ability to unlink emails (#698) --- app/controllers/sessions_controller.rb | 34 ++++++++++++++++++++++++++ app/models/email_address.rb | 5 ++++ app/models/user.rb | 9 +++++++ app/views/users/edit.html.erb | 20 +++++++++++---- config/routes.rb | 1 + 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 160e338..db4ba7a 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -172,6 +172,40 @@ class SessionsController < ApplicationController redirect_to my_settings_path, alert: "Failed to add email: #{e.record.errors.full_messages.join(', ')}" end + def unlink_email + unless current_user + redirect_to root_path, alert: "Please sign in first to unlink an email" + return + end + + email = params[:email].downcase + + email_record = current_user.email_addresses.find_by( + email: email + ) + + unless email_record + redirect_to my_settings_path, alert: "Email must exist to be unlinked" + return + end + + unless current_user.can_delete_email_address?(email_record) + redirect_to my_settings_path, alert: "Email must be registered for signing in to unlink" + return + end + + email_verification_request = current_user.email_verification_requests.find_by( + email: email + ) + + email_record.destroy! + email_verification_request.destroy + + redirect_to my_settings_path, notice: "Email unlinked!" + rescue ActiveRecord::RecordNotDestroyed => e + redirect_to my_settings_path, alert: "Failed to unlink email: #{e.record.errors.full_messages.join(', ')}" + end + def token verification_request = EmailVerificationRequest.valid.find_by(token: params[:token]) diff --git a/app/models/email_address.rb b/app/models/email_address.rb index ea82c15..501263d 100644 --- a/app/models/email_address.rb +++ b/app/models/email_address.rb @@ -15,6 +15,11 @@ class EmailAddress < ApplicationRecord before_validation :downcase_email + def can_unlink? + # only allow unlinking if signin email + self.source_signing_in? + end + private def downcase_email diff --git a/app/models/user.rb b/app/models/user.rb index 298e27f..33547c3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -153,6 +153,15 @@ class User < ApplicationRecord last_audit.created_at <= 365.days.ago end + def can_delete_emails? + # don't let user delete emails if email count is <= 1 + email_addresses.size > 1 + end + + def can_delete_email_address?(email) + email.can_unlink? && can_delete_emails? + end + if Rails.env.development? def self.slow_find_by_email(email) # This is an n+1 query, but provided for developer convenience diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 6c7ef84..3736aa5 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -245,11 +245,21 @@ <% if @user.email_addresses.any? %>