%PDF- %PDF-
| Direktori : /backups/router/usr/local/opnsense/mvc/app/views/OPNsense/Firewall/ |
| Current File : //backups/router/usr/local/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt |
{#
# Copyright (c) 2018-2023 Deciso B.V.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#}
<link href="{{ cache_safe('/ui/css/flags/flag-icon.css') }}" rel="stylesheet">
<style>
@media (min-width: 768px) {
#DialogAlias > .modal-dialog {
width: 90%;
max-width:1200px;
}
}
.dropdown-fixup {
overflow-x: hidden !important;
}
.alias_table {
background-color: transparent !important;
}
.update_table {
background-color: transparent !important;
}
.geo_area_check {
cursor: pointer;
}
.geo_area_uncheck {
cursor: pointer;
}
.geo_label {
margin-bottom: 0px;
font-style: italic;
}
ul.dropdown-menu.inner > li > a > span.text {
width: 100% !important;
}
</style>
<script>
$( document ).ready(function() {
$("#grid-aliases").UIBootgrid({
search:'/api/firewall/alias/searchItem',
get:'/api/firewall/alias/getItem/',
set:'/api/firewall/alias/setItem/',
add:'/api/firewall/alias/addItem/',
del:'/api/firewall/alias/delItem/',
toggle:'/api/firewall/alias/toggleItem/',
options:{
requestHandler: function(request){
if ( $('#type_filter').val().length > 0) {
request['type'] = $('#type_filter').val();
}
if ( $('#category_filter').val().length > 0) {
request['category'] = $('#category_filter').val();
}
return request;
},
formatters: {
commands: function (column, row) {
if (row.uuid.includes('-') === true) {
// exclude buttons for internal aliases (which uses names instead of valid uuid's)
return '<button type="button" class="btn btn-xs btn-default command-edit bootgrid-tooltip" data-row-id="' + row.uuid + '"><span class="fa fa-fw fa-pencil"></span></button> ' +
'<button type="button" class="btn btn-xs btn-default command-copy bootgrid-tooltip" data-row-id="' + row.uuid + '"><span class="fa fa-fw fa-clone"></span></button>' +
'<button type="button" class="btn btn-xs btn-default command-delete bootgrid-tooltip" data-row-id="' + row.uuid + '"><span class="fa fa-fw fa-trash-o"></span></button>';
}
},
rowtoggle: function (column, row) {
if (!row.uuid.includes('-')) {
return '<span class="fa fa-fw fa-check-square-o"></span>';
} else if (parseInt(row[column.id], 2) === 1) {
return '<span style="cursor: pointer;" class="fa fa-fw fa-check-square-o command-toggle bootgrid-tooltip" data-value="1" data-row-id="' + row.uuid + '"></span>';
} else {
return '<span style="cursor: pointer;" class="fa fa-fw fa-square-o command-toggle bootgrid-tooltip" data-value="0" data-row-id="' + row.uuid + '"></span>';
}
},
name : function (column, row) {
if (row.categories_uuid.length === 0) {
return row.name;
} else {
let html = [row.name + ' '];
for (i=0; i < row.categories_uuid.length ; ++i) {
let item = $("#"+row.categories_uuid[i]);
if (item && item.data('color')) {
html.push("<i class='fa fa-circle category-item' style='color:#"+
item.data('color')+"' title='"+item.text()+"'></i>");
}
}
return html.join(' ');
}
},
timestamp: function (column, row) {
if (row[column.id] && row[column.id].includes('.')) {
return row[column.id].split('.')[0].replace('T', ' ');
}
return row[column.id];
}
}
}
});
$("#type_filter, #category_filter").change(function(){
$('#grid-aliases').bootgrid('reload');
});
$("#grid-aliases").bootgrid().on("loaded.rs.jquery.bootgrid", function (e){
// network content field should only contain valid aliases, we need to fetch them separately
// since the form field misses context
ajaxGet("/api/firewall/alias/list_network_aliases", {}, function(data){
$("#network_content").empty();
$.each(data, function(alias, value) {
let $opt = $("<option/>").val(alias).text(value.name);
$opt.data('subtext', value.description);
$("#network_content").append($opt);
});
$("#network_content").selectpicker('refresh');
});
$(".category-item").tooltip();
}).on("load.rs.jquery.bootgrid", function (e){
// reload categories before grid load
ajaxCall('/api/firewall/alias/list_categories', {}, function(data, status){
if (data.rows !== undefined) {
let current_selection = $("#category_filter").val();
$("#category_filter").empty();
for (i=0; i < data.rows.length ; ++i) {
let row = data.rows[i];
let opt_val = $('<div/>').html(row.name).text();
let bgcolor = row.color != "" ? row.color : '31708f;'; // set category color
let option = $("<option/>").val(row.uuid).html(row.name);
if (row.used > 0) {
option.data(
'content',
"<span>"+opt_val + "</span>"+
"<span style='background:#"+bgcolor+";' class='badge pull-right'>" + row.used + "</span>"
);
option.data('color', bgcolor);
option.attr('id', row.uuid);
}
$("#category_filter").append(option);
}
$("#category_filter").val(current_selection);
$("#category_filter").selectpicker('refresh');
}
});
});
$('#grid-aliases').bootgrid().trigger('load.rs.jquery.bootgrid');
/**
* Open form with alias selected
*/
if ("{{selected_alias}}" !== "") {
// UIBootgrid doesn't return a promise, wait for some time before opening the requested item
setTimeout(function(){
ajaxGet("/api/firewall/alias/getAliasUUID/{{selected_alias}}", {}, function(data, status){
if (data.uuid !== undefined) {
var edit_item = $(".command-edit:eq(0)").clone(true);
edit_item.data('row-id', data.uuid).click();
}
});
}, 100);
}
/**
* update geoip labels
**/
function geoip_update_labels() {
$("select.geoip_select").each(function(){
var option_count = $(this).find('option').length;
var selected_count = $(this).find('option:selected').length;
if (selected_count > 0) {
var label = "{{ lang._('%s out of %s selected')}}";
label = label.replace('%s', selected_count).replace('%s', option_count);
$("label[data-id='"+$(this).data('id')+"_label']").text(label);
} else {
$("label[data-id='"+$(this).data('id')+"_label']").text("");
}
});
}
/**
* show tables limits, counts and alerts
**/
function get_aliases_stat() {
ajaxGet("/api/firewall/alias/get_table_size", {}, function(data){
perc_full = Math.round(100*data.used/data.size);
$('#room_left').attr('aria-valuenow', perc_full + '%').css("width", perc_full + "%");
$('#entries_bar > span > span').text(perc_full + "% (" + data.used + "/" + data.size + ")");
bar_color = (perc_full > 50) ? "orangered" : (perc_full < 50 && perc_full > 30) ? "yellowgreen" : "greenyellow";
$('#room_left').css("background-color", bar_color);
});
}
/**
* fetch regions and countries for geoip selection
*/
ajaxGet("/api/firewall/alias/listCountries", {}, function(data){
var regions = [];
$.each(data, function(country, item) {
if (!regions.includes(item.region) && item.region != null) {
regions.push(item.region);
}
});
regions.sort();
regions.map(function(item){
var $tr = $("<tr/>");
$tr.append($("<td/>").text(item));
var geo_select = $("<td/>");
geo_select.append($("<select class='selectpicker geoip_select' multiple='multiple' data-size='10' data-live-search='true' data-container='body' data-id='"+'geoip_region_'+item+"'/>"));
geo_select.append($("<i class=\"fa fa-fw geo_area_check fa-check-square-o\" aria-hidden=\"true\" data-id='"+'geoip_region_'+item+"'></i>"));
geo_select.append($("<i class=\"fa fa-fw geo_area_uncheck fa-square-o\" aria-hidden=\"true\" data-id='"+'geoip_region_'+item+"'></i>"));
geo_select.append($("<label class='geo_label' data-id='geoip_region_"+item+"_label'/>"));
$tr.append(geo_select);
$("#alias_type_geoip > tbody").append($tr);
});
$.each(data, function(country, item) {
if (item.region != null) {
$('.geoip_select[data-id="geoip_region_'+item.region+'"]').append(
$("<option/>")
.val(country)
.data('icon', 'flag-icon flag-icon-' + country.toLowerCase() + ' flag-icon-squared')
.html(item.name)
);
}
});
$(".geoip_select").selectpicker();
$("select.geoip_select").change(function(){
// unlink on change event
$("#alias\\.content").unbind('tokenize:tokens:change');
// copy items from geoip fields to content field
$("#alias\\.content").tokenize2().trigger('tokenize:clear');
$("select.geoip_select").each(function () {
$.each($(this).val(), function(key, item){
$("#alias\\.content").tokenize2().trigger('tokenize:tokens:add', item);
});
});
$("#alias\\.content").tokenize2().trigger('tokenize:select');
$("#alias\\.content").tokenize2().trigger('tokenize:dropdown:hide');
// link on change event back
$("#alias\\.content").on('tokenize:tokens:change', function(e, value){
$("#alias\\.content").change();
});
geoip_update_labels();
});
$(".geo_area_check").click(function(){
var area_id = $(this).data('id');
var area_select = $(".geoip_select[data-id='"+area_id+"']");
area_select.find('option').prop("selected", true);
area_select.selectpicker('refresh');
area_select.change();
});
$(".geo_area_uncheck").click(function(){
var area_id = $(this).data('id');
var area_select = $(".geoip_select[data-id='"+area_id+"']");
area_select.find('option').prop("selected", false);
area_select.selectpicker('refresh');
area_select.change();
});
});
/**
* fetch user groups
**/
ajaxGet("/api/firewall/alias/list_user_groups", {}, function(data){
$("#authgroup_content").empty();
$.each(data, function(alias, value) {
let $opt = $("<option/>").val(alias).text(value.name);
$opt.data('subtext', value.description);
$("#authgroup_content").append($opt);
});
$("#authgroup_content").selectpicker('refresh');
});
/**
* hook network group type changes, replicate content
*/
$("#network_content, #authgroup_content").change(function(){
let target = $(this);
let $content = $("#alias\\.content");
$content.unbind('tokenize:tokens:change');
$content.tokenize2().trigger('tokenize:clear');
target.each(function () {
$.each($(this).val(), function(key, item){
$content.tokenize2().trigger('tokenize:tokens:add', item);
});
});
$content.tokenize2().trigger('tokenize:select');
$content.tokenize2().trigger('tokenize:dropdown:hide');
// link on change event back
$content.on('tokenize:tokens:change', function(e, value){
$content.change();
});
});
/**
* Type selector, show correct type input.
*/
$("#alias\\.type").change(function(){
$(".alias_type").hide();
$("#row_alias\\.updatefreq").hide();
$("#row_alias\\.authtype").hide();
$("#row_alias\\.interface").hide();
$("#row_alias\\.path_expression").hide();
$("#copy-paste").hide();
switch ($(this).val()) {
case 'authgroup':
$("#alias_type_authgroup").show();
$("#alias\\.proto").selectpicker('hide');
break;
case 'geoip':
$("#alias_type_geoip").show();
$("#alias\\.proto").selectpicker('show');
/* work around JS injection of nasty overflow scroll bar being injected */
$("#row_alias\\.type > td > .dropdown:last > .dropdown-menu > .inner").addClass('dropdown-fixup');
break;
case 'asn':
$("#alias_type_default").show();
$("#alias\\.proto").selectpicker('show');
$("#copy-paste").show();
break;
case 'external':
break;
case 'networkgroup':
$("#alias_type_networkgroup").show();
$("#alias\\.proto").selectpicker('hide');
break;
case 'dynipv6host':
$("#row_alias\\.interface").show();
$("#alias\\.proto").selectpicker('hide');
$("#alias_type_default").show();
break;
case 'urljson':
$("#row_alias\\.path_expression").show();
/* FALLTHROUGH */
case 'urltable':
$("#row_alias\\.updatefreq").show();
/* FALLTHROUGH */
case 'url':
$("#row_alias\\.authtype").show();
$("#alias\\.authtype").change(function() {
$("#alias\\.username").hide();
$("#alias\\.password").hide();
switch ($(this).val()) {
case 'Basic':
$("#alias\\.username").show();
$("#alias\\.password").show().attr('placeholder', '{{lang._('Password')}}');
break;
case 'Bearer':
$("#alias\\.password").show().attr('placeholder', '{{lang._('API token')}}');
break;
}
});
/* FALLTHROUGH */
default:
$("#alias_type_default").show();
$("#alias\\.proto").selectpicker('hide');
$("#copy-paste").show();
break;
}
if ($(this).val() === 'port') {
$("#row_alias\\.counters").hide();
} else {
$("#row_alias\\.counters").show();
}
});
/**
* push content changes to GeopIP selectors and network groups
*/
$("#alias\\.content").change(function(){
var items = $(this).val();
['#authgroup_content', '#network_content', '.geoip_select'].forEach(function(target){
$(target).each(function(){
var content_item = $(this);
content_item.val([]);
for (var i=0; i < items.length; ++i) {
content_item.find('option[value="' + $.escapeSelector(items[i]) + '"]').prop("selected", true);
}
});
$(target).selectpicker('refresh');
});
geoip_update_labels();
});
/**
* update expiration (updatefreq is split into days and hours on the form)
*/
$("#alias\\.updatefreq").change(function(){
if ($(this).val() !== "") {
var freq = $(this).val();
var freq_hours = ((parseFloat(freq) - parseInt(freq)) * 24.0).toFixed(2);
var freq_days = parseInt(freq);
$("input[data-id=\"alias.updatefreq_hours\"]").val(freq_hours);
$("input[data-id=\"alias.updatefreq_days\"]").val(freq_days);
} else {
$("input[data-id=\"alias.updatefreq_hours\"]").val("");
$("input[data-id=\"alias.updatefreq_days\"]").val("");
}
});
$(".updatefreq").keyup(function(){
var freq = 0.0;
if ($("input[data-id=\"alias.updatefreq_days\"]").val().trim() != "") {
freq = parseFloat($("input[data-id=\"alias.updatefreq_days\"]").val());
}
if ($("input[data-id=\"alias.updatefreq_hours\"]").val().trim() != "") {
freq += (parseFloat($("input[data-id=\"alias.updatefreq_hours\"]").val()) / 24.0);
}
if (freq != 0.0) {
$("#alias\\.updatefreq").val(freq);
} else {
$("#alias\\.updatefreq").val("");
}
});
/**
* export all configured aliases to json
*/
$("#exportbtn").click(function(){
ajaxGet("/api/firewall/alias/export", {}, function(data, status){
if (data.aliases) {
let output_data = JSON.stringify(data, null, 2);
let a_tag = $('<a></a>').attr('href','data:application/json;charset=utf8,' + encodeURIComponent(output_data))
.attr('download','aliases.json').appendTo('body');
a_tag.ready(function() {
if ( window.navigator.msSaveOrOpenBlob && window.Blob ) {
var blob = new Blob( [ output_data ], { type: "text/csv" } );
navigator.msSaveOrOpenBlob( blob, 'aliases.json' );
} else {
a_tag.get(0).click();
}
});
}
});
});
/**
* import aliases from json file
*/
$("#importbtn").click(function(){
let $msg = $("<div/>");
let $imp_file = $("<input type='file' id='import_filename' />");
let $table = $("<table class='table table-condensed'/>");
let $tbody = $("<tbody/>");
$table.append(
$("<thead/>").append(
$("<tr>").append(
$("<th/>").text("{{ lang._('source')}}")
).append(
$("<th/>").text("{{ lang._('message')}}")
)
)
);
$table.append($tbody);
$table.append(
$("<tfoot/>").append(
$("<tr/>").append($("<td colspan='2'/>").text(
"{{ lang._('Please note that none of the aliases provided are imported due to the errors above')}}"
))
)
);
$imp_file.click(function(){
// make sure upload resets when new file is provided (bug in some browsers)
this.value = null;
});
$msg.append($imp_file);
$msg.append($("<hr/>"));
$msg.append($table);
$table.hide();
BootstrapDialog.show({
title: "{{ lang._('Import aliases') }}",
message: $msg,
type: BootstrapDialog.TYPE_INFO,
draggable: true,
buttons: [{
label: '<i class="fa fa-cloud-upload" aria-hidden="true"></i>',
action: function(sender){
$table.hide();
$tbody.empty();
if ($imp_file[0].files[0] !== undefined) {
const reader = new FileReader();
reader.readAsBinaryString($imp_file[0].files[0]);
reader.onload = function(readerEvt) {
let import_data = null;
try {
import_data = JSON.parse(readerEvt.target.result);
} catch (error) {
$tbody.append(
$("<tr/>").append(
$("<td>").text("*")
).append(
$("<td>").text(error)
)
);
$table.show();
}
if (import_data !== null) {
ajaxCall("/api/firewall/alias/import", {'data': import_data}, function(data,status) {
if (data.validations !== undefined) {
Object.keys(data.validations).forEach(function(key) {
$tbody.append(
$("<tr/>").append(
$("<td>").text(key)
).append(
$("<td>").text(data.validations[key])
)
);
});
$table.show();
} else {
sender.close();
}
});
}
}
}
}
},{
label: "{{ lang._('Close') }}",
action: function(sender){
sender.close();
}
}]
});
});
function loadSettings() {
let data_get_map = {'frm_GeopIPSettings':"/api/firewall/alias/getGeoIP"};
mapDataToFormUI(data_get_map).done(function(data){
if (data.frm_GeopIPSettings.alias.geoip.usages) {
if (!data.frm_GeopIPSettings.alias.geoip.subscription && !data.frm_GeopIPSettings.alias.geoip.address_count) {
let $msg = "{{ lang._('In order to use GeoIP, you need to configure a source in the GeoIP settings tab') }}";
BootstrapDialog.show({
title: "{{ lang._('GeoIP') }}",
message: $msg,
type: BootstrapDialog.TYPE_INFO,
buttons: [{
label: "{{ lang._('Close') }}",
action: function(sender){
sender.close();
}
}]
});
}
}
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
get_aliases_stat();
});
}
loadSettings();
/**
* reconfigure
*/
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/firewall/alias/set", 'frm_GeopIPSettings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status){
loadSettings();
}
});
// update history on tab state and implement navigation
if (window.location.hash != "") {
$('a[href="' + window.location.hash + '"]').click();
} else {
$('a[href="#aliases"]').click();
}
$('.nav-tabs a').on('shown.bs.tab', function (e) {
history.pushState(null, null, e.target.hash);
});
// move filter into action header
$("#type_filter_container").detach().prependTo('#grid-aliases-header > .row > .actionBar > .actions');
// alias size in service container
$("#aliases_stat").detach().prependTo('#service_status_container');
$("#service_status_container").css('width', '250px');
$("#aliases_stat").tooltip({placement: 'bottom'});
});
</script>
<div id="aliases_stat" title="{{ lang._('Current Tables Entries/Firewall Maximum Table Entries') }}">
<div class="col-xs-1"><i class="fa fa-fw fa-info-circle"></i></div>
<div id="entries_bar" class="progress" style="text-align: center;">
<div id="room_left" class="progress-bar" role="progressbar" aria-valuenow="0%" aria-valuemin="0" aria-valuemax="100" style="width: 0%; z-index: 0;"></div>
<span class="state_text" style="position:absolute;right:0;left:0;">
<span>{{ lang._('loading data..') }}</span>
</span>
</div>
</div>
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
<li><a data-toggle="tab" href="#aliases" id="aliases_tab">{{ lang._('Aliases') }}</a></li>
<li><a data-toggle="tab" href="#geoip" id="geoip_tab">{{ lang._('GeoIP settings') }}</a></li>
</ul>
<div class="tab-content content-box">
<div id="aliases" class="tab-pane fade in">
<div class="row">
<section class="col-xs-12">
<div class="content-box">
<div class="hidden">
<!-- filter per type container -->
<div id="type_filter_container" class="btn-group">
<select id="type_filter" data-title="{{ lang._('Filter type') }}" class="selectpicker" data-size="10" data-live-search="true" multiple="multiple" data-width="200px">
<option value="host">{{ lang._('Host(s)') }}</option>
<option value="network">{{ lang._('Network(s)') }}</option>
<option value="port">{{ lang._('Port(s)') }}</option>
<option value="url">{{ lang._('URL (IPs)') }}</option>
<option value="urltable">{{ lang._('URL Table (IPs)') }}</option>
<option value="geoip">{{ lang._('GeoIP') }}</option>
<option value="networkgroup">{{ lang._('Network group') }}</option>
<option value="mac">{{ lang._('MAC address') }}</option>
<option value="asn">{{ lang._('BGP ASN') }}</option>
<option value="dynipv6host">{{ lang._('Dynamic IPv6 Host') }}</option>
<option value="authgroup">{{ lang._('(OpenVPN) user groups') }}</option>
<option value="internal">{{ lang._('Internal (automatic)') }}</option>
<option value="external">{{ lang._('External (advanced)') }}</option>
</select>
<select id="category_filter" data-title="{{ lang._('Categories') }}" class="selectpicker" data-size="10" data-live-search="true" data-size="5" multiple data-width="200px">
</select>
</div>
</div>
<table id="grid-aliases" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogAlias" data-editAlert="aliasChangeMessage">
<thead>
<tr>
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
<th data-column-id="name" data-width="20em" data-formatter="name">{{ lang._('Name') }}</th>
<th data-column-id="type" data-width="12em" data-type="string">{{ lang._('Type') }}</th>
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
<th data-column-id="content" data-type="string">{{ lang._('Content') }}</th>
<th data-column-id="current_items" data-type="string">{{ lang._('Loaded#') }}</th>
<th data-column-id="last_updated" data-formatter="timestamp" data-type="string">{{ lang._('Last updated') }}</th>
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-fw fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button>
</td>
</tr>
<tr>
<td></td>
<td>
<button id="exportbtn" data-toggle="tooltip" title="{{ lang._('download')}}" type="button" class="btn btn-xs btn-default"> <span class="fa fa-fw fa-cloud-download"></span></button>
<button id="importbtn" data-toggle="tooltip" title="{{ lang._('upload')}}" type="button" class="btn btn-xs btn-default"> <span class="fa fa-fw fa-cloud-upload"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
</section>
</div>
</div>
<div id="geoip" class="tab-pane fade in">
{{ partial("layout_partials/base_form",['fields':formGeoIPSettings,'id':'frm_GeopIPSettings'])}}
</div>
</div>
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<br/>
<div id="aliasChangeMessage" class="alert alert-info" style="display: none" role="alert">
{{ lang._('After changing settings, please remember to apply them with the button below') }}
</div>
<button class="btn btn-primary" id="reconfigureAct"
data-endpoint='/api/firewall/alias/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring aliases') }}"
type="button"
></button>
<br/><br/>
</div>
</div>
</section>
{# Edit dialog #}
<div class="modal fade" id="DialogAlias" tabindex="-1" role="dialog" aria-labelledby="DialogAliasLabel">
<div class="modal-backdrop fade in"></div>
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="{{ lang._('Close') }}"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="formDialogAliasLabel">{{lang._('Edit Alias')}}</h4>
</div>
<div class="modal-body">
<form id="frm_DialogAlias">
<div class="table-responsive">
<table class="table table-striped table-condensed">
<colgroup>
<col class="col-md-3"/>
<col class="col-md-5"/>
<col class="col-md-4"/>
</colgroup>
<tbody>
<tr>
<td></td>
<td colspan="2" style="text-align:right;">
<small>{{ lang._('full help') }} </small>
<a href="#">
<i class="fa fa-toggle-off text-danger" id="show_all_help_formDialogformDialogAlias">
</i>
</a>
</td>
</tr>
<tr id="row_alias.enabled">
<td>
<div class="control-label" id="control_label_alias.enabled">
<a id="help_for_alias.enabled" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Enabled')}}</b>
</div>
</td>
<td>
<input type="checkbox" id="alias.enabled">
<div class="hidden" data-for="help_for_alias.enabled">
<small>{{lang._('Enable this alias')}}</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.enabled"></span>
</td>
</tr>
<tr id="row_alias.name">
<td>
<div class="control-label" id="control_label_alias.name">
<a id="help_for_alias.name" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Name')}}</b>
</div>
</td>
<td>
<input type="text" class="form-control" size="50" id="alias.name">
<div class="hidden" data-for="help_for_alias.name">
<small>
{{lang._('The name must start with a letter or single underscore, be less than 32 characters and only consist of alphanumeric characters or underscores. Aliases can be nested using this name.')}}
</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.name"></span>
</td>
</tr>
<tr id="row_alias.type">
<td>
<div class="control-label" id="control_label_alias.type">
<i class="fa fa-info-circle text-muted"></i>
<b>{{lang._('Type')}}</b>
</div>
</td>
<td>
<select id="alias.type" class="selectpicker" data-container="body" data-width="245px"></select>
<select id="alias.proto" multiple="multiple" title="IPv4, IPv6" class="selectpicker" data-container="body" data-width="100px"></select>
</td>
<td>
<span class="help-block" id="help_block_alias.type"></span>
</td>
</tr>
<tr id="row_alias.categories">
<td>
<div class="control-label" id="control_label_alias.type">
<a id="help_for_alias.categories" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Categories')}}</b>
</div>
</td>
<td>
<select id="alias.categories" multiple="multiple" class="tokenize" data-container="body" data-width="348px"></select>
<span class="hidden" data-for="help_for_alias.categories">
{{lang._('For grouping purposes you may select multiple groups here to organize items.')}}
</span>
</td>
<td>
<span class="help-block" id="help_block_alias.categories"></span>
</td>
</tr>
<tr id="row_alias.updatefreq">
<td>
<div class="control-label" id="control_label_alias.updatefreq">
<a id="help_for_alias.frequency" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Refresh Frequency')}}</b>
</div>
</td>
<td>
<input type="text" class="form-control" id="alias.updatefreq" style="display: none">
<table class="table table-condensed update_table">
<thead>
<tr>
<th>{{lang._('Days')}}</th>
<th>{{lang._('Hours')}}</th>
</tr>
</thead>
<tbody>
<tr>
<td><input data-id="alias.updatefreq_days" type="text" class="updatefreq form-control"></td>
<td><input data-id="alias.updatefreq_hours" type="text" class="updatefreq form-control"></td>
</tr>
</tbody>
</table>
<div class="hidden" data-for="help_for_alias.frequency">
<small>
{{lang._('The frequency that the list will be refreshed, in days + hours, so 1 day and 8 hours means the alias will be refreshed after 32 hours. ')}}
</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.updatefreq"></span>
</td>
</tr>
<tr id="row_alias.content">
<td>
<div class="control-label" id="control_label_alias.content">
<i class="fa fa-info-circle text-muted"></i>
<b>{{lang._('Content')}}</b>
</div>
</td>
<td>
<div class="alias_type" id="alias_type_default">
<select multiple="multiple"
id="alias.content"
class="tokenize"
data-width="348px"
data-allownew="true"
data-nbdropdownelements="10"
data-live-search="true"
data-container="body"
data-separator="#10">
</select>
</div>
<div class="alias_type" id="alias_type_networkgroup">
<select multiple="multiple" class="selectpicker" id="network_content" data-container="body" data-size="10" data-live-search="true">
</select>
</div>
<table class="table table-condensed alias_table alias_type" id="alias_type_geoip" style="display: none;">
<thead>
<tr>
<th>{{lang._('Region')}}</th>
<th>{{lang._('Countries')}}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="alias_type" id="alias_type_authgroup" style="display: none;">
<select multiple="multiple" class="selectpicker" id="authgroup_content" data-container="body" data-size="10" data-live-search="true">
</select>
</div>
<a href="#" class="text-danger" id="clear-options_alias.content"><i class="fa fa-times-circle"></i>
<small>{{lang._('Clear All')}}</small></a><span id="copy-paste">
<a href="#" class="text-danger" id="copy-options_alias.content"><i class="fa fa-copy"></i>
<small>{{ lang._('Copy') }}</small></a>
<a href="#" class="text-danger" id="paste-options_alias.content" style="display:none"><i class="fa fa-paste"></i>
<small>{{ lang._('Paste') }}</small></a></span>
</td>
<td>
<span class="help-block" id="help_block_alias.content"></span>
</td>
</tr>
<tr id="row_alias.path_expression">
<td>
<div class="control-label" id="control_label_alias.path_expression">
<a id="help_for_alias.path_expression" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Path expression')}}</b>
</div>
</td>
<td>
<input type="text" class="form-control" size="50" id="alias.path_expression"/>
<div class="hidden" data-for="help_for_alias.path_expression">
<small>
{{lang._('Simplified expression to select a field inside a container, a dot [.] is used as field separator (e.g. container.fieldname).')}}
</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.authtype"></span>
</td>
</tr>
<tr id="row_alias.authtype">
<td>
<div class="control-label" id="control_label_alias.authtype">
<a id="help_for_alias.authtype" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Authorization')}}</b>
</div>
</td>
<td>
<select id="alias.authtype" data-container="body" class="selectpicker" style="margin-bottom: 3px;"></select>
<input type="text" placeholder="{{lang._('Username')}}" class="form-control" size="50" id="alias.username"/>
<input type="password" class="form-control" size="50" id="alias.password"/>
<div class="hidden" data-for="help_for_alias.authtype">
<small>
{{lang._('If the remote server enforces authorization, you can specify the authorization type here.')}}
</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.authtype"></span>
</td>
</tr>
<tr id="row_alias.interface">
<td>
<div class="alias interface" id="alias_interface">
<a id="help_for_alias.interface" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Interface')}}</b>
</div>
</td>
<td>
<select class="selectpicker" id="alias.interface" data-container="body" data-width="200px"></select>
<div class="hidden" data-for="help_for_alias.interface">
<small>{{lang._('Select the interface for the V6 dynamic IP')}}</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.interface"></span>
</td>
</tr>
<tr id="row_alias.counters">
<td>
<div class="control-label" id="control_label_alias.counters">
<a id="help_for_alias.counters" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Statistics')}}</b>
</div>
</td>
<td>
<input type="checkbox" id="alias.counters">
<div class="hidden" data-for="help_for_alias.counters">
<small>{{lang._('Maintain a set of counters for each table entry')}}</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.enabled"></span>
</td>
</tr>
<tr id="row_alias.description">
<td>
<div class="control-label" id="control_label_alias.description">
<a id="help_for_alias.description" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Description')}}</b>
</div>
</td>
<td>
<input type="text" class="form-control" size="50" id="alias.description">
<div class="hidden" data-for="help_for_alias.description">
<small>{{lang._('You may enter a description here for your reference (not parsed).')}}</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.description"></span>
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ lang._('Cancel') }}</button>
<button type="button" class="btn btn-primary" id="btn_DialogAlias_save">{{ lang._('Save') }}
<i id="btn_formDialogAlias_save_progress" class=""></i></button>
</div>
</div>
</div>
</div>