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
.