More page formatting

Added server-side logic for register.html validation
Keep form firelds on register.html in the event of wrong input fields to save users from retyping info
More button rounding
This commit is contained in:
Tyler Todd 2023-02-13 03:57:21 +00:00
parent d38a919644
commit c00ddea2fc
24 changed files with 1234 additions and 1125 deletions

View File

@ -400,7 +400,7 @@ def login():
desc_prop = Setting().get('oidc_oauth_account_description_property') desc_prop = Setting().get('oidc_oauth_account_description_property')
account_to_add = [] account_to_add = []
#If the name_property and desc_property exist in me (A variable that contains all the userinfo from the IdP). #If the name_property and desc_property exist in me (A variable that contains all the userinfo from the IdP).
if name_prop in me and desc_prop in me: if name_prop in me and desc_prop in me:
accounts_name_prop = [me[name_prop]] if type(me[name_prop]) is not list else me[name_prop] accounts_name_prop = [me[name_prop]] if type(me[name_prop]) is not list else me[name_prop]
accounts_desc_prop = [me[desc_prop]] if type(me[desc_prop]) is not list else me[desc_prop] accounts_desc_prop = [me[desc_prop]] if type(me[desc_prop]) is not list else me[desc_prop]
@ -415,7 +415,7 @@ def login():
account_to_add.append(account) account_to_add.append(account)
user_accounts = user.get_accounts() user_accounts = user.get_accounts()
# Add accounts # Add accounts
for account in account_to_add: for account in account_to_add:
if account not in user_accounts: if account not in user_accounts:
account.add_user(user) account.add_user(user)
@ -651,55 +651,73 @@ def logout():
@index_bp.route('/register', methods=['GET', 'POST']) @index_bp.route('/register', methods=['GET', 'POST'])
def register(): def register():
CAPTCHA_ENABLE = current_app.config.get('CAPTCHA_ENABLE') CAPTCHA_ENABLE = current_app.config.get('CAPTCHA_ENABLE')
if Setting().get('signup_enabled'): if Setting().get('signup_enabled'):
if request.method == 'GET': if current_user.is_authenticated:
return render_template('register.html', captcha_enable=CAPTCHA_ENABLE) return redirect(url_for('index.index'))
elif request.method == 'POST': if request.method == 'GET':
username = request.form.get('username', '').strip() return render_template('register.html', captcha_enable=CAPTCHA_ENABLE)
password = request.form.get('password', '') elif request.method == 'POST':
firstname = request.form.get('firstname', '').strip() username = request.form.get('username', '').strip()
lastname = request.form.get('lastname', '').strip() password = request.form.get('password', '')
email = request.form.get('email', '').strip() firstname = request.form.get('firstname', '').strip()
rpassword = request.form.get('rpassword', '') lastname = request.form.get('lastname', '').strip()
email = request.form.get('email', '').strip()
rpassword = request.form.get('rpassword', '')
if not username or not password or not email: is_valid_email = re.compile(r'[\w\.-]+@[\w\.-]+')
return render_template(
'register.html', error='Please input required information', captcha_enable=CAPTCHA_ENABLE)
if password != rpassword: error_messages = {}
return render_template( if not firstname:
'register.html', error_messages['firstname'] = 'First Name is required'
error="Password confirmation does not match", captcha_enable=CAPTCHA_ENABLE) if not lastname:
error_messages['lastname'] = 'Last Name is required'
if not username:
error_messages['username'] = 'Username is required'
if not password:
error_messages['password'] = 'Password is required'
if not rpassword:
error_messages['rpassword'] = 'Password confirmation is required'
if not email:
error_messages['email'] = 'Email is required'
if not is_valid_email.match(email):
error_messages['email'] = 'Invalid email address'
if password != rpassword:
error_messages['password'] = 'Password confirmation does not match'
error_messages['rpassword'] = 'Password confirmation does not match'
if not captcha.validate(): if not captcha.validate():
return render_template( return render_template(
'register.html', error='Invalid CAPTCHA answer', captcha_enable=CAPTCHA_ENABLE) 'register.html', error='Invalid CAPTCHA answer', error_messages=error_messages, captcha_enable=CAPTCHA_ENABLE)
user = User(username=username, if error_messages:
plain_text_password=password, return render_template('register.html', error_messages=error_messages, captcha_enable=CAPTCHA_ENABLE)
firstname=firstname,
lastname=lastname,
email=email)
try: user = User(username=username,
result = user.create_local_user() plain_text_password=password,
if result and result['status']: firstname=firstname,
if Setting().get('verify_user_email'): lastname=lastname,
send_account_verification(email) email=email
if Setting().get('otp_force') and Setting().get('otp_field_enabled'): )
user.update_profile(enable_otp=True)
prepare_welcome_user(user.id) try:
return redirect(url_for('index.welcome')) result = user.create_local_user()
else: if result and result['status']:
return redirect(url_for('index.login')) if Setting().get('verify_user_email'):
else: send_account_verification(email)
return render_template('register.html', if Setting().get('otp_force') and Setting().get('otp_field_enabled'):
error=result['msg'], captcha_enable=CAPTCHA_ENABLE) user.update_profile(enable_otp=True)
except Exception as e: prepare_welcome_user(user.id)
return render_template('register.html', error=e, captcha_enable=CAPTCHA_ENABLE) return redirect(url_for('index.welcome'))
else:
return redirect(url_for('index.login'))
else:
return render_template('register.html',
error=result['msg'], captcha_enable=CAPTCHA_ENABLE)
except Exception as e:
return render_template('register.html', error=e, captcha_enable=CAPTCHA_ENABLE)
else: else:
return render_template('errors/404.html'), 404 return render_template('errors/404.html'), 404
# Show welcome page on first login if otp_force is enabled # Show welcome page on first login if otp_force is enabled

View File

@ -1,9 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_accounts" %} {% set active_page = "admin_accounts" %}
{% block title %}<title>Edit Account - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Edit Account - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<div class="content-header"> <div class="content-header">
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
@ -30,7 +35,7 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-4">
<div class="card card-primary"> <div class="card shadow">
<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> </div>
@ -107,8 +112,8 @@
</form> </form>
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-8">
<div class="card card-primary"> <div class="card shadow">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">Help with creating a new account</h3> <h3 class="card-title">Help with creating a new account</h3>
</div> </div>

View File

@ -1,12 +1,17 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_keys" %} {% set active_page = "admin_keys" %}
{% if (key is not none and key.role.name != "User") %}{% set hide_opts = True %}{%else %}{% set hide_opts = False %}{% endif %} {% if (key is not none and key.role.name != "User") %}{% set hide_opts = True %}{%else %}{% set hide_opts = False %}{% endif %}
{% block title %} {% block title %}
<title>Edit Key - {{ SITE_NAME }}</title> <title>
Edit Key - {{ SITE_NAME }}
</title>
{% endblock %} {% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) --> <div class="content-header">
<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">
@ -25,61 +30,59 @@
</div> </div>
</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-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 %} Key</h3> <h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} Key</h3>
</div> </div>
<!-- /.box-header --> <form role="form" method="post"
<!-- form start --> action="{% if create %}{{ url_for('admin.edit_key') }}{% else %}{{ url_for('admin.edit_key', key_id=key.id) }}{% endif %}">
<form role="form" method="post" <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
action="{% if create %}{{ url_for('admin.edit_key') }}{% else %}{{ url_for('admin.edit_key', key_id=key.id) }}{% endif %}"> <input type="hidden" name="create" value="{{ create }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <div class="card-body">
<input type="hidden" name="create" value="{{ create }}"> <div class="form-group has-feedback">
<div class="card-body"> <label class="control-label" for="role">Role</label>
<div class="form-group has-feedback"> <select class="key_role form-control" id="key_role" name="key_role">
<label class="control-label" for="role">Role</label> {% for role in roles %}
<select class="key_role form-control" id="key_role" name="key_role"> <option value="{{ role.name }}"
{% for role in roles %} {% if (key is not none) and (role.id==key.role.id) %}selected{% endif %}
<option value="{{ role.name }}" {% if (key is none) and (role.name=="User") %}selected{% endif %}>
{% if (key is not none) and (role.id==key.role.id) %}selected{% endif %} {{ role.name }}
{% if (key is none) and (role.name=="User") %}selected{% endif %} </option>
>{{ role.name }}</option> {% endfor %}
{% endfor %} </select>
</select> </div>
</div> <div class="form-group has-feedback">
<div class="form-group has-feedback"> <label class="control-label" for="description">Description</label>
<label class="control-label" for="description">Description</label> <input type="text" class="form-control" placeholder="Description" name="description"
<input type="text" class="form-control" placeholder="Description" name="description" {% if key is not none %} value="{{ key.description }}" {% endif %}>
{% if key is not none %} value="{{ key.description }}" {% endif %}> <span <span class="glyphicon glyphicon-pencil form-control-feedback"></span>
class="glyphicon glyphicon-pencil form-control-feedback"></span> </div>
</div> </div>
</div> <div class="card-header with-border key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
<div class="card-header with-border key-opts"{% if hide_opts %} style="display: none;"{% endif %}> <h3 class="card-title">Accounts Access Control</h3>
<h3 class="card-title">Accounts Access Control</h3> </div>
</div> <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 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-2">
<div class="form-group col-2"> <select multiple="multiple" class="form-control" id="key_multi_account" name="key_multi_account">
<select multiple="multiple" class="form-control" id="key_multi_account" {% for account in accounts %}
name="key_multi_account"> <option {% if key and account in key.accounts %}selected{% endif %} value="{{ account.name }}">{{ account.name }}</option>
{% for account in accounts %} {% endfor %}
<option {% if key and account in key.accounts %}selected{% endif %} value="{{ account.name }}">{{ account.name }}</option> </select>
{% endfor %} </div>
</select> </div>
</div> <div class="card-header with-border key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
</div> <h3 class="card-title">Domain Access Control</h3>
<div class="card-header with-border key-opts"{% if hide_opts %} style="display: none;"{% endif %}> </div>
<h3 class="card-title">Domain Access Control</h3>
</div>
<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>
@ -115,8 +118,10 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
$('form').submit(function (e) { $('form').submit(function (e) {

View File

@ -1,210 +1,201 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_global_search" %}
{% block title %}
<title>Global Search - {{ SITE_NAME }}</title>
{% endblock %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Global Search <small>Search for domains, records and comments directly from PDNS API</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Global Search</li>
</ol>
</section>
<div class="content-header"> {% set active_page = "admin_global_search" %}
{% block title %}
<title>
Global Search - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %}
<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 Global Search
<small>Control panel</small> <small>Search for domains, records and comments directly from PDNS API</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 active">Global Search</li>
</ol> </ol>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% block content %}
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box-body">
<!-- search form -->
<form action="" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Your keyword...">
<div class="input-group-btn">
<button type="submit" class="btn btn-success"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
<div>
<p><b>Hints:</b> The * character can be used in your keyword as a wildcard character and the ? character can be used as
a wildcard for a
single character.</p>
</div>
<!-- /.search form -->
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Domains ({{ domains|length }})</h3>
</div>
<div class="box-body">
<table id="tbl_domain" class="table table-bordered table-striped">
<thead>
<tr>
<th>Domain</th>
</tr>
</thead>
<tbody>
{% for domain in domains %}
<tr class="odd gradeX">
<td>
<a href="{{ url_for('domain.domain', domain_name=domain['name']) }}">{{ domain['name'] }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Records ({{ records|length }})</h3>
</div>
<div class="box-body">
<table id="tbl_record" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Status</th>
<th>TTL</th>
<th>Data</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr class="odd gradeX">
<td>
<a href="{{ url_for('domain.domain', domain_name=record['zone_id']) }}">{{ record['name'] }}</a>
</td>
<td>{{ record['type'] }}</td>
<td>{{ 'Disabled' if record['disabled'] else 'Active' }}</td>
<td>{{ record['ttl'] }}</td>
<td>{{ record['content'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Comments ({{ comments|length }})</h3>
</div>
<div class="box-body">
<table id="tbl_comment" class="table table-bordered table-striped">
<thead>
<tr>
<th>Comment</th>
<th>Record</th>
<th>Domain</th>
</tr>
</thead>
<tbody>
{% for comment in comments %}
<tr class="odd gradeX">
<td>{{ comment['content'] }}</td>
<td>{{ comment['name'] }}</td>
<td>
<a href="{{ url_for('domain.domain', domain_name=comment['zone_id']) }}">{{ comment['zone_id'] }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
</section>
{% endblock %} {% endblock %}
{% block content %}
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header">
<h3 class="card-title">Global Search</h3>
</div>
<div class="card-body">
<form action="" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Your keyword...">
<div class="input-group-btn">
<button type="submit" class="btn btn-success"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
<div>
<p><b>Hints:</b> The * character can be used in your keyword as a wildcard character and the ? character can be used as
a wildcard for a
single character.
</p>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header">
<h3 class="card-title">Domains ({{ domains|length }})</h3>
</div>
<div class="card-body">
<table id="tbl_domain" class="table table-bordered table-striped">
<thead>
<tr>
<th>Domain</th>
</tr>
</thead>
<tbody>
{% for domain in domains %}
<tr class="odd gradeX">
<td>
<a href="{{ url_for('domain.domain', domain_name=domain['name']) }}">{{ domain['name'] }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header">
<h3 class="card-title">Records ({{ records|length }})</h3>
</div>
<div class="card-body">
<table id="tbl_record" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Status</th>
<th>TTL</th>
<th>Data</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr class="odd gradeX">
<td>
<a href="{{ url_for('domain.domain', domain_name=record['zone_id']) }}">{{ record['name'] }}</a>
</td>
<td>{{ record['type'] }}</td>
<td>{{ 'Disabled' if record['disabled'] else 'Active' }}</td>
<td>{{ record['ttl'] }}</td>
<td>{{ record['content'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header">
<h3 class="card-title">Comments ({{ comments|length }})</h3>
</div>
<div class="card-body">
<table id="tbl_comment" class="table table-bordered table-striped">
<thead>
<tr>
<th>Comment</th>
<th>Record</th>
<th>Domain</th>
</tr>
</thead>
<tbody>
{% for comment in comments %}
<tr class="odd gradeX">
<td>{{ comment['content'] }}</td>
<td>{{ comment['name'] }}</td>
<td>
<a href="{{ url_for('domain.domain', domain_name=comment['zone_id']) }}">{{ comment['zone_id'] }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// set up domain result data table // set up domain result data table
$("#tbl_domain").DataTable({ $("#tbl_domain").DataTable({
"paging": false, "paging": false,
"lengthChange": false, "lengthChange": false,
"searching": false, "searching": false,
"ordering": true, "ordering": true,
"info": false, "info": false,
"autoWidth": false, "autoWidth": false,
"order": [ "order": [
[0, "asc"] [0, "asc"]
] ]
}); });
</script>
<script>
// set up domain result data table // set up domain result data table
$("#tbl_record").DataTable({ $("#tbl_record").DataTable({
"paging": false, "paging": false,
"lengthChange": false, "lengthChange": false,
"searching": false, "searching": false,
"ordering": true, "ordering": true,
"info": false, "info": false,
"autoWidth": false, "autoWidth": false,
"order": [ "order": [
[0, "asc"] [0, "asc"]
] ]
}); });
</script>
<script>
// set up domain result data table // set up domain result data table
$("#tbl_comment").DataTable({ $("#tbl_comment").DataTable({
"paging": false, "paging": false,
"lengthChange": false, "lengthChange": false,
"searching": false, "searching": false,
"ordering": true, "ordering": true,
"info": false, "info": false,
"autoWidth": false, "autoWidth": false,
"order": [ "order": [
[0, "asc"] [0, "asc"]
] ]
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,11 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_history" %}
{% block title %}
<title>History - {{ SITE_NAME }}</title>
{% endblock %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<div class="content-header"> {% set active_page = "admin_history" %}
{% block title %}
<title>
History - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %}
<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">
@ -23,17 +27,14 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% import 'applied_change_macro.html' as applied_change_macro %} {% import 'applied_change_macro.html' as applied_change_macro %}
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-12">
<div class="card card-outline card-secondary"> <div class="card card-outline card-secondary">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">History Management</h3> <h3 class="card-title">History Management</h3>

View File

@ -6,7 +6,7 @@
</p> </p>
{% endif %} {% endif %}
<div class="box-body"></div> <div class="card-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>

View File

@ -1,9 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_accounts" %} {% set active_page = "admin_accounts" %}
{% block title %} {% block title %}
<title>Account Management - {{ SITE_NAME }}</title> <title>
{% endblock %} {% block dashboard_stat %} Account Management - {{ SITE_NAME }}
<div class="content-header"> </title>
{% endblock %}
{% block dashboard_stat %}
<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">
@ -21,12 +27,13 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %}
{% endblock %} {% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-12"> <div class="col-12">
<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">Account Management</h3> <h3 class="card-title">Account Management</h3>
@ -133,8 +140,8 @@
<p></p> <p></p>
</div> </div>
<div class="modal-footer"> <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-default pull-left" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-flat btn-danger" id="button_delete_confirm">Delete</button> <button type="button" class="btn btn-danger" id="button_delete_confirm">Delete</button>
</div> </div>
</div> </div>
<!-- /.modal-content --> <!-- /.modal-content -->

View File

@ -1,9 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_keys" %} {% set active_page = "admin_keys" %}
{% block title %} {% block title %}
<title>Key Management - {{ SITE_NAME }}</title> <title>
{% endblock %} {% block dashboard_stat %} Key Management - {{ SITE_NAME }}
<div class="content-header"> </title>
{% endblock %}
{% block dashboard_stat %}
<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">
@ -21,7 +27,9 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% block content %} {% endblock %}
{% block content %}
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="card"> <div class="card">
@ -74,63 +82,62 @@
</div> </div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// set up key data table // set up key data table
$("#tbl_keys").DataTable({ $("#tbl_keys").DataTable({
"paging": true, "paging": true,
"lengthChange": true, "lengthChange": true,
"searching": true, "searching": true,
"ordering": true, "ordering": true,
"info": false, "info": false,
"autoWidth": false, "autoWidth": false,
"lengthMenu": [ "lengthMenu": [
[10, 25, 50, 100, -1], [10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"] [10, 25, 50, 100, "All"]
], ],
"pageLength": 10 "pageLength": 10
}); });
// handle deletion of keys // handle deletion of keys
$(document.body).on('click', '.button_delete', function () { $(document.body).on('click', '.button_delete', function () {
var modal = $("#modal_delete"); var modal = $("#modal_delete");
var key_id = $(this).prop('id'); var key_id = $(this).prop('id');
var info = "Are you sure you want to delete key #" + key_id + "?"; var info = "Are you sure you want to delete key #" + key_id + "?";
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 () {
var postdata = { var postdata = {
'action': 'delete_key', 'action': 'delete_key',
'data': key_id, 'data': key_id,
'_csrf_token': '{{ csrf_token() }}' '_csrf_token': '{{ csrf_token() }}'
} }
applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-keys', false, true); applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-keys', false, true);
modal.modal('hide'); modal.modal('hide');
}) })
modal.modal('show'); modal.modal('show');
}); });
</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" 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> <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-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-default float-left" 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>
{% endblock %} {% endblock %}

View File

@ -1,9 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_users" %} {% set active_page = "admin_users" %}
{% block title %} {% block title %}
<title>User Management - {{ SITE_NAME }}</title> <title>
{% endblock %} {% block dashboard_stat %} User Management - {{ SITE_NAME }}
<div class="content-header"> </title>
{% endblock %}
{% block dashboard_stat %}
<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">
@ -21,196 +27,195 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% block content %}
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-header with-border">
<h3 class="card-title">User Management</h3>
</div>
<div class="card-body">
<a href="{{ url_for('admin.edit_user') }}">
<button type="button" class="btn btn-flat btn-primary pull-left button_add_user">
Add User&nbsp;<i class="fa fa-plus"></i>
</button>
</a>
</div>
<div class="card-body">
<table id="tbl_users" class="table table-bordered table-striped">
<thead>
<tr>
<th>Username</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Role</th>
<th>Privileges</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr class="odd gradeX">
<td>{{ user.username }}</td>
<td>{{ user.firstname }}</td>
<td>{{ user.lastname }}</td>
<td>{{ user.email }}</td>
<td>
<select id="{{ user.username }}" class="user_role"
{% if user.username==current_user.username or (current_user.role.name=='Operator' and user.role.name=='Administrator') %}disabled{% endif %}>
{% for role in roles %}
<option value="{{ role.name }}"
{% if role.id==user.role.id %}selected{% endif %}>{{ role.name }}</option>
{% endfor %}
</select>
</td>
<td width="6%">
<button type="button" class="btn btn-flat btn-warning button_revoke"
id="{{ user.username }}"
{% if current_user.role.name=='Operator' and user.role.name=='Administrator' %}disabled{% endif %}>
Revoke&nbsp;<i class="fa fa-lock"></i>
</button>
</td>
<td width="15%">
<button type="button" class="btn btn-flat btn-success button_edit"
onclick="window.location.href='{{ url_for('admin.edit_user', user_username=user.username) }}'"
{% if current_user.role.name=='Operator' and user.role.name=='Administrator' %}disabled{% endif %}>
Edit&nbsp;<i class="fa fa-lock"></i>
</button>
<button type="button" class="btn btn-flat btn-danger button_delete"
id="{{ user.username }}"
{% if user.username==current_user.username or (current_user.role.name=='Operator' and user.role.name=='Administrator') %}disabled{% endif %}>
Delete&nbsp;<i class="fa fa-trash"></i>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</div>
</section>
{% endblock %} {% endblock %}
{% block content %}
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header with-border">
<h3 class="card-title">User Management</h3>
</div>
<div class="card-body">
<a href="{{ url_for('admin.edit_user') }}">
<button type="button" class="btn btn-primary pull-left button_add_user">
<i class="fa fa-plus"></i>&nbsp;Add User
</button>
</a>
</div>
<div class="card-body">
<table id="tbl_users" class="table table-bordered table-striped">
<thead>
<tr>
<th>Username</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Role</th>
<th>Privileges</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr class="odd gradeX">
<td>{{ user.username }}</td>
<td>{{ user.firstname }}</td>
<td>{{ user.lastname }}</td>
<td>{{ user.email }}</td>
<td>
<select id="{{ user.username }}" class="user_role"
{% if user.username==current_user.username or (current_user.role.name=='Operator' and user.role.name=='Administrator') %}disabled{% endif %}>
{% for role in roles %}
<option value="{{ role.name }}"
{% if role.id==user.role.id %}selected{% endif %}>
{{ role.name }}
</option>
{% endfor %}
</select>
</td>
<td width="6%">
<button type="button" class="btn btn-warning button_revoke"
id="{{ user.username }}"
{% if current_user.role.name=='Operator' and user.role.name=='Administrator' %}disabled{% endif %}>
<i class="fa fa-lock"></i>&nbsp;Revoke
</button>
</td>
<td width="15%">
<button type="button" class="btn btn-success button_edit"
onclick="window.location.href='{{ url_for('admin.edit_user', user_username=user.username) }}'"
{% if current_user.role.name=='Operator' and user.role.name=='Administrator' %}disabled{% endif %}>
<i class="fa fa-lock"></i>&nbsp;Edit
</button>
<button type="button" class="btn btn-danger button_delete"
id="{{ user.username }}"
{% if user.username==current_user.username or (current_user.role.name=='Operator' and user.role.name=='Administrator') %}disabled{% endif %}>
<i class="fa fa-trash"></i>&nbsp;Delete
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// set up user data table // set up user data table
$("#tbl_users").DataTable({ $("#tbl_users").DataTable({
"paging": true, "paging": true,
"lengthChange": true, "lengthChange": true,
"searching": true, "searching": true,
"ordering": true, "ordering": true,
"info": false, "info": false,
"autoWidth": false, "autoWidth": false,
"lengthMenu": [ "lengthMenu": [
[10, 25, 50, 100, -1], [10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"] [10, 25, 50, 100, "All"]
], ],
"pageLength": 10 "pageLength": 10
}); });
// handle revocation of privileges // handle revocation of privileges
$(document.body).on('click', '.button_revoke', function () { $(document.body).on('click', '.button_revoke', function () {
var modal = $("#modal_revoke"); var modal = $("#modal_revoke");
var username = $(this).prop('id'); var username = $(this).prop('id');
var info = "Are you sure you want to revoke all privileges for " + username + var info = "Are you sure you want to revoke all privileges for user " + username +
". They will not able to access any domain."; "? They will not able to access any domain.";
modal.find('.modal-body p').text(info); modal.find('.modal-body p').text(info);
modal.find('#button_revoke_confirm').click(function () { modal.find('#button_revoke_confirm').click(function () {
var postdata = { var postdata = {
'action': 'revoke_user_privileges', 'action': 'revoke_user_privileges',
'data': username, 'data': username,
'_csrf_token': '{{ csrf_token() }}' '_csrf_token': '{{ csrf_token() }}'
} }
applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-user', true); applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-user', true);
modal.modal('hide'); modal.modal('hide');
}) })
modal.modal('show'); modal.modal('show');
}); });
// handle deletion of user // handle deletion of user
$(document.body).on('click', '.button_delete', function () { $(document.body).on('click', '.button_delete', function () {
var modal = $("#modal_delete"); var modal = $("#modal_delete");
var username = $(this).prop('id'); var username = $(this).prop('id');
var info = "Are you sure you want to delete " + username + "?"; var info = "Are you sure you want to delete user " + username + "?";
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 () {
var postdata = { var postdata = {
'action': 'delete_user', 'action': 'delete_user',
'data': username, 'data': username,
'_csrf_token': '{{ csrf_token() }}' '_csrf_token': '{{ csrf_token() }}'
} }
applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-user', false, true); applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-user', false, true);
modal.modal('hide'); modal.modal('hide');
}) })
modal.modal('show'); modal.modal('show');
}); });
// handle user role changing // handle user role changing
$(document.body).on('change', '.user_role', function () { $(document.body).on('change', '.user_role', function () {
var role_name = this.value; var role_name = this.value;
var username = $(this).prop('id'); var username = $(this).prop('id');
var postdata = { var postdata = {
'action': 'update_user_role', 'action': 'update_user_role',
'data': { 'data': {
'username': username, 'username': username,
'role_name': role_name 'role_name': role_name
}, },
'_csrf_token': '{{ csrf_token() }}' '_csrf_token': '{{ csrf_token() }}'
}; };
applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-user', showResult = true); applyChanges(postdata, $SCRIPT_ROOT + '/admin/manage-user', showResult = true);
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
<div class="modal fade modal-warning" id="modal_revoke"> <div class="modal fade modal-warning" id="modal_revoke">
<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></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" id="button_revoke_confirm">Revoke</button>
</div>
</div> </div>
<!-- /.modal-content --> <div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger" id="button_revoke_confirm">Revoke</button>
</div>
</div>
</div> </div>
<!-- /.modal-dialog --> </div>
</div>
<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" 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></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" 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-default pull-left" 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>
{% endblock %} {% endblock %}

View File

@ -1,136 +1,127 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_console" %} {% set active_page = "admin_console" %}
{% block title %}<title>Admin Console - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Admin Console - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) --> <div class="content-header">
<section class="content-header">
<h1>
PowerDNS server configuration & statistics
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Admin Console</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 PowerDNS
<small>Control panel</small> <small>Server Statistics & Configuration</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 active">PowerDNS Server Statistics & Configuration</li>
</ol> </ol>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="row"> <div class="container-fluid">
<div class="col-xs-12"> <div class="row">
<div class="box"> <div class="col-12">
<div class="box-header"> <div class="card">
<h3 class="box-title">PDNS Statistics</h3> <div class="card-header">
</div> <h3 class="card-title">PowerDNS Server Statistics</h3>
<div class="box-body">
<table id="tbl_statistics" class="table table-bordered table-striped">
<thead>
<tr>
<th width="6%">Docs</th>
<th>Statistic</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for statistic in statistics %}
<tr class="odd gradeX">
<td><a href="https://doc.powerdns.com/authoritative/search.html?q={{ statistic['name'] }}"
target="_blank" class="btn btn-flat btn-xs blue"><i
class="fa fa-search"></i></a></td>
<td>{{ statistic['name'] }}</td>
<td>{{ statistic['value'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div> </div>
<!-- /.box --> <div class="card-body">
</div> <table id="tbl_statistics" class="table table-bordered table-striped">
<!-- /.col --> <thead>
</div> <tr>
<!-- /.row --> <th width="30%">Statistic</th>
<div class="row"> <th>Value</th>
<div class="col-xs-12"> </tr>
<div class="box"> </thead>
<div class="box-header"> <tbody>
<h3 class="box-title">PDNS Configuration</h3> {% for statistic in statistics %}
</div> <tr class="odd gradeX">
<div class="box-body"> <td>
<table id="tbl_configuration" class="table table-bordered table-striped"> <a href="https://doc.powerdns.com/authoritative/search.html?q={{ statistic['name'] }}"
<thead> target="_blank" class="btn btn-primary">
<tr> <i class="fa fa-search"></i>&nbsp;{{ statistic['name'] }}
<th width="6%">Docs</th> </a>
<th>Statistic</th> </td>
<th>Value</th> <td>{{ statistic['value'] }}</td>
</tr> </tr>
</thead> {% endfor %}
<tbody> </tbody>
{% for config in configs %} </table>
<tr class="odd gradeX">
<td><a href="https://doc.powerdns.com/authoritative/search.html?q={{ config['name'] }}"
target="_blank" class="btn btn-flat btn-xs blue"><i
class="fa fa-search"></i></a></td>
<td>{{ config['name'] }}</td>
<td>
{{ config['value'] }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div> </div>
<!-- /.box --> </div>
</div> </div>
<!-- /.col --> </div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">PowerDNS Server Configuration</h3>
</div>
<div class="card-body">
<table id="tbl_configuration" class="table table-bordered table-striped">
<thead>
<tr>
<th width="30%">Configuration</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for config in configs %}
<tr class="odd gradeX">
<td>
<a href="https://doc.powerdns.com/authoritative/search.html?q={{ config['name'] }}"
target="_blank" class="btn btn-primary">
<i class="fa fa-search"></i>&nbsp;{{ config['name'] }}
</a>
</td>
<td>
{{ config['value'] }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div> </div>
<!-- /.row --> </section>
</section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// set up statistics data table // set up statistics data table
$("#tbl_statistics").DataTable({ $("#tbl_statistics").DataTable({
"paging": true, "paging": true,
"lengthChange": false, "lengthChange": true,
"searching": true, "searching": true,
"ordering": true, "ordering": true,
"info": true, "info": true,
"autoWidth": false "autoWidth": false
}); });
// set up configuration data table // set up configuration data table
$("#tbl_configuration").DataTable({ $("#tbl_configuration").DataTable({
"paging": true, "paging": true,
"lengthChange": false, "lengthChange": true,
"searching": true, "searching": true,
"ordering": true, "ordering": true,
"info": true, "info": true,
"autoWidth": false "autoWidth": false
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,9 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_settings" %} {% set active_page = "admin_settings" %}
{% block title %} {% block title %}
<title>Basic Settings - {{ SITE_NAME }}</title> <title>
{% endblock %} {% block dashboard_stat %} Basic Settings - {{ SITE_NAME }}
<!-- Content Header (Page header) --> </title>
{% endblock %}
{% block dashboard_stat %}
<div class="content-header"> <div class="content-header">
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
@ -22,8 +27,9 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %}
{% endblock %} {% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="card"> <div class="card">
@ -34,9 +40,9 @@
<table id="tbl_settings" class="table table-bordered table-striped"> <table id="tbl_settings" class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Setting Name</th>
<th>Value</th> <th>Current Value</th>
<th>Change</th> <th>Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -45,12 +51,18 @@
<td> <td>
{{ setting }} {{ setting }}
</td> </td>
{% if SETTING.get(setting) in [True, False] %} {% if SETTING.get(setting) in [False] %}
<td>{{ SETTING.get(setting)|display_setting_state }}</td> <td>{{ SETTING.get(setting)|display_setting_state }}</td>
<td width="6%"> <td width="6%">
<button type="button" class="btn btn-warning setting-toggle-button" id="{{ setting }}"> <button type="button" class="btn btn-success setting-toggle-button" id="{{ setting }}">
Toggle <i class="fas fa-toggle-on"></i>&nbsp;Turn On
<i class="fa fa-info"></i> </button>
</td>
{% elif SETTING.get(setting) in [True] %}
<td>{{ SETTING.get(setting)|display_setting_state }}</td>
<td width="6%">
<button type="button" class="btn btn-danger setting-toggle-button" id="{{ setting }}">
<i class="fas fa-toggle-off"></i>&nbsp;Turn Off
</button> </button>
</td> </td>
{% else %} {% else %}
@ -58,9 +70,8 @@
<input name="value" id="value" value="{{ SETTING.get(setting) }}"> <input name="value" id="value" value="{{ SETTING.get(setting) }}">
</td> </td>
<td width="6%"> <td width="6%">
<button type="button" class="btn btn-warning setting-save-button" id="{{ setting }}"> <button type="button" class="btn btn-primary setting-save-button" id="{{ setting }}">
Save <i class="fas fa-save"></i>&nbsp;Save
<i class="fa fa-info"></i>
</button> </button>
</td> </td>
{% endif %} {% endif %}
@ -73,32 +84,33 @@
</div> </div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// set up history data table // set up history data table
$("#tbl_settings").DataTable({ $("#tbl_settings").DataTable({
"paging": false, "paging": false,
"lengthChange": false, "lengthChange": false,
"searching": true, "searching": true,
"ordering": true, "ordering": true,
"info": true, "info": true,
"autoWidth": false "autoWidth": false
}); });
$(document.body).on('click', '.setting-toggle-button', function () { $(document.body).on('click', '.setting-toggle-button', function () {
var setting = $(this).prop('id'); var setting = $(this).prop('id');
applyChanges({ applyChanges({
'_csrf_token': '{{ csrf_token() }}' '_csrf_token': '{{ csrf_token() }}'
}, $SCRIPT_ROOT + '/admin/setting/basic/' + setting + '/toggle', false, true) }, $SCRIPT_ROOT + '/admin/setting/basic/' + setting + '/toggle', false, true)
}); });
$(document.body).on('click', '.setting-save-button', function () { $(document.body).on('click', '.setting-save-button', function () {
var setting = $(this).prop('id'); var setting = $(this).prop('id');
var value = $(this).parents('tr').find('#value')[0].value; var value = $(this).parents('tr').find('#value')[0].value;
var postdata = { var postdata = {
'value': value, 'value': value,
'_csrf_token': '{{ csrf_token() }}' '_csrf_token': '{{ csrf_token() }}'
}; };
applyChanges(postdata, $SCRIPT_ROOT + '/admin/setting/basic/' + setting + '/edit', false, true) applyChanges(postdata, $SCRIPT_ROOT + '/admin/setting/basic/' + setting + '/edit', false, true)
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,93 +1,108 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_settings" %} {% set active_page = "admin_settings" %}
{% block title %} {% block title %}
<title>PDNS Settings - {{ SITE_NAME }}</title> <title>
{% endblock %} {% block dashboard_stat %} PDNS Settings - {{ SITE_NAME }}
<!-- Content Header (Page header) --> </title>
<div class="content-header">
<h1>
Settings <small>PowerDNS-Admin settings</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li><a href="#">Setting</a></li>
<li class="active">PDNS</li>
</ol>
</div>
{% endblock %} {% endblock %}
{% block content %}
<section class="content"> {% block dashboard_stat %}
<div class="row"> <div class="content-header">
<div class="col-md-4"> <div class="container-fluid">
<div class="box box-primary"> <div class="row mb-2">
<div class="box-header with-border"> <div class="col-sm-6">
<h3 class="box-title">PDNS Settings</h3> <h1 class="m-0 text-dark">
</div> Settings
<!-- /.box-header --> <small>PowerDNS Authoritative Server</small>
<!-- form start --> </h1>
<form role="form" method="post" data-toggle="validator">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<div class="box-body">
{% if not SETTING.get('pdns_api_url') or not SETTING.get('pdns_api_key') or not SETTING.get('pdns_version') %}
<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>
Please complete your PowerDNS API configuration before continuing
</div>
{% endif %}
<div class="form-group has-feedback">
<label class="control-label" for="pdns_api_url">PDNS API URL</label>
<input type="url" class="form-control" placeholder="PowerDNS API url" name="pdns_api_url"
data-error="Please input a valid PowerDNS API URL" required value="{{ pdns_api_url }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pdns_api_key">PDNS API KEY</label>
<input type="password" class="form-control" placeholder="PowerDNS API key"
name="pdns_api_key" data-error="Please input a valid PowerDNS API key" required
value="{{ pdns_api_key }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pdns_version">PDNS VERSION</label>
<input type="text" class="form-control" placeholder="PowerDNS version" name="pdns_version"
data-error="Please input PowerDNS version" required value="{{ pdns_version }}">
<span class="help-block with-errors"></span>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-flat btn-primary">Update</button>
</div>
</form>
</div>
</div> </div>
<div class="col-md-8"> <div class="col-sm-6">
<div class="box box-primary"> <ol class="breadcrumb float-sm-right">
<div class="box-header with-border"> <li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<h3 class="box-title">Help</h3> <li class="breadcrumb-item active">Settings - PowerDNS Authoritative Server</li>
</div> </ol>
<div class="box-body">
<dl class="dl-horizontal">
<p>You must configure the API connection information before PowerDNS-Admin can query your
PowerDNS data. Following fields are required:</p>
<dt>PDNS API URL</dt>
<dd>Your PowerDNS API URL (eg. http://127.0.0.1:8081/).</dd>
<dt>PDNS API KEY</dt>
<dd>Your PowerDNS API key.</dd>
<dt>PDNS VERSION</dt>
<dd>Your PowerDNS version number (eg. 4.1.1).</dd>
</dl>
<p>Find more details at <a
href="https://doc.powerdns.com/md/httpapi/README/">https://doc.powerdns.com/md/httpapi/README/</a>
</p>
</div>
</div>
</div> </div>
</div>
</div> </div>
</section> </div>
{% endblock %} {% endblock %}
{% block content %}
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-4">
<div class="card card-primary">
<div class="card-header with-border">
<h3 class="card-title">PDNS Settings</h3>
</div>
<form role="form" method="post" data-toggle="validator">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<div class="card-body">
{% if not SETTING.get('pdns_api_url') or not SETTING.get('pdns_api_key') or not SETTING.get('pdns_version') %}
<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>
Please complete your PowerDNS API configuration before continuing
</div>
{% endif %}
<div class="form-group has-feedback">
<label class="control-label" for="pdns_api_url">PowerDNS API URL</label>
<input type="url" class="form-control" placeholder="PowerDNS API URL" name="pdns_api_url"
data-error="Please input a valid PowerDNS API URL" required value="{{ pdns_api_url }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pdns_api_key">PowerDNS API Key</label>
<input type="password" class="form-control" placeholder="PowerDNS API Key"
name="pdns_api_key" data-error="Please input a valid PowerDNS API key" required
value="{{ pdns_api_key }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pdns_version">PowerDNS Version</label>
<input type="text" class="form-control" placeholder="PowerDNS Version" name="pdns_version"
data-error="Please input PowerDNS version" required value="{{ pdns_version }}">
<span class="help-block with-errors"></span>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary"><i class="fas fa-save"></i>&nbsp;Update</button>
</div>
</form>
</div>
</div>
<div class="col-8">
<div class="card card-primary">
<div class="card-header with-border">
<h3 class="card-title">Help</h3>
</div>
<div class="card-body">
<dl class="dl-horizontal">
<p>You must configure the API connection information before PowerDNS-Admin can query your
PowerDNS data. Following fields are required:</p>
<dt>PowerDNS API URL</dt>
<dd>Your PowerDNS API URL (eg. http://127.0.0.1:8081/).</dd>
<dt>PowerDNS API Key</dt>
<dd>Your PowerDNS API key.</dd>
<dt>PowerDNS Version</dt>
<dd>Your PowerDNS version number (eg. 4.1.1).</dd>
</dl>
<p>Find more details at
<a href="https://doc.powerdns.com/md/httpapi/README/">https://doc.powerdns.com/md/httpapi/README/</a>
</p>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %} {% block extrascripts %}
{% assets "js_validation" -%} {% assets "js_validation" -%}
<script type="text/javascript" src="{{ ASSET_URL }}"></script> <script type="text/javascript" src="{{ ASSET_URL }}"></script>
{%- endassets %} {%- endassets %}
{% endblock %} {% endblock %}

View File

@ -1,83 +1,99 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_settings" %} {% set active_page = "admin_settings" %}
{% block title %} {% block title %}
<title>DNS Records Settings - {{ SITE_NAME }}</title> <title>
{% endblock %} {% block dashboard_stat %} DNS Records Settings - {{ SITE_NAME }}
<!-- Content Header (Page header) --> </title>
<section class="content-header">
<h1>
Settings <small>PowerDNS-Admin settings</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li><a href="#">Setting</a></li>
<li class="active">Records</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">
Settings
<small>Records</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">Settings - Records </li>
</ol>
</div>
</div>
</div>
</div>
{% 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-5"> <div class="col-5">
<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">DNS record Settings</h3> <h3 class="card-title">DNS record Settings</h3>
</div> </div>
<!-- /.box-header --> <form role="form" method="post">
<!-- form start --> <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<form role="form" method="post"> <input type="hidden" name="create" value="{{ create }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <div class="card-body">
<input type="hidden" name="create" value="{{ create }}"> <table class="table table-bordered">
<div class="box-body"> <tr>
<table class="table table-bordered"> <th style="width: 10px">#</th>
<tr> <th style="width: 40px">Record</th>
<th style="width: 10px">#</th> <th>Forward Zone</th>
<th style="width: 40px">Record</th> <th>Reverse Zone</th>
<th>Forward Zone</th> </tr>
<th>Reverse Zone</th> {% for record in f_records %}
</tr> <tr>
{% for record in f_records %} <td>{{ loop.index }}</td>
<tr> <td>{{ record }}</td>
<td>{{ loop.index }}</td> <td>
<td>{{ record }}</td> <input type="checkbox" id="fr_{{ record|lower }}" name="fr_{{ record|lower }}"
<td> class="checkbox" {% if f_records[record] %}checked{% endif %}>
<input type="checkbox" id="fr_{{ record|lower }}" name="fr_{{ record|lower }}" </td>
class="checkbox" {% if f_records[record] %}checked{% endif %}> <td>
</td> <input type="checkbox" id="rr_{{ record|lower }}" name="rr_{{ record|lower }}"
<td> class="checkbox" {% if r_records[record] %}checked{% endif %}>
<input type="checkbox" id="rr_{{ record|lower }}" name="rr_{{ record|lower }}" </td>
class="checkbox" {% if r_records[record] %}checked{% endif %}> </tr>
</td> {% endfor %}
</tr> </table>
{% endfor %}
</table>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-flat btn-primary">Update</button>
</div>
</form>
</div> </div>
</div> <div class="card-footer">
<div class="col-md-7"> <button type="submit" class="btn btn-flat btn-primary">Update</button>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Help</h3>
</div>
<div class="box-body">
<p>Select record types you allow user to edit in the forward zone and reverse zone. Take a look at
<a href="https://doc.powerdns.com/authoritative/appendices/types.html">PowerDNS docs</a> for
full list of supported record types.</p>
</div>
</div> </div>
</form>
</div> </div>
</div>
<div class="col-7">
<div class="card card-primary">
<div class="card-header with-border">
<h3 class="card-title">Help</h3>
</div>
<div class="card-body">
<p>Select record types you allow user to edit in the forward zone and reverse zone. Take a look at
<a href="https://doc.powerdns.com/authoritative/appendices/types.html">PowerDNS docs</a> for
full list of supported record types.
</p>
</div>
</div>
</div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
$('.checkbox').iCheck({ $('.checkbox').iCheck({
checkboxClass: 'icheckbox_square-blue', checkboxClass: 'icheckbox_square-blue',
increaseArea: '20%' increaseArea: '20%'
}) })
</script> </script>
{% endblock %} {% endblock %}

View File

@ -137,7 +137,7 @@
<li class="{{ 'nav-item active' if active_page == 'admin_console' else 'nav-item' }}"> <li class="{{ 'nav-item active' if active_page == 'admin_console' else 'nav-item' }}">
<a href="{{ url_for('admin.pdns_stats') }}" class="nav-link"> <a href="{{ url_for('admin.pdns_stats') }}" class="nav-link">
<i class="nav-icon fas fa-info-circle"></i> <i class="nav-icon fas fa-info-circle"></i>
<p>PDNS</p> <p>PowerDNS Info</p>
</a> </a>
</li> </li>
<li class="{{ 'nav-item active' if active_page == 'admin_global_search' else 'nav-item' }}"> <li class="{{ 'nav-item active' if active_page == 'admin_global_search' else 'nav-item' }}">
@ -201,7 +201,7 @@
<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 far fa-circle"></i> <i class="nav-icon far fa-circle"></i>
<p>PDNS</p> <p>PowerDNS Connection</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">

View File

@ -36,7 +36,7 @@
{% 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-3"> <div class="col-3">
<div class="card"> <div class="card shadow card-outline card-secondary">
<div class="card-header"> <div class="card-header">
<h3 class="card-title">Statistics</h3> <h3 class="card-title">Statistics</h3>
</div> </div>
@ -104,7 +104,7 @@
</div> </div>
</div> </div>
<div class="col-9"> <div class="col-9">
<div class="card"> <div class="card shadow card-outline card-secondary">
<div class="card-header"> <div class="card-header">
<h3 class="card-title">Recent History</h3> <h3 class="card-title">Recent History</h3>
</div> </div>
@ -151,35 +151,34 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
<!--SYBPATCH START--> <div class="row">
<row> <div class="col-12">
<div class="nav-tabs-custom"> <div class="card shadow card-outline card-secondary">
<ul class="nav nav-tabs" id="custom-content-below-tab" role="tablist"> <div class="card-header">
<li class="nav-link"> <div class="nav-tabs-custom">
<a href="#tab_{{custom_boxes.order[0]}}"data-toggle="pill" role="tab"> <ul class="nav nav-tabs" id="custom-content-below-tab" role="tablist">
Hosted Domains <b>{{custom_boxes.boxes[custom_boxes.order[0]][0]}}</b> <li class="nav-item">
</a> <a class="nav-link active" href="#tab_{{custom_boxes.order[0]}}" data-toggle="pill" role="tab">
</li> Hosted Domains <b>{{custom_boxes.boxes[custom_boxes.order[0]][0]}}</b>
{% for boxId in custom_boxes.order[1:] %} </a>
<li class="nav-link" > </li>
<a href="#tab_{{boxId}}" data-toggle="pill" role="tab">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></a> {% for boxId in custom_boxes.order[1:] %}
</li> <li class="nav-item" >
{% endfor %} <a class="nav-link" href="#tab_{{boxId}}" data-toggle="pill" role="tab">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></a>
</ul> </li>
<div class="tab-content"> {% endfor %}
{% for boxId in custom_boxes.order %} </ul>
<div class="tab-pane" id='tab_{{boxId}}'> <div class="tab-content">
<div class="row"> {% for boxId in custom_boxes.order %}
<div class="col-12"> <div class="tab-pane" id='tab_{{boxId}}'>
<div class="card">
<div class="card-header"> <div class="card-header">
<h3 class="card-title">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></h3> <h3 class="card-title">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></h3>
{% if show_bg_domain_button %} {% if show_bg_domain_button %}
<button type="button" class="btn btn-primary refresh-bg-button float-right"> <button type="button" class="btn btn-primary refresh-bg-button float-right">
<i class="fas fa-sync"></i> <i class="fas fa-sync"></i>
&nbsp;Sync domains &nbsp;Sync domains
</button> </button>
{% endif %} {% endif %}
</div> </div>
<div class="card-body"> <div class="card-body">
<table id='tbl_domain_list_{{boxId}}' class="table table-bordered table-striped"> <table id='tbl_domain_list_{{boxId}}' class="table table-bordered table-striped">
@ -191,23 +190,22 @@
<th>Serial</th> <th>Serial</th>
<th>Master</th> <th>Master</th>
<th>Account</th> <th>Account</th>
<th>Action</th> <th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> {% endfor %}
</div> </div>
</div> </div>
{% endfor %} </div>
</div><!-- /.tab-content --> </div>
</div><!-- custom tabs --> </div>
<!--SYBPATCH END--> </div>
</row> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
@ -217,7 +215,7 @@
function setUpDomainList(id ,url){ function setUpDomainList(id ,url){
$(id).DataTable({ $(id).DataTable({
"paging" : true, "paging" : true,
"lengthChange" : false, "lengthChange" : true,
language: { language: {
searchPlaceholder: "Use ^ and $ for start and end", searchPlaceholder: "Use ^ and $ for start and end",
}, },

View File

@ -33,8 +33,8 @@
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-4">
<div class="card card-outline card-secondary"> <div class="card shadow card-outline card-secondary">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">Create new domain</h3> <h3 class="card-title">Create new domain</h3>
</div> </div>
@ -128,8 +128,8 @@
</form> </form>
</div> </div>
</div> </div>
<div class="col-md-8"> <div class="col-8">
<div class="card card-outline card-secondary"> <div class="card shadow card-outline card-secondary">
<div class="card-header with-border"> <div class="card-header with-border">
<h3 class="card-title">Help with creating a new domain</h3> <h3 class="card-title">Help with creating a new domain</h3>
</div> </div>

View File

@ -1,5 +1,10 @@
{% 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 %}
<div class="content-header"> <div class="content-header">
@ -31,7 +36,7 @@
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<button type="button" class="btn btn-primary pull-left button_show_records" id="{{ domain.name }}"> <button type="button" class="btn btn-primary pull-left button_show_records" id="{{ domain.name }}">

View File

@ -33,9 +33,9 @@
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-4">
<div class="card card-outline card-secondary"> <div class="card shadow card-outline card-secondary">
<div class="card-header with-border"> <div class="card-header">
<h3 class="card-title">Remove domain</h3> <h3 class="card-title">Remove domain</h3>
</div> </div>
<form role="form" method="post" action="{{ url_for('domain.remove') }}"> <form role="form" method="post" action="{{ url_for('domain.remove') }}">
@ -58,9 +58,9 @@
</form> </form>
</div> </div>
</div> </div>
<div class="col-md-8"> <div class="col-8">
<div class="card card-outline card-secondary"> <div class="card shadow card-outline card-secondary">
<div class="card-header with-border"> <div class="card-header">
<h3 class="card-title">Help with removing a new domain</h3> <h3 class="card-title">Help with removing a new domain</h3>
</div> </div>
<div class="card-body"> <div class="card-body">

View File

@ -1,7 +1,13 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}<title>Domain Management - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Domain Management - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
{% if status %} {% if status %}
{% if status.get('status') == 'ok' %} {% if status.get('status') == 'ok' %}
<div class="alert alert-success"> <div class="alert alert-success">
@ -31,7 +37,7 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-12">
<div class="box"> <div class="box">
<form method="post" action="{{ url_for('domain.setting', domain_name=domain.name) }}"> <form method="post" action="{{ url_for('domain.setting', domain_name=domain.name) }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">

View File

@ -28,98 +28,121 @@
</div> </div>
<div class="card-body"> <div class="card-body">
{% if error %} {% if error %}
<div class="alert alert-danger alert-dismissible"> <div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
{{ error }} {{ error }}
</div> </div>
{% endif %} {% endif %}
<p class="login-box-msg">Enter your personal details below</p> <p class="login-box-msg">Enter your personal details below</p>
<form action="{{ url_for('index.register') }}" method="post" class="needs-validation" novalidate> <form action="{{ url_for('index.register') }}" method="post" novalidate>
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<div class="input-group mb-3"> <div class="form-group">
<input type="text" class="form-control" placeholder="First Name" name="firstname" id="firstname" required> <div class="input-group mb-3">
<div class="input-group-append"> <div class="input-group-prepend">
<div class="input-group-text"> <span class="input-group-text">
<span class="fas fa-user"></span> <i class="fas fa-user"></i>
</span>
</div> </div>
</div> <input type="text" class="form-control {{ 'is-invalid' if 'firstname' in error_messages else '' }}" placeholder="First Name" name="firstname" id="firstname" value="{{ request.form.firstname }}" required>
<div class="invalid-feedback"> {% if 'firstname' in error_messages %}
Please input your first name <div class="invalid-feedback">
{{ error_messages['firstname'] }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="input-group mb-3"> <div class="form-group">
<input type="text" class="form-control" placeholder="Last name" name="lastname" id="lastname" required> <div class="input-group mb-3">
<div class="input-group-append"> <div class="input-group-prepend">
<div class="input-group-text"> <span class="input-group-text">
<span class="fas fa-user"></span> <i class="fas fa-user"></i>
</span>
</div> </div>
</div> <input type="text" class="form-control {{ 'is-invalid' if 'lastname' in error_messages else '' }}" placeholder="Last name" name="lastname" id="lastname" value="{{ request.form.lastname }}" required>
<div class="invalid-feedback"> {% if 'lastname' in error_messages %}
Please input your last name <div class="invalid-feedback">
{{ error_messages['lastname'] }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="input-group mb-3"> <div class="form-group">
<input type="email" class="form-control" placeholder="Email" name="email" id="email" required> <div class="input-group mb-3">
<div class="input-group-append"> <div class="input-group-prepend">
<div class="input-group-text"> <span class="input-group-text">
<span class="fas fa-envelope"></span> <i class="fas fa-envelope"></i>
</span>
</div> </div>
</div> <input type="email" class="form-control {{ 'is-invalid' if 'email' in error_messages else '' }}" placeholder="Email" name="email" id="email" value="{{ request.form.email }}" required>
<div class="invalid-feedback"> {% if 'email' in error_messages %}
Please input a valid email address <div class="invalid-feedback">
<i class="fas fa-exclamation-triangle"></i>
{{ error_messages['email'] }}
</div>
{% endif %}
</div> </div>
</div> </div>
<p class="login-box-msg">Enter your account details below</p> <p class="login-box-msg">Enter your account details below</p>
<div class="input-group mb-3"> <div class="form-group">
<input type="text" class="form-control" placeholder="Username" name="username" id="username" required> <div class="input-group mb-3">
<div class="input-group-append"> <div class="input-group-prepend">
<div class="input-group-text"> <span class="input-group-text">
<span class="fas fa-user"></span> <i class="fas fa-user"></i>
</span>
</div> </div>
</div> <input type="text" class="form-control {{ 'is-invalid' if 'username' in error_messages else '' }}" placeholder="Username" name="username" id="username" value="{{ request.form.username }}" required>
<div class="invalid-feedback"> {% if 'email' in error_messages %}
Please input desired username <div class="invalid-feedback">
{{ error_messages['username'] }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="input-group mb-3"> <div class="form-group">
<input type="password" class="form-control" placeholder="Password" id="password" name="password" id="password" required> <div class="input-group mb-3">
<div class="input-group-append"> <div class="input-group-prepend">
<div class="input-group-text"> <span class="input-group-text">
<span class="fas fa-lock"></span> <i class="fas fa-lock"></i>
</span>
</div> </div>
</div> <input type="password" class="form-control {{ 'is-invalid' if 'password' in error_messages else '' }}" placeholder="Password" id="password" name="password" required>
<div class="invalid-feedback"> {% if 'email' in error_messages %}
Please input desired username <div class="invalid-feedback">
{{ error_messages['password'] }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="form-group">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-lock"></i>
</span>
</div>
<input type="password" class="form-control {{ 'is-invalid' if 'rpassword' in error_messages else '' }}" placeholder="Retype password" id="rpassword" name="rpassword" required>
{% if 'rpassword' in error_messages %}
<div class="invalid-feedback">
{{ error_messages['rpassword'] }}
</div>
{% endif %}
</div>
</div>
<div class="form-group has-feedback"> {% if captcha_enable %}
<input type="password" class="form-control" placeholder="Retype password" name="rpassword" data-match="#password" data-match-error="Password confirmation does not match" required> <p class="login-box-msg">Please complete the CAPTCHA below</p>
<span class="fas fa-lock form-control-feedback"></span> <div class="form-group has-feedback">
<span class="help-block with-errors"></span>
</div>
{% if captcha_enable %}
<div class="input-group mb-3">
<p class="login-box-msg">Please complete the CAPTCHA below</p>
{{ captcha() }} {{ captcha() }}
<br> <input type="text" class="form-control" placeholder="CAPTCHA" name="captcha"
<input type="text" class="form-control" placeholder="CAPTCHA" id="captcha" name="captcha" required> data-error="Please complete the CAPTCHA" required>
<div class="input-group-append"> <span class="help-block with-errors"></span>
<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 %}
@ -133,7 +156,7 @@
</div> </div>
</form> </form>
</div> </div>
<div class="login--footer"> <div class="login-box-footer">
<center> <center>
<p>Powered by <a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin">PowerDNS-Admin</a></p> <p>Powered by <a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin">PowerDNS-Admin</a></p>
</center> </center>
@ -151,24 +174,6 @@
window.location.href = '{{ url_for('index.login') }}'; window.location.href = '{{ url_for('index.login') }}';
}) })
}); });
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script> </script>
</body> </body>
</html> </html>

View File

@ -1,108 +1,121 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_domain_template" %} {% set active_page = "admin_domain_template" %}
{% block title %}<title>Templates - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Templates - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header"> <div class="content-header">
<h1> <div class="container-fluid">
Templates <div class="row mb-2">
<small>List</small> <div class="col-sm-6">
</h1> <h1 class="m-0 text-dark">
<ol class="breadcrumb"> Templates
<li><a href="{{ url_for('admin.templates') }}"><i class="fa fa-dashboard"></i> Templates</a></li> <small>List</small>
<li class="active">List</li> </h1>
</ol> </div>
</section> <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">Templates - List</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<!-- Main content -->
<section class="content"> <section class="content">
{% with errors = get_flashed_messages(category_filter=["error"]) %} {% if errors %} <div class="container-fluid">
<div class="row"> {% with errors = get_flashed_messages(category_filter=["error"]) %}
<div class="col-md-12"> {% if errors %}
<div class="alert alert-danger alert-dismissible"> <div class="row">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <div class="col-12">
<h4> <div class="alert alert-danger alert-dismissible">
<i class="icon fa fa-ban"></i> Error! <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
</h4> <h4>
<div class="alert-message block-message error"> <i class="icon fa fa-ban"></i> Error!
<a class="close" href="#">x</a> </h4>
<ul> <div class="alert-message block-message error">
{%- for msg in errors %} <a class="close" href="#">x</a>
<li>{{ msg }}</li> {% endfor -%} <ul>
</ul> {%- for msg in errors %}
<li>{{ msg }}</li>
{% endfor -%}
</ul>
</div>
</div>
</div>
</div>
{% endif %}
{% endwith %}
<div class="row">
<div class="col-12">
<div class="card shadow card-outline card-secondary">
<div class="card-header">
<h3 class="card-title">Templates</h3>
<a href="{{ url_for('admin.create_template') }}">
<button type="button" class="btn btn-primary float-right">
<i class="fa fa-plus"></i>&nbsp;Create Template
</button>
</a>
</div>
<div class="card-body">
<table id="tbl_template_list" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Number of Records</th>
<th width="20%">Action</th>
</tr>
</thead>
<tbody>
{% for template in templates %}
<tr>
<td>
<a href="{{ url_for('admin.edit_template', template=template.name) }}">
<strong>{{ template.name }}</strong>
</a>
</td>
<td>
{{ template.description }}
</td>
<td>
{{ template.records|count }}
</td>
<td>
<a href="{{ url_for('admin.edit_template', template=template.name) }}">
<button type="button" class="btn btn-warning button_edit" id="btn_edit">
Edit&nbsp;<i class="fa fa-edit"></i>
</button>
</a>
<button type="button" class="btn btn-danger button_delete" id="{{template.name}}">
Delete&nbsp;<i class="fa fa-trash"></i>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endif %} {% endwith %}
<div class="row">
<div class="container-fluid">
<div class="col-xs-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Templates</h3>
</div>
<div class="card-body">
<a href="{{ url_for('admin.create_template') }}">
<button type="button" class="btn btn-flat btn-primary pull-left">
Create Template&nbsp;<i class="fa fa-plus"></i>
</button>
</a>
</div>
<div class="card-body">
<table id="tbl_template_list" class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Number of Records</th>
<th width="20%">Action</th>
</tr>
</thead>
<tbody>
{% for template in templates %}
<tr>
<td>
<a
href="{{ url_for('admin.edit_template', template=template.name) }}"><strong>{{ template.name }}</strong></a>
</td>
<td>
{{ template.description }}
</td>
<td>
{{ template.records|count }}
</td>
<td>
<a href="{{ url_for('admin.edit_template', template=template.name) }}">
<button type="button" class="btn btn-warning button_edit" id="btn_edit">
Edit&nbsp;<i class="fa fa-edit"></i>
</button>
</a>
<button type="button" class="btn btn-danger button_delete" id="{{template.name}}">
Delete&nbsp;<i class="fa fa-trash"></i>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
</div>
<!-- /.row -->
</section> </section>
<!-- /.content -->
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
// set up history data table // set up template data table
$("#tbl_template_list").DataTable({ $("#tbl_template_list").DataTable({
"paging": true, "paging": true,
"lengthChange": true, "lengthChange": true,
@ -111,6 +124,7 @@
"info": false, "info": false,
"autoWidth": false "autoWidth": false
}); });
// handle delete button // handle delete button
$(document.body).on("click", ".button_delete", function (e) { $(document.body).on("click", ".button_delete", function (e) {
var template = $(this).prop('id'); var template = $(this).prop('id');
@ -119,9 +133,9 @@
}, function () { }, function () {
window.location.href = '{{ url_for('admin.templates') }}'; window.location.href = '{{ url_for('admin.templates') }}';
}); });
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
{% endblock %} {% endblock %}

View File

@ -1,9 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_domain_template" %} {% set active_page = "admin_domain_template" %}
{% block title %}<title>Create Template - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Create Template - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<div class="content-header"> <div class="content-header">
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
@ -22,91 +27,88 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
{% with errors = get_flashed_messages(category_filter=["error"]) %} {% {% with errors = get_flashed_messages(category_filter=["error"]) %}
if errors %} {% if errors %}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-12">
<div class="alert alert-danger alert-dismissible"> <div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<h4> <h4>
<i class="icon fa fa-ban"></i> Error! <i class="icon fa fa-ban"></i> Error!
</h4> </h4>
<div class="alert-message block-message error"> <div class="alert-message block-message error">
<a class="close" href="#">x</a> <a class="close" href="#">x</a>
<ul> <ul>
{%- for msg in errors %} {%- for msg in errors %}
<li>{{ msg }}</li> {% endfor -%} <li>{{ msg }}</li>
</ul> {% endfor -%}
</div> </ul>
</div> </div>
</div> </div>
</div> </div>
{% endif %} {% endwith %} {% endif %}
{% endwith %}
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-4">
<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">Create new template</h3> <h3 class="card-title">Create new template</h3>
</div> </div>
<!-- /.box-header --> <form role="form" method="post" action="{{ url_for('admin.create_template') }}">
<!-- form start --> <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<form role="form" method="post" action="{{ url_for('admin.create_template') }}"> <div class="box-body">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> <div class="form-group">
<div class="box-body"> <input type="text" class="form-control" name="name" id="name"
<div class="form-group"> placeholder="Enter a valid template name (required)">
<input type="text" class="form-control" name="name" id="name" </div>
placeholder="Enter a valid template name (required)"> <div class="form-group">
</div> <input type="text" class="form-control" name="description" id="description"
<div class="form-group"> placeholder="Enter a template description (optional)">
<input type="text" class="form-control" name="description" id="description" </div>
placeholder="Enter a template description (optional)"> </div>
</div> <div class="box-footer">
</div> <button type="submit" class="btn btn-flat btn-primary">Submit</button>
<div class="box-footer"> <button type="button" class="btn btn-flat btn-default"
<button type="submit" class="btn btn-flat btn-primary">Submit</button> onclick="window.location.href='{{ url_for('admin.templates') }}'">Cancel</button>
<button type="button" class="btn btn-flat btn-default" </div>
onclick="window.location.href='{{ url_for('admin.templates') }}'">Cancel</button> </form>
</div> </div>
</form> </div>
</div> <div class="col-8">
<!-- /.box --> <div class="card card-primary">
</div> <div class="card-header with-border">
<div class="col-md-8"> <h3 class="card-title">Help with creating a new template</h3>
<div class="box box-primary"> </div>
<div class="box-header with-border"> <div class="card-body">
<h3 class="box-title">Help with creating a new template</h3> <dl class="dl-horizontal">
</div> <dt>Template name</dt>
<div class="box-body"> <dd>Enter your template name, this is the name of the template that
<dl class="dl-horizontal"> will be shown to users. The name should not have any spaces but
<dt>Template name</dt> can have symbols.</dd>
<dd>Enter your template name, this is the name of the template that <dt>Template description</dt>
will be shown to users. The name should not have any spaces but <dd>Enter your template description, this is to help better
can have symbols.</dd> identify the template.</dd>
<dt>Template description</dt> </dl>
<dd>Enter your template description, this is to help better </div>
identify the template.</dd> </div>
</dl> </div>
</div> </div>
</div>
</div>
</div>
</section> </section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
$("input[name=radio_type]").change(function () { $("input[name=radio_type]").change(function () {
var type = $(this).val(); var type = $(this).val();
if (type == "slave") { if (type == "slave") {
$("#domain_master_address_div").show(); $("#domain_master_address_div").show();
} else { } else {
$("#domain_master_address_div").hide(); $("#domain_master_address_div").hide();
} }
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,6 +1,12 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_domain_template" %} {% set active_page = "admin_domain_template" %}
{% block title %}<title>Edit Template - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Edit Template - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<section class="content-header"> <section class="content-header">
@ -19,7 +25,7 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-12">
<div class="box"> <div class="box">
<div class="box-header"> <div class="box-header">
<h3 class="box-title">Manage Template Records for {{ template }}</h3> <h3 class="box-title">Manage Template Records for {{ template }}</h3>

View File

@ -30,7 +30,7 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-12">
<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">Edit my profile{% if session['authentication_type'] != 'LOCAL' %} [Disabled - <h3 class="card-title">Edit my profile{% if session['authentication_type'] != 'LOCAL' %} [Disabled -