mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Set password functionality
This commit is contained in:
parent
446921111e
commit
493bb77169
@ -84,7 +84,11 @@ app.use(function (err, req, res, next) {
|
||||
|
||||
// Not every error is worth logging - but this is good for now until it gets annoying.
|
||||
if (typeof err.stack !== 'undefined' && err.stack) {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
log.warn(err.stack);
|
||||
} else {
|
||||
log.warn(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
|
@ -19,7 +19,7 @@ const internalUser = {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
create: (access, data) => {
|
||||
let auth = data.auth;
|
||||
let auth = data.auth || null;
|
||||
delete data.auth;
|
||||
|
||||
data.avatar = data.avatar || '';
|
||||
@ -39,8 +39,7 @@ const internalUser = {
|
||||
.insertAndFetch(data);
|
||||
})
|
||||
.then(user => {
|
||||
return internalUser.get(access, {id: user.id});
|
||||
/*
|
||||
if (auth) {
|
||||
return authModel
|
||||
.query()
|
||||
.insert({
|
||||
@ -50,9 +49,14 @@ const internalUser = {
|
||||
meta: {}
|
||||
})
|
||||
.then(() => {
|
||||
return internalUser.get(access, {id: user.id});
|
||||
return user;
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
return user;
|
||||
}
|
||||
})
|
||||
.then(user => {
|
||||
return internalUser.get(access, {id: user.id});
|
||||
});
|
||||
},
|
||||
|
||||
@ -60,6 +64,7 @@ const internalUser = {
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {Integer} data.id
|
||||
* @param {String} [data.email]
|
||||
* @param {String} [data.name]
|
||||
* @return {Promise}
|
||||
*/
|
||||
@ -337,18 +342,39 @@ const internalUser = {
|
||||
return user;
|
||||
})
|
||||
.then(user => {
|
||||
// Get auth, patch if it exists
|
||||
return authModel
|
||||
.query()
|
||||
.where('user_id', user.id)
|
||||
.andWhere('type', data.type)
|
||||
.first()
|
||||
.then(existing_auth => {
|
||||
if (existing_auth) {
|
||||
// patch
|
||||
return authModel
|
||||
.query()
|
||||
.where('user_id', user.id)
|
||||
.andWhere('type', data.type)
|
||||
.patch({
|
||||
type: data.type,
|
||||
type: data.type, // This is required for the model to encrypt on save
|
||||
secret: data.secret
|
||||
});
|
||||
} else {
|
||||
// insert
|
||||
return authModel
|
||||
.query()
|
||||
.insert({
|
||||
user_id: user.id,
|
||||
type: data.type,
|
||||
secret: data.secret,
|
||||
meta: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return true;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,19 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* User Password Form
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
showUserPasswordForm: function (model) {
|
||||
if (Cache.User.isAdmin() || model.get('id') === Cache.User.get('id')) {
|
||||
require(['./main', './user/password'], function (App, View) {
|
||||
App.UI.showModalDialog(new View({model: model}));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Error
|
||||
*
|
||||
|
@ -2,59 +2,23 @@
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg order-lg-first">
|
||||
<ul class="nav nav-tabs border-0 flex-column flex-lg-row">
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown"><i class="fe fe-monitor"></i> Hosts</a>
|
||||
<div class="dropdown-menu dropdown-menu-arrow">
|
||||
<a href="/nginx/proxy" class="dropdown-item ">Proxy Hosts</a>
|
||||
<a href="/nginx/redirection" class="dropdown-item ">Redirections</a>
|
||||
<a href="/nginx/stream" class="dropdown-item ">Streams</a>
|
||||
<a href="/nginx/404" class="dropdown-item ">404 Hosts</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/" class="nav-link"><i class="fe fe-home"></i> Home</a>
|
||||
<a href="/nginx/access" class="nav-link"><i class="fe fe-lock"></i> Access Lists</a>
|
||||
</li>
|
||||
<% if (showUsers()) { %>
|
||||
<li class="nav-item">
|
||||
<a href="/users" class="nav-link"><i class="fe fe-users"></i> Users</a>
|
||||
</li>
|
||||
<% } %>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown"><i class="fe fe-box"></i> Interface</a>
|
||||
<div class="dropdown-menu dropdown-menu-arrow">
|
||||
<a href="../cards.html" class="dropdown-item ">Cards design</a>
|
||||
<a href="../charts.html" class="dropdown-item ">Charts</a>
|
||||
<a href="../pricing-cards.html" class="dropdown-item ">Pricing cards</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown"><i class="fe fe-calendar"></i> Components</a>
|
||||
<div class="dropdown-menu dropdown-menu-arrow">
|
||||
<a href="../maps.html" class="dropdown-item ">Maps</a>
|
||||
<a href="../icons.html" class="dropdown-item ">Icons</a>
|
||||
<a href="../store.html" class="dropdown-item ">Store</a>
|
||||
<a href="../blog.html" class="dropdown-item ">Blog</a>
|
||||
<a href="../carousel.html" class="dropdown-item ">Carousel</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown"><i class="fe fe-file"></i> Pages</a>
|
||||
<div class="dropdown-menu dropdown-menu-arrow">
|
||||
<a href="../profile.html" class="dropdown-item ">Profile</a>
|
||||
<a href="../login.html" class="dropdown-item ">Login</a>
|
||||
<a href="../register.html" class="dropdown-item ">Register</a>
|
||||
<a href="../forgot-password.html" class="dropdown-item ">Forgot password</a>
|
||||
<a href="../400.html" class="dropdown-item ">400 error</a>
|
||||
<a href="../401.html" class="dropdown-item ">401 error</a>
|
||||
<a href="../403.html" class="dropdown-item ">403 error</a>
|
||||
<a href="../404.html" class="dropdown-item ">404 error</a>
|
||||
<a href="../500.html" class="dropdown-item ">500 error</a>
|
||||
<a href="../503.html" class="dropdown-item ">503 error</a>
|
||||
<a href="../email.html" class="dropdown-item ">Email</a>
|
||||
<a href="../empty.html" class="dropdown-item ">Empty page</a>
|
||||
<a href="../rtl.html" class="dropdown-item ">RTL mode</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="../form-elements.html" class="nav-link"><i class="fe fe-check-square"></i> Forms</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="../gallery.html" class="nav-link"><i class="fe fe-image"></i> Gallery</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="../docs/index.html" class="nav-link"><i class="fe fe-file-text"></i> Documentation</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
30
src/frontend/js/app/user/password.ejs
Normal file
30
src/frontend/js/app/user/password.ejs
Normal file
@ -0,0 +1,30 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Change Password <%- isSelf() ? '' : 'for' + name %></h5>
|
||||
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<% if (isSelf()) { %>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Current Password</label>
|
||||
<input type="password" name="current_password" class="form-control" placeholder="" minlength="8" required>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">New Password</label>
|
||||
<input type="password" name="new_password1" class="form-control" placeholder="" minlength="8" required>
|
||||
<div class="invalid-feedback secret-error"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Confirm Password</label>
|
||||
<input type="password" name="new_password2" class="form-control" placeholder="" minlength="8" required>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-teal save">Save</button>
|
||||
</div>
|
||||
</div>
|
63
src/frontend/js/app/user/password.js
Normal file
63
src/frontend/js/app/user/password.js
Normal file
@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const template = require('./password.ejs');
|
||||
const Controller = require('../controller');
|
||||
const Api = require('../api');
|
||||
const App = require('../main');
|
||||
const Cache = require('../cache');
|
||||
|
||||
require('jquery-serializejson');
|
||||
|
||||
module.exports = Mn.View.extend({
|
||||
template: template,
|
||||
className: 'modal-dialog',
|
||||
|
||||
ui: {
|
||||
form: 'form',
|
||||
buttons: '.modal-footer button',
|
||||
cancel: 'button.cancel',
|
||||
save: 'button.save',
|
||||
error: '.secret-error'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click @ui.save': function (e) {
|
||||
e.preventDefault();
|
||||
this.ui.error.hide();
|
||||
let form = this.ui.form.serializeJSON();
|
||||
|
||||
if (form.new_password1 !== form.new_password2) {
|
||||
this.ui.error.text('Passwords do not match!').show();
|
||||
return;
|
||||
}
|
||||
|
||||
let data = {
|
||||
type: 'password',
|
||||
current: form.current_password,
|
||||
secret: form.new_password1
|
||||
};
|
||||
|
||||
this.ui.buttons.prop('disabled', true).addClass('btn-disabled');
|
||||
Api.Users.setPassword(this.model.get('id'), data)
|
||||
.then(() => {
|
||||
App.UI.closeModal();
|
||||
Controller.showUsers();
|
||||
})
|
||||
.catch(err => {
|
||||
this.ui.error.text(err.message).show();
|
||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
isSelf: function () {
|
||||
return Cache.User.get('id') === this.model.get('id');
|
||||
},
|
||||
|
||||
templateContext: function () {
|
||||
return {
|
||||
isSelf: this.isSelf.bind(this)
|
||||
};
|
||||
}
|
||||
});
|
@ -6,7 +6,7 @@
|
||||
<td>
|
||||
<div><%- name %></div>
|
||||
<div class="small text-muted">
|
||||
Created: Mar 19, 2018
|
||||
Created: <%- formatDbDate(created_on, 'Do MMMM YYYY') %>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
|
@ -26,7 +26,7 @@ module.exports = Mn.View.extend({
|
||||
|
||||
'click @ui.password': function (e) {
|
||||
e.preventDefault();
|
||||
//Controller.showUserPasswordForm(this.model);
|
||||
Controller.showUserPasswordForm(this.model);
|
||||
},
|
||||
|
||||
'click @ui.delete': function (e) {
|
||||
|
@ -39,15 +39,21 @@ Mn.Renderer.render = function (template, data, view) {
|
||||
* @param {String} date
|
||||
* @returns {String}
|
||||
*/
|
||||
data.shortDate = function (date) {
|
||||
let shortdate = '';
|
||||
|
||||
data.formatDbDate = function (date, format) {
|
||||
if (typeof date === 'number') {
|
||||
shortdate = moment.unix(date).format('YYYY-MM-DD');
|
||||
} else {
|
||||
shortdate = moment(date).format('YYYY-MM-DD');
|
||||
return moment.unix(date).format(format);
|
||||
}
|
||||
|
||||
return moment(date).format(format);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {String} date
|
||||
* @returns {String}
|
||||
*/
|
||||
data.shortDate = function (date) {
|
||||
let shortdate = data.formatDbDate(date, 'YYYY-MM-DD');
|
||||
|
||||
return moment().format('YYYY-MM-DD') === shortdate ? 'Today' : shortdate;
|
||||
};
|
||||
|
||||
@ -56,15 +62,7 @@ Mn.Renderer.render = function (template, data, view) {
|
||||
* @returns {String}
|
||||
*/
|
||||
data.shortTime = function (date) {
|
||||
let shorttime = '';
|
||||
|
||||
if (typeof date === 'number') {
|
||||
shorttime = moment.unix(date).format('H:mm A');
|
||||
} else {
|
||||
shorttime = moment(date).format('H:mm A');
|
||||
}
|
||||
|
||||
return shorttime;
|
||||
return data.formatDbDate(date, 'H:mm A');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -9,9 +9,7 @@
|
||||
<input name="identity" type="email" class="form-control" placeholder="Enter email" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
Password
|
||||
</label>
|
||||
<label class="form-label">Password</label>
|
||||
<input name="secret" type="password" class="form-control" placeholder="Password" required>
|
||||
<div class="invalid-feedback secret-error"></div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user