Remove btn-flat to convert to round buttons (first pass)

Convert col-xs-* to just col-* as part of bootstrap v3 -> v4
Convert box-* -> card-* as part of bootstrap v3 -> v4
Moved domain actions on main dashboard to a dropdown menu to avoid clutter
Added "Log Out" to top header left
Hid OTP on admin edit user to only show the disable card & options if the user account has OTP enabled
This commit is contained in:
Tyler Todd 2023-02-06 15:45:13 +00:00
parent 7f25e3b555
commit ac786f45be
24 changed files with 1264 additions and 1152 deletions

View File

@ -6,7 +6,9 @@
"bootstrap-validator": "^0.11.9", "bootstrap-validator": "^0.11.9",
"datatables.net-plugins": "^1.13.1", "datatables.net-plugins": "^1.13.1",
"icheck": "^1.0.2", "icheck": "^1.0.2",
"ionicons": "^6.1.1",
"jquery-slimscroll": "^1.3.8", "jquery-slimscroll": "^1.3.8",
"jquery-sparkline": "^2.4.0",
"jquery-ui-dist": "^1.13.2", "jquery-ui-dist": "^1.13.2",
"jquery.quicksearch": "^2.4.0", "jquery.quicksearch": "^2.4.0",
"jtimeout": "^3.2.0", "jtimeout": "^3.2.0",

View File

@ -2,67 +2,64 @@ from flask_assets import Bundle, Environment, Filter
class ConcatFilter(Filter): class ConcatFilter(Filter):
""" """
Filter that merges files, placing a semicolon between them. Filter that merges files, placing a semicolon between them.
Fixes issues caused by missing semicolons at end of JS assets, for example Fixes issues caused by missing semicolons at end of JS assets, for example
with last statement of jquery.pjax.js. with last statement of jquery.pjax.js.
""" """
def concat(self, out, hunks, **kw): def concat(self, out, hunks, **kw):
out.write(';'.join([h.data() for h, info in hunks])) out.write(';'.join([h.data() for h, info in hunks]))
css_login = Bundle(
'node_modules/ionicons/dist/collection/components/icon/icon.css',
'node_modules/icheck/skins/square/blue.css',
'node_modules/admin-lte/dist/css/adminlte.css',
filters=('cssmin', 'cssrewrite'),
output='generated/login.css')
css_login = Bundle('node_modules/bootstrap/dist/css/bootstrap.css', js_login = Bundle(
'node_modules/font-awesome/css/font-awesome.css', 'node_modules/jquery/dist/jquery.js',
'node_modules/ionicons/dist/css/ionicons.css', 'node_modules/bootstrap/dist/js/bootstrap.js',
'node_modules/icheck/skins/square/blue.css', 'node_modules/icheck/icheck.js',
'node_modules/admin-lte/dist/css/AdminLTE.css', 'custom/js/custom.js',
filters=('cssmin', 'cssrewrite'), filters=(ConcatFilter, 'rjsmin'),
output='generated/login.css') output='generated/login.js')
js_login = Bundle('node_modules/jquery/dist/jquery.js', js_validation = Bundle(
'node_modules/bootstrap/dist/js/bootstrap.js', 'node_modules/bootstrap-validator/dist/validator.js',
'node_modules/icheck/icheck.js', output='generated/validation.js')
'custom/js/custom.js',
filters=(ConcatFilter, 'rjsmin'),
output='generated/login.js')
js_validation = Bundle('node_modules/bootstrap-validator/dist/validator.js',
output='generated/validation.js')
css_main = Bundle( css_main = Bundle(
'node_modules/bootstrap/dist/css/bootstrap.css', 'node_modules/datatables.net-bs4/css/dataTables.bootstrap4.min.css',
'node_modules/font-awesome/css/font-awesome.css', 'node_modules/icheck/skins/square/blue.css',
'node_modules/ionicons/dist/css/ionicons.css', 'node_modules/multiselect/css/multi-select.css',
'node_modules/datatables.net-bs/css/dataTables.bootstrap.css', 'node_modules/admin-lte/dist/css/adminlte.css',
'node_modules/icheck/skins/square/blue.css', 'custom/css/custom.css',
'node_modules/multiselect/css/multi-select.css', 'node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.css',
'node_modules/admin-lte/dist/css/AdminLTE.css', filters=('cssmin', 'cssrewrite'),
'node_modules/admin-lte/dist/css/skins/_all-skins.css', output='generated/main.css')
'custom/css/custom.css',
'node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.css',
filters=('cssmin', 'cssrewrite'),
output='generated/main.css')
js_main = Bundle('node_modules/jquery/dist/jquery.js', js_main = Bundle(
'node_modules/jquery-ui-dist/jquery-ui.js', 'node_modules/jquery/dist/jquery.js',
'node_modules/bootstrap/dist/js/bootstrap.js', 'node_modules/jquery-ui-dist/jquery-ui.js',
'node_modules/datatables.net/js/jquery.dataTables.js', 'node_modules/bootstrap/dist/js/bootstrap.bundle.js',
'node_modules/datatables.net-bs/js/dataTables.bootstrap.js', 'node_modules/datatables.net/js/jquery.dataTables.js',
'node_modules/jquery-sparkline/jquery.sparkline.js', 'node_modules/datatables.net-bs4/js/dataTables.bootstrap4.js',
'node_modules/jquery-slimscroll/jquery.slimscroll.js', 'node_modules/jquery-sparkline/jquery.sparkline.js',
'node_modules/icheck/icheck.js', 'node_modules/jquery-slimscroll/jquery.slimscroll.js',
'node_modules/fastclick/lib/fastclick.js', 'node_modules/icheck/icheck.js',
'node_modules/moment/moment.js', 'node_modules/fastclick/lib/fastclick.js',
'node_modules/admin-lte/dist/js/adminlte.js', 'node_modules/moment/moment.js',
'node_modules/multiselect/js/jquery.multi-select.js', 'node_modules/admin-lte/dist/js/adminlte.js',
'node_modules/datatables.net-plugins/sorting/natural.js', 'node_modules/multiselect/js/jquery.multi-select.js',
'node_modules/jtimeout/src/jTimeout.js', 'node_modules/datatables.net-plugins/sorting/natural.js',
'node_modules/jquery.quicksearch/src/jquery.quicksearch.js', 'node_modules/jtimeout/src/jTimeout.js',
'custom/js/custom.js', 'node_modules/jquery.quicksearch/src/jquery.quicksearch.js',
'node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js', 'custom/js/custom.js',
filters=(ConcatFilter, 'rjsmin'), 'node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js',
output='generated/main.js') filters=(ConcatFilter, 'rjsmin'),
output='generated/main.js')
assets = Environment() assets = Environment()
assets.register('js_login', js_login) assets.register('js_login', js_login)

View File

@ -27,110 +27,113 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-4">
<div class="card card-primary"> <div class="card card-primary">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} account</h3> <h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} account</h3>
</div>
<form role="form" method="post" action="{% if create %}{{ url_for('admin.edit_account') }}{% else %}{{ url_for('admin.edit_account', account_name=account.name) }}{% endif %}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<input type="hidden" name="create" value="{{ create }}">
<div class="card-body">
{% if error %}
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<h4><i class="icon fa fa-ban"></i> Error!</h4>
{{ error }}
</div> </div>
<!-- /.box-header --> <span class="help-block">{{ error }}</span>
<!-- form start --> {% endif %}
<form role="form" method="post" <div class="form-group has-feedback {% if invalid_accountname or duplicate_accountname %}has-error{% endif %}">
action="{% if create %}{{ url_for('admin.edit_account') }}{% else %}{{ url_for('admin.edit_account', account_name=account.name) }}{% endif %}"> <label class="control-label" for="accountname">Name</label>
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <input type="text" class="form-control" placeholder="Account Name (required)"
<input type="hidden" name="create" value="{{ create }}"> name="accountname" {% if account %}value="{{ account.name }}" {% endif %}
<div class="card-body"> {% if not create %}disabled{% endif %}>
{% if error %} <span class="fa fa-cog form-control-feedback"></span>
<div class="alert alert-danger alert-dismissible"> {% if invalid_accountname %}
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <span class="help-block">Cannot be blank and must only contain alphanumeric
<h4><i class="icon fa fa-ban"></i> Error!</h4> characters{% if SETTING.get('account_name_extra_chars') %}, dots, hyphens or underscores{% endif %}.
{{ error }} </span>
</div> {% elif duplicate_accountname %}
<span class="help-block">{{ error }}</span> <span class="help-block">Account name already in use.</span>
{% endif %} {% endif %}
<div </div>
class="form-group has-feedback {% if invalid_accountname or duplicate_accountname %}has-error{% endif %}"> <div class="form-group has-feedback">
<label class="control-label" for="accountname">Name</label> <label class="control-label" for="accountdescription">Description</label>
<input type="text" class="form-control" placeholder="Account Name (required)" <input type="text" class="form-control" placeholder="Account Description (optional)"
name="accountname" {% if account %}value="{{ account.name }}" {% endif %} name="accountdescription" {% if account %}value="{{ account.description }}" {% endif %}>
{% if not create %}disabled{% endif %}> <span class="fa fa-industry form-control-feedback"></span>
<span class="fa fa-cog form-control-feedback"></span> </div>
{% if invalid_accountname %} <div class="form-group has-feedback">
<span class="help-block">Cannot be blank and must only contain alphanumeric <label class="control-label" for="accountcontact">Contact Person</label>
characters{% if SETTING.get('account_name_extra_chars') %}, dots, hyphens or underscores{% endif %}.</span> <input type="text" class="form-control" placeholder="Contact Person (optional)"
{% elif duplicate_accountname %} name="accountcontact" {% if account %}value="{{ account.contact }}" {% endif %}>
<span class="help-block">Account name already in use.</span> <span class="fa fa-user form-control-feedback"></span>
{% endif %} </div>
</div> <div class="form-group has-feedback">
<div class="form-group has-feedback"> <label class="control-label" for="accountmail">Mail Address</label>
<label class="control-label" for="accountdescription">Description</label> <input type="email" class="form-control" placeholder="Mail Address (optional)"
<input type="text" class="form-control" placeholder="Account Description (optional)" name="accountmail" {% if account %}value="{{ account.mail }}" {% endif %}>
name="accountdescription" {% if account %}value="{{ account.description }}" {% endif %}> <span class="fa fa-envelope form-control-feedback"></span>
<span class="fa fa-industry form-control-feedback"></span> </div>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="accountcontact">Contact Person</label>
<input type="text" class="form-control" placeholder="Contact Person (optional)"
name="accountcontact" {% if account %}value="{{ account.contact }}" {% endif %}>
<span class="fa fa-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="accountmail">Mail Address</label>
<input type="email" class="form-control" placeholder="Mail Address (optional)"
name="accountmail" {% if account %}value="{{ account.mail }}" {% endif %}>
<span class="fa fa-envelope form-control-feedback"></span>
</div>
</div>
<div class="card-header with-border">
<h3 class="card-title">Access Control</h3>
</div>
<div class="card-body">
<p>Users on the right have access to manage records in all domains
associated with the account.</p>
<p>Click on users to move between columns.</p>
<div class="form-group col-xs-2">
<select multiple="multiple" class="form-control" id="account_multi_user"
name="account_multi_user">
{% for user in users %}
<option {% if user.id in account_user_ids|default([]) %}selected{% endif %}
value="{{ user.username }}">{{ user.username }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="card-footer">
<button type="submit"
class="btn btn-flat btn-primary">{% if create %}Create{% else %}Update{% endif %}
Account</button>
</div>
</form>
</div> </div>
</div> <div class="card-header with-border">
<div class="col-md-6"> <h3 class="card-title">Access Control</h3>
<div class="card card-primary">
<div class="card-header with-border">
<h3 class="card-title">Help with creating a new account</h3>
</div>
<div class="card-body">
<p>
An account allows grouping of domains belonging to a particular entity, such as a customer or
department.<br />
A domain can be assigned to an account upon domain creation or through the domain administration
page.
</p>
<p>Fill in all the fields to the in the form to the left.</p>
<p>
<strong>Name</strong> is an account identifier. It will be lowercased and can contain alphanumeric
characters{% if SETTING.get('account_name_extra_chars') %}, dots, hyphens and underscores (no space or other special character is allowed)
{% else %} (no extra character is allowed){% endif %}.<br />
<strong>Description</strong> is a user friendly name for this account.<br />
<strong>Contact person</strong> is the name of a contact person at the account.<br />
<strong>Mail Address</strong> is an e-mail address for the contact person.
</p>
</div>
</div> </div>
<div class="card-body">
<p>Users on the right have access to manage records in all domains
associated with the account.
</p>
<p>Click on users to move between columns.</p>
<div class="form-group col-2">
<select multiple="multiple" class="form-control" id="account_multi_user"
name="account_multi_user">
{% for user in users %}
<option {% if user.id in account_user_ids|default([]) %}selected{% endif %}
value="{{ user.username }}">{{ user.username }}
</option>
{% endfor %}
</select>
</div>
</div>
<div class="card-footer">
<button type="submit"
class="btn btn-flat btn-primary">{% if create %}Create{% else %}Update{% endif %}
Account
</button>
</div>
</form>
</div> </div>
</div>
<div class="col-6">
<div class="card card-primary">
<div class="card-header with-border">
<h3 class="card-title">Help with creating a new account</h3>
</div>
<div class="card-body">
<p>
An account allows grouping of domains belonging to a particular entity, such as a customer or
department.
<br />
A domain can be assigned to an account upon domain creation or through the domain administration
page.
</p>
<p>Fill in all the fields to the in the form to the left.</p>
<p>
<strong>Name</strong> is an account identifier. It will be lowercased and can contain alphanumeric
characters{% if SETTING.get('account_name_extra_chars') %}, dots, hyphens and underscores (no space or other special character is allowed)
{% else %} (no extra character is allowed){% endif %}.<br />
<strong>Description</strong> is a user friendly name for this account.<br />
<strong>Contact person</strong> is the name of a contact person at the account.<br />
<strong>Mail Address</strong> is an e-mail address for the contact person.
</p>
</div>
</div>
</div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}

View File

@ -31,7 +31,7 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-4">
<div class="card card-primary"> <div class="card card-primary">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} Key</h3> <h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} Key</h3>
@ -68,7 +68,7 @@
<p>This key will be linked to the accounts on the right,</p> <p>This key will be linked to the accounts on the right,</p>
<p>thus granting access to domains owned by the selected accounts.</p> <p>thus granting access to domains owned by the selected accounts.</p>
<p>Click on accounts to move between the columns.</p> <p>Click on accounts to move between the columns.</p>
<div class="form-group col-xs-2"> <div class="form-group col-2">
<select multiple="multiple" class="form-control" id="key_multi_account" <select multiple="multiple" class="form-control" id="key_multi_account"
name="key_multi_account"> name="key_multi_account">
{% for account in accounts %} {% for account in accounts %}
@ -83,7 +83,7 @@
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}> <div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
<p>This key will have acess to the domains on the right.</p> <p>This key will have acess to the domains on the right.</p>
<p>Click on domains to move between the columns.</p> <p>Click on domains to move between the columns.</p>
<div class="form-group col-xs-2"> <div class="form-group col-2">
<select multiple="multiple" class="form-control" id="key_multi_domain" <select multiple="multiple" class="form-control" id="key_multi_domain"
name="key_multi_domain"> name="key_multi_domain">
{% for domain in domains %} {% for domain in domains %}
@ -94,13 +94,13 @@
</div> </div>
<div class="card-footer"> <div class="card-footer">
<button type="submit" <button type="submit"
class="btn btn-flat btn-primary" id="key_submit">{% if create %}Create{% else %}Update{% endif %} class="btn btn-flat btn-primary float-right" id="key_submit">{% if create %}Create{% else %}Update{% endif %}
Key</button> Key</button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-8">
<div class="card card-primary"> <div class="card card-primary">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">Help with {% if create %}creating a new{% else%}updating a{% endif %} key <h3 class="card-title">Help with {% if create %}creating a new{% else%}updating a{% endif %} key

View File

@ -1,34 +1,28 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_users" %} {% set active_page = "admin_users" %}
{% block title %}<title>Edit User - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
{% if create %}Add user{% else %}Edit user "{{ user.username }}"{% endif %} - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) --> <div class="content-header">
<section class="content-header">
<h1>
User
<small>{% if create %}New user{% else %}{{ user.username }}{% endif %}</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i>Home</a></li>
<li><a href="{{ url_for('admin.manage_user') }}">User</a></li>
<li class="active">{% if create %}Add{% else %}Edit{% endif %} user</li>
</ol>
</section>
<div class="content-header">
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
<div class="col-sm-6"> <div class="col-sm-6">
<h1 class="m-0 text-dark"> <h1 class="m-0 text-dark">
Dashboard Users
<small>Control panel</small> <small>{% if create %}New user{% else %}Edit user {{ user.username }}{% endif %}</small>
</h1> </h1>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<ol class="breadcrumb float-sm-right"> <ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li> <li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item active">Dashboard v1</li> <li class="breadcrumb-item"><a href="{{ url_for('admin.manage_user') }}">Users</a></li>
<li class="breadcrumb-item active">{% if create %}Add user{% else %}Edit user "{{ user.username }}"{% endif %}</li>
</ol> </ol>
</div> </div>
</div> </div>
@ -38,109 +32,117 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-4">
<div class="box box-primary"> <div class="card card-secondary">
<div class="box-header with-border"> <div class="card-header with-border">
<h3 class="box-title">{% if create %}Add{% else %}Edit{% endif %} user</h3> <h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} user</h3>
</div>
<form role="form" method="post"
action="{% if create %}{{ url_for('admin.edit_user') }}{% else %}{{ url_for('admin.edit_user', user_username=user.username) }}{% endif %}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<input type="hidden" name="create" value="{{ create }}">
<div class="card-body">
{% if error %}
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<h4><i class="icon fa fa-ban"></i> Error!</h4>
{{ error }}
</div> </div>
<!-- /.box-header --> <span class="help-block">{{ error }}</span>
<!-- form start --> {% endif %}
<form role="form" method="post" <div class="form-group has-feedback">
action="{% if create %}{{ url_for('admin.edit_user') }}{% else %}{{ url_for('admin.edit_user', user_username=user.username) }}{% endif %}"> <label class="control-label" for="firstname">First Name</label>
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <input type="text" class="form-control" placeholder="First Name" name="firstname"
<input type="hidden" name="create" value="{{ create }}"> {% if user %}value="{{ user.firstname }}" {% endif %}>
<div class="box-body"> <span class="glyphicon glyphicon-user form-control-feedback"></span>
{% if error %} </div>
<div class="alert alert-danger alert-dismissible"> <div class="form-group has-feedback">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <label class="control-label" for="lastname">Last Name</label>
<h4><i class="icon fa fa-ban"></i> Error!</h4> <input type="text" class="form-control" placeholder="Last name" name="lastname"
{{ error }} {% if user %}value="{{ user.lastname }}" {% endif %}>
</div> <span class="glyphicon glyphicon-user form-control-feedback"></span>
<span class="help-block">{{ error }}</span> </div>
{% endif %} <div class="form-group has-feedback">
<div class="form-group has-feedback"> <label class="control-label" for="email">E-mail address</label>
<label class="control-label" for="firstname">First Name</label> <input type="email" class="form-control" placeholder="Email" name="email" id="email"
<input type="text" class="form-control" placeholder="First Name" name="firstname" {% if user %}value="{{ user.email }}" {% endif %}>
{% if user %}value="{{ user.firstname }}" {% endif %}> <span <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
class="glyphicon glyphicon-user form-control-feedback"></span> </div>
</div> <p class="login-box-msg">Enter the account details below</p>
<div class="form-group has-feedback"> <div class="form-group has-feedback">
<label class="control-label" for="lastname">Last Name</label> <label class="control-label" for="username">Username</label>
<input type="text" class="form-control" placeholder="Last name" name="lastname" <input type="text" class="form-control" placeholder="Username" name="username"
{% if user %}value="{{ user.lastname }}" {% endif %}> <span {% if user %}value="{{ user.username }}" {% endif %}
class="glyphicon glyphicon-user form-control-feedback"></span> {% if not create %}disabled{% endif %}>
</div> <span class="glyphicon glyphicon-user form-control-feedback"></span>
<div class="form-group has-feedback"> </div>
<label class="control-label" for="email">E-mail address</label> <div class="form-group has-feedback {% if blank_password %}has-error{% endif %}">
<input type="email" class="form-control" placeholder="Email" name="email" id="email" <label class="control-label" for="username">Password</label>
{% if user %}value="{{ user.email }}" {% endif %}> <span <input type="password" class="form-control"
class="glyphicon glyphicon-envelope form-control-feedback"></span> placeholder="Password {% if create %}(Required){% else %}(Leave blank to keep unchanged){% endif %}"
</div> name="password">
<p class="login-box-msg">Enter the account details below</p> <span class="glyphicon glyphicon-lock form-control-feedback"></span>
<div class="form-group has-feedback"> {% if blank_password %}
<label class="control-label" for="username">Username</label> <span class="help-block">The password cannot be blank.</span>
<input type="text" class="form-control" placeholder="Username" name="username" {% endif %}
{% if user %}value="{{ user.username }}" {% endif %} </div>
{% if not create %}disabled{% endif %}> <span
class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback {% if blank_password %}has-error{% endif %}">
<label class="control-label" for="username">Password</label>
<input type="password" class="form-control"
placeholder="Password {% if create %}(Required){% else %}(Leave blank to keep unchanged){% endif %}"
name="password"> <span class="glyphicon glyphicon-lock form-control-feedback"></span>
{% if blank_password %}
<span class="help-block">The password cannot be blank.</span>
{% endif %}
</div>
</div>
<div class="box-footer">
<button type="submit"
class="btn btn-flat btn-primary">{% if create %}Create{% else %}Update{% endif %}
User</button>
</div>
</form>
</div> </div>
{% if not create %} <div class="card-footer">
<div class="box box-secondary"> <button type="submit" class="btn btn-primary">
<div class="box-header with-border"> {% if create %}Create{% else %}Update{% endif %} User
<h3 class="box-title">Two Factor Authentication</h3> </button>
</div>
<div class="box-body">
<p>If two factor authentication was configured and is causing problems due to a lost device or
technical issue, it can be disabled here.</p>
<p>The user will need to reconfigure two factor authentication, to re-enable it.</p>
<p><strong>Beware: This could compromise security!</strong></p>
</div>
<div class="box-footer">
<button type="button" class="btn btn-flat btn-warning button_otp_disable" id="{{ user.username }}"
{% if not user.otp_secret %}disabled{% endif %}>Disable Two Factor Authentication</button>
</div>
</div> </div>
</form>
</div>
{% if not create %}
{% if user.otp_secret %}
<div class="card card-secondary">
<div class="card-header with-border">
<h3 class="card-title">Two Factor Authentication</h3>
</div>
<div class="card-body">
<p>If two factor authentication is configured for this user and is causing problems due to a lost device or
technical issue, it can be disabled here.
</p>
<p>The user will need to reconfigure two factor authentication, to re-enable it.</p>
<p><strong>Beware: This could compromise security!</strong></p>
</div>
<div class="card-footer">
<button type="button" class="btn btn-warning button_otp_disable" id="{{ user.username }}">
Disable Two Factor Authentication
</button>
</div>
</div>
{% endif %}
{% endif %}
</div>
<div class="col-8">
<div class="card card-secondary">
<div class="card-header with-border">
<h3 class="card-title">
Help with {% if create %}creating a new{% else%}editing a{% endif %} user
</h3>
</div>
<div class="card-body">
<p>Fill in all the fields to the in the form to the left.</p>
{% if create %}
<p><strong>Newly created users do not have access to any domains.</strong> You will need to grant
access to the user once it is created via the domain management buttons on the dashboard.
</p>
{% else %}
<p><strong>Username</strong> cannot be changed.</p>
<p><strong>Password</strong> can be left empty to keep the current password.</p>
{% endif %} {% endif %}
</div>
</div> </div>
<div class="col-md-8"> </div>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Help with {% if create %}creating a new{% else%}updating a{% endif %} user
</h3>
</div>
<div class="box-body">
<p>Fill in all the fields to the in the form to the left.</p>
{% if create %}
<p><strong>Newly created users do not have access to any domains.</strong> You will need to grant
access to the user once it is created via the domain management buttons on the dashboard.</p>
{% else %}
<p><strong>Password</strong> can be left empty to keep the current password.</p>
<p><strong>Username</strong> cannot be changed.</p>
{% endif %}
</div>
</div>
</div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// handle disabling two factor authentication // handle disabling two factor authentication

View File

@ -34,25 +34,40 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="card"> <div class="card card-outline card-secondary">
<div class="card-header"> <div class="card-header with-border">
<h3 class="card-title">History Management</h3> <h3 class="card-title">History Management</h3>
</div> {% if current_user.role.name != 'User' %}
<div class="card-body clearfix"> <button type="button" class="btn btn-danger float-right" data-toggle="modal" data-target="#modal_clear_history" {% if current_user.role.name != 'Administrator' %}disabled{% endif %}>
<button type="button" class="btn btn-flat btn-danger pull-right" data-toggle="modal" data-target="#modal_clear_history" {% if current_user.role.name != 'Administrator' %}disabled{% endif %}> <i class="fas fa-trash"></i>
Clear History &nbsp;Clear History
<i class="fa fa-trash"></i> </button>
</button> {% endif %}
</div> </div>
<div class="card-body clearfix"> <div class="card-body clearfix">
<form id="history-search-form" autocomplete="off"> <form id="history-search-form" autocomplete="off">
<div class="nav-tabs-custom" id="tabs"> <ul class="nav nav-tabs" id="custom-content-below-tab" role="tablist">
<ul class="nav nav-tabs" id="nav_nav_tabs" name="nav_nav_tabs"> <li class="nav-item">
<li id="activity_tab" class="active"><a href="#tabs-act" data-toggle="tab">Search for All Activity</a></li> <a class="nav-link active" href="#tabs-act" data-toggle="pill" role="tab">
<li id="domain_tab"><a href="#tabs-domain" data-toggle="tab">Search By Domain</a></li> Search for All Activity
<li id="account_tab"><a href="#tabs-account" data-toggle="tab">Search By Account</a></li> </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tabs-domain" data-toggle="pill" role="tab">
Search By Domain
</a>
</li>
<li class="nav-item">
<a class="nav-link with-border" href="#tabs-account" data-toggle="pill" role="tab">
Search By Account
</a>
</li>
{% if current_user.role.name != 'User' %} {% if current_user.role.name != 'User' %}
<li id="user_auth_tab"><a href="#tabs-auth" data-toggle="tab">Search for User Authentication</a></li> <li class="nav-item">
<a class="nav-link" href="#tabs-auth" data-toggle="pill" role="tab">
Search for User Authentication
</a>
</li>
{% endif %} {% endif %}
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
@ -82,11 +97,11 @@ class="checkbox" style="border:2px dotted #00f;display:block;background:#ff0000;
<td> <td>
<div class="autocomplete" style="width:250px;"> <div class="autocomplete" style="width:250px;">
<input type="text" class="form-control" id="account_name_filter" name="account_name_filter" placeholder="Enter * to search for any account" value=""> <input type="text" class="form-control" id="account_name_filter" name="account_name_filter" placeholder="Enter * to search for any account" value="">
</div> </div>
</td> </td>
</div> </div>
<div class="tab-pane" id="tabs-auth"> <div class="tab-pane" id="tabs-auth">
<td><label>Username</label></td> <td><label>Username</label></td>
<td> <td>
<div class="autocomplete" style="width:250px;"> <div class="autocomplete" style="width:250px;">
<input type="text" class="form-control" id="auth_name_filter" name="auth_name_filter" placeholder="Enter * to search for any username" value=""> <input type="text" class="form-control" id="auth_name_filter" name="auth_name_filter" placeholder="Enter * to search for any username" value="">
@ -154,15 +169,14 @@ class="checkbox" style="border:2px dotted #00f;display:block;background:#ff0000;
<tr><td>&nbsp</td></tr> <tr><td>&nbsp</td></tr>
<tr> <tr>
<td> <td>
<button type="submit" id="search-submit" name="search-submit" class="btn btn-flat btn-primary button-filter">Search&nbsp;<i class="fa fa-search"></i></button> <button type="submit" id="search-submit" name="search-submit" class="btn btn-primary button-filter"><i class="fa fa-search"></i>&nbsp;Search</button>
</td> </td>
<td> <td>
<button id="clear-filters" name="clear-filters" class="btn btn-flat btn-warning button-clearf">Clear Filters&nbsp;<i class="fa fa-trash"></i></button> <button id="clear-filters" name="clear-filters" class="btn btn-warning button-clearf"><i class="fa fa-trash"></i>&nbsp;Clear Filters</button>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</form> </form>
</div> </div>
<div id="table_from_ajax"></div> <div id="table_from_ajax"></div>
@ -470,49 +484,45 @@ class="checkbox" style="border:2px dotted #00f;display:block;background:#ff0000;
</script> </script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
<!-- Clear History Confirmation Box --> <!-- Clear History Confirmation Box -->
<div class="modal fade modal-warning" id="modal_clear_history"> <div class="modal fade modal-warning" id="modal_clear_history">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <h4 class="modal-title">Confirmation</h4>
<span aria-hidden="true">&times;</span> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button> <span aria-hidden="true">&times;</span>
<h4 class="modal-title">Confirmation</h4> </button>
</div>
<div class="modal-body">
<p>Are you sure you want to remove all history?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-default pull-left" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-flat btn-danger"
onclick="applyChanges({'_csrf_token': '{{ csrf_token() }}'}, $SCRIPT_ROOT + '/admin/history', false, true);">Clear
History</button>
</div>
</div> </div>
<!-- /.modal-content --> <div class="modal-body">
<p>Are you sure you want to remove all history?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger float-right" onclick="applyChanges({'_csrf_token': '{{ csrf_token() }}'}, $SCRIPT_ROOT + '/admin/history', false, true);">
Clear History
</button>
</div>
</div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div> <!-- History Details Box -->
<div class="modal fade" id="modal_history_info"> <div class="modal fade" id="modal_history_info">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <h4 class="modal-title">History Details</h4>
<span aria-hidden="true">&times;</span> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button> <span aria-hidden="true">&times;</span>
<h4 class="modal-title">History Details</h4> </button>
</div>
<div class="modal-body">
<div id="modal-info-content"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-default pull-right" data-dismiss="modal">Close</button>
</div>
</div> </div>
<!-- /.modal-content --> <div class="modal-body">
<div id="modal-info-content"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default float-right" data-dismiss="modal">Close</button>
</div>
</div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div>
<!-- /.modal -->
{% endblock %} {% endblock %}

View File

@ -1,90 +1,86 @@
{% import 'applied_change_macro.html' as applied_change_macro %} {% import 'applied_change_macro.html' as applied_change_macro %}
{% if len_histories >= lim %} {% if len_histories >= lim %}
<p style="color: rgb(224, 3, 3);"><b>Limit of loaded history records has been reached! Only {{lim}} history records are shown. </b></p> <p style="color: rgb(224, 3, 3);">
<b>Limit of loaded history records has been reached! Only {{lim}} history records are shown.</b>
</p>
{% endif %} {% endif %}
<div class="box-body"></div> <div class="box-body"></div>
<table id="tbl_history" class="table table-bordered table-striped"> <table id="tbl_history" class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<th>Changed by</th> <th>Changed by</th>
<th>Content</th> <th>Content</th>
<th>Time</th> <th>Time</th>
<th>Detail</th> <th>Detail</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for history in histories %} {% for history in histories %}
<tr class="odd gradeX"> <tr class="odd gradeX">
<td>{{ history.history.created_by }}</td> <td>{{ history.history.created_by }}</td>
<td>{{ history.history.msg }}</td> <td>{{ history.history.msg }}</td>
<td>{{ history.history.created_on }}</td> <td>{{ history.history.created_on }}</td>
<td width="6%">
<td width="6%"> <div id="history-info-div-{{ loop.index0 }}" style="display: none;">
<div id="history-info-div-{{ loop.index0 }}" style="display: none;"> {{ history.detailed_msg | safe }}
{{ history.detailed_msg | safe }} {% if history.change_set %}
{% if history.change_set %} <div class="content">
<div class="content"> <div id="change_index_definition"></div>
<div id="change_index_definition"></div> {% call applied_change_macro.applied_change_template(history.change_set) %}
{% call applied_change_macro.applied_change_template(history.change_set) %} {% endcall %}
{% endcall %} </div>
</div> {% endif %}
{% endif %} </div>
</div> <button type="button" class="btn btn-primary history-info-button"
<button type="button" class="btn btn-flat btn-primary history-info-button" {% if history.detailed_msg == "" and history.change_set is none %}
{% if history.detailed_msg == "" and history.change_set is none %} style="visibility: hidden;"
style="visibility: hidden;" {% endif %} value="{{ loop.index0 }}">
{% endif %} value="{{ loop.index0 }}">Info&nbsp;<i class="fa fa-info"></i> <i class="fa fa-info"></i>
</button> &nbsp;Info
</td> </button>
</tr> </td>
{% endfor %} </tr>
</tbody> {% endfor %}
</table> </tbody>
</table>
</div> </div>
<script> <script>
var table; var table;
$(document).ready(function () { $(document).ready(function () {
table = $('#tbl_history').DataTable({
table = $('#tbl_history').DataTable({ "order": [
"order": [ [2, "desc"]
[2, "desc"] ],
], "searching": true,
"searching": true, "columnDefs": [{
"columnDefs": [{ "type": "time",
"type": "time", "render": function (data, type, row) {
"render": function (data, type, row) { return moment.utc(data).local().format('YYYY-MM-DD HH:mm:ss');
return moment.utc(data).local().format('YYYY-MM-DD HH:mm:ss'); },
}, "targets": 2
"targets": 2 }],
}], "info": true,
"info": true, "autoWidth": false,
"autoWidth": false, orderCellsTop: true,
orderCellsTop: true, fixedHeader: true
fixedHeader: true });
});
$(document.body).on('click', '.history-info-button', function () { $(document.body).on('click', '.history-info-button', function () {
var modal = $("#modal_history_info"); var modal = $("#modal_history_info");
var history_id = $(this).val(); var history_id = $(this).val();
var info = $("#history-info-div-" + history_id).html(); var info = $("#history-info-div-" + history_id).html();
$('#modal-info-content').html(info); $('#modal-info-content').html(info);
modal.modal('show'); modal.modal('show');
}); });
$(document.body).on("click", ".button-filter", function (e) { $(document.body).on("click", ".button-filter", function (e) {
e.stopPropagation(); e.stopPropagation();
var nextRow = $("#filter-table") var nextRow = $("#filter-table")
if (nextRow.css("visibility") == "visible") if (nextRow.css("visibility") == "visible")
nextRow.css("visibility", "collapse") nextRow.css("visibility", "collapse")
else else
nextRow.css("visibility", "visible") nextRow.css("visibility", "visible")
}); });
});
}); </script>
</script>

View File

@ -23,8 +23,9 @@
</div> </div>
{% endblock %} {% block content %} {% endblock %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-sm-12">
<div class="card"> <div class="card">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">User Management</h3> <h3 class="card-title">User Management</h3>
@ -96,6 +97,7 @@
<!-- /.col --> <!-- /.col -->
</div> </div>
<!-- /.row --> <!-- /.row -->
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en" class>
<head> <head>
{% block head %} {% block head %}
<meta charset="utf-8"> <meta charset="utf-8">
@ -28,7 +28,7 @@
{% endblock %} {% endblock %}
</head> </head>
<body class="hold-transition skin-blue sidebar-mini {% if not SETTING.get('fullscreen_layout') %}layout-boxed{% endif %}"> <body class="hold-transition sidebar-mini text-sm {% if not SETTING.get('fullscreen_layout') %}layout-boxed{% endif %}">
{% set user_image_url = url_for('user.image', username=current_user.username) %} {% set user_image_url = url_for('user.image', username=current_user.username) %}
<div class="wrapper"> <div class="wrapper">
{% block pageheader %} {% block pageheader %}
@ -41,10 +41,17 @@
<i class="fas fa-bars"></i> <i class="fas fa-bars"></i>
</a> </a>
</li> </li>
{% if current_user.id is defined %}
<li class="nav-item d-none d-inline-block">
<a class="nav-link" href="{{ url_for('index.logout') }}">
Logout
</a>
</li>
{% endif %}
</ul> </ul>
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
{% if current_user.id is defined %} <!-- {% if current_user.id is defined %}
<li class="nav-item dropdown user-menu"> <li class="nav-item dropdown user-menu">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"> <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">
<img src="{{ user_image_url }}" class="user-image img-circle elevation-2" alt="User Image"/> <img src="{{ user_image_url }}" class="user-image img-circle elevation-2" alt="User Image"/>
@ -53,7 +60,7 @@
</span> </span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li class="user-header"> <li class="user-header bg-dark">
<img src="{{ user_image_url }}" class="img-circle elevation-2" alt="User Image"/> <img src="{{ user_image_url }}" class="img-circle elevation-2" alt="User Image"/>
<p> <p>
{{ current_user.firstname }} {{ current_user.lastname }} {{ current_user.firstname }} {{ current_user.lastname }}
@ -61,12 +68,13 @@
</p> </p>
</li> </li>
<li class="user-footer"> <li class="user-footer">
<a href="{{ url_for('user.profile') }}" class="btn btn-default">My Profile</a> <a href="{{ url_for('user.profile') }}" class="btn btn-primary">My Profile</a>
<a href="{{ url_for('index.logout') }}" class="btn btn-default float-right">Log out</a> <a href="{{ url_for('index.logout') }}" class="btn btn-warning float-right">Log out</a>
</li> </li>
</ul> </ul>
</li> </li>
{% endif %} {% endif %}
-->
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-widget="fullscreen" href="#" role="button"> <a class="nav-link" data-widget="fullscreen" href="#" role="button">
<i class="fas fa-expand-arrows-alt"></i> <i class="fas fa-expand-arrows-alt"></i>
@ -140,7 +148,7 @@
</li> </li>
<li class="{{ 'nav-item active' if active_page == 'admin_history' else 'nav-item' }}"> <li class="{{ 'nav-item active' if active_page == 'admin_history' else 'nav-item' }}">
<a href="{{ url_for('admin.history') }}" class="nav-link"> <a href="{{ url_for('admin.history') }}" class="nav-link">
<i class="nav-icon fas fa-calendar"></i> <i class="nav-icon fas fa-calendar-alt"></i>
<p>History</p> <p>History</p>
</a> </a>
</li> </li>
@ -179,26 +187,26 @@
<ul class="nav nav-treeview" {% if active_page == 'admin_settings' %}style="display: block;"{% endif %}> <ul class="nav nav-treeview" {% if active_page == 'admin_settings' %}style="display: block;"{% endif %}>
<li class="nav-item"> <li class="nav-item">
<a href="{{ url_for('admin.setting_basic') }}" class="nav-link"> <a href="{{ url_for('admin.setting_basic') }}" class="nav-link">
<i class="nav-icon fas fa-circle"></i> <i class="nav-icon far fa-circle"></i>
<p>Basic</p> <p>Basic</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ url_for('admin.setting_records') }}" class="nav-link"> <a href="{{ url_for('admin.setting_records') }}" class="nav-link">
<i class="nav-icon fas fa-circle"></i> <i class="nav-icon far fa-circle"></i>
<p>Records</p> <p>Records</p>
</a> </a>
</li> </li>
{% if current_user.role.name == 'Administrator' %} {% if current_user.role.name == 'Administrator' %}
<li class="nav-item"> <li class="nav-item">
<a href="{{ url_for('admin.setting_pdns') }}" class="nav-link"> <a href="{{ url_for('admin.setting_pdns') }}" class="nav-link">
<i class="nav-icon fas fa-circle"></i> <i class="nav-icon far fa-circle"></i>
<p>PDNS</p> <p>PDNS</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ url_for('admin.setting_authentication') }}" class="nav-link"> <a href="{{ url_for('admin.setting_authentication') }}" class="nav-link">
<i class="nav-icon fas fa-circle"></i> <i class="nav-icon far fa-circle"></i>
<p>Authentication</p> <p>Authentication</p>
</a> </a>
</li> </li>
@ -208,9 +216,9 @@
{% elif SETTING.get('allow_user_view_history') %} {% elif SETTING.get('allow_user_view_history') %}
<li class="nav-header">ADMINISTRATION</li> <li class="nav-header">ADMINISTRATION</li>
<li class="{{ 'nav-item active' if active_page == 'admin_history' else 'nav-item' }}"> <li class="{{ 'nav-item active' if active_page == 'admin_history' else 'nav-item' }}">
<a href="{{ url_for('admin.history') }}"> <a href="{{ url_for('admin.history') }}" class="nav-link">
<i class="nav-icon fa fa-calendar"></i> <i class="nav-icon fas fa-calendar-alt"></i>
<span>History</span> <p>History</p>
</a> </a>
</li> </li>
{% endif %} {% endif %}

View File

@ -1,67 +1,78 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "dashboard" %}
{% block title %}<title>Dashboard - {{ SITE_NAME }}</title>{% endblock %}
{% set active_page = "dashboard" %}
{% block title %}
<title>
Dashboard - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) --> <div class="content-header">
<section class="content-header"> <div class="container-fluid">
<h1> <div class="row mb-2">
Dashboard <div class="col-sm-6">
<small>Info</small> <h1 class="m-0 text-dark">
</h1> Dashboard
<ol class="breadcrumb"> <small>Info</small>
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li> </h1>
<li class="active">Dashboard</li> </div>
</ol> <div class="col-sm-6">
</section> <ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% import 'applied_change_macro.html' as applied_change_macro %} {% import 'applied_change_macro.html' as applied_change_macro %}
{% block content %} {% block content %}
<!-- Main content --> <section class="content">
<section class="content"> <div class="container-fluid">
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %} {% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<div class="row"> <div class="row">
<div class="col-xs-3"> <div class="col-3">
<div class="box"> <div class="card">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Statistics</h3> <h3 class="card-title">Statistics</h3>
</div> </div>
<div class="box-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-lg-6"> <div class="col-6">
<!-- small box --> <!-- small box -->
<div class="small-box bg-aqua"> <div class="small-box bg-info">
<div class="inner"> <div class="inner">
<h3>{{ domain_count }}</h3> <h3>{{ domain_count }}</h3>
<p>{% if domain_count > 1 %}Domains{% else %}Domain{% endif %}</p> <p>{% if domain_count > 1 %}Domains{% else %}Domain{% endif %}</p>
</div> </div>
<div class="icon"> <div class="icon">
<i class="fa fa-book"></i> <i class="fa fa-book"></i>
</div>
</div> </div>
</div> </div>
{% if current_user.role.name in ['Administrator', 'Operator'] %} </div>
<div class="col-lg-6"> {% if current_user.role.name in ['Administrator', 'Operator'] %}
<div class="col-6">
<a href="{{ url_for('admin.manage_user') }}"> <a href="{{ url_for('admin.manage_user') }}">
<div class="small-box bg-green"> <div class="small-box bg-green">
<div class="inner"> <div class="inner">
<h3>{{ user_num }}</h3> <h3>{{ user_num }}</h3>
<p>{% if user_num > 1 %}Users{% else %}User{% endif %}</p> <p>{% if user_num > 1 %}Users{% else %}User{% endif %}</p>
</div>
<div class="icon">
<i class="fa fa-users"></i>
</div>
</div> </div>
<div class="icon">
<i class="fa fa-users"></i>
</div>
</div>
</a> </a>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-6"> <div class="col-6">
<a href="{{ url_for('admin.history') }}"> <a href="{{ url_for('admin.history') }}">
<div class="small-box bg-green"> <div class="small-box bg-green">
<div class="inner"> <div class="inner">
<h3>{{ history_number }}</h3> <h3>{{ history_number }}</h3>
@ -71,95 +82,108 @@
<i class="fa fa-calendar"></i> <i class="fa fa-calendar"></i>
</div> </div>
</div> </div>
</a> </a>
</div> </div>
{% if current_user.role.name in ['Administrator', 'Operator'] %} {% if current_user.role.name in ['Administrator', 'Operator'] %}
<div class="col-lg-6"> <div class="col-6">
<a href="{{ url_for('admin.pdns_stats') }}"> <a href="{{ url_for('admin.pdns_stats') }}">
<div class="small-box bg-green"> <div class="small-box bg-green">
<div class="inner"> <div class="inner">
<h3><span style="font-size: 18px">{{ uptime|display_second_to_time }}</span></h3> <h3><span style="font-size: 18px">{{ uptime|display_second_to_time }}</span></h3>
<p>Uptime</p> <p>Uptime</p>
</div>
<div class="icon">
<i class="fa fa-clock"></i>
</div>
</div> </div>
<div class="icon">
<i class="fa fa-clock-o"></i>
</div>
</div>
</a> </a>
</div> </div>
{% endif %} {% endif %}
</div>
</div> </div>
</div>
</div> </div>
</div> </div>
<div class="col-xs-9"> <div class="col-9">
<div class="box"> <div class="card">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Recent History</h3> <h3 class="card-title">Recent History</h3>
</div> </div>
<div class="box-body"> <div class="card-body">
<table id="tbl_history" class="table table-bordered table-striped"> <table id="tbl_history" class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<th>Changed By</th> <th>Changed By</th>
<th>Content</th> <th>Content</th>
<th>Time</th> <th>Time</th>
<th>Detail</th> <th>Detail</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for history in histories %} {% for history in histories %}
<tr class="odd"> <tr class="odd">
<td>{{ history.history.created_by }}</td> <td>{{ history.history.created_by }}</td>
<td>{{ history.history.msg }}</td> <td>{{ history.history.msg }}</td>
<td>{{ history.history.created_on }}</td> <td>{{ history.history.created_on }}</td>
<td width="6%"> <td width="6%">
<div id="history-info-div-{{ loop.index0 }}" style="display: none;"> <div id="history-info-div-{{ loop.index0 }}" style="display: none;">
{{ history.detailed_msg | safe }} {{ history.detailed_msg | safe }}
{% if history.change_set %} {% if history.change_set %}
<div class="content"> <div class="content">
<div id="change_index_definition"></div> <div id="change_index_definition"></div>
{% call applied_change_macro.applied_change_template(history.change_set) %} {% call applied_change_macro.applied_change_template(history.change_set) %}
{% endcall %} {% endcall %}
</div> </div>
{% endif %} {% endif %}
</div> </div>
<button type="button" class="btn btn-flat btn-primary history-info-button" <button type="button" class="btn btn-sm btn-primary history-info-button"
{% if history.detailed_msg == "" and history.change_set is none %} {% if history.detailed_msg == "" and history.change_set is none %}
style="visibility: hidden;" style="visibility: hidden;"
{% endif %} value="{{ loop.index0 }}">Info&nbsp;<i class="fa fa-info"></i> {% endif %} value="{{ loop.index0 }}">
</button> &nbsp;Info
</td> </button>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div>
</div> </div>
</div>
{% endif %} {% endif %}
<!--SYBPATCH START-->
<!--SYBPATCH START--> <row>
<div class="nav-tabs-custom"> <div class="nav-tabs-custom">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs" id="custom-content-below-tab" role="tablist">
<li class="active"><a href="#tab_{{custom_boxes.order[0]}}" data-toggle="tab">Hosted Domains <b>{{custom_boxes.boxes[custom_boxes.order[0]][0]}}</b></a></li> <li class="nav-link">
<a href="#tab_{{custom_boxes.order[0]}}"data-toggle="pill" role="tab">
Hosted Domains <b>{{custom_boxes.boxes[custom_boxes.order[0]][0]}}</b>
</a>
</li>
{% for boxId in custom_boxes.order[1:] %} {% for boxId in custom_boxes.order[1:] %}
<li><a href="#tab_{{boxId}}" data-toggle="tab">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></a></li> <li class="nav-link" >
<a href="#tab_{{boxId}}" data-toggle="pill" role="tab">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
{% for boxId in custom_boxes.order %} {% for boxId in custom_boxes.order %}
<div class="tab-pane" id='tab_{{boxId}}'> <div class="tab-pane" id='tab_{{boxId}}'>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-12">
<div class="box"> <div class="card">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></h3>{% if show_bg_domain_button %}<button type="button" class="btn btn-flat btn-primary refresh-bg-button pull-right"><i class="fa fa-refresh"></i> Sync domains </button>{% endif %} <h3 class="card-title">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></h3>
</div> {% if show_bg_domain_button %}
<div class="box-body"> <button type="button" class="btn btn-primary refresh-bg-button float-right">
<table id='tbl_domain_list_{{boxId}}' class="table table-bordered table-striped"> <i class="fas fa-sync"></i>
<thead> &nbsp;Sync domains
</button>
{% endif %}
</div>
<div class="card-body">
<table id='tbl_domain_list_{{boxId}}' class="table table-bordered table-striped">
<thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>DNSSEC</th> <th>DNSSEC</th>
@ -167,32 +191,33 @@
<th>Serial</th> <th>Serial</th>
<th>Master</th> <th>Master</th>
<th>Account</th> <th>Account</th>
<th {% if current_user.role.name not in ['Administrator','Operator'] %}width="6%"{% else %}width="25%"{% endif %}>Action</th> <th>Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div>
</div> </div>
{% endfor %} {% endfor %}
</div><!-- /.tab-content --> </div><!-- /.tab-content -->
</div><!-- custom tabs --> </div><!-- custom tabs -->
<!--SYBPATCH END--> <!--SYBPATCH END-->
</row>
</section> </div>
<!-- /.content --> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
//SYBPATCH START// //SYBPATCH START//
function setUpDomainList(id ,url){ function setUpDomainList(id ,url){
$(id).DataTable({ $(id).DataTable({
"paging" : true, "paging" : true,
"lengthChange" : true, "lengthChange" : false,
language: { language: {
searchPlaceholder: "Use ^ and $ for start and end", searchPlaceholder: "Use ^ and $ for start and end",
}, },
@ -230,7 +255,7 @@
"searching" : false, "searching" : false,
"ordering" : false, "ordering" : false,
"info" : false, "info" : false,
"autoWidth" : false, "autoWidth" : true,
"columnDefs": [ "columnDefs": [
{ {
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
@ -351,11 +376,10 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <h4 class="modal-title">DNSSEC</h4>
aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title">DNSSEC</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p></p> <p></p>

View File

@ -4,9 +4,9 @@
{% macro dnssec(domain) %} {% macro dnssec(domain) %}
{% if domain.dnssec %} {% if domain.dnssec %}
<td><span style="cursor:pointer" class="label label-success button_dnssec" id="{{ domain.name }}"><i class="fa fa-lock"></i>&nbsp;Enabled</span></td> <td><span style="cursor:pointer" class="btn btn-lg btn-success button_dnssec" id="{{ domain.name }}"><i class="fa fa-lock"></i>&nbsp;Enabled</span></td>
{% else %} {% else %}
<td><span style="cursor:pointer" class="label label-primary button_dnssec" id="{{ domain.name }}"><i class="fa fa-unlock-alt"></i>&nbsp;Disabled</span></td> <td><span style="cursor:pointer" class="btn btn-sm btn-danger button_dnssec" id="{{ domain.name }}"><i class="fa fa-unlock-alt"></i>&nbsp;Disabled</span></td>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
@ -30,30 +30,46 @@
{% macro actions(domain) %} {% macro actions(domain) %}
{% if current_user.role.name in ['Administrator', 'Operator'] %} {% if current_user.role.name in ['Administrator', 'Operator'] %}
<td width="25%"> <td width="6%">
<button type="button" class="btn btn-flat btn-success button_template" id="{{ domain.name }}">
Template&nbsp;<i class="fa fa-clone"></i> <div class="dropdown">
</button> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button type="button" class="btn btn-flat btn-success" onclick="window.location.href='{{ url_for('domain.domain', domain_name=domain.name) }}'"> Options
Manage&nbsp;<i class="fa fa-cog"></i> </button>
</button> <div class="dropdown-menu" aria-labelledby="dropdownMenu">
<button type="button" class="btn btn-flat btn-danger" onclick="window.location.href='{{ url_for('domain.setting', domain_name=domain.name) }}'"> <button class="dropdown-item btn-success button_template" id="{{ domain.name }}" type="button">
Admin&nbsp;<i class="fa fa-cog"></i> <i class="fa fa-clone"></i>&nbsp;Template
</button> </button>
<button type="button" class="btn btn-flat btn-primary" onclick="window.location.href='{{ url_for('domain.changelog', domain_name=domain.name) }}'"> <button class="dropdown-item btn-success" type="button" onclick="window.location.href='{{ url_for('domain.domain', domain_name=domain.name) }}'">
Changelog&nbsp;<i class="fa fa-history" aria-hidden="true"></i> <i class="fa fa-cog"></i>&nbsp;Manage
</button> </button>
<button class="dropdown-item btn-danger" type="button" onclick="window.location.href='{{ url_for('domain.setting', domain_name=domain.name) }}'">
<i class="fa fa-cog"></i>&nbsp;Admin
</button>
<button class="dropdown-item btn-primary" type="button" onclick="window.location.href='{{ url_for('domain.changelog', domain_name=domain.name) }}'">
<i class="fa fa-history" aria-hidden="true"></i>&nbsp;Changelog
</button>
</div>
</div>
</td> </td>
{% else %} {% else %}
<td width="6%"> <td width="6%">
<button type="button" class="btn btn-flat btn-success" onclick="window.location.href='{{ url_for('domain.domain', domain_name=domain.name) }}'"> <div class="dropdown">
Manage&nbsp;<i class="fa fa-cog"></i> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button> Options
{% if allow_user_view_history %} </button>
<button type="button" class="btn btn-flat btn-primary" onclick="window.location.href='{{ url_for('domain.changelog', domain_name=domain.name) }}'"> <div class="dropdown-menu" aria-labelledby="dropdownMenu">
Changelog&nbsp;<i class="fa fa-history" aria-hidden="true"></i> <button class="dropdown-item btn-success" type="button" onclick="window.location.href='{{ url_for('domain.domain', domain_name=domain.name) }}'">
</button> <i class="fa fa-cog"></i>&nbsp;Manage
{% endif %} </button>
{% if allow_user_view_history %}
<button class="dropdown-item btn-primary" type="button" onclick="window.location.href='{{ url_for('domain.changelog', domain_name=domain.name) }}'">
<i class="fa fa-history" aria-hidden="true"></i>&nbsp;Changelog
</button>
{% endif %}
</div>
</div>
</td> </td>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}

View File

@ -1,133 +1,135 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}<title>{{ domain.name | pretty_domain_name }} - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
{{ domain.name | pretty_domain_name }} - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<section class="content-header"> <div class="content-header">
<h1> <div class="container-fluid">
Manage domain: <b>{{ domain.name | pretty_domain_name }}</b> <div class="row mb-2">
</h1> <div class="col-sm-6">
<ol class="breadcrumb"> <h1 class="m-0 text-dark">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i Domain: <b>{{ domain.name | pretty_domain_name }}</b>
class="fa fa-dashboard"></i> Home</a></li> </h1>
<li>Domain</li> </div>
<li class="active">{{ domain.name | pretty_domain_name }}</li> <div class="col-sm-6">
</ol> <ol class="breadcrumb float-sm-right">
</section> <li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item active">Domain: {{ domain.name | pretty_domain_name }}</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-12">
<div class="box"> <div class="card">
<div class="box-body"> <div class="card-header">
{% if domain.type != 'Slave' %}
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-primary pull-left button_add_record" id="{{ domain.name }}">
<i class="fas fa-plus"></i>
&nbsp;Add Record
</button>
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-primary pull-right button_apply_changes" id="{{ domain.name }}" value="{{ domain.serial }}">
<i class="fas fa-save"></i>
&nbsp;Apply Changes
</button>
{% else %}
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-primary pull-left button_update_from_master" id="{{ domain.name }}">
<i class="fas fa-download"></i>
&nbsp;Update from Master
</button>
{% endif %}
{% if current_user.role.name in ['Administrator', 'Operator'] %}
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-primary pull-left btn-danger" onclick="window.location.href='{{ url_for('domain.setting', domain_name=domain.name) }}'">
<i class="fas fa-cog"></i>
&nbsp;Admin
</button>
{% endif %}
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-primary button_changelog" id="{{ domain.name }}">
<i class="fas fa-history" aria-hidden="true"></i>
&nbsp;Changelog
</button>
{% endif %}
</div>
<div class="card-body">
<table id="tbl_records" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Status</th>
<th>TTL</th>
<th>Data</th>
<th>Comment</th>
<th>Edit</th>
<th>Delete</th>
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<th >Changelog</th>
{% endif %}
<th>Invisible Sorting Column</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr class="odd row_record" id="{{ domain.name }}">
<td>{{ (record.name,domain.name) | display_record_name | pretty_domain_name }}</td>
<td>{{ record.type }}</td>
<td>{{ record.status }}</td>
<td>{{ record.ttl }}</td>
<td>{{ record.data | pretty_domain_name }}</td>
<td>{{ record.comment }}</td>
{% if domain.type != 'Slave' %} {% if domain.type != 'Slave' %}
<button type="button" class="btn btn-flat btn-primary pull-left button_add_record" id="{{ domain.name }}"> <td width="6%">
Add Record&nbsp;<i class="fa fa-plus"></i> {% if record.is_allowed_edit() %}
</button> <button type="button" class="btn btn-warning button_edit"><i class="fa fa-edit"></i></button>
<button type="button" class="btn btn-flat btn-primary pull-right button_apply_changes" id="{{ domain.name }}" value="{{ domain.serial }}"> {% else %}
Apply Changes&nbsp;<i class="fa fa-floppy-o"></i> <button type="button" class="btn btn-warning"><i class="fa fa-exclamation-circle"></i></button>
</button> {% endif %}
</td>
<td width="6%">
{% if record.is_allowed_delete() %}
<button type="button" class="btn btn-danger button_delete"><i class="fa fa-trash"></i></button>
{% endif %}
</td>
{% else %} {% else %}
<button type="button" class="btn btn-flat btn-primary pull-left button_update_from_master" id="{{ domain.name }}"> <td width="6%">
Update from Master&nbsp;<i class="fa fa-download"></i> <button type="button" class="btn btn-warning"><i class="fa fa-exclamation-circle"></i></button>
</button> </td>
{% endif %} <td width="6%">
{% if current_user.role.name in ['Administrator', 'Operator'] %} <button type="button" class="btn btn-warning"><i class="fa fa-exclamation-circle"></i></button>
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-flat btn-primary pull-left btn-danger" onclick="window.location.href='{{ url_for('domain.setting', domain_name=domain.name) }}'"> </td>
Admin&nbsp;<i class="fa fa-cog"></i>
</button>
{% endif %} {% endif %}
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %} {% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<button type="button" style="position: relative; margin-left: 20px" class="btn btn-flat btn-primary button_changelog" id="{{ domain.name }}"> <td width="6%">
Changelog&nbsp;<i class="fa fa-history" aria-hidden="true"></i> <button type="button" onclick="show_record_changelog('{{record.name}}','{{record.type}}',event)" class="btn btn-primary">
</i> <i class="fa fa-history" aria-hidden="true"></i>
</button> </button>
</td>
{% endif %} {% endif %}
</div> <!-- hidden column that we can sort on -->
<div class="box-body"> <td>1</td>
<table id="tbl_records" class="table table-bordered table-striped"> </tr>
<thead> {% endfor %}
<tr> </tbody>
<th>Name</th> </table>
<th>Type</th> </div>
<th>Status</th>
<th>TTL</th>
<th>Data</th>
<th>Comment</th>
<th>Edit</th>
<th>Delete</th>
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<th >Changelog</th>
{% endif %}
<th>Invisible Sorting Column</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr class="odd row_record" id="{{ domain.name }}">
<td>
{{ (record.name,domain.name) | display_record_name | pretty_domain_name }}
</td>
<td>
{{ record.type }}
</td>
<td>
{{ record.status }}
</td>
<td>
{{ record.ttl }}
</td>
<td>
{{ record.data | pretty_domain_name }}
</td>
<td>
{{ record.comment }}
</td>
{% if domain.type != 'Slave' %}
<td width="6%">
{% if record.is_allowed_edit() %}
<button type="button" class="btn btn-flat btn-warning button_edit">Edit&nbsp;<i class="fa fa-edit"></i></button>
{% else %}
<button type="button" class="btn btn-flat btn-warning">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i></button>
{% endif %}
</td>
<td width="6%">
{% if record.is_allowed_delete() %}
<button type="button" class="btn btn-flat btn-danger button_delete">Delete&nbsp;<i class="fa fa-trash"></i></button>
{% endif %}
</td>
{% else %}
<td width="6%">
<button type="button" class="btn btn-flat btn-warning">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button>
</td>
<td width="6%">
<button type="button" class="btn btn-flat btn-warning">&nbsp;&nbsp;<i class="fa fa-exclamation-circle"></i>&nbsp;&nbsp;</button>
</td>
{% endif %}
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<td width="6%">
<button type="button" onclick="show_record_changelog('{{record.name}}','{{record.type}}',event)" class="btn btn-flat btn-primary">&nbsp;&nbsp;
<i class="fa fa-history" aria-hidden="true"></i>&nbsp;&nbsp;&nbsp;
</button>
</td>
{% endif %}
<!-- hidden column that we can sort on -->
<td>1</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div> </div>
<!-- /.col --> </div>
</div> </div>
<!-- /.row --> </div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// superglobals // superglobals
@ -284,7 +286,7 @@
// add new row // add new row
var default_type = records_allow_edit[0] var default_type = records_allow_edit[0]
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %} {% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '', '0']); var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '', '0']);
{% else %} {% else %}
var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '0']); var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', window.ttl_options[0][0], '', '', '', '', '0']);
{% endif %} {% endif %}
@ -553,72 +555,64 @@
{% endif %} {% endif %}
</script> </script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
<div class="modal fade modal-warning" id="modal_delete"> <div class="modal fade modal-warning" id="modal_delete">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <h4 class="modal-title">Confirmation</h4>
aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title">Confirmation</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-default pull-left" id="button_delete_cancel"
data-dismiss="modal">Close</button>
<button type="button" class="btn btn-flat btn-danger" id="button_delete_confirm">Delete</button>
</div>
</div> </div>
<!-- /.modal-content --> <div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary pull-left" id="button_delete_cancel" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger" id="button_delete_confirm">Delete</button>
</div>
</div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div>
<div class="modal fade modal-primary" id="modal_apply_changes"> <div class="modal fade modal-primary" id="modal_apply_changes">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <h4 class="modal-title">Confirmation</h4>
aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title">Confirmation</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-default pull-left"
data-dismiss="modal">Close</button>
<button type="button" class="btn btn-flat btn-primary" id="button_apply_confirm">Apply</button>
</div>
</div> </div>
<!-- /.modal-content --> <div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" id="button_apply_confirm">Apply</button>
</div>
</div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div>
<div class="modal fade modal-primary" id="modal_custom_record"> <div class="modal fade modal-primary" id="modal_custom_record">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <h4 class="modal-title">Custom Record</h4>
aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title">Custom Record</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-primary" id="button_save">Save</button>
</div>
</div> </div>
<!-- /.modal-content --> <div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="button_save">Save</button>
</div>
</div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div>
{% endblock %} {% endblock %}

View File

@ -1,221 +1,239 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "new_domain" %} {% set active_page = "new_domain" %}
{% block title %}<title>Add Domain - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Add Domain - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) --> <div class="content-header">
<section class="content-header"> <div class="container-fluid">
<h1> <div class="row mb-2">
Domain <div class="col-sm-6">
<small>Create new</small> <h1 class="m-0 text-dark">
</h1> Domain
<ol class="breadcrumb"> <small>New Domain</small>
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i>Home</a></li> </h1>
<li><a href="{{ url_for('dashboard.dashboard') }}">Domain</a></li> </div>
<li class="active">Add Domain</li> <div class="col-sm-6">
</ol> <ol class="breadcrumb float-sm-right">
</section> <li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item active">Domain - New Domain</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="box box-primary"> <div class="card card-outline card-secondary">
<div class="box-header with-border"> <div class="card-header with-border">
<h3 class="box-title">Create new domain</h3> <h3 class="card-title">Create new domain</h3>
</div>
<form role="form" method="post" action="{{ url_for('domain.add') }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<div class="card-body">
<div class="form-group">
<input type="text" class="form-control" name="domain_name" id="domain_name" placeholder="Enter a valid domain name (required)">
</div>
{% if domain_override_toggle == True %}
<div class="form-group">
<label>Domain Override Record</label>
<input type="checkbox" id="domain_override" name="domain_override" class="checkbox">
</div> </div>
<!-- /.box-header --> {% endif %}
<!-- form start --> <select name="accountid" class="form-control" style="width:15em;">
<form role="form" method="post" action="{{ url_for('domain.add') }}"> <option value="0">- No Account -</option>
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> {% for account in accounts %}
<div class="box-body"> <option value="{{ account.id }}">{{ account.name }}</option>
<div class="form-group"> {% endfor %}
<input type="text" class="form-control" name="domain_name" id="domain_name" </select>
placeholder="Enter a valid domain name (required)"> <br />
</div> <div class="form-group">
{% if domain_override_toggle == True %} <label>Type</label>
<div class="form-group"> <div class="radio">
<label>Domain Override Record</label> <label>
<input type="checkbox" id="domain_override" name="domain_override" <input type="radio" name="radio_type" id="radio_type_native" value="native" checked>
class="checkbox"> Native
</div> </label>
{% endif %} </div>
<select name="accountid" class="form-control" style="width:15em;"> <div class="radio">
<option value="0">- No Account -</option> <label>
{% for account in accounts %} <input type="radio" name="radio_type" id="radio_type_master" value="master">
<option value="{{ account.id }}">{{ account.name }}</option> Primary
{% endfor %} </label>
</select><br /> </div>
<div class="form-group"> <div class="radio">
<label>Type</label> <label>
<div class="radio"> <input type="radio" name="radio_type" id="radio_type_slave" value="slave">
<label> Secondary
<input type="radio" name="radio_type" id="radio_type_native" value="native" checked> </label>
Native </div>
</label> </div>
&nbsp;&nbsp;&nbsp; <div class="form-group">
<label> <label>Select a template</label>
<input type="radio" name="radio_type" id="radio_type_master" value="master"> Master <select class="form-control" id="domain_template" name="domain_template">
</label> <option value="0">No template</option>
&nbsp;&nbsp;&nbsp; {% for template in templates %}
<label> <option value="{{ template.id }}">{{ template.name }}</option>
<input type="radio" name="radio_type" id="radio_type_slave" value="slave">Slave {% endfor %}
</label> </select>
</div> </div>
</div> <div class="form-group" style="display: none;" id="domain_master_address_div">
<div class="form-group"> <input type="text" class="form-control" name="domain_master_address" id="domain_master_address" placeholder="Enter valid master ip addresses (separated by commas)">
<label>Select a template</label> </div>
<select class="form-control" id="domain_template" name="domain_template"> <div class="form-group">
<option value="0">No template</option> <label>SOA-EDIT-API</label>
{% for template in templates %} <div class="radio">
<option value="{{ template.id }}">{{ template.name }}</option> <label>
{% endfor %} <input type="radio" name="radio_type_soa_edit_api" id="radio_default" value="DEFAULT" checked>
</select> DEFAULT
</div> </label>
<div class="form-group" style="display: none;" id="domain_master_address_div"> </div>
<input type="text" class="form-control" name="domain_master_address" <div class="radio">
id="domain_master_address" <label>
placeholder="Enter valid master ip addresses (separated by commas)"> <input type="radio" name="radio_type_soa_edit_api" id="radio_increase" value="INCREASE">
</div> INCREASE
<div class="form-group"> </label>
<label>SOA-EDIT-API</label> </div>
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="radio_type_soa_edit_api" id="radio_default" <input type="radio" name="radio_type_soa_edit_api" id="radio_epoch" value="EPOCH">
value="DEFAULT" checked> DEFAULT EPOCH
</label> </label>
</div> </div>
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="radio_type_soa_edit_api" id="radio_increase" <input type="radio" name="radio_type_soa_edit_api" id="radio_off" value="OFF"> OFF
value="INCREASE"> INCREASE </label>
</label> </div>
</div> </div>
<div class="radio">
<label>
<input type="radio" name="radio_type_soa_edit_api" id="radio_epoch" value="EPOCH">
EPOCH
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="radio_type_soa_edit_api" id="radio_off" value="OFF"> OFF
</label>
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-flat btn-primary">Submit</button>
<button type="button" class="btn btn-flat btn-default"
onclick="window.location.href='{{ url_for('dashboard.dashboard') }}'">Cancel</button>
</div>
</form>
</div> </div>
<!-- /.box --> <div class="card-footer">
</div> <button type="submit" class="btn btn-primary">
<div class="col-md-8"> Submit
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Help with creating a new domain</h3>
</div>
<div class="box-body">
<dl class="dl-horizontal">
<dt>Domain name</dt>
<dd>Enter your domain name in the format of name.tld (eg. powerdns-admin.com). You can also
enter sub-domains to create a sub-root zone (eg. sub.powerdns-admin.com) in case you want to
delegate sub-domain management to specific users.</dd>
<dt>Type</dt>
<dd>The type decides how the domain will be replicated across multiple DNS servers.
<ul>
<li>
Native - PowerDNS will not perform any replication. Use this if you only have one
PowerDNS server or you handle replication via your backend.
</li>
<li>
Master - This PowerDNS server will serve as the master and will send zone transfers
(AXFRs) to other servers configured as slaves.
</li>
<li>
Slave - This PowerDNS server will serve as the slave and will request and receive
zone transfers (AXFRs) from other servers configured as masters.
</li>
</ul>
</dd>
<dt>SOA-EDIT-API</dt>
<dd>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a change is
made to the domain.
<ul>
<li>
DEFAULT - Generate a soa serial of YYYYMMDD01. If the current serial is lower than
the generated serial, use the generated serial. If the current serial is higher or
equal to the generated serial, increase the current serial by 1.
</li>
<li>
INCREASE - Increase the current serial by 1.
</li>
<li>
EPOCH - Change the serial to the number of seconds since the EPOCH, aka unixtime.
</li>
<li>
OFF - Disable automatic updates of the SOA serial.
</li>
</ul>
</dd>
</dl>
<p>Find more details at <a href="https://docs.powerdns.com/md/">https://docs.powerdns.com/md/</a>
</p>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %}
<script>
$("input[name=radio_type]").change(function () {
var type = $(this).val();
if (type == "slave") {
$("#domain_master_address_div").show();
} else {
$("#domain_master_address_div").hide();
}
});
</script>
{% endblock %}
{% block modals %}
<script>
{% if domain_override_message %}
$(document.body).ready(function () {
var modal = $("#modal_warning");
var info = "{{ domain_override_message }}";
modal.find('.modal-body p').text(info);
modal.modal('show');
});
{% endif %}
</script>
</div>
<div class="modal fade" id="modal_warning">
<div class="modal-dialog">
<div class="modal-content modal-sm">
<div class="modal-header alert-danger">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="button_close_warn_modal">
<span aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title">WARNING</h4> <button type="button" class="btn btn-default" onclick="window.location.href='{{ url_for('dashboard.dashboard') }}'">
Cancel
</button>
</div>
</form>
</div>
</div>
<div class="col-md-8">
<div class="card card-outline card-secondary">
<div class="card-header with-border">
<h3 class="card-title">Help with creating a new domain</h3>
</div> </div>
<div class="modal-body"> <div class="card-body">
<p></p> <dl class="dl-horizontal">
</div> <dt>Domain name</dt>
<div class="modal-footer"> <dd>Enter your domain name in the format of name.tld (eg. powerdns-admin.com). You can also
<button type="button" class="btn btn-flat btn-primary center-block" data-dismiss="modal" id="button_confirm_warn_modal"> enter sub-domains to create a sub-root zone (eg. sub.powerdns-admin.com) in case you want to
CLOSE</button> delegate sub-domain management to specific users.
</dd>
<dt>Type</dt>
<dd>The type decides how the domain will be replicated across multiple DNS servers.
<ul>
<li>
<b>Native - </b>{{ SITE_NAME }} will not perform any Primary or Secondary zone functions.
</li>
<li>
<b>Primary - </b>{{ SITE_NAME }} will serve as the Primary and will send zone transfers
(AXFRs) to other servers configured as secondaries.
</li>
<li>
<b>Secondary - </b>{{ SITE_NAME }} will serve as the Secondary and will request and receive
zone transfers (AXFRs) from other servers configured as Primaries.
</li>
</ul>
</dd>
<dt>SOA-EDIT-API</dt>
<dd>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a change is
made to the domain.
<ul>
<li>
<b>DEFAULT - </b>Generate a soa serial of YYYYMMDD01. If the current serial is lower than
the generated serial, use the generated serial. If the current serial is higher or
equal to the generated serial, increase the current serial by 1.
</li>
<li>
<b>INCREASE - </b>Increase the current serial by 1.
</li>
<li>
<b>EPOCH - </b>Change the serial to the number of seconds since the EPOCH, aka unixtime.
</li>
<li>
<b>OFF - </b>Disable automatic updates of the SOA serial.
</li>
</ul>
</dd>
</dl>
<p>
Find more details at <a href="https://docs.powerdns.com/md/">https://docs.powerdns.com/md/</a>
</p>
</div>
</div>
</div> </div>
</div> </div>
<!-- /.modal-content --> </div>
</div> </section>
<!-- /.modal-dialog -->
</div>
{% endblock %} {% endblock %}
{% block extrascripts %}
<script>
$("input[name=radio_type]").change(function () {
var type = $(this).val();
if (type == "slave") {
$("#domain_master_address_div").show();
} else {
$("#domain_master_address_div").hide();
}
});
</script>
{% endblock %}
{% block modals %}
<script>
{% if domain_override_message %}
$(document.body).ready(function () {
var modal = $("#modal_warning");
var info = "{{ domain_override_message }}";
modal.find('.modal-body p').text(info);
modal.modal('show');
});
{% endif %}
</script>
<div class="modal fade" id="modal_warning">
<div class="modal-dialog">
<div class="modal-content modal-sm">
<div class="modal-header alert-danger">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="button_close_warn_modal">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
WARNING
</h4>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-flat btn-primary center-block" data-dismiss="modal" id="button_confirm_warn_modal">
CLOSE
</button>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -2,72 +2,79 @@
{% block title %}<title>{{ domain.name | pretty_domain_name }} - {{ SITE_NAME }}</title>{% endblock %} {% block title %}<title>{{ domain.name | pretty_domain_name }} - {{ SITE_NAME }}</title>{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<section class="content-header"> <div class="content-header">
<h1> <div class="container-fluid">
{% if record_name and record_type %} <div class="row mb-2">
Record changelog: <b>{{ record_name}} &nbsp {{ record_type }}</b> <div class="col-sm-6">
{% else %} <h1 class="m-0 text-dark">
Domain changelog: <b>{{ domain.name | pretty_domain_name }}</b> {% if record_name and record_type %}
{% endif %} Record changelog: <b>{{ record_name}} &nbsp {{ record_type }}</b>
</h1> {% else %}
<ol class="breadcrumb"> Domain changelog: <b>{{ domain.name | pretty_domain_name }}</b>
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li> {% endif %}
<li>Domain</li> </h1>
<li class="active">{{ domain.name | pretty_domain_name }}</li> </div>
</ol> <div class="col-sm-6">
</section> <ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item active">Changelog: {{ domain.name | pretty_domain_name }}</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% import 'applied_change_macro.html' as applied_change_macro %} {% import 'applied_change_macro.html' as applied_change_macro %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="card">
<div class="box-body"> <div class="card-body">
<button type="button" class="btn btn-flat btn-primary pull-left button_show_records" <button type="button" class="btn btn-primary pull-left button_show_records" id="{{ domain.name }}">
id="{{ domain.name }}"> <i class="fas fa-arrow-left"></i>
Manage &nbsp;<i class="fa fa-arrow-left"></i> &nbsp;Manage
</button> </button>
</div> </div>
<div class="box-body"> <div class="card-body">
<table id="tbl_changelog" class="table table-bordered table-striped">
<table id="tbl_changelog" class="table table-bordered table-striped"> <thead>
<thead> <tr>
<tr> <th>Changed on</th>
<th>Changed on</th> <th>Changed by</th>
<th>Changed by</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {% for applied_change in allHistoryChanges %}
{% for applied_change in allHistoryChanges %} <tr class="odd row_record" id="{{ domain.name }}">
<td id="changed_on" class="changed_on">
<tr class="odd row_record" id="{{ domain.name }}"> {{ allHistoryChanges[applied_change][0].history_entry.created_on }}
<td id="changed_on" class="changed_on"> </td>
{{ allHistoryChanges[applied_change][0].history_entry.created_on }} <td>
</td> {{allHistoryChanges[applied_change][0].history_entry.created_by }}
<td> </td>
{{allHistoryChanges[applied_change][0].history_entry.created_by }} </tr>
</td> <!-- Nested Table -->
</tr> <tr style='visibility:collapse'>
<!-- Nested Table --> <td colspan="2">
<tr style='visibility:collapse'> <div class="content">
<td colspan="2"> {% call applied_change_macro.applied_change_template(allHistoryChanges[applied_change]) %}
<div class="content"> {% endcall %}
{% call applied_change_macro.applied_change_template(allHistoryChanges[applied_change]) %} </div>
{% endcall %} </td>
</div> </tr>
</td> <!-- end nested table -->
</tr> {% endfor %}
<!-- end nested table --> </tbody>
{% endfor %} </table>
</tbody> </div>
</table>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}

View File

@ -1,127 +1,135 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "remove_domain" %} {% set active_page = "remove_domain" %}
{% block title %}<title>Remove Domain - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Remove Domain - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) --> <div class="content-header">
<section class="content-header"> <div class="container-fluid">
<h1> <div class="row mb-2">
Domain <div class="col-sm-6">
<small>Remove existing</small> <h1 class="m-0 text-dark">
</h1> Domain
<ol class="breadcrumb"> <small>Remove</small>
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i>Home</a></li> </h1>
<li><a href="{{ url_for('dashboard.dashboard') }}">Domain</a></li> </div>
<li class="active">Remove Domain</li> <div class="col-sm-6">
</ol> <ol class="breadcrumb float-sm-right">
</section> <li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item active">Domain - Remove Domain</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="box box-primary"> <div class="card card-outline card-secondary">
<div class="box-header with-border"> <div class="card-header with-border">
<h3 class="box-title">Remove domain</h3> <h3 class="card-title">Remove domain</h3>
</div> </div>
<!-- /.box-header --> <form role="form" method="post" action="{{ url_for('domain.remove') }}">
<!-- form start --> <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<form role="form" method="post" action="{{ url_for('domain.remove') }}"> <div class="card-body">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <select id=domainid class="form-control" style="width:15em;">
<div class="box-body"> <option value="0">- Select Domain -</option>
<select id=domainid class="form-control" style="width:15em;"> {% for domain in domainss %}
<option value="0">- Select Domain -</option> <option value="{{ domain.id }}">{{ domain.name }}</option>
{% for domain in domainss %} {% endfor %}
<option value="{{ domain.id }}">{{ domain.name }}</option> </select>
{% endfor %} <br />
</select><br />
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="button" class="btn btn-flat btn-danger button_delete">Remove</button>
<button type="button" class="btn btn-flat btn-default"
onclick="window.location.href='{{ url_for('dashboard.dashboard') }}'">Cancel</button>
</div>
</form>
</div> </div>
<!-- /.box --> <div class="card-footer">
</div> <button type="button" class="btn btn-default" onclick="window.location.href='{{ url_for('dashboard.dashboard') }}'">
<div class="col-md-8"> Cancel
<div class="box box-primary"> </button>
<div class="box-header with-border"> <button type="button" class="btn btn-danger button_delete float-right">Remove</button>
<h3 class="box-title">Help with removing a new domain</h3>
</div>
<div class="box-body">
<dl class="dl-horizontal">
<dt>Domain name</dt>
<dd>Select domain you wish to remove from DNS.</dd>
</dl>
<p>Find more details at <a href="https://docs.powerdns.com/md/">https://docs.powerdns.com/md/</a>
</p>
</div>
</div> </div>
</form>
</div> </div>
</div>
<div class="col-md-8">
<div class="card card-outline card-secondary">
<div class="card-header with-border">
<h3 class="card-title">Help with removing a new domain</h3>
</div>
<div class="card-body">
<dl class="dl-horizontal">
<dt>Domain name</dt>
<dd>Select domain you wish to remove from DNS.</dd>
</dl>
<p>Find more details at <a href="https://docs.powerdns.com/md/">https://docs.powerdns.com/md/</a></p>
</div>
</div>
</div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// handle delete button // handle delete button
$(document.body).on("click", ".button_delete", function(e) { $(document.body).on("click", ".button_delete", function(e) {
e.stopPropagation(); e.stopPropagation();
if ( $("#domainid").val() == 0 ){ if ( $("#domainid").val() == 0 ){
showErrorModal("Please select domain to remove."); showErrorModal("Please select domain to remove.");
return; return;
} }
var modal = $("#modal_delete");
var modal = $("#modal_delete"); var domain = $("#domainid option:selected").text();
var domain = $("#domainid option:selected").text(); var info = "Are you sure you want to delete " + domain + "?";
var info = "Are you sure you want to delete " + domain + "?"; modal.find('.modal-body p').text(info);
modal.find('.modal-body p').text(info); modal.find('#button_delete_confirm').click(function () {
modal.find('#button_delete_confirm').click(function () { $.post($SCRIPT_ROOT + '/domain/remove' , {
$.post($SCRIPT_ROOT + '/domain/remove' , { '_csrf_token': '{{ csrf_token() }}',
'_csrf_token': '{{ csrf_token() }}', 'domainid': domain,
'domainid': domain, }, function () {
}, function () { window.location.href = '{{ url_for('dashboard.dashboard') }}';
window.location.href = '{{ url_for('dashboard.dashboard') }}'; });
}); modal.modal('hide');
modal.modal('hide'); })
}) modal.modal('show');
modal.modal('show'); $("#button_delete_cancel").unbind().one('click', function(e) {
modal.modal('hide');
$("#button_delete_cancel").unbind().one('click', function(e) {
modal.modal('hide');
});
}); });
});
</script> </script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
<div class="modal fade modal-warning" id="modal_delete"> <div class="modal fade modal-warning" id="modal_delete">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <h4 class="modal-title">Confirmation</h4>
aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title">Confirmation</h4> </div>
</div> <div class="modal-body">
<div class="modal-body"> <p></p>
<p></p> </div>
</div> <div class="modal-footer">
<div class="modal-footer"> <button type="button" class="btn btn-default" id="button_delete_cancel" data-dismiss="modal">
<button type="button" class="btn btn-flat btn-default pull-left" id="button_delete_cancel" Close
data-dismiss="modal">Close</button> </button>
<button type="button" class="btn btn-flat btn-danger" id="button_delete_confirm">Delete</button> <button type="button" class="btn btn-danger float-right" id="button_delete_confirm">
</div> Delete
</div> </button>
<!-- /.modal-content --> </div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -2,7 +2,7 @@
{% block title %} {% block title %}
<title> <title>
{{ SITE_NAME }} - 400 Error 400 Error - {{ SITE_NAME }}
</title> </title>
{% endblock %} {% endblock %}
@ -35,7 +35,7 @@
</h2> </h2>
<div class="error-content"> <div class="error-content">
<h3> <h3>
<i class="fa fa-warning text-yellow"></i> <i class="fas fa-exclamation-triangle text-yellow"></i>
Oops! Bad request Oops! Bad request
</h3> </h3>
<p> <p>

View File

@ -2,7 +2,7 @@
{% block title %} {% block title %}
<title> <title>
{{ SITE_NAME }} - 403 Error 403 Error - {{ SITE_NAME }}
</title> </title>
{% endblock %} {% endblock %}
@ -35,7 +35,7 @@
</h2> </h2>
<div class="error-content"> <div class="error-content">
<h3> <h3>
<i class="fa fa-warning text-yellow"></i> <i class="fas fa-exclamation-triangle text-yellow"></i>
Oops! Access denied Oops! Access denied
</h3> </h3>
<p> <p>

View File

@ -2,7 +2,7 @@
{% block title %} {% block title %}
<title> <title>
{{ SITE_NAME }} - 404 Error 404 Error - {{ SITE_NAME }}
</title> </title>
{% endblock %} {% endblock %}
@ -35,7 +35,7 @@
</h2> </h2>
<div class="error-content"> <div class="error-content">
<h3> <h3>
<i class="fa fa-warning text-yellow"></i> <i class="fas fa-exclamation-triangle text-yellow"></i>
Oops! You're lost Oops! You're lost
</h3> </h3>
<p> <p>

View File

@ -2,7 +2,7 @@
{% block title %} {% block title %}
<title> <title>
{{ SITE_NAME }} - 500 Error 500 Error - {{ SITE_NAME }}
</title> </title>
{% endblock %} {% endblock %}
@ -35,7 +35,7 @@
</h2> </h2>
<div class="error-content"> <div class="error-content">
<h3> <h3>
<i class="fa fa-warning text-yellow"></i> <i class="fas fa-exclamation-triangle text-yellow"></i>
Oops! Something went wrong Oops! Something went wrong
</h3> </h3>
<p> <p>

View File

@ -2,7 +2,7 @@
{% block title %} {% block title %}
<title> <title>
{{ SITE_NAME }} - SAML Authentication Error SAML Authentication Error - {{ SITE_NAME }}
</title> </title>
{% endblock %} {% endblock %}
@ -39,7 +39,8 @@
<br/> <br/>
<div class="error-content"> <div class="error-content">
<h3> <h3>
<i class="fa fa-warning text-yellow"></i> Oops! Something went wrong <i class="fas fa-exclamation-triangle text-yellow"></i>
Oops! Something went wrong
</h3> </h3>
<br> <br>
<p> <p>

View File

@ -106,15 +106,23 @@
<span class="help-block with-errors"></span> <span class="help-block with-errors"></span>
</div> </div>
{% if captcha_enable %} {% if captcha_enable %}
<p class="login-box-msg">Please complete the CAPTCHA below</p> <div class="input-group mb-3">
<div class="form-group has-feedback"> <p class="login-box-msg">Please complete the CAPTCHA below</p>
{{ captcha() }} {{ captcha() }}
<input type="text" class="form-control" placeholder="CAPTCHA" name="captcha" data-error="Please complete the CAPTCHA" required> <br>
<span class="help-block with-errors"></span> <input type="text" class="form-control" placeholder="CAPTCHA" id="captcha" name="captcha" required>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
<div class="invalid-feedback">
Please complete the CAPTCHA
</div>
</div> </div>
{% endif %} {% endif %}
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<button type="button" class="btn btn-block" id="button_back">Back</button> <button type="button" class="btn btn-block" id="button_back">Back</button>

View File

@ -38,19 +38,20 @@
</div> </div>
{% endif %} {% endwith %} {% endif %} {% endwith %}
<div class="row"> <div class="row">
<div class="container-fluid">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="card">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Templates</h3> <h3 class="card-title">Templates</h3>
</div> </div>
<div class="box-body"> <div class="card-body">
<a href="{{ url_for('admin.create_template') }}"> <a href="{{ url_for('admin.create_template') }}">
<button type="button" class="btn btn-flat btn-primary pull-left"> <button type="button" class="btn btn-flat btn-primary pull-left">
Create Template&nbsp;<i class="fa fa-plus"></i> Create Template&nbsp;<i class="fa fa-plus"></i>
</button> </button>
</a> </a>
</div> </div>
<div class="box-body"> <div class="card-body">
<table id="tbl_template_list" class="table table-bordered table-striped"> <table id="tbl_template_list" class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
@ -75,11 +76,11 @@
</td> </td>
<td> <td>
<a href="{{ url_for('admin.edit_template', template=template.name) }}"> <a href="{{ url_for('admin.edit_template', template=template.name) }}">
<button type="button" class="btn btn-flat btn-warning button_edit" id="btn_edit"> <button type="button" class="btn btn-warning button_edit" id="btn_edit">
Edit&nbsp;<i class="fa fa-edit"></i> Edit&nbsp;<i class="fa fa-edit"></i>
</button> </button>
</a> </a>
<button type="button" class="btn btn-flat btn-danger button_delete" id="{{template.name}}"> <button type="button" class="btn btn-danger button_delete" id="{{template.name}}">
Delete&nbsp;<i class="fa fa-trash"></i> Delete&nbsp;<i class="fa fa-trash"></i>
</button> </button>
</td> </td>
@ -94,6 +95,7 @@
</div> </div>
<!-- /.col --> <!-- /.col -->
</div> </div>
</div>
<!-- /.row --> <!-- /.row -->
</section> </section>
<!-- /.content --> <!-- /.content -->

View File

@ -1,28 +1,42 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}<title>My Profile - {{ SITE_NAME }}</title>{% endblock %}
{% block dashboard_stat %} {% block title %}
<!-- Content Header (Page header) --> <title>
<section class="content-header"> My Profile - {{ SITE_NAME }}
<h1> </title>
Profile
<small>Edit my profile</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i>Home</a></li>
<li class="active">My Profile</li>
</ol>
</section>
{% endblock %} {% endblock %}
{% block dashboard_stat %}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0 text-dark">
User
<small>My Profile</small>
</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item active">My Profile</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box box-primary"> <div class="card card-primary">
<div class="box-header with-border"> <div class="card-header with-border">
<h3 class="box-title">Edit my profile{% if session['authentication_type'] != 'LOCAL' %} [Disabled - <h3 class="card-title">Edit my profile{% if session['authentication_type'] != 'LOCAL' %} [Disabled -
Authenticated externally]{% endif %}</h3> Authenticated externally]{% endif %}</h3>
</div> </div>
<div class="box-body"> <div class="card-body">
<!-- Custom Tabs --> <!-- Custom Tabs -->
<div class="nav-tabs-custom" id="tabs"> <div class="nav-tabs-custom" id="tabs">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">

View File

@ -29,6 +29,6 @@ Flask-Mail==0.9.1
flask-session==0.4.0 flask-session==0.4.0
Jinja2==3.1.2 Jinja2==3.1.2
itsdangerous==2.1.2 itsdangerous==2.1.2
werkzeug==2.1.3 werkzeug==2.1.2
cryptography==36.0.2 cryptography==36.0.2
flask_session_captcha==1.3.0 flask_session_captcha==1.3.0