IGNITE-843 WIP on 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/2aa1ce8a Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/2aa1ce8a Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/2aa1ce8a Branch: refs/heads/ignite-1201 Commit: 2aa1ce8ab021aaf2e2af26233a39daeb262d2081 Parents: 675a0cf Author: AKuznetsov <akuznet...@gridgain.com> Authored: Thu Aug 6 03:03:16 2015 +0700 Committer: AKuznetsov <akuznet...@gridgain.com> Committed: Thu Aug 6 03:03:16 2015 +0700 ---------------------------------------------------------------------- .../src/main/js/controllers/common-module.js | 12 +- .../main/js/controllers/metadata-controller.js | 32 +++++- .../main/js/controllers/models/metadata.json | 44 +++---- .../control-center-web/src/main/js/package.json | 1 + .../src/main/js/public/stylesheets/style.scss | 12 +- .../src/main/js/routes/notebooks.js | 38 +++---- .../src/main/js/routes/public.js | 114 +++++++++++++++++-- .../main/js/views/configuration/summary.jade | 2 +- .../src/main/js/views/includes/controls.jade | 6 +- .../src/main/js/views/login.jade | 29 ++--- .../src/main/js/views/reset.jade | 22 ++++ .../src/main/js/views/resetModal.jade | 34 ++++++ .../src/main/js/views/templates/layout.jade | 2 +- 13 files changed, 272 insertions(+), 76 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/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 186914e..05186a9 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 @@ -613,11 +613,11 @@ controlCenterModule.controller('auth', [ $scope.userDropdown.push({text: 'Log Out', href: '/logout'}); } - // Pre-fetch an external template populated with a custom scope + // Pre-fetch modal dialogs. var authModal = $modal({scope: $scope, templateUrl: '/login', show: false}); + var resetModal = $modal({scope: $scope, templateUrl: '/resetModal', show: false}); $scope.login = function () { - // Show when some event occurs (use $promise property to ensure the template has been loaded) authModal.$promise.then(function () { authModal.show(); @@ -625,6 +625,14 @@ controlCenterModule.controller('auth', [ }); }; + $scope.reset = function () { + resetModal.$promise.then(function () { + resetModal.show(); + + $focus('user_password'); + }); + }; + $scope.auth = function (action, user_info) { $http.post('/' + action, user_info) .success(function () { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/controllers/metadata-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/metadata-controller.js b/modules/control-center-web/src/main/js/controllers/metadata-controller.js index be616f8..64ec7d2 100644 --- a/modules/control-center-web/src/main/js/controllers/metadata-controller.js +++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js @@ -61,7 +61,37 @@ controlCenterModule.controller('metadataController', [ {value: 'h2', label: 'H2 database'} ]; - $scope.rdbms = 'oracle'; + $scope.presets = { + oracle: { + drvClass: 'oracle.jdbc.OracleDriver', + drvUrl: 'jdbc:oracle:thin:@[host]:[port]:[database]', + user: 'system' + }, + db2: { + drvClass: 'com.ibm.db2.jcc.DB2Driver', + drvUrl: 'jdbc:db2://[host]:[port]/[database]', + user: 'db2admin' + }, + mssql: { + drvClass: 'com.microsoft.sqlserver.jdbc.SQLServerDriver', + drvUrl: 'jdbc:sqlserver://[host]:[port][;databaseName=database]', + user: 'sa' + }, + postgre: { + drvClass: 'org.postgresql.Driver', drvUrl: 'jdbc:postgresql://[host]:[port]/[database]', + user: 'sa' + }, + mysql: { + drvClass: 'com.mysql.jdbc.Driver', + drvUrl: 'jdbc:mysql://[host]:[port]/[database]', user: 'root' + }, + h2: {drvClass: 'org.h2.Driver', drvUrl: 'jdbc:h2:[database]', user: 'sa'} + }; + + $scope.preset = { + rdbms: 'oracle' + + }; $scope.jdbcTypes = [ {value: 'BIT', label: 'BIT'}, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/controllers/models/metadata.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json index 8e2b5b5..84ad9e4 100644 --- a/modules/control-center-web/src/main/js/controllers/models/metadata.json +++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json @@ -196,43 +196,40 @@ ], "metadataDb": [ { - "label": "Name", - "type": "text", - "model": "name" - }, - { - "label": "Database type", + "label": "Database preset", "type": "select", - "model": "rdbms", + "model": "preset", "items": "databases", "tip": [ "Select database type to connect for loading tables metadata." ] }, { - "label": "Database name", + "label": "Driver JAR", "type": "text", - "model": "dbName", + "model": "drvJar", + "placeholder": "JAR with JDBC driver", "tip": [ - "Database name to connect for loading tables metadata." + "Select appropriate JAR with JDBC driver." ] }, { - "label": "Host", + "label": "JDBC Driver", "type": "text", - "model": "host", - "placeholder": "IP address or host", + "model": "drvClass", + "placeholder": "Full class name of JDBC driver", "tip": [ - "IP address or host name where database server deployed." + "Full class name of JDBC driver that will be used to connect to database." ] }, { - "label": "Port", - "type": "number", - "model": "port", - "max": 65535, + "label": "JDBC URL", + "type": "text", + "model": "jdbcUrl", + "placeholder": "JDBC URL", "tip": [ - "Port number for connecting to database." + "JDBC URL for connecting to database.", + "Refer to your database documentation for details." ] }, { @@ -251,6 +248,15 @@ "Password for connecting to database.", "Note, password would not be saved." ] + }, + { + "label": "Tables only", + "type": "check", + "model": "tablesOnly", + "tip": [ + "If selected then only tables metadata will be parsed.", + "Otherwise table and view metadata will be parsed." + ] } ] } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/package.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/package.json b/modules/control-center-web/src/main/js/package.json index 39c138b..72a0497 100644 --- a/modules/control-center-web/src/main/js/package.json +++ b/modules/control-center-web/src/main/js/package.json @@ -37,6 +37,7 @@ "passport": "^0.2.1", "passport-local": "^1.0.0", "passport-local-mongoose": "^1.0.0", + "nodemailer": "1.4.0", "serve-favicon": "~2.2.0", "ws": "~0.7.2" }, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/public/stylesheets/style.scss ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/public/stylesheets/style.scss b/modules/control-center-web/src/main/js/public/stylesheets/style.scss index c5eba0c..4b0e754 100644 --- a/modules/control-center-web/src/main/js/public/stylesheets/style.scss +++ b/modules/control-center-web/src/main/js/public/stylesheets/style.scss @@ -898,6 +898,10 @@ label { overflow: hidden; } +.labelHeader { + font-weight: bold; +} + .labelField { float: left; margin-right: 5px; @@ -908,6 +912,10 @@ label { line-height: $input-height; } +.labelLogin { + margin-right: 10px; +} + .form-horizontal .form-group { margin: 0; } @@ -1212,10 +1220,6 @@ a { } } -.labelHeader { - font-weight: bold; -} - .ace_editor, #ace_document { margin: 0.65em 0 0 0; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/routes/notebooks.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/notebooks.js b/modules/control-center-web/src/main/js/routes/notebooks.js index 0560d3b..0c37d85 100644 --- a/modules/control-center-web/src/main/js/routes/notebooks.js +++ b/modules/control-center-web/src/main/js/routes/notebooks.js @@ -1,20 +1,18 @@ /* + * 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 * - * * 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. + * 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 router = require('express').Router(); @@ -68,7 +66,7 @@ router.post('/get', function (req, res) { }); // Get all metadata for spaces. - db.Notebook.findOne({$or : [{space: {$in: space_ids}}, {_id: req.body.noteId}]}).exec(function (err, notebook) { + db.Notebook.findOne({$or: [{space: {$in: space_ids}}, {_id: req.body.noteId}]}).exec(function (err, notebook) { if (err) return res.status(500).send(err.message); @@ -77,10 +75,10 @@ router.post('/get', function (req, res) { }); }); -function _randomValueHex (len) { - return crypto.randomBytes(Math.ceil(len/2)) +function _randomValueHex(len) { + return crypto.randomBytes(Math.ceil(len / 2)) .toString('hex') // convert to hexadecimal format - .slice(0,len); // return required number of characters + .slice(0, len); // return required number of characters } /** @@ -97,7 +95,7 @@ router.get('/new', function (req, res) { if (err) return res.status(500).send(err.message); - var name = 'Notebook' + ' ' + _randomValueHex(8); + var name = 'Notebook' + ' ' + _randomValueHex(8); (new db.Notebook({space: space.id, name: name, paragraph: []})).save(function (err, notebook) { if (err) @@ -108,4 +106,4 @@ router.get('/new', function (req, res) { }); }); -module.exports = router; \ No newline at end of file +module.exports = router; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/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 b3cb983..817c93b 100644 --- a/modules/control-center-web/src/main/js/routes/public.js +++ b/modules/control-center-web/src/main/js/routes/public.js @@ -17,6 +17,8 @@ var router = require('express').Router(); var passport = require('passport'); +var crypto = require('crypto'); +var nodemailer = require('nodemailer'); var db = require('../db'); // GET dropdown-menu template. @@ -39,11 +41,21 @@ router.get('/copy', function (req, res) { res.render('templates/copy', {}); }); -/* GET login page. */ +/* GET login dialog. */ router.get('/login', function (req, res) { res.render('login'); }); +/* GET reset password page. */ +router.get('/reset', function (req, res) { + res.render('reset'); +}); + +/* GET reset password page. */ +router.get('/resetModal', function (req, res) { + res.render('resetModal'); +}); + /** * Register new account. */ @@ -73,6 +85,96 @@ router.post('/register', function (req, res) { }); }); +router.post('/restore', function(req, res) { + var token = crypto.randomBytes(20).toString('hex'); + + db.Account.findOne({ email: req.body.email }, function(err, user) { + if (err) + return res.status(401).send('No account with that email address exists!'); + + 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!'); + + var transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: '!!! YOUR USERNAME !!!', + pass: '!!! YOUR PASSWORD !!!' + } + }); + + var mailOptions = { + from: 'passwordreset@YOUR.DOMAIN', + 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' + }; + + transporter.sendMail(mailOptions, function(err, info){ + 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.'); + }); + }); + }); +}); + +router.post('/reset/:token', function(req, res) { + db.Account.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) { + if (err) + return res.status(500).send(err); + + user.setPassword(newPassword, function (err, updatedUser) { + if (err) + return res.status(500).send(err.message); + + user.resetPasswordToken = undefined; + user.resetPasswordExpires = undefined; + + updatedUser.save(function (err) { + if (err) + return res.status(500).send(err.message); + + var transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: '!!! YOUR USERNAME !!!', + pass: '!!! YOUR PASSWORD !!!' + } + }); + + var mailOptions = { + from: 'passwordreset@YOUR.DOMAIN', + 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' + }; + + transporter.sendMail(mailOptions, function(err, info){ + if (err) + return res.status(401).send('Failed to send e-mail with reset link!'); + + console.log('Message sent: ' + info.response); + + res.redirect('/login'); + }); + }); + }); + }); +}); + /** * Login in exist account. */ @@ -110,14 +212,4 @@ router.get('/', function (req, res) { res.render('index'); }); -///* GET sql page. */ -//router.get('/sql', function(req, res) { -// res.render('sql', { user: req.user }); -//}); -// -///* GET clients page. */ -//router.get('/clients', function(req, res) { -// res.render('clients', { user: req.user }); -//}); - module.exports = router; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/views/configuration/summary.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/summary.jade b/modules/control-center-web/src/main/js/views/configuration/summary.jade index 86661d1..07e177e 100644 --- a/modules/control-center-web/src/main/js/views/configuration/summary.jade +++ b/modules/control-center-web/src/main/js/views/configuration/summary.jade @@ -97,7 +97,7 @@ block content .panel-collapse(role='tabpanel' bs-collapse-target) div(ng-show='selectedItem') .details-row(ng-repeat='field in clientFields') - +form-row-custom(['col-sm-3'], ['col-sm-3']) + +form-row-custom(['col-sm-3'], ['col-sm-3'], 'backupItem') div(bs-tabs style='margin-top: 0.65em') div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane) div(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlClient') http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/views/includes/controls.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade index fccafac..3f4cd49 100644 --- a/modules/control-center-web/src/main/js/views/includes/controls.jade +++ b/modules/control-center-web/src/main/js/views/includes/controls.jade @@ -209,10 +209,10 @@ mixin table-group-item-edit(fieldName, className, direction, index) select.form-control(id=focusIdNext2 ng-model=direction ng-options='item.value as item.label for item in {{sortDirections}}' on-enter=btnVisibleAndSave on-escape='tableReset()') mixin form-row - +form-row-custom(['col-sm-2'], ['col-sm-4']) + +form-row-custom(['col-sm-2'], ['col-sm-4'], 'backupItem') -mixin form-row-custom(lblClasses, fieldClasses) - - var fieldMdl = 'getModel(backupItem, field)[field.model]'; +mixin form-row-custom(lblClasses, fieldClasses, dataSource) + - var fieldMdl = 'getModel('+ dataSource + ', field)[field.model]'; - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)'}; - var fieldRequiredClass = '{true: "required"}[field.required || required(field)]' - var fieldHide = '{{field.hide}}' http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/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 index d32378f..47bb2c5 100644 --- a/modules/control-center-web/src/main/js/views/login.jade +++ b/modules/control-center-web/src/main/js/views/login.jade @@ -20,16 +20,15 @@ mixin lbl(txt) .modal.center(role='dialog') .modal-dialog .modal-content - .modal-header.header - div(id='errors-container') + #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') + form.form-horizontal(name='loginForm' ng-init='action == "login"') .modal-body.row - .col-sm-9.login.col-sm-offset-1 + .col-sm-9.col-sm-offset-1 .details-row(ng-show='action == "register"') +lbl('Full Name:') .col-sm-9 @@ -38,17 +37,19 @@ mixin lbl(txt) +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='y...@domain.com' required) - .details-row + .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' required on-enter='action == "login" && auth(action, user_info)') - .details-row(ng-show='action == "register"') + 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-tip.has-feedback - input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required on-enter='auth(action, user_info)') + .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.show-signup.ng-hide(event-focus='click' event-focus-id='user_email' ng-show='action != "login"' ng-click='action = "login";') log in - a.show-signup(event-focus='click' event-focus-id='user_name' ng-show='action != "register"' ng-click='action = "register"') sign up - | or - button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In - button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up + 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/2aa1ce8a/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 new file mode 100644 index 0000000..c9c4d88 --- /dev/null +++ b/modules/control-center-web/src/main/js/views/reset.jade @@ -0,0 +1,22 @@ +//- + 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. + +extends templates/layout + +block container + .row + .text-center(ng-controller='auth') + button.btn.btn-primary(ng-click='reset()' href='#') Reset Password http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/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 new file mode 100644 index 0000000..0878525 --- /dev/null +++ b/modules/control-center-web/src/main/js/views/resetModal.jade @@ -0,0 +1,34 @@ +//- + 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. + +.modal.center(role='dialog') + .modal-dialog + .modal-content + #errors-container.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"') + .modal-body.row + .col-sm-9.col-sm-offset-1 + .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)') + .modal-footer + button.btn.btn-primary(ng-disabled='resetForm.$invalid' ng-click='resetPassword(user_info)') Reset Password + http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2aa1ce8a/modules/control-center-web/src/main/js/views/templates/layout.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/templates/layout.jade b/modules/control-center-web/src/main/js/views/templates/layout.jade index 2e3fc5d..10aaa75 100644 --- a/modules/control-center-web/src/main/js/views/templates/layout.jade +++ b/modules/control-center-web/src/main/js/views/templates/layout.jade @@ -17,7 +17,7 @@ doctype html html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}') head - title= title + title=title block css // Bootstrap