| 1 | # frozen_string_literal: true |
| 2 | |
| 3 | class PasswordsController < ApplicationController |
| 4 | before_action :noindex! |
| 5 | before_action :redirect_if_signed_in |
| 6 | |
| 7 | # GET /auth/password/reset |
| 8 | def new |
| 9 | end |
| 10 | |
| 11 | # POST /auth/password/reset |
| 12 | def create |
| 13 | email = params[:email].to_s.strip.downcase |
| 14 | |
| 15 | if email.blank? |
| 16 | flash.now[:alert] = "Email is required." |
| 17 | return render :new, status: :unprocessable_entity |
| 18 | end |
| 19 | |
| 20 | SmbcloudAuthService.reset_password(email: email) |
| 21 | |
| 22 | # The endpoint never reveals whether the account exists, so we always show |
| 23 | # the same neutral message. |
| 24 | redirect_to signin_path, |
| 25 | notice: "If that email has an account, we've sent password reset instructions. Please check your inbox." |
| 26 | |
| 27 | rescue KeyError => e |
| 28 | Rails.logger.error("smbCloud configuration error during reset password: #{e.message}") |
| 29 | flash.now[:alert] = "Authentication service is not configured. Please contact support." |
| 30 | render :new, status: :internal_server_error |
| 31 | |
| 32 | rescue SmbcloudAuthService::AuthenticationError => e |
| 33 | Rails.logger.warn("reset password failed for #{email.inspect}: #{e.message}") |
| 34 | flash.now[:alert] = "Something went wrong sending the reset email. Please try again." |
| 35 | render :new, status: :internal_server_error |
| 36 | end |
| 37 | |
| 38 | # GET /auth/password/edit?reset_password_token=... |
| 39 | # Landing page from the reset email (smbCloud redirects here). Shows the form |
| 40 | # to choose a new password; the token rides in a hidden field. |
| 41 | def edit |
| 42 | @reset_password_token = params[:reset_password_token].to_s |
| 43 | end |
| 44 | |
| 45 | # POST /auth/password/edit |
| 46 | def update |
| 47 | @reset_password_token = params[:reset_password_token].to_s |
| 48 | password = params[:password].to_s |
| 49 | password_confirmation = params[:password_confirmation].to_s |
| 50 | |
| 51 | if @reset_password_token.blank? |
| 52 | flash.now[:alert] = "This reset link is missing its token. Please request a new one." |
| 53 | return render :edit, status: :unprocessable_entity |
| 54 | end |
| 55 | |
| 56 | if password.blank? |
| 57 | flash.now[:alert] = "Please enter a new password." |
| 58 | return render :edit, status: :unprocessable_entity |
| 59 | end |
| 60 | |
| 61 | SmbcloudAuthService.complete_password_reset( |
| 62 | reset_password_token: @reset_password_token, |
| 63 | password: password, |
| 64 | password_confirmation: password_confirmation |
| 65 | ) |
| 66 | |
| 67 | redirect_to signin_path, notice: "Your password has been reset. Please sign in." |
| 68 | |
| 69 | rescue KeyError => e |
| 70 | Rails.logger.error("smbCloud configuration error during reset complete: #{e.message}") |
| 71 | flash.now[:alert] = "Authentication service is not configured. Please contact support." |
| 72 | render :edit, status: :internal_server_error |
| 73 | |
| 74 | rescue SmbcloudAuthService::AuthenticationError => e |
| 75 | Rails.logger.warn("reset password complete failed: #{e.message}") |
| 76 | flash.now[:alert] = e.message.presence || |
| 77 | "We couldn't reset your password. The link may have expired — request a new one." |
| 78 | render :edit, status: :unprocessable_entity |
| 79 | end |
| 80 | |
| 81 | private |
| 82 | |
| 83 | def redirect_if_signed_in |
| 84 | redirect_to root_path, notice: "You are already signed in." if signed_in? |
| 85 | end |
| 86 | end |