lynndylanhurley/devise_token_auth

Default URL params confirmation_instructions.html.erb conflicts with ones permitted in DeviseTokenAuth::ConfirmationsController

BirkhoffLee opened this issue · 0 comments

  • Version: 1.2.1
  • Request and response headers:
    > curl -v "http://localhost:3000/api/v1/recruitment/auth/applicant/confirmation?config=default&confirmation_token=2E2sF2z_uz_GZCWUYzqv&redirect_url=%2F"
    *   Trying 127.0.0.1:3000...
    * Connected to localhost (127.0.0.1) port 3000 (#0)
    > GET /api/v1/recruitment/auth/applicant/confirmation?config=default&confirmation_token=2E2sF2z_uz_GZCWUYzqv&redirect_url=%2F HTTP/1.1
    > Host: localhost:3000
    > User-Agent: curl/7.79.1
    > Accept: */*
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 404 Not Found
    < Content-Type: application/json; charset=UTF-8
    < X-Request-Id: 6ec5463a-ee44-464d-bdb5-40f0d9a8f372
    < X-Runtime: 0.156990
    < Server-Timing: start_processing.action_controller;dur=0.10, unpermitted_parameters.action_controller;dur=0.04, sql.active_record;dur=2.24, instantiation.active_record;dur=8.55, process_action.action_controller;dur=14.98
    < Content-Length: 17250
    < 
    {"status":404,"error":"Not Found","exception":"...
    
  • Rails Stacktrace: None
  • Environmental Info:
    • Routes: Nothing special
    • Gems: Nothing special
    • Custom Overrides: None
    • Custom Frontend: Not yet

The Issue

I'm new to Ruby and Rails, trying to build a RESTful API with Rails 7 API mode. Our team is trying to integrate this gem and when developing the email confirmation feature I found Rails keep complaining about

Started GET "/api/v1/recruitment/auth/applicant/confirmation?config=default&confirmation_token=[FILTERED]&redirect_url=%2F" for 127.0.0.1 at 2022-10-06 21:20:05 +0800
Processing by DeviseTokenAuth::ConfirmationsController#show as */*
  Parameters: {"config"=>"default", "confirmation_token"=>"[FILTERED]", "redirect_url"=>"/"}
Unpermitted parameters: :config, :redirect_url. Context: { controller: DeviseTokenAuth::ConfirmationsController, action: show, request: #<ActionDispatch::Request:0x000000010b3b3420>, params: {"config"=>"default", "confirmation_token"=>"[FILTERED]", "redirect_url"=>"/", "controller"=>"devise_token_auth/confirmations", "action"=>"show"} }
  RApplicant Load (0.1ms)  SELECT "r_applicants".* FROM "r_applicants" WHERE "r_applicants"."confirmation_token" = ? ORDER BY "r_applicants"."id" ASC LIMIT ?  [["confirmation_token", "[FILTERED]"], ["LIMIT", 1]]
Completed 404 Not Found in 15ms (ActiveRecord: 0.9ms | Allocations: 8631)

ActionController::RoutingError (Not Found):

In particular, take a look on this:

Unpermitted parameters: :config, :redirect_url. Context: { controller: DeviseTokenAuth::ConfirmationsController, action: show, request: #<ActionDispatch::Request:0x000000010b3b3420>, params: {"config"=>"default", "confirmation_token"=>"[FILTERED]", "redirect_url"=>"/", "controller"=>"devise_token_auth/confirmations", "action"=>"show"} }

What I have tried

After hours of research I found some evidence indicating that this is a devise_token_auth bug, yet I had to do some more research on Strong Parameters, and I learned that somewhere in the ConfirmationsController there are those "Strong Parameters Settings", which is in app/controllers/devise_token_auth/confirmations_controller.rb#L74:

...
    private

    def resource_params
      params.permit(:email, :confirmation_token, :config_name)
    end
...

These params do not match the ones in the default email template:

<p><%= link_to t('.confirm_account_link'), confirmation_url(@resource, {confirmation_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url']}).html_safe %></p>

This is obviously why Rails did not complain about confirmation_token - because it's the only param overlapping in both places.

Mitigations

Right now before there is a fix, a temporal fix is to override resource_params method in DeviseTokenAuth::ConfirmationsController:

class Auth::ConfirmationsController < DeviseTokenAuth::ConfirmationsController
  private
    def resource_params
      params.permit(:email, :confirmation_token, :config_name, :redirect_url)
    end
end

and use this controller with:

mount_devise_token_auth_for 'RApplicant', at: 'api/v1/recruitment/auth/applicant', controllers: {
  confirmations: 'auth/confirmations'
}

Potential fix

Have the strong params in confirmations_controller.rb match with the ones in confirmation_instructions.html.erb.