mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Tweak setup wizard to enhance whole process
This commit is contained in:
parent
f8827f31ea
commit
0bf3af7089
3 changed files with 165 additions and 85 deletions
|
|
@ -104,7 +104,7 @@ location /setup/check {
|
|||
local http = require "resty.http".new()
|
||||
local res, err = http:request_uri("https://" .. args["server_name"] .. "/setup/check", {ssl_verify = false})
|
||||
if not res then
|
||||
ngx.print("ko")
|
||||
ngx.print("error")
|
||||
logger:log(ngx.ERR, "Server name check failed : " .. err)
|
||||
return
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,22 +33,22 @@ $(document).ready(() => {
|
|||
isValid = validateCondition(
|
||||
password.length >= 8,
|
||||
"#length-check i",
|
||||
isValid,
|
||||
isValid
|
||||
);
|
||||
isValid = validateCondition(
|
||||
/[A-Z]/.test(password),
|
||||
"#uppercase-check i",
|
||||
isValid,
|
||||
isValid
|
||||
);
|
||||
isValid = validateCondition(
|
||||
/\d/.test(password),
|
||||
"#number-check i",
|
||||
isValid,
|
||||
isValid
|
||||
);
|
||||
isValid = validateCondition(
|
||||
/[ -~]/.test(password),
|
||||
"#special-check i",
|
||||
isValid,
|
||||
isValid
|
||||
); // Check for special characters
|
||||
|
||||
return isValid;
|
||||
|
|
@ -121,10 +121,12 @@ $(document).ready(() => {
|
|||
const text = (await response.text()).trim().toLowerCase();
|
||||
if (response.status === 200 && text === "ok") {
|
||||
return true;
|
||||
} else if (text === "error") {
|
||||
return "Server name check failed";
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
return false;
|
||||
return error.message;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -146,30 +148,50 @@ $(document).ready(() => {
|
|||
const primaryURL = `https://${serverName}/setup/check`;
|
||||
const fallbackURL = `${window.location.origin}/setup/check?server_name=${serverName}`;
|
||||
|
||||
let isSuccess = await fetchCheck(primaryURL);
|
||||
let result = await fetchCheck(primaryURL);
|
||||
|
||||
if (!isSuccess) {
|
||||
isSuccess = await fetchCheck(fallbackURL);
|
||||
if (!result || typeof result === "string") {
|
||||
result = await fetchCheck(fallbackURL);
|
||||
}
|
||||
|
||||
$overviewUniqueServerName
|
||||
.find("i")
|
||||
.toggleClass("bx-question-mark text-warning", false);
|
||||
|
||||
const $input = $("#SERVER_NAME");
|
||||
const isValid = result && typeof result !== "string";
|
||||
|
||||
// Toggle valid/invalid classes
|
||||
$input.toggleClass("is-invalid", !isValid);
|
||||
|
||||
// Manage the invalid-feedback element
|
||||
let $feedback = $input.siblings(".invalid-feedback");
|
||||
if (!$feedback.length) {
|
||||
const $textSpan = $input.parent().find("span.input-group-text");
|
||||
$feedback = $('<div class="invalid-feedback"></div>').insertAfter(
|
||||
$textSpan.length ? $textSpan : $input
|
||||
);
|
||||
}
|
||||
|
||||
const feedbackToast = $("#feedback-toast").clone(); // Clone the feedback toast
|
||||
feedbackToast.attr("id", `feedback-toast-${toastNum++}`); // Corrected to set the ID for the toast
|
||||
if (!isSuccess) {
|
||||
if (!isValid) {
|
||||
$feedback.text("Server name is not unique.");
|
||||
feedbackToast.removeClass("bg-primary");
|
||||
feedbackToast.addClass("bg-danger");
|
||||
feedbackToast.find("span").text("Server name is not unique.");
|
||||
feedbackToast
|
||||
.find("div.toast-body")
|
||||
.text("Please choose a different server name.");
|
||||
$overviewUniqueServerName
|
||||
.find("i")
|
||||
.toggleClass("bx-check text-success", false)
|
||||
.toggleClass("bx-x text-danger", true);
|
||||
if (typeof result !== "string")
|
||||
$overviewUniqueServerName
|
||||
.find("i")
|
||||
.toggleClass("bx-check text-success", false)
|
||||
.toggleClass("bx-x text-danger", true);
|
||||
} else {
|
||||
$feedback.text("");
|
||||
feedbackToast.removeClass("bg-danger");
|
||||
feedbackToast.addClass("bg-primary");
|
||||
feedbackToast.find("span").text("Server name is unique.");
|
||||
feedbackToast
|
||||
.find("div.toast-body")
|
||||
|
|
@ -179,8 +201,11 @@ $(document).ready(() => {
|
|||
.toggleClass("bx-check text-success", true)
|
||||
.toggleClass("bx-x text-danger", false);
|
||||
}
|
||||
|
||||
feedbackToast.appendTo("#feedback-toast-container"); // Ensure the toast is appended to the container
|
||||
feedbackToast.toast("show");
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -231,7 +256,7 @@ $(document).ready(() => {
|
|||
if (!$feedback.length) {
|
||||
const $textSpan = $input.parent().find("span.input-group-text");
|
||||
$feedback = $('<div class="invalid-feedback"></div>').insertAfter(
|
||||
$textSpan.length ? $textSpan : $input,
|
||||
$textSpan.length ? $textSpan : $input
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -324,14 +349,34 @@ $(document).ready(() => {
|
|||
*/
|
||||
const populateOverview = () => {
|
||||
if (!uiUser) {
|
||||
$("#overview_username").val($("#username").val());
|
||||
$("#overview_password").val($("#password").val());
|
||||
const $overviewEmail = $("#overview_email");
|
||||
const $overviewUsername = $("#overview_username");
|
||||
const $overviewPassword = $("#overview_password");
|
||||
const adminEmail = $("#email").val();
|
||||
|
||||
if (adminEmail) {
|
||||
$overviewEmail.val(adminEmail);
|
||||
$overviewEmail.closest(".col-12").removeClass("d-none");
|
||||
$overviewUsername.closest(".col-12").addClass("col-md-4");
|
||||
$overviewPassword
|
||||
.closest(".col-12")
|
||||
.addClass("col-md-4")
|
||||
.removeClass("col-sm-6");
|
||||
} else {
|
||||
$overviewEmail.closest(".col-12").addClass("d-none");
|
||||
$overviewUsername.closest(".col-12").removeClass("col-md-4");
|
||||
$overviewPassword
|
||||
.closest(".col-12")
|
||||
.removeClass("col-md-4")
|
||||
.addClass("col-sm-6");
|
||||
}
|
||||
$overviewUsername.val($("#username").val());
|
||||
$overviewPassword.val($("#password").val());
|
||||
}
|
||||
if (!uiReverseProxy) {
|
||||
$("#overview_service_url").val(
|
||||
`https://${getServerName()}${$("#REVERSE_PROXY_URL").val()}`,
|
||||
`https://${getServerName()}${$("#REVERSE_PROXY_URL").val()}`
|
||||
);
|
||||
$("#overview_email_lets_encrypt").val($("#EMAIL_LETS_ENCRYPT").val());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -339,11 +384,11 @@ $(document).ready(() => {
|
|||
* Handles navigation to the next or previous step.
|
||||
* @param {boolean} isNext - True if navigating forward, false if backward.
|
||||
*/
|
||||
const handleStepNavigation = (isNext) => {
|
||||
const handleStepNavigation = async (isNext, force = false) => {
|
||||
const newStep = isNext ? currentStep + 1 : currentStep - 1;
|
||||
const $currentStepContainer = $(`#navs-steps-${currentStep}`);
|
||||
|
||||
if (isNext) {
|
||||
if (!force && isNext) {
|
||||
let isStepValid = validateCurrentStepInputs($currentStepContainer);
|
||||
|
||||
// Additional validation for step 1 (password confirmation)
|
||||
|
|
@ -359,7 +404,7 @@ $(document).ready(() => {
|
|||
.parent()
|
||||
.find("span.input-group-text");
|
||||
$feedback = $(
|
||||
'<div class="invalid-feedback">Passwords do not match.</div>',
|
||||
'<div class="invalid-feedback">Passwords do not match.</div>'
|
||||
).insertAfter($textSpan.length ? $textSpan : $confirmPasswordInput);
|
||||
} else {
|
||||
$feedback.text("Passwords do not match.");
|
||||
|
|
@ -369,6 +414,29 @@ $(document).ready(() => {
|
|||
$confirmPasswordInput.removeClass("is-invalid");
|
||||
$confirmPasswordInput.siblings(".invalid-feedback").text("");
|
||||
}
|
||||
} else if (!uiReverseProxy && currentStep === 2) {
|
||||
const result = await checkDNS();
|
||||
const modal = $("#modal-confirm-dns");
|
||||
const $checkUrl = $("#check-url");
|
||||
const serverName = getServerName();
|
||||
$checkUrl.attr("href", `https://${serverName}/setup/check`);
|
||||
isStepValid = false;
|
||||
|
||||
if (typeof result === "string") {
|
||||
$("#dns-check-title").text("Error");
|
||||
$("#dns-check-result").html(
|
||||
`Are you sure you want to proceed to the next step?<br/>Error: ${result}`
|
||||
);
|
||||
modal.modal("show");
|
||||
} else if (!result) {
|
||||
$("#dns-check-title").text("Server name is not unique");
|
||||
$("#dns-check-result").html(
|
||||
`Are you sure you want to proceed to the next step?<br/>Server name "${serverName}" is not unique.`
|
||||
);
|
||||
modal.modal("show");
|
||||
} else {
|
||||
isStepValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStepValid) return;
|
||||
|
|
@ -389,7 +457,7 @@ $(document).ready(() => {
|
|||
debounce(function () {
|
||||
const isValid = validatePassword();
|
||||
updateValidationState(this, isValid);
|
||||
}, 100),
|
||||
}, 100)
|
||||
);
|
||||
|
||||
// Real-time validation for other plugin settings
|
||||
|
|
@ -404,7 +472,7 @@ $(document).ready(() => {
|
|||
$this
|
||||
.toggleClass("is-valid", isValid)
|
||||
.toggleClass("is-invalid", !isValid);
|
||||
}, 100),
|
||||
}, 100)
|
||||
);
|
||||
|
||||
// Remove validation state on focus out
|
||||
|
|
@ -442,11 +510,11 @@ $(document).ready(() => {
|
|||
formData.append("ui_url", ui_url);
|
||||
formData.append(
|
||||
"auto_lets_encrypt",
|
||||
$("#AUTO_LETS_ENCRYPT").prop("checked") ? "yes" : "no",
|
||||
$("#AUTO_LETS_ENCRYPT").prop("checked") ? "yes" : "no"
|
||||
);
|
||||
formData.append(
|
||||
"lets_encrypt_staging",
|
||||
$("#LETS_ENCRYPT_STAGING").prop("checked") ? "yes" : "no",
|
||||
$("#LETS_ENCRYPT_STAGING").prop("checked") ? "yes" : "no"
|
||||
);
|
||||
formData.append("email_lets_encrypt", $("#EMAIL_LETS_ENCRYPT").val());
|
||||
}
|
||||
|
|
@ -501,17 +569,8 @@ $(document).ready(() => {
|
|||
e.preventDefault();
|
||||
|
||||
const isNext = $(this).hasClass("next-step");
|
||||
handleStepNavigation(isNext);
|
||||
});
|
||||
|
||||
// DNS Check Button Click
|
||||
$("#check-dns").on("click", function (e) {
|
||||
e.preventDefault();
|
||||
if (uiReverseProxy) return;
|
||||
|
||||
if (currentStep !== CHECK_STEP) return;
|
||||
|
||||
checkDNS();
|
||||
const confirmDNS = this.id === "confirm-dns";
|
||||
handleStepNavigation(isNext, confirmDNS);
|
||||
});
|
||||
|
||||
$2faInput.on("input", function () {
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@
|
|||
{% if not ui_user %}
|
||||
<h6 class="mt-2 mb-1 fw-bold">Admin User</h6>
|
||||
{% set input_readonly = true %}
|
||||
<div class="col-12 col-sm-6 pb-3">
|
||||
<div class="col-12 col-sm-6 col-md-4 pb-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<label id="label-overview_username"
|
||||
for="overview_username"
|
||||
|
|
@ -435,7 +435,17 @@
|
|||
{% set setting_data = {"type": "text", "id": "overview_username", "regex": "^.{1,256}$"} %}
|
||||
{% include "models/input_setting.html" %}
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 pb-3">
|
||||
<div class="col-12 col-sm-6 col-md-4 pb-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<label id="label-overview_email"
|
||||
for="overview_email"
|
||||
class="form-label fw-semibold text-truncate">Admin Email</label>
|
||||
</div>
|
||||
{% set setting = "email" %}
|
||||
{% set setting_data = {"type": "email", "id": "overview_email", "regex": "^.*$"} %}
|
||||
{% include "models/input_setting.html" %}
|
||||
</div>
|
||||
<div class="col-12 col-md-4 pb-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<label id="label-overview_password"
|
||||
for="overview_password"
|
||||
|
|
@ -449,52 +459,21 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% if not ui_reverse_proxy %}
|
||||
<h6 class="mt-2 mb-1 fw-bold">UI specific Settings</h6>
|
||||
<div class="col-12 col-sm-6 pb-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<label id="label-overview_service_url"
|
||||
for="overview_service_url"
|
||||
class="form-label fw-semibold text-truncate">
|
||||
BunkerWeb UI final URL
|
||||
</label>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-6 pb-3">
|
||||
<h6 class="mt-2 mb-1 fw-bold">BunkerWeb UI final URL</h6>
|
||||
{% set setting = "SERVER_NAME + REVERSE_PROXY_HOST" %}
|
||||
{% set setting_data = {"type": "text", "id": "overview_service_url", "regex": "^.+$"} %}
|
||||
{% include "models/input_setting.html" %}
|
||||
</div>
|
||||
{% set setting = "SERVER_NAME + REVERSE_PROXY_HOST" %}
|
||||
{% set setting_data = {"type": "text", "id": "overview_service_url", "regex": "^.+$"} %}
|
||||
{% include "models/input_setting.html" %}
|
||||
</div>
|
||||
<div class="col-sm-6 pb-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<label id="label-overview_email_lets_encrypt"
|
||||
for="overview_email_lets_encrypt"
|
||||
class="form-label fw-semibold text-truncate">
|
||||
Email for Let's Encrypt
|
||||
</label>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="badge rounded-pill bg-secondary-subtle text-dark d-flex align-items-center justify-content-center p-1"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
data-bs-original-title="The email address that will be used for Let's Encrypt">
|
||||
<span class="bx bx-question-mark bx-xs"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% set setting = "EMAIL_LETS_ENCRYPT" %}
|
||||
{% set setting_data = {"type": "text", "id": "overview_email_lets_encrypt", "regex": "^.*$"} %}
|
||||
{% include "models/input_setting.html" %}
|
||||
</div>
|
||||
<div class="text-center pt-2 mb-6">
|
||||
<h6 class="mb-1 fw-bold">Check server name DNS</h6>
|
||||
<button id="check-dns" class="btn btn-primary">Check DNS</button>
|
||||
<p class="mt-1 mb-0">
|
||||
In case of issues, you can also click <a id="check_url"
|
||||
class="fw-semibold"
|
||||
href="https://www.example.com/setup/check"
|
||||
target="_blank"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
data-bs-original-title='If the shown text is "ok", that means that the server name is available'>here</a> to perform a manual check.
|
||||
</p>
|
||||
</div>
|
||||
<!-- <div class="text-center pt-2 mb-6">
|
||||
<h6 class="mb-1 fw-bold">Check server name DNS</h6>
|
||||
<button id="check-dns" class="btn btn-primary">Check DNS</button>
|
||||
<p class="mt-1 mb-0">
|
||||
In case of issues, you can also click <a id="check_url" class="fw-semibold" href="https://www.example.com/setup/check" target="_blank" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title='If the shown text is "ok", that means that the server name is available'>here</a> to perform a manual check.
|
||||
</p>
|
||||
</div> -->
|
||||
{% endif %}
|
||||
<div class="row p-0">
|
||||
<div class="col-md-{% if not ui_user %}4{% else %}6{% endif %}">
|
||||
|
|
@ -593,12 +572,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="feedback-toast"
|
||||
class="bs-toast toast fade bg-primary text-white"
|
||||
class="bs-toast toast fade"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
aria-atomic="true"
|
||||
data-bs-autohide="true"
|
||||
data-bs-delay="8000">
|
||||
data-bs-delay="10000">
|
||||
<div class="toast-header">
|
||||
<i class="d-block w-px-20 h-auto rounded me-2 tf-icons bx bx-bell"></i>
|
||||
<span class="fw-medium me-auto">BunkerWeb Forever</span>
|
||||
|
|
@ -610,6 +589,48 @@
|
|||
</div>
|
||||
<div class="toast-body">If you read this, it means that you're curious 👀</div>
|
||||
</div>
|
||||
{% if not ui_reverse_proxy %}
|
||||
<div class="modal fade"
|
||||
id="modal-confirm-dns"
|
||||
data-bs-backdrop="static"
|
||||
tabindex="-1"
|
||||
aria-hidden="true"
|
||||
role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 id="dns-check-title" class="modal-title">Server name is not unique</h5>
|
||||
<button type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="dns-check-result"
|
||||
class="alert alert-danger text-center"
|
||||
role="alert">Are you sure you want to proceed to the next step?</div>
|
||||
<p class="mt-1 mb-0 text-center">
|
||||
In case of issues, you can also click <a id="check-url"
|
||||
class="fw-semibold"
|
||||
href="https://www.example.com/setup/check"
|
||||
target="_blank"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
data-bs-original-title='If the shown text is "ok", that means that the server name is available'>here</a> to perform a manual check.
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-center">
|
||||
<button id="confirm-dns"
|
||||
class="btn btn-outline-danger next-step me-2"
|
||||
data-bs-dismiss="modal">Proceed</button>
|
||||
<button type="reset"
|
||||
class="btn btn-outline-secondary"
|
||||
data-bs-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="modal fade"
|
||||
id="loadingModal"
|
||||
data-bs-backdrop="static"
|
||||
|
|
|
|||
Loading…
Reference in a new issue