<!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') }}"> <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') }}"> <!-- 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 %} {% block head_styles %}{% endblock %} {% endblock %} </head> <body class="hold-transition sidebar-mini {% 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-white navbar-light"> <!-- 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="fa-solid fa-bars"></i> </a> </li> </ul> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <a class="nav-link" data-widget="fullscreen" href="#" role="button"> <i class="fa-solid 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"> <img src="{{ url_for('static', filename='img/favicon.png') }}" alt="PowerDNS-Admin FavIcon" class="brand-image img-circle elevation-3" style="opacity: .8"> <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"> <p>{{ current_user.firstname }} {{ current_user.lastname }}</p> <span> <a href="{{ url_for('user.profile') }}"><i class="nav-icon fa-solid fa-user"></i> Edit Profile</a> | <a href="{{ url_for('index.logout') }}"><i class="nav-icon fa-solid fa-sign-out-alt"></i> Logout</a> </span> </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">Zone Management</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 fa-solid 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 fa-solid fa-plus"></i> <p>Create Zone</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 fa-solid fa-trash-alt"></i> <p>Remove Zone</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 == 'server_statistics' else 'nav-item' }}"> <a href="{{ url_for('admin.server_statistics') }}" class="nav-link"> <i class="nav-icon fa-solid fa-chart-simple"></i> <p>Server Statistics</p> </a> </li> <li class="{{ 'nav-item active' if active_page == 'server_configuration' else 'nav-item' }}"> <a href="{{ url_for('admin.server_configuration') }}" class="nav-link"> <i class="nav-icon fa-solid fa-cog"></i> <p>Server Configuration</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 fa-solid 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 fa-solid fa-timeline"></i> <p>Activity</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 fa-solid fa-clone"></i> <p>Zone 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 fa-solid fa-users-rectangle"></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 fa-solid 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 fa-solid 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 fa-solid fa-cog"></i> <p> Settings <i class="right fa-solid 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 fa-solid fa-gears"></i> <p>Basic</p> </a> </li> <li class="nav-item"> <a href="{{ url_for('admin.setting_records') }}" class="nav-link"> <i class="nav-icon fa-regular fa-rectangle-list"></i> <p>Zone 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 fa-solid fa-server"></i> <p>Server</p> </a> </li> <li class="nav-item"> <a href="{{ url_for('admin.setting_authentication') }}" class="nav-link"> <i class="nav-icon fa-solid fa-user-shield"></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 fa-solid 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 }}; 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"> <h4 class="modal-title">Error</h4> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p></p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary float-right" data-dismiss="modal"> Close </button> </div> </div> </div> </div> <!-- /.modal --> <div class="modal fade modal-success" id="modal_success"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Success</h4> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p></p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary float-right" data-dismiss="modal"> Close </button> </div> </div> </div> </div> <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-success float-right button_stay_signed_in" data-dismiss="modal"> Stay Signed In </button> <button type="button" class="btn btn-danger float-left button_sign_out" data-dismiss="modal"> Sign Out </button> </div> </div> </div> </div> {% endblock %} {% block modals %} {% endblock %} </body> </html>