From 88a2688ac83acb410e2435be2e8ee80a9148a42d Mon Sep 17 00:00:00 2001 From: Emi Matchu Date: Sun, 7 Apr 2024 07:52:23 -0700 Subject: [PATCH] Add form to disconnect NeoPass Can't connect it back yet! But you can disconnect it! :3 --- .../devise/registrations/edit.sass | 3 -- .../neopass_connections_controller.rb | 29 +++++++++++++++++++ app/models/auth_user.rb | 21 ++++++++++++++ app/models/user.rb | 2 +- app/views/devise/registrations/edit.html.erb | 11 +++++-- config/routes.rb | 2 ++ 6 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 app/controllers/neopass_connections_controller.rb diff --git a/app/assets/stylesheets/devise/registrations/edit.sass b/app/assets/stylesheets/devise/registrations/edit.sass index f003c168..8e942239 100644 --- a/app/assets/stylesheets/devise/registrations/edit.sass +++ b/app/assets/stylesheets/devise/registrations/edit.sass @@ -53,6 +53,3 @@ .neopass-explanation font-size: .85em - - p:last-of-type - margin-bottom: 0 diff --git a/app/controllers/neopass_connections_controller.rb b/app/controllers/neopass_connections_controller.rb new file mode 100644 index 00000000..050d755f --- /dev/null +++ b/app/controllers/neopass_connections_controller.rb @@ -0,0 +1,29 @@ +class NeopassConnectionsController < ApplicationController + def destroy + @user = load_user + + if @user.disconnect_neopass + flash[:notice] = "Your NeoPass has been disconnected. In the future, " + + "to log into this account, you'll need to use your password or your " + + "recovery email. You can also connect a different NeoPass, if you'd " + + "like." + else + flash[:alert] = "Whoops, there was an error disconnecting your " + + "NeoPass from your account, sorry. If this keeps happening, let us " + + "know!" + end + + redirect_to edit_auth_user_registration_path + end + + private + + def load_user + # Well, what we *actually* do is just use `current_user`, and enforce that + # the provided user ID matches. The user ID param is only really for REST + # semantics and such! + raise AccessDenied unless user_signed_in? + raise AccessDenied unless current_user.id.to_s == params[:user_id] + current_user + end +end diff --git a/app/models/auth_user.rb b/app/models/auth_user.rb index 17424324..a6d077e0 100644 --- a/app/models/auth_user.rb +++ b/app/models/auth_user.rb @@ -48,6 +48,27 @@ class AuthUser < AuthRecord neopass_email || uid end + def disconnect_neopass + # If there's no NeoPass, we're already done! + return true if !neopass? + + begin + # Remove all of the NeoPass fields, and return whether we were + # successful. (I don't know why it wouldn't be, but let's be resilient!) + # + # NOTE: I considered leaving `neopass_email` in place, to help us support + # users who accidentally got locked out… but I think it's more + # important to respect data privacy and not be holding onto an + # email address the user doesn't realize we have! + update(provider: nil, uid: nil, neopass_email: nil) + rescue => error + # If something strange happens, log it and gracefully return `false`! + Sentry.capture_exception error + Rails.logger.error error + false + end + end + def self.from_omniauth(auth) raise MissingAuthInfoError, "Email missing" if auth.info.email.blank? diff --git a/app/models/user.rb b/app/models/user.rb index e78f646c..058250d4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,7 +4,7 @@ class User < ApplicationRecord PreviewTopContributorsCount = 3 belongs_to :auth_user, foreign_key: :remote_id, inverse_of: :user - delegate :neopass?, to: :auth_user + delegate :neopass?, :disconnect_neopass, to: :auth_user has_many :closet_hangers has_many :closet_lists diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 15aa2502..790296aa 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -53,8 +53,14 @@ <% end %> <% if resource.neopass? %> - <%= form_with model: resource, url: registration_path(resource_name), - html: { method: :put, class: "settings-form" } do |form| %> + <%= form_with url: user_neopass_connection_path(resource), method: :delete, + class: "settings-form", data: { + turbo_confirm: "Are you sure? Without a NeoPass, you'll need to use " + + "your password or your recovery email \"#{resource.email}\" to " + + "log in again.\n\nMake sure you have everything all set up first! " + + "Otherwise, you might be locked out of this account forever!" + } do |form| + %>

Your NeoPass

@@ -70,6 +76,7 @@ Impress account, using the Email saved in "Your info".

+ <%= form.submit "Disconnect your NeoPass" %> <% end %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index 27e874cb..cc41e4ac 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -66,6 +66,8 @@ OpenneoImpressItems::Application.routes.draw do resources :neopets_connections, path: 'neopets-connections', only: [:create, :destroy] + + resource :neopass_connection, path: "neopass-connection", only: [:destroy] end get 'users/current-user/closet' => 'closet_hangers#index', :as => :your_items