janko / rodauth-rails

Rails integration for Rodauth authentication framework
https://github.com/jeremyevans/rodauth
MIT License
571 stars 40 forks source link

Roda views and how to edit them #62

Closed woller closed 2 years ago

woller commented 2 years ago

Hi and thanks for a great gem.

I am currently using this gem to implement a couple of different user types in an app, where account creation is done entirely in the back end. In my accounts table, I have a couple of extra fields (phone and name).

I currently have this implementation, but it both costs an extra query and comes with a risky race condition.

  def create
    RodauthApp.rodauth(:admin).create_account(rodauth_admin_params)
    Admin.last.update(admin_params.except(:email))

    redirect_to admins_path
  end

In the rodauth documentation I found this guide explaining how to send extra params during account creation: http://rodauth.jeremyevans.net/rdoc/files/doc/guides/registration_field_rdoc.html#top Specifically this seems to be the solution to my problem:

You need to override the create-account template, which by default in Rodauth you can do by adding a create-account.erb template in your Roda views directory.

But I cannot figure out where to do this in rodauth-rails.

The configuration for my admin account looks like this:

  # ==> Secondary configurations
  configure(:admin) do
    enable :create_account, :verify_account, :verify_account_grace_period,
    :login, :logout, :remember,
    :reset_password, :change_password, :change_password_notify,
    :change_login, :verify_login_change,
    :close_account, :internal_request

    account_status_column :status
    account_unverified_status_value "unverified"
    account_open_status_value "verified"
    account_closed_status_value "closed"

    # Set password when creating account instead of when verifying.
    verify_account_set_password? true

    before_create_account do
      throw_error_status(422, "name", "must be present") if param("name").empty?
      throw_error_status(422, "phone", "must be present") if param("phone").empty?
      account[:name] = param("name")
      account[:phone] = param("phone")
      account[:type] = "Admin"
    end

    methods.grep(/_table$/) do |table_method|
      public_send(table_method) { super().to_s.sub("account", "user").to_sym }
    end
  end
janko commented 2 years ago

Have you seen the views section in the rodauth-rails README?

woller commented 2 years ago

I had misdiagnosed the problem. When I called RodauthApp.rodauth(:admin).create_account(rodauth_admin_params), I got a warning and then an error

unhandled options passed to create_account: {"name"=>"Erik Eriksen", "phone"=>"22334455"}
Rodauth::InternalRequestError: There was an error creating your account ({"name"=>"must be present"})

Turns out I needed to call create_account with params as a keyword:

RodauthApp.rodauth(:admin).create_account(params: rodauth_admin_params)

Now everything works as expected.