FIX: only invalidate password reset links using javascript
This commit is contained in:
parent
0ba1e8a76f
commit
c7df6783a9
|
@ -23,6 +23,7 @@ class UsersController < ApplicationController
|
|||
:send_activation_email,
|
||||
:authorize_email,
|
||||
:password_reset,
|
||||
:confirm_email_token,
|
||||
:admin_login]
|
||||
|
||||
def index
|
||||
|
@ -355,7 +356,12 @@ class UsersController < ApplicationController
|
|||
expires_now
|
||||
|
||||
if EmailToken.valid_token_format?(params[:token])
|
||||
@user = EmailToken.confirm(params[:token])
|
||||
if request.put?
|
||||
@user = EmailToken.confirm(params[:token])
|
||||
else
|
||||
email_token = EmailToken.confirmable(params[:token])
|
||||
@user = email_token.try(:user)
|
||||
end
|
||||
|
||||
if @user
|
||||
session["password-#{params[:token]}"] = @user.id
|
||||
|
@ -387,6 +393,12 @@ class UsersController < ApplicationController
|
|||
render layout: 'no_ember'
|
||||
end
|
||||
|
||||
def confirm_email_token
|
||||
expires_now
|
||||
EmailToken.confirm(params[:token])
|
||||
render json: success_json
|
||||
end
|
||||
|
||||
def logon_after_password_reset
|
||||
message = if Guardian.new(@user).can_access_forum?
|
||||
# Log in the user
|
||||
|
|
|
@ -44,7 +44,7 @@ class EmailToken < ActiveRecord::Base
|
|||
def self.confirm(token)
|
||||
return unless valid_token_format?(token)
|
||||
|
||||
email_token = EmailToken.where("token = ? and expired = FALSE AND ((NOT confirmed AND created_at >= ?) OR (confirmed AND created_at >= ?))", token, EmailToken.valid_after, EmailToken.confirm_valid_after).includes(:user).first
|
||||
email_token = confirmable(token)
|
||||
return if email_token.blank?
|
||||
|
||||
user = email_token.user
|
||||
|
@ -59,12 +59,17 @@ class EmailToken < ActiveRecord::Base
|
|||
user.save!
|
||||
end
|
||||
end
|
||||
|
||||
# redeem invite, if available
|
||||
return User.find_by(email: Email.downcase(user.email)) if Invite.redeem_from_email(user.email).present?
|
||||
user
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
# If the user's email is already taken, just return nil (failure)
|
||||
end
|
||||
|
||||
def self.confirmable(token)
|
||||
EmailToken.where("token = ? and expired = FALSE AND ((NOT confirmed AND created_at >= ?) OR (confirmed AND created_at >= ?))", token, EmailToken.valid_after, EmailToken.confirm_valid_after).includes(:user).first
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
<%end%>
|
||||
</div>
|
||||
|
||||
<%- content_for(:no_ember_head) do %>
|
||||
<%= script "ember_jquery" %>
|
||||
<%- end %>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementById('user_password').focus();
|
||||
|
||||
|
@ -56,4 +60,6 @@
|
|||
sk = e.shiftKey?e.shiftKey:((kc == 16)?true:false);
|
||||
(((kc >= 65 && kc <= 90) && !sk)||((kc >= 97 && kc <= 122) && sk)) ? document.getElementById('capsLockWarning').style.visibility = 'visible' : document.getElementById('capsLockWarning').style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
$.ajax('<%= path "/users/confirm-email-token/#{params[:token]}" %>', {dataType: 'json'});
|
||||
</script>
|
||||
|
|
|
@ -266,6 +266,7 @@ Discourse::Application.routes.draw do
|
|||
get "users/search/users" => "users#search_users"
|
||||
get "users/account-created/" => "users#account_created"
|
||||
get "users/password-reset/:token" => "users#password_reset"
|
||||
get "users/confirm-email-token/:token" => "users#confirm_email_token", constraints: { format: 'json' }
|
||||
put "users/password-reset/:token" => "users#password_reset"
|
||||
get "users/activate-account/:token" => "users#activate_account"
|
||||
put "users/activate-account/:token" => "users#perform_account_activation", as: 'perform_activate_account'
|
||||
|
|
|
@ -326,6 +326,16 @@ describe UsersController do
|
|||
expect(user.auth_token).to_not eq old_token
|
||||
expect(user.auth_token.length).to eq 32
|
||||
end
|
||||
|
||||
it "doesn't invalidate the token when loading the page" do
|
||||
user = Fabricate(:user, auth_token: SecureRandom.hex(16))
|
||||
email_token = user.email_tokens.create(email: user.email)
|
||||
|
||||
get :password_reset, token: email_token.token
|
||||
|
||||
email_token.reload
|
||||
expect(email_token.confirmed).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'submit change' do
|
||||
|
@ -361,6 +371,24 @@ describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.confirm_email_token' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
it "token doesn't match any records" do
|
||||
email_token = user.email_tokens.create(email: user.email)
|
||||
get :confirm_email_token, token: SecureRandom.hex, format: :json
|
||||
expect(response).to be_success
|
||||
expect(email_token.reload.confirmed).to eq(false)
|
||||
end
|
||||
|
||||
it "token matches" do
|
||||
email_token = user.email_tokens.create(email: user.email)
|
||||
get :confirm_email_token, token: email_token.token, format: :json
|
||||
expect(response).to be_success
|
||||
expect(email_token.reload.confirmed).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.admin_login' do
|
||||
let(:admin) { Fabricate(:admin) }
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
|
Loading…
Reference in New Issue