Add a link that allows you to send activation email again

This commit is contained in:
Neil Lalonde 2013-02-22 11:49:48 -05:00
parent 45ab3ab892
commit ff3e012034
11 changed files with 106 additions and 3 deletions

View File

@ -0,0 +1,11 @@
<div class="modal-body">
{{#if view.emailSent}}
{{{i18n login.sent_activation_email_again currentEmail="view.currentEmail"}}}
{{else}}
{{{i18n login.not_activated sentTo="view.sentTo"}}}
<a href="#" {{action "sendActivationEmail" target="view"}}>{{i18n login.resend_activation_email}}</a>
{{/if}}
</div>
<div class="modal-footer">
<button class='btn btn-primary' data-dismiss="modal">{{i18n close}}</button>
</div>

View File

@ -45,7 +45,10 @@
}).success(function(result) { }).success(function(result) {
if (result.error) { if (result.error) {
_this.set('loggingIn', false); _this.set('loggingIn', false);
return _this.flash(result.error, 'error'); if( result.reason == 'not_activated' ) {
return _this.showView(Discourse.NotActivatedView.create({username: _this.get('loginName'), sentTo: result.sent_to_email, currentEmail: result.current_email}));
}
_this.flash(result.error, 'error');
} else { } else {
return window.location.reload(); return window.location.reload();
} }

View File

@ -19,7 +19,7 @@
// like an actual ember view // like an actual ember view
flash: function(msg, flashClass) { flash: function(msg, flashClass) {
var $alert; var $alert;
if (!flashClass) flashClass = "success"; if (!flashClass) flashClass = "success";
$alert = jQuery('#modal-alert').hide().removeClass('alert-error', 'alert-success'); $alert = jQuery('#modal-alert').hide().removeClass('alert-error', 'alert-success');
$alert.addClass("alert alert-" + flashClass).html(msg); $alert.addClass("alert alert-" + flashClass).html(msg);
return $alert.fadeIn(); return $alert.fadeIn();

View File

@ -0,0 +1,11 @@
window.Discourse.NotActivatedView = window.Discourse.ModalBodyView.extend(Discourse.Presence, {
templateName: 'modal/not_activated',
title: Em.String.i18n('log_in'),
emailSent: false,
sendActivationEmail: function() {
$.get('/users/' + this.get('username') + '/send_activation_email');
this.set('emailSent', true);
}
});

View File

@ -27,7 +27,7 @@ class SessionController < ApplicationController
render_serialized(@user, UserSerializer) render_serialized(@user, UserSerializer)
return return
else else
render :json => {error: I18n.t("login.not_activated")} render :json => {error: I18n.t("login.not_activated"), reason: 'not_activated', sent_to_email: @user.email_logs.where(email_type: 'signup').order('created_at DESC').first.try(:to_address), current_email: @user.email}
return return
end end
end end

View File

@ -292,6 +292,16 @@ class UsersController < ApplicationController
render :layout => 'no_js' render :layout => 'no_js'
end end
def send_activation_email
@user = fetch_user_from_params
@email_token = @user.email_tokens.unconfirmed.active.first
if @user
@email_token = @user.email_tokens.create(email: @user.email) if @email_token.nil?
Jobs.enqueue(:user_email, type: :signup, user_id: @user.id, email_token: @email_token.token)
end
render nothing: true
end
def search_users def search_users
term = params[:term].to_s.strip term = params[:term].to_s.strip
topic_id = params[:topic_id] topic_id = params[:topic_id]

View File

@ -22,6 +22,14 @@ class EmailToken < ActiveRecord::Base
1.week.ago 1.week.ago
end end
def self.unconfirmed
where(confirmed: false)
end
def self.active
where(expired: false)
end
def self.generate_token def self.generate_token
SecureRandom.hex(EmailToken.token_length) SecureRandom.hex(EmailToken.token_length)
end end

View File

@ -0,0 +1,14 @@
<div id='simple-container'>
<p>
<% if @user %>
<%= t 'login.sent_activate_email_again', email: @user.email %>
<% else %>
<%
# We should never get here because we only show the link to resend
# the activation email if you successfully logged in, but your
# email hasn't been confirmed.
%>
<%= t 'login.incorrect_username_email_or_password' %>
<% end %>
</p>
</div>

View File

@ -233,6 +233,9 @@ en:
authenticating: "Authenticating..." authenticating: "Authenticating..."
awaiting_confirmation: "Your account is awaiting activation, use the forgot password link to issue another activation email." awaiting_confirmation: "Your account is awaiting activation, use the forgot password link to issue another activation email."
awaiting_approval: "Your account has not been approved by a moderator yet. You will receive an email when it is approved." awaiting_approval: "Your account has not been approved by a moderator yet. You will receive an email when it is approved."
not_activated: "You can't log in yet. We sent an activation email to you at <b>{{sentTo}}</b>. Please follow the instructions in the email to activate your account."
resend_activation_email: "Click here to send the activation email again."
sent_activation_email_again: "We sent another activation email to you at your current email address: <b>{{currentEmail}}</b>. It might take a few minutes for it to arrive. Be sure to check your spam folder."
google: google:
title: "Log In with Google" title: "Log In with Google"
message: "Authenticating with Google (make sure pop up blockers are not enabled)" message: "Authenticating with Google (make sure pop up blockers are not enabled)"

View File

@ -96,6 +96,7 @@ Discourse::Application.routes.draw do
put 'users/:username/preferences/username' => 'users#username', :format => false, :constraints => {:username => USERNAME_ROUTE_FORMAT} put 'users/:username/preferences/username' => 'users#username', :format => false, :constraints => {:username => USERNAME_ROUTE_FORMAT}
get 'users/:username/avatar(/:size)' => 'users#avatar', :constraints => {:username => USERNAME_ROUTE_FORMAT} get 'users/:username/avatar(/:size)' => 'users#avatar', :constraints => {:username => USERNAME_ROUTE_FORMAT}
get 'users/:username/invited' => 'users#invited', :constraints => {:username => USERNAME_ROUTE_FORMAT} get 'users/:username/invited' => 'users#invited', :constraints => {:username => USERNAME_ROUTE_FORMAT}
get 'users/:username/send_activation_email' => 'users#send_activation_email', :constraints => {:username => USERNAME_ROUTE_FORMAT}
resources :uploads resources :uploads

View File

@ -761,4 +761,46 @@ describe UsersController do
end end
describe 'send_activation_email' do
context 'for an existing user' do
let(:user) { Fabricate(:user) }
before do
UsersController.any_instance.stubs(:fetch_user_from_params).returns(user)
end
context 'with a valid email_token' do
it 'should send the activation email' do
Jobs.expects(:enqueue).with(:user_email, has_entries(type: :signup))
xhr :get, :send_activation_email, username: user.username
end
end
context 'without an existing email_token' do
before do
user.email_tokens.each {|t| t.destroy}
user.reload
end
it 'should generate a new token' do
expect {
xhr :get, :send_activation_email, username: user.username
}.to change{ user.email_tokens(true).count }.by(1)
end
it 'should send an email' do
Jobs.expects(:enqueue).with(:user_email, has_entries(type: :signup))
xhr :get, :send_activation_email, username: user.username
end
end
end
context 'when username does not exist' do
it 'should not send an email' do
Jobs.expects(:enqueue).never
xhr :get, :send_activation_email, username: 'nopenopenopenope'
end
end
end
end end