- Fixes oauth registration deleting account with unverified e-mail

- Improves layout of new password requested
pull/2427/head
Marcelo Schmidt 10 years ago
parent 7767b808ff
commit 0f60d14d1c
  1. 3
      HISTORY.md
  2. 1
      i18n/en.i18n.json
  3. 43
      packages/rocketchat-lib/server/models/Users.coffee
  4. 8
      packages/rocketchat-ui-login/reset-password/resetPassword.html
  5. 60
      packages/rocketchat-ui-login/reset-password/resetPassword.js
  6. 2
      packages/rocketchat-ui-master/master/main.html
  7. 2
      packages/rocketchat-ui/package.js
  8. 19
      packages/rocketchat-ui/views/app/requestPasswordChange.html
  9. 33
      packages/rocketchat-ui/views/app/requestPasswordChange.js
  10. 16
      server/configuration/accounts_meld.coffee
  11. 12
      server/methods/setUserPassword.coffee
  12. 1
      server/publications/fullUserData.coffee
  13. 1
      server/publications/userData.coffee

@ -1,5 +1,8 @@
## NEXT
- Fixes oauth registration deleting account with unverified e-mail
- Improves layout of new password requested
## 0.20.0, 2016-Feb-29
- Ability to disable sending nickname and message via push notification

@ -597,6 +597,7 @@
"The_user_will_be_removed_from_s" : "The user will be removed from %s",
"The_user_wont_be_able_to_type_in_s" : "The user won't be able to type in %s",
"There_are_no_integrations" : "There are no integrations",
"This_email_has_already_been_used_and_has_not_been_verified__Please_change_your_password" : "This email has already been used and has not been verified. Please change your password.",
"This_is_a_desktop_notification" : "This is a desktop notification",
"This_is_a_push_test_messsage" : "This is a push test messsage",
"True" : "True",

@ -19,15 +19,6 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
return @findOne query, options
findOneByVerifiedEmailAddress: (emailAddress, verified=true, options) ->
query =
emails:
$elemMatch:
address: emailAddress
verified: verified
return @findOne query, options
findOneVerifiedFromSameDomain: (email, options) ->
domain = s.strRight(email, '@')
query =
@ -171,6 +162,20 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
return @update _id, update
setEmailVerified: (_id, email) ->
query =
_id: _id
emails:
$elemMatch:
address: email
verified: false
update =
$set:
'emails.$.verified': true
return @update query, update
setName: (_id, name) ->
update =
$set:
@ -217,6 +222,17 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
update =
$unset:
"requirePasswordChange" : true
"requirePasswordChangeReason" : true
return @update _id, update
resetPasswordAndSetRequirePasswordChange: (_id, requirePasswordChange, requirePasswordChangeReason) ->
update =
$unset:
"services.password": 1
$set:
"requirePasswordChange" : requirePasswordChange,
"requirePasswordChangeReason": requirePasswordChangeReason
return @update _id, update
@ -269,15 +285,6 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
removeById: (_id) ->
return @remove _id
removeByUnverifiedEmail: (email) ->
query =
emails:
$elemMatch:
address: email
verified: false
return @remove query
###
Find users to send a message by email if:
- he is not online

@ -2,7 +2,15 @@
<form id="login-card" action="/">
<div class="fields">
<header>
{{#if requirePasswordChange}}
{{#if requirePasswordChangeReason}}
<p>{{_ requirePasswordChangeReason}}</p>
{{else}}
<p>{{_ 'You_need_to_change_your_password'}}</p>
{{/if}}
{{else}}
<p>{{_ "Please_enter_your_new_password_below"}}</p>
{{/if}}
</header>
<div class="input-text active">
<input type="password" name="newPassword" placeholder="{{_ "Type_your_new_password"}}" dir="auto" />

@ -1,3 +1,18 @@
Template.resetPassword.helpers({
requirePasswordChange() {
let user = Meteor.user();
if (user) {
return user.requirePasswordChange;
}
},
requirePasswordChangeReason() {
let user = Meteor.user();
if (user) {
return user.requirePasswordChangeReason;
}
}
});
Template.resetPassword.events({
'submit #login-card': function(event, instance) {
event.preventDefault();
@ -5,19 +20,38 @@ Template.resetPassword.events({
var button = instance.$('button.resetpass');
RocketChat.Button.loading(button);
Accounts.resetPassword(FlowRouter.getParam('token'), instance.find('[name=newPassword]').value, function(error) {
RocketChat.Button.reset(button);
if (error) {
console.log(error);
swal({
title: t('Error_changing_password'),
type: 'error'
});
} else {
FlowRouter.go('home');
toastr.success(t('Password_changed_successfully'));
}
});
if (Meteor.userId()) {
Meteor.call('setUserPassword', instance.find('[name=newPassword]').value, function(error) {
if (error) {
console.log(error);
swal({
title: t('Error_changing_password'),
type: 'error'
});
} else {
Meteor.call('clearRequirePasswordChange', function() {
FlowRouter.go('home');
toastr.success(t('Password_changed_successfully'));
});
}
});
} else {
Accounts.resetPassword(FlowRouter.getParam('token'), instance.find('[name=newPassword]').value, function(error) {
RocketChat.Button.reset(button);
if (error) {
console.log(error);
swal({
title: t('Error_changing_password'),
type: 'error'
});
} else {
Meteor.call('clearRequirePasswordChange', function() {
FlowRouter.go('home');
toastr.success(t('Password_changed_successfully'));
});
}
});
}
}
});

@ -52,7 +52,7 @@
{{> username}}
{{else}}
{{#if requirePasswordChange}}
{{> logoLayout render="requestPasswordChange"}}
{{> logoLayout render="resetPassword"}}
{{else}}
{{> spotlight}}
{{> mobileMessageMenu}}

@ -86,7 +86,6 @@ Package.onUse(function(api) {
api.addFiles('views/app/pageContainer.html', 'client');
api.addFiles('views/app/pageSettingsContainer.html', 'client');
api.addFiles('views/app/privateHistory.html', 'client');
api.addFiles('views/app/requestPasswordChange.html', 'client');
api.addFiles('views/app/room.html', 'client');
api.addFiles('views/app/roomSearch.html', 'client');
api.addFiles('views/app/secretURL.html', 'client');
@ -103,7 +102,6 @@ Package.onUse(function(api) {
api.addFiles('views/app/burguer.coffee', 'client');
api.addFiles('views/app/home.coffee', 'client');
api.addFiles('views/app/privateHistory.coffee', 'client');
api.addFiles('views/app/requestPasswordChange.js', 'client');
api.addFiles('views/app/room.coffee', 'client');
api.addFiles('views/app/roomSearch.coffee', 'client');
api.addFiles('views/app/secretURL.coffee', 'client');

@ -1,19 +0,0 @@
<template name="requestPasswordChange">
<div class="content">
<div class="attention-message">
<i class="icon-attention"></i>
<span>{{_ 'You_need_to_change_your_password'}}</span>
</div>
<div class="rocket-form request-password">
<form>
<fieldset>
<label for="oldPassword">{{_ "Old_Password"}}</label><input type="password" name="oldPassword" id="oldPassword" />
<label for="newPassword">{{_ "Password"}}</label><input type="password" name="newPassword" id="newPassword" />
<div class="submit">
<button type="submit" class="button save"><i class="icon-send"></i><span>{{_ "Save"}}</span></button>
</div>
</fieldset>
</form>
</div>
</div>
</template>

@ -1,33 +0,0 @@
Template.requestPasswordChange.events({
'submit'(e, instance) {
e.preventDefault();
oldPassword = s.trim(instance.$('#oldPassword').val());
newPassword = s.trim(instance.$('#newPassword').val());
instance.changePassword(oldPassword, newPassword);
}
})
Template.requestPasswordChange.onCreated(function() {
this.changePassword = function(oldPassword, newPassword) {
if (!oldPassword || !newPassword) {
toastr.warning(t('Old_and_new_password_required'));
} else if (oldPassword === newPassword) {
toastr.warning(t('Old_and_new_password_must_be_different'));
} else {
Accounts.changePassword(oldPassword, newPassword, function(error) {
if(error) {
toastr.error(t('Incorrect_Password'));
} else {
Meteor.call('clearRequirePasswordChange', function() {
toastr.success(t('Password_changed_successfully'))
return true;
});
}
});
}
}
})
Template.requestPasswordChange.onRendered(function() {
this.$('#oldPassword').focus();
})

@ -19,13 +19,17 @@ Accounts.updateOrCreateUserFromExternalService = (serviceName, serviceData, opti
if serviceData.email
# Remove not verified users that have same email
RocketChat.models.Users.removeByUnverifiedEmail serviceData.email
# Try to get existent user with same email verified
user = RocketChat.models.Users.findOneByVerifiedEmailAddress(serviceData.email, true)
# Find user with given email
user = RocketChat.models.Users.findOneByEmailAddress serviceData.email
if user?
# If e-mail is not verified, reset password and require password change
if not _.findWhere user.emails, { address: serviceData.email, verified: true }
RocketChat.models.Users.resetPasswordAndSetRequirePasswordChange(user._id, true, 'This_email_has_already_been_used_and_has_not_been_verified__Please_change_your_password')
# Merge accounts
RocketChat.models.Users.setServiceId user._id, serviceName, serviceData.id
# Validate e-mail
RocketChat.models.Users.setEmailVerified user._id, serviceData.email
return orig_updateOrCreateUserFromExternalService.apply(this, arguments)

@ -0,0 +1,12 @@
Meteor.methods
setUserPassword: (password) ->
if not Meteor.userId()
throw new Meteor.Error 'invalid-user', '[methods] setUserPassword -> Invalid user'
user = RocketChat.models.Users.findOneById Meteor.userId()
if user and user.requirePasswordChange isnt true
throw new Meteor.Error 'not-authorized', '[methods] setUserPassword -> Not authorized'
Accounts.setPassword(Meteor.userId(), password, { logout: false });
return true;

@ -19,6 +19,7 @@ Meteor.publish 'fullUserData', (filter, limit) ->
services: 1
roles : 1
requirePasswordChange : 1
requirePasswordChangeReason : 1
else
limit = 1

@ -17,3 +17,4 @@ Meteor.publish 'userData', ->
'services.github.id': 1
'services.gitlab.id': 1
requirePasswordChange: 1
requirePasswordChangeReason: 1

Loading…
Cancel
Save