Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add create action to confirmations for consistency #547

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 74 additions & 23 deletions app/controllers/devise_token_auth/confirmations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,84 @@
module DeviseTokenAuth
class ConfirmationsController < DeviseTokenAuth::ApplicationController

before_action :setup_confirmation, :only => [:create, :show]

def create
return unless @successful_confirmation
yield if block_given?

update_auth_header
render_create_success
end

def show
@resource = resource_class.confirm_by_token(params[:confirmation_token])

if @resource and @resource.id
# create client id
client_id = SecureRandom.urlsafe_base64(nil, false)
token = SecureRandom.urlsafe_base64(nil, false)
token_hash = BCrypt::Password.create(token)
expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i

@resource.tokens[client_id] = {
token: token_hash,
expiry: expiry
return unless @successful_confirmation
yield if block_given?

redirect_to(@resource.build_auth_url(params[:redirect_url], {
token: @token,
client_id: @client_id,
account_confirmation_success: true,
config: params[:config]
}))
end

private

def setup_confirmation
@successful_confirmation = false

@resource = get_resource

render_create_error_invalid_resource && return \
unless @resource.present?

create_resource_token

render_create_error && return \
unless @resource.save

@successful_confirmation = true
end

def get_resource
resource = resource_class.confirm_by_token(params[:confirmation_token])
resource = nil unless resource.try(:id).present?
resource
end

def create_resource_token
# create client id and token
@client_id = SecureRandom.urlsafe_base64(nil, false)
@token = SecureRandom.urlsafe_base64(nil, false)

# store client + token in user's token hash
@resource.tokens[@client_id] = {
token: BCrypt::Password.create(@token),
expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
}
end

@resource.save!
def render_create_success
render json: {
success: true,
data: @resource.token_validation_response
}
end

yield if block_given?
def render_create_error_invalid_resource
render json: {
success: false,
errors: [I18n.t("devise_token_auth.confirmations.bad_token")]
}, status: 401
end

redirect_to(@resource.build_auth_url(params[:redirect_url], {
token: token,
client_id: client_id,
account_confirmation_success: true,
config: params[:config]
}))
else
raise ActionController::RoutingError.new('Not Found')
def render_create_error
render json: {
success: false,
errors: resource_errors
}, status: 422
end
end

end
end
2 changes: 2 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ en:
password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
missing_passwords: "You must fill out the fields labeled 'Password' and 'Password confirmation'."
successfully_updated: "Your password has been successfully updated."
confirmations:
bad_token: "Invalid confirmation token. Please try email link again."
errors:
messages:
already_in_use: "already in use"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DeviseTokenAuth::ConfirmationsControllerTest < ActionController::TestCase
assert @new_user.confirmation_token
end

describe "success" do
describe "show success" do
before do
xhr :get, :show, {confirmation_token: @token, redirect_url: @redirect_url}
@resource = assigns(:resource)
Expand All @@ -49,13 +49,33 @@ class DeviseTokenAuth::ConfirmationsControllerTest < ActionController::TestCase

describe "failure" do
test "user should not be confirmed" do
assert_raises(ActionController::RoutingError) {
xhr :get, :show, {confirmation_token: "bogus"}
}
xhr :get, :show, {confirmation_token: "bogus"}
assert_equal 401, response.status
end
end

describe "create success" do
before do
xhr :get, :create, {confirmation_token: @token, redirect_url: @redirect_url}
@resource = assigns(:resource)
refute @resource.confirmed?
end

test "user should now be confirmed" do
assert @resource.confirmed?
end

test "should redirect to success url" do
assert_equal 200, response.status
end
end

describe "failure" do
test "user should not be confirmed" do
xhr :get, :create, {confirmation_token: "bogus"}
assert_equal 401, response.status
end
end

end

# test with non-standard user class
Expand Down