mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-11-04 01:15:14 +00:00 
			
		
		
		
	v2.1.0 (#293)
* Fix wrapping when too many hosts are shown (#207) * Update npm packages, fixes CVE-2019-10757 * Revert some breaking packages * Major overhaul - Docker buildx support in CI - Cypress API Testing in CI - Restructured folder layout (insert clean face meme) - Added Swagger documentation and validate API against that (to be completed) - Use common base image for all supported archs, which includes updated nginx with ipv6 support - Updated certbot and changes required for it - Large amount of Hosts names will wrap in UI - Updated packages for frontend - Version bump 2.1.0 * Updated documentation * Fix JWT expire time going crazy. Now set to 1day * Backend JS formatting rules * Remove v1 importer, I doubt anyone is using v1 anymore * Added backend formatting rules and enforce them in Jenkins builds * Fix CI, doesn't need a tty * Thanks bcrypt. Why can't you just be normal. * Cleanup after syntax check Co-authored-by: Marcelo Castagna <margaale@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										19
									
								
								frontend/js/app/user/delete.ejs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								frontend/js/app/user/delete.ejs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
<div class="modal-content">
 | 
			
		||||
    <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title"><%- i18n('users', 'delete', {name: name}) %></h5>
 | 
			
		||||
        <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-body">
 | 
			
		||||
        <form>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-sm-12 col-md-12">
 | 
			
		||||
                    <%= i18n('users', 'delete-confirm', {name: name}) %>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
 | 
			
		||||
        <button type="button" class="btn btn-danger save"><%- i18n('str', 'sure') %></button>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										34
									
								
								frontend/js/app/user/delete.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								frontend/js/app/user/delete.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
const Mn       = require('backbone.marionette');
 | 
			
		||||
const template = require('./delete.ejs');
 | 
			
		||||
const App      = require('../main');
 | 
			
		||||
 | 
			
		||||
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'
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    events: {
 | 
			
		||||
 | 
			
		||||
        'click @ui.save': function (e) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
 | 
			
		||||
            App.Api.Users.delete(this.model.get('id'))
 | 
			
		||||
                .then(() => {
 | 
			
		||||
                    App.Controller.showUsers();
 | 
			
		||||
                    App.UI.closeModal();
 | 
			
		||||
                })
 | 
			
		||||
                .catch(err => {
 | 
			
		||||
                    alert(err.message);
 | 
			
		||||
                    this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										58
									
								
								frontend/js/app/user/form.ejs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								frontend/js/app/user/form.ejs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
<div class="modal-content">
 | 
			
		||||
    <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title"><%- i18n('users', 'form-title', {id: id}) %></h5>
 | 
			
		||||
        <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-body">
 | 
			
		||||
        <form>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-sm-6 col-md-6">
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label class="form-label"><%- i18n('users', 'full-name') %> <span class="form-required">*</span></label>
 | 
			
		||||
                        <input name="name" type="text" class="form-control" placeholder="Joe Citizen" value="<%- name %>" required>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-sm-6 col-md-6">
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label class="form-label"><%- i18n('users', 'nickname') %></label>
 | 
			
		||||
                        <input name="nickname" type="text" class="form-control" placeholder="Joe" value="<%- nickname %>">
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-sm-12 col-md-12">
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label class="form-label"><%- i18n('str', 'email') %> <span class="form-required">*</span></label>
 | 
			
		||||
                        <input name="email" type="email" class="form-control" placeholder="joe@example.com" value="<%- email %>" required>
 | 
			
		||||
                        <div class="invalid-feedback secret-error"></div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <% if (isAdmin() && !isSelf()) { %>
 | 
			
		||||
                <div class="col-sm-12 col-md-12">
 | 
			
		||||
                    <div class="form-label"><%- i18n('roles', 'title') %></div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-sm-6 col-md-6">
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label class="custom-switch">
 | 
			
		||||
                            <input type="checkbox" class="custom-switch-input" name="is_admin" value="1"<%- isAdminUser() ? ' checked' : '' %><%- isSelf() ? ' disabled' : '' %>>
 | 
			
		||||
                            <span class="custom-switch-indicator"></span>
 | 
			
		||||
                            <span class="custom-switch-description"><%- i18n('roles', 'admin') %></span>
 | 
			
		||||
                        </label>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-sm-6 col-md-6">
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label class="custom-switch">
 | 
			
		||||
                            <input type="checkbox" class="custom-switch-input" name="is_disabled" value="1"<%- is_disabled ? ' checked' : '' %><%- isSelf() ? ' disabled' : '' %>>
 | 
			
		||||
                            <span class="custom-switch-indicator"></span>
 | 
			
		||||
                            <span class="custom-switch-description"><%- i18n('str', 'disabled') %></span>
 | 
			
		||||
                        </label>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <% } %>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
 | 
			
		||||
        <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										108
									
								
								frontend/js/app/user/form.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								frontend/js/app/user/form.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
const Mn        = require('backbone.marionette');
 | 
			
		||||
const App       = require('../main');
 | 
			
		||||
const UserModel = require('../../models/user');
 | 
			
		||||
const template  = require('./form.ejs');
 | 
			
		||||
 | 
			
		||||
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 view = this;
 | 
			
		||||
            let data = this.ui.form.serializeJSON();
 | 
			
		||||
 | 
			
		||||
            let show_password = this.model.get('email') === 'admin@example.com';
 | 
			
		||||
 | 
			
		||||
            // admin@example.com is not allowed
 | 
			
		||||
            if (data.email === 'admin@example.com') {
 | 
			
		||||
                this.ui.error.text(App.i18n('users', 'default_error')).show();
 | 
			
		||||
                this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Manipulate
 | 
			
		||||
            data.roles = [];
 | 
			
		||||
            if ((this.model.get('id') === App.Cache.User.get('id') && this.model.isAdmin()) || (typeof data.is_admin !== 'undefined' && data.is_admin)) {
 | 
			
		||||
                data.roles.push('admin');
 | 
			
		||||
                delete data.is_admin;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            data.is_disabled = typeof data.is_disabled !== 'undefined' ? !!data.is_disabled : false;
 | 
			
		||||
            this.ui.buttons.prop('disabled', true).addClass('btn-disabled');
 | 
			
		||||
            let method = App.Api.Users.create;
 | 
			
		||||
 | 
			
		||||
            if (this.model.get('id')) {
 | 
			
		||||
                // edit
 | 
			
		||||
                method  = App.Api.Users.update;
 | 
			
		||||
                data.id = this.model.get('id');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            method(data)
 | 
			
		||||
                .then(result => {
 | 
			
		||||
                    if (result.id === App.Cache.User.get('id')) {
 | 
			
		||||
                        App.Cache.User.set(result);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (view.model.get('id') !== App.Cache.User.get('id')) {
 | 
			
		||||
                        App.Controller.showUsers();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    view.model.set(result);
 | 
			
		||||
                    App.UI.closeModal(function () {
 | 
			
		||||
                        if (method === App.Api.Users.create) {
 | 
			
		||||
                            // Show permissions dialog immediately
 | 
			
		||||
                            App.Controller.showUserPermissions(view.model);
 | 
			
		||||
                        } else if (show_password) {
 | 
			
		||||
                            App.Controller.showUserPasswordForm(view.model);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .catch(err => {
 | 
			
		||||
                    this.ui.error.text(err.message).show();
 | 
			
		||||
                    this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    templateContext: function () {
 | 
			
		||||
        let view = this;
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            isSelf: function () {
 | 
			
		||||
                return view.model.get('id') === App.Cache.User.get('id');
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            isAdmin: function () {
 | 
			
		||||
                return App.Cache.User.isAdmin();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            isAdminUser: function () {
 | 
			
		||||
                return view.model.isAdmin();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            isDisabled: function () {
 | 
			
		||||
                return view.model.isDisabled();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    initialize: function (options) {
 | 
			
		||||
        if (typeof options.model === 'undefined' || !options.model) {
 | 
			
		||||
            this.model = new UserModel.Model();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										30
									
								
								frontend/js/app/user/password.ejs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								frontend/js/app/user/password.ejs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
<div class="modal-content">
 | 
			
		||||
    <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title"><%- i18n('users', 'password-title', {self: isSelf(), name: 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"><%- i18n('users', '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"><%- i18n('users', '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"><%- i18n('users', '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"><%- i18n('str', 'cancel') %></button>
 | 
			
		||||
        <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										58
									
								
								frontend/js/app/user/password.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								frontend/js/app/user/password.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
const Mn       = require('backbone.marionette');
 | 
			
		||||
const App      = require('../main');
 | 
			
		||||
const template = require('./password.ejs');
 | 
			
		||||
 | 
			
		||||
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');
 | 
			
		||||
            App.Api.Users.setPassword(this.model.get('id'), data)
 | 
			
		||||
                .then(() => {
 | 
			
		||||
                    App.UI.closeModal();
 | 
			
		||||
                    App.Controller.showUsers();
 | 
			
		||||
                })
 | 
			
		||||
                .catch(err => {
 | 
			
		||||
                    this.ui.error.text(err.message).show();
 | 
			
		||||
                    this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    isSelf: function () {
 | 
			
		||||
        return App.Cache.User.get('id') === this.model.get('id');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    templateContext: function () {
 | 
			
		||||
        return {
 | 
			
		||||
            isSelf: this.isSelf.bind(this)
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										68
									
								
								frontend/js/app/user/permissions.ejs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								frontend/js/app/user/permissions.ejs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
<div class="modal-content">
 | 
			
		||||
    <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title"><%- i18n('users', 'permissions-title', {name: name}) %></h5>
 | 
			
		||||
        <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-body">
 | 
			
		||||
        <form>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-sm-12 col-md-12">
 | 
			
		||||
 | 
			
		||||
                    <% if (isAdmin()) { %>
 | 
			
		||||
                    <div class="alert alert-icon alert-secondary" role="alert">
 | 
			
		||||
                        <i class="fe fe-alert-triangle mr-2" aria-hidden="true"></i>
 | 
			
		||||
                        <%- i18n('users', 'admin-perms') %>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <% } %>
 | 
			
		||||
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label class="form-label"><%- i18n('users', 'perms-visibility') %></label>
 | 
			
		||||
                        <div class="selectgroup w-100">
 | 
			
		||||
                            <label class="selectgroup-item">
 | 
			
		||||
                                <input type="radio" name="visibility" value="user" class="selectgroup-input"<%- getPerm('visibility') !== 'all' ? ' checked' : '' %>>
 | 
			
		||||
                                <span class="selectgroup-button"><%- i18n('users', 'perms-visibility-user') %></span>
 | 
			
		||||
                            </label>
 | 
			
		||||
                            <label class="selectgroup-item">
 | 
			
		||||
                                <input type="radio" name="visibility" value="all" class="selectgroup-input"<%- getPerm('visibility') === 'all' ? ' checked' : '' %>>
 | 
			
		||||
                                <span class="selectgroup-button"><%- i18n('users', 'perms-visibility-all') %></span>
 | 
			
		||||
                            </label>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <%
 | 
			
		||||
                var list = ['proxy-hosts', 'redirection-hosts', 'dead-hosts', 'streams', 'access-lists', 'certificates'];
 | 
			
		||||
                list.map(function(item) {
 | 
			
		||||
                    var perm = item.replace('-', '_');
 | 
			
		||||
                    %>
 | 
			
		||||
                    <div class="col-sm-12 col-md-12">
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <label class="form-label"><%- i18n(item, 'title') %></label>
 | 
			
		||||
                            <div class="selectgroup w-100">
 | 
			
		||||
                                <label class="selectgroup-item">
 | 
			
		||||
                                    <input type="radio" name="<%- perm %>" value="manage" class="selectgroup-input" <%- getPermProps(perm, 'manage', true) %>>
 | 
			
		||||
                                    <span class="selectgroup-button"><%- i18n('users', 'perm-manage') %></span>
 | 
			
		||||
                                </label>
 | 
			
		||||
                                <label class="selectgroup-item">
 | 
			
		||||
                                    <input type="radio" name="<%- perm %>" value="view" class="selectgroup-input" <%- getPermProps(perm, 'view') %>>
 | 
			
		||||
                                    <span class="selectgroup-button"><%- i18n('users', 'perm-view') %></span>
 | 
			
		||||
                                </label>
 | 
			
		||||
                                <label class="selectgroup-item">
 | 
			
		||||
                                    <input type="radio" name="<%- perm %>" value="hidden" class="selectgroup-input" <%- getPermProps(perm, 'hidden') %>>
 | 
			
		||||
                                    <span class="selectgroup-button"><%- i18n('users', 'perm-hidden') %></span>
 | 
			
		||||
                                </label>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <%
 | 
			
		||||
                });
 | 
			
		||||
                %>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
 | 
			
		||||
        <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										95
									
								
								frontend/js/app/user/permissions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								frontend/js/app/user/permissions.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
const Mn        = require('backbone.marionette');
 | 
			
		||||
const App       = require('../main');
 | 
			
		||||
const UserModel = require('../../models/user');
 | 
			
		||||
const template  = require('./permissions.ejs');
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
 | 
			
		||||
            let view = this;
 | 
			
		||||
            let data = this.ui.form.serializeJSON();
 | 
			
		||||
 | 
			
		||||
            // Manipulate
 | 
			
		||||
            if (view.model.isAdmin()) {
 | 
			
		||||
                // Force some attributes for admin
 | 
			
		||||
                data = _.assign({}, data, {
 | 
			
		||||
                    access_lists:      'manage',
 | 
			
		||||
                    dead_hosts:        'manage',
 | 
			
		||||
                    proxy_hosts:       'manage',
 | 
			
		||||
                    redirection_hosts: 'manage',
 | 
			
		||||
                    streams:           'manage',
 | 
			
		||||
                    certificates:      'manage'
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.ui.buttons.prop('disabled', true).addClass('btn-disabled');
 | 
			
		||||
 | 
			
		||||
            App.Api.Users.setPermissions(view.model.get('id'), data)
 | 
			
		||||
                .then(() => {
 | 
			
		||||
                    if (view.model.get('id') === App.Cache.User.get('id')) {
 | 
			
		||||
                        App.Cache.User.set({permissions: data});
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    view.model.set({permissions: data});
 | 
			
		||||
                    App.UI.closeModal();
 | 
			
		||||
                })
 | 
			
		||||
                .catch(err => {
 | 
			
		||||
                    this.ui.error.text(err.message).show();
 | 
			
		||||
                    this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    templateContext: function () {
 | 
			
		||||
        let perms    = this.model.get('permissions');
 | 
			
		||||
        let is_admin = this.model.isAdmin();
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            getPerm: function (key) {
 | 
			
		||||
                if (perms !== null && typeof perms[key] !== 'undefined') {
 | 
			
		||||
                    return perms[key];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return null;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            getPermProps: function (key, item, forced_admin) {
 | 
			
		||||
                if (forced_admin && is_admin) {
 | 
			
		||||
                    return 'checked disabled';
 | 
			
		||||
                } else if (is_admin) {
 | 
			
		||||
                    return 'disabled';
 | 
			
		||||
                } else if (perms !== null && typeof perms[key] !== 'undefined' && perms[key] === item) {
 | 
			
		||||
                    return 'checked';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return '';
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            isAdmin: function () {
 | 
			
		||||
                return is_admin;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    initialize: function (options) {
 | 
			
		||||
        if (typeof options.model === 'undefined' || !options.model) {
 | 
			
		||||
            this.model = new UserModel.Model();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user