I am creating an api in rails and I am implementing the authentication with devise gem. Right now I am creating a custom verify endpoint but I am getting the following error:
Unknown action
Could not find devise mapping for path "/api/v1/verify?confirmation_token=qzfNwsjp3UUPDc7VXrUG".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
get "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
@request.env["devise.mapping"] = Devise.mappings[:user]
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
devise_for :users, path: "", path_names: {
sign_in: "login",
sign_out: "logout",
registration: "signup",
confirmation: "confirm"
}, controllers: {
sessions: "api/v1/users/sessions",
registrations: "api/v1/users/registrations",
confirmations: "api/v1/users/confirmations"
}
devise_scope :user do
get "verify", to: "users/confirmations#verify"
end
end
end
end
This is my confirmations_controller.rb:
# frozen_string_literal: true
class Api::V1::Users::ConfirmationsController < Devise::ConfirmationsController
respond_to :json
prepend_before_action { request.env["devise.mapping"] = Devise.mappings[:user] }
def verify
token = params[:confirmation_token].to_s
user = User.confirm_by_token(token)
if user.errors.empty?
render json: { message: "Email confirmed successfully." }, status: :ok
else
render json: { message: "Email confirmation failed.", errors: user.errors.full_messages }, status: :unprocessable_entity
end
end
end
And this is how I have my controllers:
app
|-controllers
|-api
|-v1
|-users
|-confirmations_controller.rb
|-passwords_controller.rb
|-registrations_controller.rb
|-sessions_controller.rb
|-unlocks_controller.rb
More information:
"devise", "~> 4.9", ">= 4.9.4"
ruby-3.4.5
Rails 8.0.3