mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2025-01-09 03:45:39 +00:00
c00ddea2fc
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
456 lines
17 KiB
HTML
456 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" class>
|
|
<head>
|
|
{% block head %}
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<link rel="icon" href="{{ url_for('static', filename='img/favicon.png') }}">
|
|
{% block title %}
|
|
<title>
|
|
{{ SITE_NAME }}
|
|
</title>
|
|
{% endblock %}
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/style.css') }}">
|
|
<!-- Get Google Fonts we like -->
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/source_sans_pro.css') }}">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/roboto_mono.css') }}">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css">
|
|
<!-- Tell the browser to be responsive to screen width -->
|
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
|
<!-- Tell Safari to not recognise telephone numbers -->
|
|
<meta name="format-detection" content="telephone=no">
|
|
{% assets "css_main" -%}
|
|
<link rel="stylesheet" href="{{ ASSET_URL }}">
|
|
{%- endassets %}
|
|
{% if SETTING.get('custom_css') %}
|
|
<link rel="stylesheet" href="/static/custom/{{ SETTING.get('custom_css') }}">
|
|
{% endif %}
|
|
{% endblock %}
|
|
</head>
|
|
|
|
<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) %}
|
|
<div class="wrapper">
|
|
{% block pageheader %}
|
|
<nav class="main-header navbar navbar-expand navbar-dark">
|
|
<!-- Header Navbar: style can be found in header.less -->
|
|
<!-- Sidebar toggle button-->
|
|
<ul class="navbar-nav">
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-widget="pushmenu" href="#" role="button">
|
|
<i class="fas fa-bars"></i>
|
|
</a>
|
|
</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 class="navbar-nav ml-auto">
|
|
<!-- {% if current_user.id is defined %}
|
|
<li class="nav-item dropdown user-menu">
|
|
<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"/>
|
|
<span class="d-none d-md-inline">
|
|
{{ current_user.firstname }} {{ current_user.lastname }}
|
|
</span>
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
<li class="user-header bg-dark">
|
|
<img src="{{ user_image_url }}" class="img-circle elevation-2" alt="User Image"/>
|
|
<p>
|
|
{{ current_user.firstname }} {{ current_user.lastname }}
|
|
<small>{{ current_user.role.name }}</small>
|
|
</p>
|
|
</li>
|
|
<li class="user-footer">
|
|
<a href="{{ url_for('user.profile') }}" class="btn btn-primary">My Profile</a>
|
|
<a href="{{ url_for('index.logout') }}" class="btn btn-warning float-right">Log out</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
{% endif %}
|
|
-->
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-widget="fullscreen" href="#" role="button">
|
|
<i class="fas fa-expand-arrows-alt"></i>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
{% endblock %}
|
|
<!-- Left side column. contains the logo and sidebar -->
|
|
<aside class="main-sidebar sidebar-dark-primary">
|
|
<!-- Logo -->
|
|
<a href="{{ url_for('index.index') }}" class="brand-link">
|
|
<span class="brand-text font-weight-light">
|
|
{% if SETTING.get('site_name') %}
|
|
<b>{{ SITE_NAME }}</b>
|
|
{% else %}
|
|
<b>PowerDNS</b>-Admin
|
|
{% endif %}
|
|
</span>
|
|
</a>
|
|
<!-- sidebar: style can be found in sidebar.less -->
|
|
<div class="sidebar">
|
|
{% if current_user.id is defined %}
|
|
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
|
|
<div class="image">
|
|
<img src="{{ user_image_url }}" class="img-circle elevation-2" alt="User Image">
|
|
</div>
|
|
<div class="info">
|
|
<a href="{{ url_for('user.profile') }}" class="d-block">{{ current_user.firstname }} {{ current_user.lastname }}</a>
|
|
</div>
|
|
</div>
|
|
<!-- sidebar menu: : style can be found in sidebar.less -->
|
|
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu">
|
|
<li class="nav-header">USER ACTIONS</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'nav-item dashboard' else 'nav-item' }}">
|
|
<a href="{{ url_for('dashboard.dashboard') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-tachometer-alt"></i>
|
|
<p>Dashboard</p>
|
|
</a>
|
|
</li>
|
|
{% if SETTING.get('allow_user_create_domain') or current_user.role.name in ['Administrator', 'Operator'] %}
|
|
<li class="{{ 'nav-item active' if active_page == 'nav-item new_domain' else 'nav-item' }}">
|
|
<a href="{{ url_for('domain.add') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-plus"></i>
|
|
<p>New Domain</p>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if SETTING.get('allow_user_remove_domain') or current_user.role.name in ['Administrator', 'Operator'] %}
|
|
<li class="{{ 'nav-item active' if active_page == 'remove_domain' else 'nav-item' }}">
|
|
<a href="{{ url_for('domain.remove') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-trash-alt"></i>
|
|
<p>Remove Domain</p>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if current_user.role.name in ['Administrator', 'Operator'] %}
|
|
<li class="nav-header">ADMINISTRATION</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_console' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.pdns_stats') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-info-circle"></i>
|
|
<p>PowerDNS Info</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_global_search' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.global_search') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-search"></i>
|
|
<p>Global Search</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_history' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.history') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-calendar-alt"></i>
|
|
<p>History</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_domain_template' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.templates') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-clone"></i>
|
|
<p>Domain Templates</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_accounts' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.manage_account') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-industry"></i>
|
|
<p>Accounts</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_users' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.manage_user') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-users"></i>
|
|
<p>Users</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_keys' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.manage_keys') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-key"></i>
|
|
<p>API Keys</p>
|
|
</a>
|
|
</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_settings' else 'nav-item' }}">
|
|
<a href="#" class="nav-link">
|
|
<i class="nav-icon fas fa-cog"></i>
|
|
<p>
|
|
Settings
|
|
<i class="right fas fa-angle-left"></i>
|
|
</p>
|
|
</a>
|
|
<ul class="nav nav-treeview" {% if active_page == 'admin_settings' %}style="display: block;"{% endif %}>
|
|
<li class="nav-item">
|
|
<a href="{{ url_for('admin.setting_basic') }}" class="nav-link">
|
|
<i class="nav-icon far fa-circle"></i>
|
|
<p>Basic</p>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="{{ url_for('admin.setting_records') }}" class="nav-link">
|
|
<i class="nav-icon far fa-circle"></i>
|
|
<p>Records</p>
|
|
</a>
|
|
</li>
|
|
{% if current_user.role.name == 'Administrator' %}
|
|
<li class="nav-item">
|
|
<a href="{{ url_for('admin.setting_pdns') }}" class="nav-link">
|
|
<i class="nav-icon far fa-circle"></i>
|
|
<p>PowerDNS Connection</p>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="{{ url_for('admin.setting_authentication') }}" class="nav-link">
|
|
<i class="nav-icon far fa-circle"></i>
|
|
<p>Authentication</p>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</li>
|
|
{% elif SETTING.get('allow_user_view_history') %}
|
|
<li class="nav-header">ADMINISTRATION</li>
|
|
<li class="{{ 'nav-item active' if active_page == 'admin_history' else 'nav-item' }}">
|
|
<a href="{{ url_for('admin.history') }}" class="nav-link">
|
|
<i class="nav-icon fas fa-calendar-alt"></i>
|
|
<p>History</p>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
{% endif %}
|
|
</div>
|
|
<!-- /.sidebar -->
|
|
</aside>
|
|
|
|
<!-- Content Wrapper. Contains page content -->
|
|
<div class="content-wrapper">
|
|
{% block dashboard_stat %}
|
|
<!-- Content Header (Page header) -->
|
|
<div class="content-header">
|
|
<div class="container-fluid">
|
|
<div class="row mb-2">
|
|
<div class="col-sm-6">
|
|
<h1 class="m-0 text-dark">
|
|
Dashboard
|
|
<small>Control panel</small>
|
|
</h1>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<ol class="breadcrumb float-sm-right">
|
|
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Home</a></li>
|
|
<li class="breadcrumb-item active">Dashboard</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
{% block content %}
|
|
{% endblock %}
|
|
</div>
|
|
<!-- /.content-wrapper -->
|
|
<footer class="main-footer">
|
|
<strong><a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin">PowerDNS-Admin</a></strong> - A PowerDNS web interface with advanced features.
|
|
</footer>
|
|
</div>
|
|
<!-- ./wrapper -->
|
|
<script type="text/javascript">
|
|
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
|
|
</script>
|
|
<script type="text/javascript">
|
|
var PDNS_VERSION = '{{ pdns_version }}'
|
|
</script>
|
|
{% block scripts %}
|
|
{% assets "js_main" -%}
|
|
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
|
{% if SETTING.get('warn_session_timeout') and current_user.is_authenticated %}
|
|
<script>
|
|
// close the session warning popup when receive
|
|
// a boradcast message
|
|
var bc = new BroadcastChannel('powerdnsadmin');
|
|
bc.addEventListener('message', function (e) {
|
|
if (e.data == 'close_session_timeout_modal'){
|
|
$("#modal_session_warning").modal('hide');
|
|
}
|
|
});
|
|
|
|
// Stay Signed In button click event
|
|
$(document.body).on("click", ".button_stay_signed_in", function (e) {
|
|
$.get({
|
|
url: $.jTimeout().options.extendUrl,
|
|
cache: false,
|
|
success: function(){
|
|
$.jTimeout().resetExpiration();
|
|
}
|
|
});
|
|
$.jTimeout().options.onClickExtend();
|
|
});
|
|
|
|
// Sign Out button click event
|
|
$(document.body).on("click", ".button_sign_out", function (e) {
|
|
window.location.replace("{{ url_for('index.logout') }}");
|
|
});
|
|
|
|
// Things happen when session warning popup shown
|
|
$(document).on('show.bs.modal','#modal_session_warning', function () {
|
|
var secondsLeft = jTimeout.getSecondsTillExpiration();
|
|
var t = timer($('#modal-time'), secondsLeft);
|
|
|
|
$(this).on('hidden.bs.modal', function () {
|
|
clearInterval(t);
|
|
$('#modal-time').text("");
|
|
$(this).off('hidden.bs.modal');
|
|
});
|
|
|
|
});
|
|
|
|
// jTimeout definition
|
|
$(function(){
|
|
$.jTimeout({
|
|
flashTitle: true,
|
|
flashTitleSpeed: 500,
|
|
flashingTitleText: '**WARNING**',
|
|
originalTitle: document.title,
|
|
timeoutAfter: {{ SETTING.get('session_timeout')|int * 60 }},
|
|
secondsPrior: 60,
|
|
heartbeat: 1,
|
|
extendOnMouseMove: true,
|
|
mouseDebounce: 30,
|
|
extendUrl: '{{ url_for("index.ping") }}',
|
|
logoutUrl: '{{ url_for("index.logout") }}',
|
|
loginUrl: '{{ url_for("index.login") }}',
|
|
|
|
onClickExtend: function(){
|
|
// broadcast a message to tell other tabes
|
|
// close the session warning popup
|
|
var bc = new BroadcastChannel('powerdnsadmin');
|
|
bc.postMessage('close_session_timeout_modal');
|
|
},
|
|
|
|
onMouseMove: function(){
|
|
// if the mouse is moving while popup is present, we
|
|
// don't extend the session.
|
|
if (!$('#modal_session_warning').hasClass('in')) {
|
|
$.get({
|
|
url: $.jTimeout().options.extendUrl,
|
|
cache: false,
|
|
success: function () {
|
|
$.jTimeout().resetExpiration();
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
onTimeout: function(jTimeout){
|
|
window.location.replace("{{ url_for('index.logout') }}");
|
|
},
|
|
|
|
onPriorCallback: function(jTimeout){
|
|
$("#modal_session_warning").modal('show');;
|
|
},
|
|
|
|
onSessionExtended:function(jTimeout){
|
|
$("#modal_session_warning").modal('hide');
|
|
}
|
|
});
|
|
});
|
|
|
|
function showErrorModal(message) {
|
|
var modal = $('#modal_error');
|
|
modal.find('.modal-body p').text(message);
|
|
modal.modal('show');
|
|
}
|
|
|
|
function showSuccessModal(message) {
|
|
var modal = $("#modal_success");
|
|
modal.find('.modal-body p').text(message);
|
|
modal.modal('show');
|
|
}
|
|
</script>
|
|
{% endif %}
|
|
{%- endassets %}
|
|
{% endblock %}
|
|
{% block extrascripts %}
|
|
{% endblock %}
|
|
{% block defaultmodals %}
|
|
<div class="modal fade modal-danger" id="modal_error">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal"
|
|
aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
<h4 class="modal-title">Error</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p></p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-flat btn-default pull-right"
|
|
data-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.modal-content -->
|
|
</div>
|
|
<!-- /.modal-dialog -->
|
|
</div>
|
|
<!-- /.modal -->
|
|
<div class="modal fade modal-success" id="modal_success">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal"
|
|
aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
<h4 class="modal-title">Success</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p></p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-flat btn-default pull-right"
|
|
data-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.modal-content -->
|
|
</div>
|
|
<!-- /.modal-dialog -->
|
|
</div>
|
|
<!-- /.modal -->
|
|
<!-- /.session-warning-modal -->
|
|
<div class="modal fade modal-warning" data-backdrop="static" id="modal_session_warning">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">Session timeout warning</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Your session is about to expire. You will be automatically signed out in</p>
|
|
<h3><span id="modal-time"></span></h3>
|
|
<p>To coninue your ssession, select <strong>Stay Signed In</strong></p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-flat btn-danger pull-left button_stay_signed_in"
|
|
data-dismiss="modal">Stay Signed In</button>
|
|
<button type="button" class="btn btn-flat btn-default pull-right button_sign_out"
|
|
data-dismiss="modal">Sign Out</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.session-warning-modal-content -->
|
|
</div>
|
|
<!-- /.session-warning-modal-dialog -->
|
|
</div>
|
|
<!-- /.session-warning-modal -->
|
|
{% endblock %}
|
|
{% block modals %}
|
|
{% endblock %}
|
|
</body>
|
|
</html> |