lynndylanhurley / lynndylanhurley/devise_token_auth
Default URL params confirmation_instructions.html.erb conflicts with ones permitted in DeviseTokenAuth::ConfirmationsController
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 3.6k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
* **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: #, 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: #, 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](https://edgeguides.rubyonrails.org/action_controller_overview.html#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](https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/controllers/devise_token_auth/confirmations_controller.rb#L74):
```ruby
...
private
def resource_params
params.permit(:email, :confirmation_token, :config_name)
end
...
```
These params do not match the ones in the [default email template](https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/views/devise/mailer/confirmation_instructions.html.erb#L5):
```erb
<%= 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 %>
```
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`:
```ruby
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:
```ruby
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`.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Compare app/controllers/devise_token_auth/confirmations_controller.rb#L74 with app/views/devise/mailer/confirmation_instructions.html.erb#L5, focusing on the permitted parameter names and the generated confirmation URL. Verify that the parameters used by the default template are accepted by the controller and that the confirmation request no longer reports them as unpermitted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rails, ruby
- Domain
- api, authentication
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100