Skip to content
This repository has been archived by the owner on May 7, 2021. It is now read-only.

Commit

Permalink
Created frontend for password reset
Browse files Browse the repository at this point in the history
The frontend includes two routes, which are the passwordreset and
passwordresetcomplete. Password reset is linked to the login page with
the text "Forgot your password?".
  • Loading branch information
Ommy committed Mar 1, 2016
1 parent 9a03921 commit da59824
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 11 deletions.
38 changes: 32 additions & 6 deletions src-backbone/app/js/controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
let App = require('utils/sanaAppInstance');
let Helpers = require('utils/helpers');
let AuthLayoutView = require('views/auth/authLayoutView');
let SignupView = require('views/auth/signupView');
let LoginView = require('views/auth/loginView');
let SettingsView = require('views/auth/settingsView');
let App = require('utils/sanaAppInstance');
let Helpers = require('utils/helpers');
let AuthLayoutView = require('views/auth/authLayoutView');
let SignupView = require('views/auth/signupView');
let LoginView = require('views/auth/loginView');
let SettingsView = require('views/auth/settingsView');
let ResetPasswordView = require('views/auth/resetPasswordView');
let ResetPasswordCompleteView = require('views/auth/resetPasswordCompleteView');


module.exports = Marionette.Controller.extend({
Expand All @@ -20,6 +22,30 @@ module.exports = Marionette.Controller.extend({
authLayoutView.showChildView('authFormArea', new SettingsView());
},

routeResetPassword: function() {
Helpers.arrivedOnView('Reset Password');

let authLayoutView = new AuthLayoutView();
App().RootView.switchMainView(authLayoutView);
authLayoutView.showChildView('authFormArea', new ResetPasswordView());
},

routeResetPasswordComplete: function() {
if (Helpers.getURLParam(Backbone.history.fragment, 'token') === null) {
if (App().session.isValid()) {
Helpers.navigateToDefaultLoggedIn();
} else {
Helpers.navigateToDefaultLoggedOut();
}
return;
}
Helpers.arrivedOnView('Reset Password');

let authLayoutView = new AuthLayoutView();
App().RootView.switchMainView(authLayoutView);
authLayoutView.showChildView('authFormArea', new ResetPasswordCompleteView());
},

routeSignup: function () {
if (App().session.isValid()) {
Helpers.navigateToDefaultLoggedIn();
Expand Down
12 changes: 7 additions & 5 deletions src-backbone/app/js/routers/authRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ module.exports = Marionette.AppRouter.extend({
},

appRoutes: {
'' : 'routeIndex',
'login' : 'routeLogin',
'logout' : 'routeLogout',
'signup' : 'routeSignup',
'account' : 'routeSettings',
'' : 'routeIndex',
'login' : 'routeLogin',
'logout' : 'routeLogout',
'signup' : 'routeSignup',
'account' : 'routeSettings',
'resetpassword' : 'routeResetPassword',
'resetpasswordcomplete' : 'routeResetPasswordComplete'
}

});
15 changes: 15 additions & 0 deletions src-backbone/app/js/templates/auth/resetPasswordCompleteView.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<form>
<div class="form-group">
<label for="new_password" class="sr-only">{{ i18n "New Password" }}</label>
<input type="password" name="new_password" class="form-control" id="new_password" placeholder="New Password">
</div>

<div class="form-group">
<label for="password_confirmation" class="sr-only">{{ i18n "Confirm Password" }}</label>
<input type="password" name="password_confirmation" class="form-control" id="password_confirmation" placeholder="Confirm Password">
</div>

<div>
<button type="submit" class="btn btn-primary btn-block" id="submit-btn">{{ i18n "Change Password" }}</button>
</div>
</form>
10 changes: 10 additions & 0 deletions src-backbone/app/js/templates/auth/resetPasswordView.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<form>
<div class="form-group">
<label for="email" class="sr-only">{{ i18n "Email" }}</label>
<input type="text" name="email" class="form-control" id="email" placeholder="Email">
</div>

<div>
<button type="submit" class="btn btn-primary btn-block" id="submit-btn">{{ i18n "Request Password Reset" }}</button>
</div>
</form>
2 changes: 2 additions & 0 deletions src-backbone/app/js/utils/configTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ module.exports = {
'terms',
'privacy',
'credits',
'resetpassword',
'resetpasswordcomplete',
],

ELEMENT_TYPES: [
Expand Down
7 changes: 7 additions & 0 deletions src-backbone/app/js/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,11 @@ module.exports = {
element.click();
document.body.removeChild(element);
},

getURLParam: function(url, param) {
param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+param+"=([^&#]*)");
var results = regex.exec(url);
return results === null ? null : results[1];
}
};
65 changes: 65 additions & 0 deletions src-backbone/app/js/views/auth/resetPasswordCompleteView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
let App = require('utils/sanaAppInstance');
const Helpers = require('utils/helpers');

module.exports = Marionette.ItemView.extend({
template: require('templates/auth/resetPasswordCompleteView'),

ui: {
form: 'form',
},

events: {
'submit': 'onSubmit',
},

onSubmit: function(event) {
event.preventDefault();

let self = this;
let $form = this.ui.form;

self.completeReset($form.serializeArray());
},

completeReset: function(data) {
let token = Helpers.getURLParam(Backbone.history.fragment, 'reset_token');
let json = {};
data.forEach(function(item) {
if (item.value !== "") {
json[item.name] = item.value;
}
});
json.reset_token = token;

$.ajax({
type: 'POST',
url: '/api/passwords/reset_password_complete',
data: JSON.stringify(json),
beforeSend: function() {
App().RootView.showSpinner();
},
complete: function() {
App().RootView.hideSpinner();
},
success: function(response) {
Helpers.navigateToDefaultLoggedOut();
App().RootView.clearNotifications();
App().RootView.showNotification({
title: 'Success!',
desc: 'Password successfully reset!',
alertType: 'success',
});
},
error: function(errors) {
App().RootView.clearNotifications();
Object.keys(errors.responseJSON).forEach(function(key) {
App().RootView.showNotification({
title: 'There was a problem',
desc: errors.responseJSON[key]
});
});
}
});
},

});
63 changes: 63 additions & 0 deletions src-backbone/app/js/views/auth/resetPasswordView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
let App = require('utils/sanaAppInstance');
const Helpers = require('utils/helpers');

module.exports = Marionette.ItemView.extend({
template: require('templates/auth/resetPasswordView'),

ui: {
form: 'form',
},

events: {
'submit': 'onSubmit',
},

onSubmit: function(event) {
event.preventDefault();

let self = this;
let $form = this.ui.form;

self.resetPassword($form.serializeArray());
},

resetPassword: function(data) {
let json = {};
data.forEach(function(item) {
if (item.value !== "") {
json[item.name] = item.value;
}
});

$.ajax({
type: 'POST',
data: JSON.stringify(json),
url: '/api/passwords/reset_password',
beforeSend: function() {
App().RootView.showSpinner();
},
complete: function() {
App().RootView.hideSpinner();
},
success: function(response) {
Helpers.navigateToDefaultLoggedOut();
App().RootView.clearNotifications();
App().RootView.showNotification({
title: 'Success!',
desc: 'Email to reset password sent!',
alertType: 'success',
});
},
error: function(errors) {
App().RootView.clearNotifications();
Object.keys(errors.responseJSON).forEach(function(key) {
App().RootView.showNotification({
title: 'There was a problem',
desc: errors.responseJSON[key]
});
});
}
});
},

});
6 changes: 6 additions & 0 deletions src-backbone/app/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
// Account Settings
"Successfuly updated account details!": "Successfuly updated account details!",
"There was a problem": "There was a problem",
"Password successfully reset!": "Password successfully reset!",
"Email to reset password sent!": "Email to reset password sent!",
"Confirm Password": "Confirm Password",
"New Password": "New Password",
"Change Password": "Change Password",
"Request Password Reset": "Request Password Reset",

// Procedures
"Hello username": "Hello {{ username }}",
Expand Down
20 changes: 20 additions & 0 deletions src-backbone/test/unit/auth/authController_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ describe('Auth Controller', function() {
let settingsView;
let settingsViewStub;

let resetPasswordView;
let resetPasswordViewStub;

let resetPasswordCompleteView;
let resetPasswordCompleteViewStub;

beforeEach(function() {
// Setup helpers
let helpers = require('utils/helpers');
Expand Down Expand Up @@ -72,6 +78,18 @@ describe('Auth Controller', function() {
};
settingsViewStub = sinon.stub().returns(settingsView);

// Setup resetPasswordView
resetPasswordView = {
name: 'resetPasswordView',
};
resetPasswordViewStub = sinon.stub().returns(resetPasswordView);

// Setup resetPasswordCompleteView
resetPasswordCompleteView = {
name: 'resetPasswordCompleteView',
};
resetPasswordCompleteViewStub = sinon.stub().returns(resetPasswordCompleteView);

// Setup authController
let AuthController = proxyquire('controllers/authController', {
'utils/sanaAppInstance': getAppInstance,
Expand All @@ -80,6 +98,8 @@ describe('Auth Controller', function() {
'views/auth/signupView': signupViewStub,
'views/auth/loginView': loginViewStub,
'views/auth/settingsView': settingsViewStub,
'views/auth/resetPasswordView': resetPasswordViewStub,
'views/auth/resetPasswordCompleteView': resetPasswordCompleteViewStub,
});
authController = new AuthController();
});
Expand Down

0 comments on commit da59824

Please sign in to comment.