You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2015/08/10 18:00:54 UTC
[12/34] incubator-ignite git commit: IGNITE-843 Implemented password
reset.
IGNITE-843 Implemented password reset.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/8406e7c0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/8406e7c0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/8406e7c0
Branch: refs/heads/ignite-1201
Commit: 8406e7c0df285bc939d969895835b10038a70589
Parents: 2aa1ce8
Author: AKuznetsov <ak...@gridgain.com>
Authored: Thu Aug 6 16:55:24 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Thu Aug 6 16:55:24 2015 +0700
----------------------------------------------------------------------
modules/control-center-web/src/main/js/app.js | 10 +-
.../js/controllers/cache-viewer-controller.js | 77 ------------
.../src/main/js/controllers/common-module.js | 56 ++++++---
modules/control-center-web/src/main/js/db.js | 5 +-
.../src/main/js/routes/agent.js | 2 +-
.../src/main/js/routes/public.js | 120 ++++++++++---------
.../src/main/js/views/includes/header.jade | 4 +-
.../src/main/js/views/login.jade | 55 ---------
.../src/main/js/views/loginModal.jade | 55 +++++++++
.../src/main/js/views/reset.jade | 3 +-
.../src/main/js/views/resetModal.jade | 12 +-
11 files changed, 185 insertions(+), 214 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app.js b/modules/control-center-web/src/main/js/app.js
index 7741822..413d92c 100644
--- a/modules/control-center-web/src/main/js/app.js
+++ b/modules/control-center-web/src/main/js/app.js
@@ -100,8 +100,14 @@ app.all('/configuration/*', mustAuthenticated);
app.all('*', function(req, res, next) {
var becomeUsed = req.session.viewedUser && req.user.admin;
- res.locals.user = becomeUsed ? req.session.viewedUser : req.user;
- res.locals.becomeUsed = becomeUsed;
+ if (req.url == '/reset') {
+ res.locals.user = null;
+ res.locals.becomeUsed = false;
+ }
+ else {
+ res.locals.user = becomeUsed ? req.session.viewedUser : req.user;
+ res.locals.becomeUsed = becomeUsed;
+ }
req.currentUserId = function() {
if (!req.user)
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js b/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js
deleted file mode 100644
index 6e0c130..0000000
--- a/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var demoResults = [
- {
- id: 256,
- s: 'com.foo.User@3213',
- fields: {
- id: 256,
- firstName: 'Ivan',
- lastName: 'Ivanov',
- old: 23
- }
- },
-
- {
- id: 384,
- s: 'com.foo.User@23214',
- fields: {
- id: 384,
- firstName: 'Sergey',
- lastName: 'Petrov',
- old: 28
- }
- },
-
- {
- id: 923,
- s: 'com.foo.User@93494',
- fields: {
- id: 923,
- firstName: 'Andrey',
- lastName: 'Sidorov',
- old: 28
- }
- }
-];
-
-var demoCaches = ['Users', 'Organizations', 'Cities'];
-
-controlCenterModule.controller('cacheViewerController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
- $scope.results = demoResults;
-
- $scope.caches = demoCaches;
-
- $scope.defCache = $scope.caches.length > 0 ? $scope.caches[0] : null;
-
- var sqlEditor = ace.edit('querySql');
-
- sqlEditor.setOptions({
- highlightActiveLine: false,
- showPrintMargin: false,
- showGutter: true,
- theme: "ace/theme/chrome",
- mode: "ace/mode/sql",
- fontSize: 14
- });
-
- sqlEditor.setValue("select u.id from User u where u.name like 'aaaa';");
-
- sqlEditor.selection.clearSelection()
-
-}]);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index 05186a9..60e02fc 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -82,11 +82,11 @@ controlCenterModule.service('$common', ['$alert', function ($alert) {
return errMsg ? errMsg : 'Internal server error.';
}
- function showError(msg) {
+ function showError(msg, placement, container) {
if (msgModal)
msgModal.hide();
- msgModal = $alert({title: errorMessage(msg)});
+ msgModal = $alert({title: errorMessage(msg), placement: placement ? placement : 'top-right', container: container ? container : 'body'});
return false;
}
@@ -596,14 +596,11 @@ controlCenterModule.controller('activeLink', [
// Login popup controller.
controlCenterModule.controller('auth', [
- '$scope', '$modal', '$alert', '$http', '$window', '$common', '$focus',
- function ($scope, $modal, $alert, $http, $window, $common, $focus) {
- $scope.errorMessage = $common.errorMessage;
-
+ '$scope', '$modal', '$http', '$window', '$timeout', '$common', '$focus',
+ function ($scope, $modal, $http, $window, $timeout, $common, $focus) {
+ $scope.showResetModal = false;
$scope.action = 'login';
- $scope.valid = false;
-
$scope.userDropdown = [{text: 'Profile', href: '/profile'}];
if (!$scope.becomeUsed) {
@@ -614,36 +611,65 @@ controlCenterModule.controller('auth', [
}
// Pre-fetch modal dialogs.
- var authModal = $modal({scope: $scope, templateUrl: '/login', show: false});
+ var loginModal = $modal({scope: $scope, templateUrl: '/loginModal', show: false});
var resetModal = $modal({scope: $scope, templateUrl: '/resetModal', show: false});
+ // Show reset modal if needed.
+ $timeout(function () {
+ if ($scope.showResetModal)
+ $scope.reset()
+ });
+
+ // Show login modal.
$scope.login = function () {
- authModal.$promise.then(function () {
- authModal.show();
+ loginModal.$promise.then(function () {
+ loginModal.show();
$focus('user_email');
});
};
+ // Show reset password modal.
$scope.reset = function () {
resetModal.$promise.then(function () {
resetModal.show();
- $focus('user_password');
+ $focus('user_token');
});
};
+ // Try to authorize user with provided credentials.
$scope.auth = function (action, user_info) {
$http.post('/' + action, user_info)
.success(function () {
- authModal.hide();
+ loginModal.hide();
$window.location = '/configuration/clusters';
})
- .error(function (data) {
- $alert({placement: 'top', container: '#errors-container', title: $scope.errorMessage(data)});
+ .error(function (data, status) {
+ if (status == 403) {
+ loginModal.hide();
+
+ $window.location = '/reset';
+ }
+ else
+ $common.showError(data, 'top', '#errors-container');
});
};
+
+ // Try to reset user password for provided token.
+ $scope.resetPassword = function (user_info) {
+ $http.post('/reset_password', user_info)
+ .success(function (data) {
+ resetModal.hide();
+
+ $scope.user_info = {email: data};
+ $scope.login();
+ })
+ .error(function (data) {
+ $common.showError(data, 'top', '#errors-container');
+ });
+ }
}]);
// Navigation bar controller.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js
index 401beff..f815266 100644
--- a/modules/control-center-web/src/main/js/db.js
+++ b/modules/control-center-web/src/main/js/db.js
@@ -33,7 +33,8 @@ var AccountSchema = new Schema({
username: String,
email: String,
lastLogin: Date,
- admin: Boolean
+ admin: Boolean,
+ resetPasswordToken: String
});
AccountSchema.plugin(passportLocalMongoose, {usernameField: 'email', limitAttempts: true, lastLoginField: 'lastLogin',
@@ -379,4 +380,4 @@ exports.upsert = function (model, data, cb) {
new model(data).save(cb);
};
-exports.mongoose = mongoose;
\ No newline at end of file
+exports.mongoose = mongoose;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/agent.js b/modules/control-center-web/src/main/js/routes/agent.js
index 45cd0ef..c92c575 100644
--- a/modules/control-center-web/src/main/js/routes/agent.js
+++ b/modules/control-center-web/src/main/js/routes/agent.js
@@ -72,7 +72,7 @@ router.post('/next_page', function(req, res) {
var cache = client.ignite().cache(req.body.cacheName);
var cmd = cache._createCommand("qryfetch").addParam("qryId", req.body.queryId).
- addParam("psz", req.body.pageSize);
+ addParam("pageSize", req.body.pageSize);
cache.__createPromise(cmd).then(function (page) {
res.json({rows: page["items"], last: page === null || page["last"]});
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/public.js b/modules/control-center-web/src/main/js/routes/public.js
index 817c93b..3f770a1 100644
--- a/modules/control-center-web/src/main/js/routes/public.js
+++ b/modules/control-center-web/src/main/js/routes/public.js
@@ -42,8 +42,8 @@ router.get('/copy', function (req, res) {
});
/* GET login dialog. */
-router.get('/login', function (req, res) {
- res.render('login');
+router.get('/loginModal', function (req, res) {
+ res.render('loginModal');
});
/* GET reset password page. */
@@ -85,19 +85,52 @@ router.post('/register', function (req, res) {
});
});
-router.post('/restore', function(req, res) {
+/**
+ * Login in exist account.
+ */
+router.post('/login', function (req, res, next) {
+ passport.authenticate('local', function (err, user) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ if (!user)
+ return res.status(401).send('Invalid email or password');
+
+ req.logIn(user, {}, function (err) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ res.redirect('/configuration/clusters');
+ });
+ })(req, res, next);
+});
+
+/**
+ * Logout.
+ */
+router.get('/logout', function (req, res) {
+ req.logout();
+
+ res.redirect('/');
+});
+
+/**
+ * Request for password reset and send e-mail to user with reset token. */
+router.post('/request_password_reset', function(req, res) {
var token = crypto.randomBytes(20).toString('hex');
db.Account.findOne({ email: req.body.email }, function(err, user) {
- if (err)
+ if (!user)
return res.status(401).send('No account with that email address exists!');
+ if (err)
+ return res.status(401).send(err);
+
user.resetPasswordToken = token;
- user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err) {
if (err)
- return res.status(401).send('Failed to send e-mail with reset link!');
+ return res.status(401).send(err);
var transporter = nodemailer.createTransport({
service: 'gmail',
@@ -108,39 +141,44 @@ router.post('/restore', function(req, res) {
});
var mailOptions = {
- from: 'passwordreset@YOUR.DOMAIN',
+ from: '!!! YOUR USERNAME !!!',
to: user.email,
subject: 'Password Reset',
text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
- 'http://' + req.headers.host + '/reset/' + token + '\n\n' +
- 'If you did not request this, please ignore this email and your password will remain unchanged.\n' +
- 'Link will be valid for one hour.\n'
+ 'http://' + req.headers.host + '/reset\n' +
+ 'And enter this reset token: ' + token + '\n\n' +
+ 'If you did not request this, please ignore this email and your password will remain unchanged.\n\n' +
+ '--------------\n' +
+ 'Apache Ignite Web Control Center\n'
};
- transporter.sendMail(mailOptions, function(err, info){
+ transporter.sendMail(mailOptions, function(err){
if (err)
return res.status(401).send('Failed to send e-mail with reset link!');
- console.log('Message sent: ' + info.response);
-
- return res.status(500).send('An e-mail has been sent with further instructions.');
+ return res.status(403).send('An e-mail has been sent with further instructions.');
});
});
});
});
-router.post('/reset/:token', function(req, res) {
- db.Account.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
+/**
+ * Reset password with given token.
+ */
+router.post('/reset_password', function(req, res) {
+ db.Account.findOne({ resetPasswordToken: req.body.token }, function(err, user) {
+ if (!user)
+ return res.status(500).send('Invalid token for password reset!');
+
if (err)
return res.status(500).send(err);
- user.setPassword(newPassword, function (err, updatedUser) {
+ user.setPassword(req.body.password, function (err, updatedUser) {
if (err)
return res.status(500).send(err.message);
- user.resetPasswordToken = undefined;
- user.resetPasswordExpires = undefined;
+ updatedUser.resetPasswordToken = undefined;
updatedUser.save(function (err) {
if (err)
@@ -155,55 +193,27 @@ router.post('/reset/:token', function(req, res) {
});
var mailOptions = {
- from: 'passwordreset@YOUR.DOMAIN',
+ from: '!!! YOUR USERNAME !!!',
to: user.email,
subject: 'Your password has been changed',
text: 'Hello,\n\n' +
- 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n'
+ 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n\n' +
+ 'Now you can login: http://' + req.headers.host + '\n\n' +
+ '--------------\n' +
+ 'Apache Ignite Web Control Center\n'
};
- transporter.sendMail(mailOptions, function(err, info){
+ transporter.sendMail(mailOptions, function(err){
if (err)
- return res.status(401).send('Failed to send e-mail with reset link!');
-
- console.log('Message sent: ' + info.response);
+ return res.status(401).send('Failed to send password reset confirmation e-mail!');
- res.redirect('/login');
+ return res.status(200).send(user.email);
});
});
});
});
});
-/**
- * Login in exist account.
- */
-router.post('/login', function (req, res, next) {
- passport.authenticate('local', function (err, user) {
- if (err)
- return res.status(401).send(err.message);
-
- if (!user)
- return res.status(401).send('Invalid email or password');
-
- req.logIn(user, {}, function (err) {
- if (err)
- return res.status(401).send(err.message);
-
- res.redirect('/configuration/clusters');
- });
- })(req, res, next);
-});
-
-/**
- * Logout.
- */
-router.get('/logout', function (req, res) {
- req.logout();
-
- res.redirect('/');
-});
-
/* GET home page. */
router.get('/', function (req, res) {
if (req.isAuthenticated())
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/views/includes/header.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/header.jade b/modules/control-center-web/src/main/js/views/includes/header.jade
index 49ea592..b690ba2 100644
--- a/modules/control-center-web/src/main/js/views/includes/header.jade
+++ b/modules/control-center-web/src/main/js/views/includes/header.jade
@@ -17,7 +17,7 @@ mixin header-item(active, ref, txt)
li
a(ng-class='{active: isActive("#{active}")}' href='#{ref}') #{txt}
-header.header(id='header')
+header#header.header
.viewedUser(ng-show='becomeUsed') Currently assuming "
strong {{user.username}}
| ",
@@ -39,4 +39,4 @@ header.header(id='header')
a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userDropdown' data-placement='bottom-right' data-ng-bind='::user.username')
span.caret
li.nav-login(ng-if='!user')
- a(ng-click='login()' href='#') Log In
\ No newline at end of file
+ a(ng-click='login()') Log In
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/login.jade b/modules/control-center-web/src/main/js/views/login.jade
deleted file mode 100644
index 47bb2c5..0000000
--- a/modules/control-center-web/src/main/js/views/login.jade
+++ /dev/null
@@ -1,55 +0,0 @@
-//-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-mixin lbl(txt)
- label.col-sm-3.required #{txt}
-
-.modal.center(role='dialog')
- .modal-dialog
- .modal-content
- #errors-container.modal-header.header
- button.close(type='button' ng-click='$hide()' aria-hidden='true') ×
- h1.navbar-brand
- a(href='/') Apache Ignite Web Configurator
- h4.modal-title(style='padding-right: 55px') Authentication
- p(style='padding-right: 55px') Log in or register in order to collaborate
- form.form-horizontal(name='loginForm' ng-init='action == "login"')
- .modal-body.row
- .col-sm-9.col-sm-offset-1
- .details-row(ng-show='action == "register"')
- +lbl('Full Name:')
- .col-sm-9
- input#user_name.form-control(enter-focus-next enter-focus-next-id='user_email' type='text' ng-model='user_info.username' placeholder='John Smith' ng-required='action=="register"')
- .details-row
- +lbl('Email:')
- .col-sm-9
- input#user_email.form-control(enter-focus-next enter-focus-next-id='user_password' type='email' ng-model='user_info.email' placeholder='you@domain.com' required)
- .details-row(ng-show='action != "restore"')
- +lbl('Password:')
- .col-sm-9
- input#user_password.form-control(enter-focus-next enter-focus-next-id='user_confirm' type='password' ng-model='user_info.password' placeholder='Password' ng-required='action != "restore"' on-enter='action == "login" && auth(action, user_info)')
- .details-row(ng-if='action == "register"')
- +lbl('Confirm:')
- .col-sm-9
- input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' ng-required='action == "register"' on-enter='auth(action, user_info)')
- .modal-footer
- a.labelField(ng-show='action != "restore"' ng-click='action = "restore"' event-focus='click' event-focus-id='user_email') Forgot password?
- a.labelField(ng-show='action == "restore"' ng-click='action = "login"' event-focus='click' event-focus-id='user_email') Log In
- a.labelLogin(ng-show='action == "register"' event-focus='click' event-focus-id='user_email' ng-click='action = "login";') Log In
- a.labelLogin(ng-show='action == "login"' event-focus='click' event-focus-id='user_name' ng-click='action = "register"') Sign Up
- button.btn.btn-primary(ng-show='action == "login"' ng-disabled='loginForm.$invalid' ng-click='auth(action, user_info)') Log In
- button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid' ng-click='auth(action, user_info)') Sign Up
- button.btn.btn-primary(ng-show='action == "restore"' ng-disabled='loginForm.$invalid' ng-click='auth(action, user_info)') Reset Password
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/views/loginModal.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/loginModal.jade b/modules/control-center-web/src/main/js/views/loginModal.jade
new file mode 100644
index 0000000..8b32aa1
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/loginModal.jade
@@ -0,0 +1,55 @@
+//-
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+mixin lbl(txt)
+ label.col-sm-3.required #{txt}
+
+.modal.center(role='dialog')
+ .modal-dialog
+ .modal-content
+ #errors-container.modal-header.header
+ button.close(type='button' ng-click='$hide()' aria-hidden='true') ×
+ h1.navbar-brand
+ a(href='/') Apache Ignite Web Configurator
+ h4.modal-title(style='padding-right: 55px') Authentication
+ p(style='padding-right: 55px') Log in or register in order to collaborate
+ form.form-horizontal(name='loginForm' ng-init='action == "login"')
+ .modal-body.row
+ .col-sm-9.col-sm-offset-1
+ .details-row(ng-show='action == "register"')
+ +lbl('Full Name:')
+ .col-sm-9
+ input#user_name.form-control(enter-focus-next enter-focus-next-id='user_email' type='text' ng-model='user_info.username' placeholder='John Smith' ng-required='action=="register"')
+ .details-row
+ +lbl('Email:')
+ .col-sm-9
+ input#user_email.form-control(enter-focus-next enter-focus-next-id='user_password' type='email' ng-model='user_info.email' placeholder='you@domain.com' required on-enter='action == "request_password_reset" && loginForm.$valid && auth(action, user_info)')
+ .details-row(ng-show='action != "request_password_reset"')
+ +lbl('Password:')
+ .col-sm-9
+ input#user_password.form-control(enter-focus-next enter-focus-next-id='user_confirm' type='password' ng-model='user_info.password' placeholder='Password' ng-required='action != "request_password_reset"' on-enter='action == "login" && loginForm.$valid && auth(action, user_info)')
+ .details-row(ng-if='action == "register"')
+ +lbl('Confirm:')
+ .col-sm-9
+ input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' ng-required='action == "register"' on-enter='loginForm.$valid && auth(action, user_info)')
+ .modal-footer
+ a.labelField(ng-show='action != "request_password_reset"' ng-click='action = "request_password_reset"' event-focus='click' event-focus-id='user_email') Forgot password?
+ a.labelField(ng-show='action == "request_password_reset"' ng-click='action = "login"' event-focus='click' event-focus-id='user_email') Log In
+ a.labelLogin(ng-show='action == "register"' event-focus='click' event-focus-id='user_email' ng-click='action = "login";') Log In
+ a.labelLogin(ng-show='action == "login"' event-focus='click' event-focus-id='user_name' ng-click='action = "register"') Sign Up
+ button.btn.btn-primary(ng-show='action == "login"' ng-disabled='loginForm.$invalid' ng-click='auth(action, user_info)') Log In
+ button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid' ng-click='auth(action, user_info)') Sign Up
+ button.btn.btn-primary(ng-show='action == "request_password_reset"' ng-disabled='loginForm.$invalid' ng-click='auth(action, user_info)') Reset Password
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/views/reset.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/reset.jade b/modules/control-center-web/src/main/js/views/reset.jade
index c9c4d88..950f1a7 100644
--- a/modules/control-center-web/src/main/js/views/reset.jade
+++ b/modules/control-center-web/src/main/js/views/reset.jade
@@ -18,5 +18,6 @@ extends templates/layout
block container
.row
- .text-center(ng-controller='auth')
+ .text-center(ng-controller='auth' ng-init='showResetModal=true')
+ p Further instructions for password reset have been sent to your e-mail address.
button.btn.btn-primary(ng-click='reset()' href='#') Reset Password
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8406e7c0/modules/control-center-web/src/main/js/views/resetModal.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/resetModal.jade b/modules/control-center-web/src/main/js/views/resetModal.jade
index 0878525..df3dec8 100644
--- a/modules/control-center-web/src/main/js/views/resetModal.jade
+++ b/modules/control-center-web/src/main/js/views/resetModal.jade
@@ -14,21 +14,25 @@
.modal.center(role='dialog')
.modal-dialog
- .modal-content
- #errors-container.modal-header.header
+ #errors-container.modal-content
+ .modal-header.header
button.close(type='button' ng-click='$hide()' aria-hidden='true') ×
h4.modal-title(style='padding-right: 55px') Reset password
- form.form-horizontal(name='loginForm' ng-init='action == "login"')
+ form.form-horizontal(name='resetForm' ng-init='action == "login"')
.modal-body.row
.col-sm-9.col-sm-offset-1
.details-row
+ label.col-sm-4.required Token:
+ .col-sm-8
+ input#user_token.form-control(enter-focus-next enter-focus-next-id='user_password' type='text' ng-model='user_info.token' placeholder='Reset token' required)
+ .details-row
label.col-sm-4.required New password:
.col-sm-8
input#user_password.form-control(enter-focus-next enter-focus-next-id='user_confirm' type='password' ng-model='user_info.password' placeholder='New password' required)
.details-row
label.col-sm-4.required Confirm:
.col-sm-8
- input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm new password' ng-required='action == "register"' on-enter='resetPassword(user_info)')
+ input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm new password' required on-enter='resetPassword(user_info)')
.modal-footer
button.btn.btn-primary(ng-disabled='resetForm.$invalid' ng-click='resetPassword(user_info)') Reset Password