module Api module V1 class AuthController < BaseController skip_before_action :authenticate_api_user!, only: %i[login register confirm resend_confirmation forgot_password reset_password] def login user = User.find_for_database_authentication(email: params[:email].to_s.downcase.strip) return render json: { error: "E-Mail oder Passwort ist falsch" }, status: :unauthorized unless user&.valid_password?(params[:password]) return render json: { error: "E-Mail-Adresse wurde noch nicht bestätigt" }, status: :forbidden unless user.confirmed? token = SecureRandom.hex(32) user.update!(api_token_digest: Digest::SHA256.hexdigest(token)) render json: { token:, user: user_payload(user) } end def register user = User.new(email: params[:email], password: params[:password], password_confirmation: params[:password_confirmation]) if user.save render json: { message: "Registrierung erfolgreich. Bitte E-Mail bestätigen." }, status: :created else render_validation(user) end end def confirm user = User.confirm_by_token(params[:token].to_s) if user.errors.empty? render json: { message: "E-Mail-Adresse wurde bestätigt. Du kannst dich jetzt anmelden." } else render json: { errors: user.errors.full_messages }, status: :unprocessable_entity end end def resend_confirmation user = User.find_by(email: params[:email].to_s.downcase.strip) user&.send_confirmation_instructions unless user&.confirmed? render json: { message: "Falls ein unbestätigtes Konto existiert, wurde ein neuer Bestätigungslink versendet." } end def forgot_password user = User.find_by(email: params[:email].to_s.downcase.strip) user&.send_reset_password_instructions render json: { message: "Falls ein Konto existiert, wurde eine E-Mail zum Zurücksetzen versendet." } end def reset_password user = User.reset_password_by_token( reset_password_token: params[:token], password: params[:password], password_confirmation: params[:password_confirmation] ) if user.errors.empty? user.update!(api_token_digest: nil) render json: { message: "Passwort wurde geändert. Du kannst dich jetzt anmelden." } else render json: { errors: user.errors.full_messages }, status: :unprocessable_entity end end def change_password unless current_user.valid_password?(params[:current_password]) return render json: { error: "Das aktuelle Passwort ist falsch" }, status: :unprocessable_entity end if current_user.update(password: params[:password], password_confirmation: params[:password_confirmation]) current_user.update!(api_token_digest: nil) render json: { message: "Passwort wurde geändert. Bitte melde dich erneut an." } else render_validation(current_user) end end def logout current_user.update!(api_token_digest: nil) head :no_content end def me render json: user_payload(current_user) end private def user_payload(user) { id: user.id, email: user.email, praepedeutikum_done: user.praepedeutikum_done, is_admin: user.is_admin? } end end end end