From 8f8ea735ee0f8ac8f328abcf676fb6467692ce54 Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Thu, 25 Sep 2014 17:42:48 +1000
Subject: [PATCH] FIX: allow retry activation of account by username or
 password

---
 app/assets/javascripts/admin/models/admin_user.js           | 2 +-
 .../javascripts/discourse/controllers/not-activated.js.es6  | 2 +-
 app/controllers/users_controller.rb                         | 6 +++++-
 config/routes.rb                                            | 2 +-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/app/assets/javascripts/admin/models/admin_user.js b/app/assets/javascripts/admin/models/admin_user.js
index 7a719e3db..d1f7a4aac 100644
--- a/app/assets/javascripts/admin/models/admin_user.js
+++ b/app/assets/javascripts/admin/models/admin_user.js
@@ -266,7 +266,7 @@ Discourse.AdminUser = Discourse.User.extend({
   },
 
   sendActivationEmail: function() {
-    Discourse.ajax('/users/' + this.get('username') + '/send_activation_email', {type: 'POST'}).then(function() {
+    Discourse.ajax('/users/action/send_activation_email', {data: {username: this.get('username')}, type: 'POST'}).then(function() {
       // succeeded
       bootbox.alert( I18n.t('admin.user.activation_email_sent') );
     }, function(e) {
diff --git a/app/assets/javascripts/discourse/controllers/not-activated.js.es6 b/app/assets/javascripts/discourse/controllers/not-activated.js.es6
index 802dee646..40fdf41b0 100644
--- a/app/assets/javascripts/discourse/controllers/not-activated.js.es6
+++ b/app/assets/javascripts/discourse/controllers/not-activated.js.es6
@@ -7,7 +7,7 @@ export default DiscourseController.extend(ModalFunctionality, {
 
   actions: {
     sendActivationEmail: function() {
-      Discourse.ajax('/users/' + this.get('username') + '/send_activation_email', {type: 'POST'});
+      Discourse.ajax('/users/action/send_activation_email', {data: {username: this.get('username')}, type: 'POST'});
       this.set('emailSent', true);
     }
   }
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index f7fa076d0..3b2333a2b 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -325,7 +325,11 @@ class UsersController < ApplicationController
   end
 
   def send_activation_email
-    @user = fetch_user_from_params(include_inactive: true)
+
+    RateLimiter.new(nil, "activate-hr-#{request.remote_ip}", 30, 1.hour).performed!
+    RateLimiter.new(nil, "activate-min-#{request.remote_ip}", 6, 1.minute).performed!
+
+    @user = User.find_by_username_or_email(params[:username].to_s)
     @email_token = @user.email_tokens.unconfirmed.active.first
     enqueue_activation_email if @user
     render nothing: true
diff --git a/config/routes.rb b/config/routes.rb
index f5d84b627..e2bc53d64 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -232,7 +232,7 @@ Discourse::Application.routes.draw do
   delete "users/:username/preferences/user_image" => "users#destroy_user_image", constraints: {username: USERNAME_ROUTE_FORMAT}
   put "users/:username/preferences/avatar/pick" => "users#pick_avatar", constraints: {username: USERNAME_ROUTE_FORMAT}
   get "users/:username/invited" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT}
-  post "users/:username/send_activation_email" => "users#send_activation_email", constraints: {username: USERNAME_ROUTE_FORMAT}
+  post "users/action/send_activation_email" => "users#send_activation_email"
   get "users/:username/activity" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
   get "users/:username/activity/:filter" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
   get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}