firewall/views/wizard.html
<style>
{{custom_css}}
.form-switch {
pargin-right:6rem;
}
#wizard_enable, #wizard_text {
border: 1px solid #DDD;
border-left: 0;
border-right: 0;
margin: 2rem 1rem 4rem 1rem;
}
#wizard_enable {
padding: 0.5rem 2rem 2rem 2rem;
}
#wizard_text:not(.collapse) {
display: flex;
}
#wizard_text_input { flex-grow: 1; max-height: 30px; }
#wizard_text_label { flex-grow: 0; }
</style>
<script type="text/javascript">
window.CONFIG_LIST = {};
function rand_string(config_name, length = 32) {
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
GBI(config_name+"_text").value = result;
update_str(config_name);
}
function show_list(config_name) {
let html = "";
for (let i=0; i < domain_list.length; i++) {
let id = config_name + "-" + i;
html += '<div style="margin-bottom:5px;" id="item_'+id+'">';
html += '<input type="text" autocomplete="off" disabled id="list_'+id+'" class="form-control txtin" style="width:80%;float:left;margin-right:10px" value="'+domain_list[i]+'">';
html += '<div class="btn btn-danger" style="cursor:pointer;padding-top:10px;padding-left:10px;" title="remove list element" onclick="remove_list(\''+config_name+'\', \''+domain_list[i]+'\', '+i+')"><span class="fe fe-trash"></span></div>';
}
return html;
}
function remove_list(config_name, value, idx) {
console.log("config name delete", config_name, value, idx);
BitFire_api("remove_list_elm", {"config_name":config_name, "config_value":value, "index":idx})
.then(r => r.json())
.then(function(res) {
if (res.success) {
window.location.reload();
} else {
alert(res.note);
window.location.reload();
}
});
}
function add_list(config_name) {
let elm = GBI("new_"+config_name);
BitFire_api("add_list_elm", {"config_name":config_name, "config_value":elm.value})
.then(r => r.json())
.then(function(res) {
if (res.success) {
window.location.reload();
} else {
alert(res.note);
window.location.reload();
}
});
}
const VERSION = {{version}};
const VERSION_STR = "{{sym_version}}";
window.CTR = 0;
function set_config(id, value) {
console.log("set config", id, value);
}
function soption(config, value) {
GBI("drop_"+config).innerText = value;
return update_value(config, value);
}
function update_value(config, value) {
GBI("spin").classList.remove("hidden");
BitFire_api("toggle_config_value", {"param":config,"value":value})
.then(r => r.json())
.then(data => {
window.CTR++;
window.EN_IDX++;
//console.log("api resp", window.CTR, window.EN_IDX);
if (window.CTR == window.EN.length) {
//console.log("window counter >= 5");
window.setTimeout(function() {
update_value("wizard", "true");
GBI("spin").classList.add("hidden");
GBI("save_changes").innerHTML = "<a href='{{self}}?page=bitfire&tooltip=1' class='white' style='color:#FFF'>Tour Dashboard <span class='fe fe-chevron-right'></span></a> ";
}, 200);
} else if (window.EN_IDX < window.EN.length) {
//console.log("update value", window.CTR, window.EN_IDX);
window.setTimeout(function() {
update_value(window.EN[window.EN_IDX][0], window.EN[window.EN_IDX][1]);
}, 100);
}
});
}
function update_str(config) {
console.log("up", config);
let e = GBI(config+"_text");
if (e) {
let value = e.value;
console.log("update str", config, value);
return update_value(config, value);
} else {
alert("error, unable to update " + config + " please create support ticket");
}
}
function toggle_report(config, report) {
if (config == "enforce_ssl_1year" && window.location.protocol != "https:") {
alert("Please switch to SSL to enable this feature");
return false;
}
GBI(config+"_spin").classList.remove("hidden");
if (report && window.CONFIG_LIST[config] == "on") {
let g = GBI(config+"_block");
if (g) { g.checked = false; }
}
if (!report && window.CONFIG_LIST[config] == "report") {
let g = GBI(config+"_report");
if (g) { g.checked = false; }
}
let value = "false";
let r = GBI(config+"_report");
if (r && r.checked) { value = "report"; }
if (GBI(config+"_block").checked) { value = "on"; }
window.CONFIG_LIST[config] = value;
if (config == "auto_start") {
let action=(value == "on") ? "install" : "uninstall";
BitFire_api(action, {})
.then(r => r.json())
.then(response => {
console.log(response);
alert(response.note);
window.setTimeout(function(){ GBI(config+"_spin").classList.add("hidden"); }, 100);
});
}
else {
BitFire_api("toggle_config_value", {"param":config,"value":value})
.then(r => r.json())
.then(data => {
console.log("response...", data);
if (!data.success) { alert("error updating " + config + " : " + data.note + " : " + data.errors.join()); }
window.setTimeout(function(){ GBI(config+"_spin").classList.add("hidden"); }, 100);
});
}
}
// config name, block|on|true / report|alert / off|false
function toggle(elm, type) {
var e = GBI(elm);
console.log(e);
e.innerText = cap(type);
BitFire_api("toggle_config_value", {"param":elm,"value":type})
.then(r => r.json())
.then(data => { console.log("toggle", data); });
if (type == "block" || type == "on" || type == "true") {
e.classList.remove("btn-warning");
e.classList.remove("btn-secondary");
e.classList.add("btn-success");
} else if (type == "report" || type == "alert") {
e.classList.remove("btn-success");
e.classList.remove("btn-secondary");
e.classList.add("btn-warning");
} else {
e.classList.remove("btn-success");
e.classList.remove("btn-warning");
e.classList.add("btn-secondary");
}
}
</script>
<script type="text/template" id="alert_template">
<div class="alert alert-warning alert-dismissible fade show">
{{text}}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</script>
<!-- NAVIGATION
================================================== -->
<div class="main-content">
{{header}}
<!-- CARDS -->
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-12 col-lg-10 col-xl-8" id="alert_block">
</div>
<div class="col-12 col-lg-10 col-xl-8">
<div class="card">
<div class="card-header">
<h3 class="card-header-title text-primary">
BitFire Setup Wizard
</h3>
<span class="text-muted">select major features to enable</span>
</div>
<div class="card-body mb-4" style="padding:1rem !important">
<h2 id="wizard_title" class="mb-2 mt-4">
</h2>
<p id="wizard_body" class="text-muted" style="min-height:60px">
</p>
<div class="col-auto tog" id="wizard_enable" data-enabled="false" data-title="Enable Feature" data-toggle="false">
<label class="form-label left" style="margin-right:70px; margin-left:-10px" id="wizard_label"> Enabled </label>
<div class="form-check form-switch right">
<input class="form-check-input success" autocomplete="off" id="wizard_enable_tog" type="checkbox" onclick="toggle_wiz(this)" data-bs-toggle="tooltip" data-bs-placement="top" title="Enable setting">
<label class="form-check-label" for="wizard_enable_tog"></label>
</div>
</div>
<div class="collapse" id="wizard_text">
<label id="wizard_text_label" for="wizard_text_input" class="form-label left" style="margin-right:70px; margin-left:-10px; padding: .5rem 2rem 0 2rem;"> Alert notification email </label>
<input type="email" class="form-contro" id="wizard_text_input" style="margin:.25rem" onchange="text_set(this)" title="setting value" value="">
</div>
<button type="button" class="btn btn-primary left" id="wizard_back" disabled="disabled"><span class="fe fe-chevron-left"></span> Back</button>
<button type="button" class="btn btn-primary hidden right" id="wizard_finish" data-bs-toggle="modal" data-bs-target="#finish_modal">Finish <span class="fe fe-chevrons-right"></span></button>
<button type="button" class="btn btn-primary right" id="wizard_next" data-idx="0">Next <span class="fe fe-chevron-right"></span></button>
</div>
<div class="card-footer card-footer-boxed">
<div class="row align-items-center">
<div class="col">
<div class="row align-items-center g-0">
<div class="col-auto">
<!-- Value -->
<small id="progress_per" class="me-2">0%</small>
</div>
<div class="col">
<!-- Progress -->
<div class="progress progress-sm">
<div id="progress_bar" class="progress-bar" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div> <!-- / .row -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal" id="finish_modal" tabindex="-1" style="margin-top: 200px">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Firewall Setup Complete</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Firewall Setup complete. You can come back here to adjust settings at any time.</p>
<div id="spin" class="text-success hidden spinner-border left mt-1 mr-2 " style="margin-left: 0" role="status"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="save_changes">Save changes</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
window.BITFIRE_NONCE = '{{api_code}}';
window.EN_IDX = 0;
window.EN = [
["auto_start", true],
["allow_ip_block", false],
["enforce_ssl_1year", (document.location.protocol == 'https:')],
["require_full_browser", true],
["whitelist_enable", true],
["hacked", false],
["notification_email", "{{your_email}}"]
];
window.WIZ = [];
window.WIZ[0] = {'title': 'Always On Protection', 'descr': 'Always on protection runs the firewall as the very first script before any plugins load. This ' +
'will protect direct access to any script on your server.\nWorks for 99.99% of all installs. Recommended setting.', 'label': 'Enabled'};
window.WIZ[1] = {'title': 'Allow IP Blocking', 'descr': 'IP Blocking will add a fast block for IP address that are sending multiple ' +
'attack probes. This will block all traffic from the offending IP address from 1 - 24 hours. <br><strong class="text-secondary">Enable if you are under active attack.</strong>', 'label': 'Enabled' };
window.WIZ[2] = {'title': 'Force SSL', 'descr' : 'This will prevent non SSL traffic from accessing your web site. All non-SSL ' +
'traffic will be disabled. Recommended setting if your site supports HTTPS.', 'label': 'Enabled' };
window.WIZ[3] = {'title': 'Require Full Browser', 'descr': 'Send javascript challenge to verify browsers are real. This will stop ' +
'99.99% of all automated attacks. Recommended setting, <small>(may reduce server traffic by eliminating bots)</small>.', 'label': 'Enabled'};
window.WIZ[4] = {'title': 'Block Impersonating Robots', 'descr': 'Hackers often impersonate search engines like GoogleBot, Bing and others to bypass filtering. ' +
'BitFire can prevent these attacks by verifying over 100 commonly used search engines and 3\'rd party services.', 'label': 'Enabled'};
window.WIZ[5] = {'title': 'Is your website compromised?', 'descr': 'if you have no reason to suspect your security has been compromised, BitFire ' +
'will mark all your files as clean and make malware scanning much easier.', 'label': 'Compromised?'};
window.WIZ[6] = {'title': 'Email Notifications', 'descr': 'BitFire can notify you if it detects malware or security issues with your plugins and themes. ' +
'Where would you like critical notifications to go?'};
function toggle_wiz(elm) {
let idx = GBI("wizard_next").getAttribute("data-idx");
let en = elm.checked;
window.EN[idx][1] = en;
}
function text_set(elm) {
let idx = GBI("wizard_next").getAttribute("data-idx");
window.EN[idx][1] = elm.value;
}
function set_percent(per) {
//console.log("set wiz pos", per, percent);
GBI("progress_per").innerText = per + "%";
let b = GBI("progress_bar");
b.style = "width: " + per + "%";
b.setAttribute("aria-valuenow", per);
}
function set_wiz_pos(pos) {
//console.log("set wiz pos", pos)
percent = Math.round((pos / window.WIZ.length) * 100);
set_percent(percent);
let t = window.WIZ[pos]["title"].replace("\n", "<br>");
let d = window.WIZ[pos]["descr"].replace("\n", "<br>");
let l = window.WIZ[pos]["label"];
GBI("wizard_title").innerHTML = t;
GBI("wizard_body").innerHTML = d;
GBI("wizard_label").innerHTML = l;
GBI("wizard_next").setAttribute("data-idx", pos);
GBI("progress_bar").setAttribute("aria-valuenow", percent);
let def = window.EN[pos][1];
if (typeof def == "string") {
let t_elm = GBI("wizard_text");
if (t_elm.classList.contains("collapse")) {
GBI("wizard_enable").classList.toggle("collapse");
t_elm.classList.toggle("collapse");
let i_elm = GBI("wizard_text_input");
console.log("t_elm value", i_elm.value, i_elm);
if (!i_elm.value || i_elm.value == "") {
console.log("set def value", def, window.EN[pos]);
i_elm.value = def;
}
}
} else {
let t_elm = GBI("wizard_enable");
if (t_elm.classList.contains("collapse")) {
GBI("wizard_enable").classList.toggle("collapse");
GBI("wizard_text").classList.toggle("collapse");
}
}
GBI("wizard_enable_tog").checked = window.EN[pos][1];
}
function next_click() {
let i = parseInt(GBI("wizard_next").getAttribute("data-idx"));
do_click(i+1);
}
function back_click() {
let i = parseInt(GBI("wizard_next").getAttribute("data-idx"));
do_click(i-1);
}
function do_click(pos, x) {
console.log("next click", pos, x);
let n = GBI("wizard_next");
let f = GBI("wizard_finish");
if (pos == 0) {
GBI("wizard_back").setAttribute("disabled", "disabled");
} else {
GBI("wizard_back").removeAttribute("disabled");
}
if (pos >= window.WIZ.length-1) {
f.classList.remove("hidden");
n.classList.add("hidden");
} else {
f.classList.add("hidden");
n.classList.remove("hidden");
}
set_wiz_pos(pos);
}
// MAIN
document.addEventListener("DOMContentLoaded", function () {
GBI("wizard_next").addEventListener("click", next_click);
//GBI("wizard_finish").addEventListener("click", next_click);
GBI("wizard_back").addEventListener("click", back_click);
GBI("save_changes").addEventListener("click", save_changes);
set_wiz_pos(0);
});
function save_changes() {
console.log("save changes", window.EN);
GBI("save_changes").removeEventListener("click", save_changes);
update_value(window.EN[window.EN_IDX][0], window.EN[window.EN_IDX][1]);
}
function toggle_features() {
var elms = document.getElementsByClassName("feature");
console.log("toggle features", elms);
Array.prototype.forEach.call(elms, function (element) {
console.log("element", element.innerText);
if (element.innerText.trim() == "report" || element.innerText.trim() == "alert") {
console.log("warn");
element.classList.remove("btn-success");
element.classList.remove("btn-secondary");
element.classList.add("btn-warning");
} else if (element.innerText.trim() == "block" || element.innerText.trim() == "true" || element.innerText.trim() == "on") {
console.log("success");
element.classList.remove("btn-warning");
element.classList.remove("btn-secondary");
element.classList.add("btn-success");
} else {
element.classList.remove("btn-success");
element.classList.remove("btn-warning");
element.classList.add("btn-secondary");
console.log("second");
}
});
}
/*
let toggles = document.getElementsByClassName("tog");
for (let i = 0; i < toggles.length; i++) {
let id = toggles[i].getAttribute("id");
let name = id.replace("_con", "");
let title = toggles[i].getAttribute("data-title");
let tog = toggles[i].hasAttribute("data-toggle");
let alert = toggles[i].getAttribute("data-enabled");
let check1 = (alert == "report") ? "checked" : "";
let check2 = (alert == "on") ? "checked" : "";
let tail1 = (tog) ? "" : " in alert mode only";
let tail2 = (tog) ? "" : " in full blocking";
let tool1 = 'data-bs-toggle="tooltip" data-bs-placement="top" title="'+title+tail1+'"';
let tool2 = 'data-bs-toggle="tooltip" data-bs-placement="top" title="'+title+tail2+'"';
let html = '<div id="'+name+'_spin" class="spinner-border text-success spinner-border-sm left mt-1 mr-2 hidden" role="status"></div>';
if (!tog) {
html += '<div class="form-check form-switch left" style="margin-left:-60px"> <input class="form-check-input warning" id="'+name+'_report" autocomplete="off" type="checkbox" onclick="return toggle_report(\''+name+'\', true)" '+check1+' '+ tool1 +'> </div>';
}
html += '\
<div class="form-switch right">\
<input class="form-check-input success" autocomplete="off" id="'+name+'_block" type="checkbox" onclick="return toggle_report(\''+name+'\', false)" '+check2+' '+tool2+'>\
</div>';
window.CONFIG_LIST[name] = alert;
toggles[i].innerHTML = html;
}
*/
</script>
<script type="text/javascript">
function alert_or_block(config) {
// console.log("alert_or_block", config);
if (config === 'report' || config === 'alert') { return 'report'; }
if (!config) { return 'off'; }
return 'on';
}
if (GBI("password_btn")) {
GBI("password_btn").addEventListener("click", function() {
GBI('password_close').classList.remove("hidden");
});
}
</script>
{{gtag}}