From 3779cc5dc7f7fc07b7edcf4415488f377d2e69ba Mon Sep 17 00:00:00 2001 From: Jordan Blasenhauer Date: Fri, 1 Dec 2023 11:24:19 +0100 Subject: [PATCH 1/3] update setup UI *fetch form instead of using vanilla html *show loader when sending fetch *redirect to url or show error message depending result *fix loading image --- src/ui/templates/setup.html | 454 +++++++++++++++--------------------- 1 file changed, 184 insertions(+), 270 deletions(-) diff --git a/src/ui/templates/setup.html b/src/ui/templates/setup.html index 9737f7397..4e76fc817 100644 --- a/src/ui/templates/setup.html +++ b/src/ui/templates/setup.html @@ -459,6 +459,9 @@ .mb-3 { margin-bottom: 0.75rem !important; } + .mb-4 { + margin-bottom: 1rem !important; + } .mb-6 { margin-bottom: 1.5rem !important; } @@ -477,18 +480,15 @@ .mt-1 { margin-top: 0.25rem !important; } + .mt-2 { + margin-top: 0.5rem !important; + } .mt-4 { margin-top: 1rem !important; } .mt-6 { margin-top: 1.5rem !important; } - .mb-4 { - margin-bottom: 1rem !important; - } - .mt-2 { - margin-top: 0.5rem !important; - } .block { display: block !important; } @@ -595,6 +595,19 @@ .border-collapse { border-collapse: collapse !important; } + .-translate-x-1 { + --tw-translate-x: -0.25rem !important; + } + .-translate-x-1, + .-translate-x-1\.5 { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) + skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)) !important; + } + .-translate-x-1\.5 { + --tw-translate-x: -0.375rem !important; + } .translate-x-1 { --tw-translate-x: 0.25rem !important; } @@ -804,6 +817,10 @@ font-size: 0.875rem !important; line-height: 1.5rem !important; } + .text-xl { + font-size: 1.25rem !important; + line-height: 1.75rem !important; + } .text-xs { font-size: 0.75rem !important; line-height: 1rem !important; @@ -998,116 +1015,13 @@ --tw-bg-opacity: 1; background-color: rgb(8 85 119 / var(--tw-bg-opacity)); } - :is(.dark .checkbox:disabled[aria-checked="true"]) { - border-color: rgb(37 47 64 / var(--tw-border-opacity)); - background-color: rgb(37 47 64 / var(--tw-bg-opacity)); - color: rgb(210 214 218 / var(--tw-text-opacity)); - } - .regular-input, :is(.dark .checkbox:disabled[aria-checked="true"]) { --tw-border-opacity: 1; - --tw-bg-opacity: 1; - --tw-text-opacity: 1; - } - .regular-input { - display: block; - width: 100%; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-radius: 0.5rem; - border-width: 1px; - border-style: solid; - border-color: rgb(210 214 218 / var(--tw-border-opacity)); - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - background-clip: padding-box; - padding: 0.25rem 0.375rem; - font-size: 0.875rem; - font-weight: 400; - line-height: 1.4rem; - color: rgb(73 80 87 / var(--tw-text-opacity)); - outline: 2px solid #0000; - outline-offset: 2px; - transition-property: all; - transition-timing-function: ease; - transition-duration: 0.15s; - transition-timing-function: ease-in; - } - .regular-input::-moz-placeholder { - --tw-text-opacity: 1; - color: rgb(173 181 189 / var(--tw-text-opacity)); - } - .regular-input::placeholder { - --tw-text-opacity: 1; - color: rgb(173 181 189 / var(--tw-text-opacity)); - } - .regular-input:focus { - border-color: #d2d6da00; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 - var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 - calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), - var(--tw-shadow, 0 0 #0000); - } - .regular-input:valid:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity)); - } - .regular-input:invalid:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(245 57 57 / var(--tw-ring-opacity)); - } - .regular-input:disabled { - --tw-bg-opacity: 1; - background-color: rgb(206 212 218 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(73 80 87 / var(--tw-text-opacity)); - opacity: 0.75; - } - :is(.dark .regular-input) { - border-color: rgb(98 117 148 / var(--tw-border-opacity)); - background-color: rgb(52 71 103 / var(--tw-bg-opacity)); - opacity: 0.9; - } - :is(.dark .regular-input), - :is(.dark .regular-input:disabled) { - --tw-border-opacity: 1; - --tw-bg-opacity: 1; - --tw-text-opacity: 1; - color: rgb(210 214 218 / var(--tw-text-opacity)); - } - :is(.dark .regular-input:disabled) { border-color: rgb(37 47 64 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; background-color: rgb(37 47 64 / var(--tw-bg-opacity)); - } - @media (min-width: 768px) { - .regular-input { - padding: 0.5rem 0.75rem; - } - } - .input-title { - margin: 0; - font-size: 0.875rem; - line-height: 1.5rem; - font-weight: 700; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, - filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, - filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, - filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: ease; - transition-duration: 0.3s; - transition-timing-function: ease-in-out; - } - :is(.dark .input-title) { --tw-text-opacity: 1; color: rgb(210 214 218 / var(--tw-text-opacity)); - opacity: 0.9; } .placeholder\:text-gray-500::-moz-placeholder { --tw-text-opacity: 1 !important; @@ -1117,6 +1031,10 @@ --tw-text-opacity: 1 !important; color: rgb(173 181 189 / var(--tw-text-opacity)) !important; } + .valid\:\!border-red-500:valid { + --tw-border-opacity: 1 !important; + border-color: rgb(245 57 57 / var(--tw-border-opacity)) !important; + } .hover\:-translate-y-px:hover { --tw-translate-y: -1px !important; } @@ -1160,6 +1078,7 @@ --tw-border-opacity: 1 !important; border-color: rgb(34 197 94 / var(--tw-border-opacity)) !important; } + .active\:\!border-red-500:active, .focus\:invalid\:border-red-500:invalid:focus { --tw-border-opacity: 1 !important; border-color: rgb(245 57 57 / var(--tw-border-opacity)) !important; @@ -1167,67 +1086,13 @@ .active\:opacity-85:active { opacity: 0.85 !important; } + .active\:valid\:\!border-red-500:valid:active { + --tw-border-opacity: 1 !important; + border-color: rgb(245 57 57 / var(--tw-border-opacity)) !important; + } .disabled\:opacity-75:disabled { opacity: 0.75 !important; } - :is(.dark .dark\:border-slate-600) { - --tw-border-opacity: 1 !important; - border-color: rgb(98 117 148 / var(--tw-border-opacity)) !important; - } - :is(.dark .dark\:bg-slate-700) { - --tw-bg-opacity: 1 !important; - background-color: rgb(52 71 103 / var(--tw-bg-opacity)) !important; - } - :is(.dark .dark\:bg-slate-850) { - --tw-bg-opacity: 1 !important; - background-color: rgb(17 28 68 / var(--tw-bg-opacity)) !important; - } - :is(.dark .dark\:fill-gray-300) { - fill: #d2d6da !important; - } - :is(.dark .dark\:text-gray-300) { - --tw-text-opacity: 1 !important; - color: rgb(210 214 218 / var(--tw-text-opacity)) !important; - } - :is(.dark .dark\:text-white) { - --tw-text-opacity: 1 !important; - color: rgb(255 255 255 / var(--tw-text-opacity)) !important; - } - :is(.dark .dark\:opacity-80) { - opacity: 0.8 !important; - } - :is(.dark .dark\:opacity-90) { - opacity: 0.9 !important; - } - :is(.dark .dark\:shadow-dark-xl) { - --tw-shadow: 0 2px 2px 0 #00000024, 0 3px 1px -2px #0003, - 0 1px 5px 0 #0000001f !important; - --tw-shadow-colored: 0 2px 2px 0 var(--tw-shadow-color), - 0 3px 1px -2px var(--tw-shadow-color), - 0 1px 5px 0 var(--tw-shadow-color) !important; - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), - var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important; - } - :is(.dark .dark\:brightness-110) { - --tw-brightness: brightness(1.1) !important; - } - :is(.dark .dark\:brightness-110), - :is(.dark .dark\:brightness-90) { - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) - var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) - var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important; - } - :is(.dark .dark\:brightness-90) { - --tw-brightness: brightness(0.9) !important; - } - @media (min-width: 576px) { - .sm\:h-14 { - height: 3.5rem !important; - } - .sm\:w-50 { - width: 12.5rem !important; - } - } @media (min-width: 768px) { .md\:mb-0 { margin-bottom: 0 !important; @@ -1276,22 +1141,29 @@
main logo +
+

+ LOADING +

+
- {% with messages = get_flashed_messages(with_categories=true) %} {% if - messages %} - {% for category, message in messages %} - {% endfor %} - - {% endif %} {% endwith %}
@@ -1335,14 +1197,12 @@
logo
-

- Setup Wizard -

+

Setup Wizard

-

+

Account

@@ -1366,7 +1224,7 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
Username
@@ -1375,7 +1233,7 @@ type="text" id="admin_username" name="admin_username" - class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" + class="col-span-12 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" placeholder="enter username" value="{{ username }}" pattern="(.*?)" @@ -1389,7 +1247,7 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
Password
@@ -1398,7 +1256,7 @@ type="password" id="admin_password" name="admin_password" - class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" + class="col-span-12 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" placeholder="enter password" value="{{ password }}" pattern="^(?=.*?\d)(?=.*?[ !\u0022#$%&'\(\)*+,.\/:;<=>?@\[\\\]^_`\u007B\u007C\u007D\u007E\u002D]).{8,}$" @@ -1412,7 +1270,7 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
Confirm Password
@@ -1423,7 +1281,7 @@ type="password" id="admin_password_check" name="admin_password_check" - class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" + class="col-span-12 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" placeholder="confirm password" value="{{ password }}" pattern="^(?=.*?\d)(?=.*?[ !\u0022#$%&'\(\)*+,.\/:;<=>?@\[\\\]^_`\u007B\u007C\u007D\u007E\u002D]).{8,}$" @@ -1438,7 +1296,7 @@

Settings

@@ -1447,7 +1305,7 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
UI Host (REVERSE_PROXY_HOST)
@@ -1457,7 +1315,7 @@ id="ui_host" name="ui_host" value="{{ ui_host }}" - class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" + class="col-span-12 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" placeholder="http://[hostname](:[port])" pattern="^https?:\/\/.{1,255}(:((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4})))?$" required @@ -1469,7 +1327,7 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
UI URL (REVERSE_PROXY_URL)
@@ -1478,7 +1336,7 @@ type="text" id="ui_url" name="ui_url" - class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" + class="col-span-12 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" placeholder="/admin" value="{{ random_url }}" pattern="\/(.*[a-z])" @@ -1491,7 +1349,7 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
Server name
@@ -1500,7 +1358,7 @@ type="text" id="server_name" name="server_name" - class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" + class="col-span-12 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-4 py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500" placeholder="www.example.com" value="www.example.com" pattern=".*" @@ -1513,14 +1371,14 @@ class="flex flex-col relative col-span-12 my-3 mx-2 max-w-[400px] w-full" >
Check server name DN
@@ -1702,27 +1560,25 @@ class Loader { constructor() { this.menuContainer = document.querySelector("[data-menu-container]"); - this.logoContainer = document.querySelector("[data-loader]"); + this.loaderContainer = document.querySelector("[data-loader]"); this.logoEl = document.querySelector("[data-loader-img]"); this.isLoading = true; this.init(); } init() { + this.loaderContainer.setAttribute("aria-hidden", "false"); this.loading(); window.addEventListener("load", (e) => { setTimeout(() => { - this.logoContainer.classList.add("opacity-0"); - }, 350); + this.loaderContainer.classList.add("opacity-0"); + }, 550); setTimeout(() => { this.isLoading = false; - this.logoContainer.classList.add("hidden"); - }, 650); - - setTimeout(() => { - this.logoContainer.remove(); - }, 800); + this.loaderContainer.classList.add("hidden"); + this.loaderContainer.setAttribute("aria-hidden", "true"); + }, 850); }); } @@ -1736,41 +1592,6 @@ } } - class FlashMsg { - constructor() { - this.delayBeforeRemove = 8000; - this.init(); - } - - //remove flash message after this.delay if exist - init() { - window.addEventListener("DOMContentLoaded", () => { - try { - const flashEl = document.querySelector("[data-flash-message]"); - setTimeout(() => { - try { - flashEl.remove(); - } catch (err) {} - }, this.delayBeforeRemove); - } catch (err) {} - }); - - window.addEventListener("click", (e) => { - try { - if ( - e.target - .closest("button") - .hasAttribute("data-close-flash-message") - ) { - const closeBtn = e.target.closest("button"); - const flashEl = closeBtn.closest("[data-flash-message]"); - flashEl.remove(); - } - } catch (err) {} - }); - } - } - class Checkbox { constructor() { this.init(); @@ -1814,16 +1635,25 @@ } } - class CheckPassword { + class SubmitForm { constructor() { this.pwEl = document.querySelector("#admin_password"); this.pwCheckEl = document.querySelector("#admin_password_check"); this.pwAlertEl = document.querySelector("[data-pw-alert]"); this.formEl = document.querySelector("#setup-form"); + this.servInp = document.querySelector("#server_name"); + this.sslCheck = document.querySelector("#auto_lets_encrypt"); + this.urlInp = document.querySelector("#ui_url"); + this.loaderContainer = document.querySelector("[data-loader]"); + this.logoEl = document.querySelector("[data-loader-img]"); + this.loaderMsg = document.querySelector("[data-loader-msg]"); + this.isLoading = false; + this.flashMsg = document.querySelector("[data-flash-message]"); this.init(); } init() { + // Check password to send this.checkSamePW(); this.pwCheckEl.addEventListener("input", (e) => { this.checkSamePW(); @@ -1833,47 +1663,131 @@ this.checkSamePW(); }); - // check that password and password check are the same + // Case error and display msg + window.addEventListener("click", (e) => { + try { + if ( + e.target + .closest("button") + .hasAttribute("data-close-flash-message") + ) { + this.hideErrMsg(); + } + } catch (err) {} + }); + + // Submit this.formEl.addEventListener("submit", (e) => { + // Case not same PW if (this.pwEl.value !== this.pwCheckEl.value) return e.preventDefault(); + + e.preventDefault(); + + // Show loader + this.showLoader(); + this.hideErrMsg(); + // Else, send form and wait for response + + const api = `http${ + this.sslCheck.getAttribute("aria-checked") === "true" ? "s" : "" + }://${this.servInp.value}${this.urlInp.value}`; + + fetch(api, { + method: "POST", + body: new FormData(this.formEl), + }) + .then((res) => { + if (res.status === 200) { + setTimeout(() => { + window.location.href = api; + }, 400); + } + }) + .catch((err) => { + setTimeout(() => { + this.stopLoader(); + this.showErrMsg(); + }, 400); + }); }); } checkSamePW() { if (!this.pwEl.value || !this.pwCheckEl.value) - return this.hideAlert(); + return this.hidePWAlert(); - if (this.pwEl.value !== this.pwCheckEl.value) return this.showAlert(); + if (this.pwEl.value !== this.pwCheckEl.value) + return this.showPWAlert(); - return this.hideAlert(); + return this.hidePWAlert(); } - hideAlert() { + showErrMsg() { + this.flashMsg.classList.remove("hidden"); + this.flashMsg.setAttribute("aria-hidden", "false"); + } + + hideErrMsg() { + this.flashMsg.classList.add("hidden"); + this.flashMsg.setAttribute("aria-hidden", "true"); + } + + hidePWAlert() { this.pwCheckEl.classList.remove( "focus:!border-red-500", - "focus:valid:!border-red-500" + "focus:valid:!border-red-500", + "active:!border-red-500", + "active:valid:!border-red-500", + "valid:!border-red-500" ); this.pwAlertEl.classList.add("opacity-0"); this.pwAlertEl.setAttribute("aria-hidden", "true"); } - showAlert() { + showPWAlert() { this.pwCheckEl.classList.add( "focus:!border-red-500", - "focus:valid:!border-red-500" + "focus:valid:!border-red-500", + "active:!border-red-500", + "active:valid:!border-red-500", + "valid:!border-red-500" ); this.pwAlertEl.classList.remove("opacity-0"); this.pwAlertEl.setAttribute("aria-hidden", "false"); } + + showLoader() { + this.loaderMsg.textContent = "Setting up..."; + // Show loader with animation + this.loaderContainer.classList.add("opacity-0"); + setTimeout(() => { + this.loaderContainer.classList.remove("hidden"); + this.loaderContainer.setAttribute("aria-hidden", "false"); + }, 5); + setTimeout(() => { + this.loaderContainer.classList.remove("opacity-0"); + }, 20); + } + + stopLoader() { + setTimeout(() => { + this.loaderContainer.classList.add("opacity-0"); + }, 350); + + setTimeout(() => { + this.isLoading = false; + this.loaderContainer.classList.add("hidden"); + this.loaderContainer.setAttribute("aria-hidden", "true"); + }, 650); + } } const setLoader = new Loader(); - const setFlash = new FlashMsg(); const setResume = new Resume(); const setCheck = new Checkbox(); const setStateServ = new ServerCheck(); - const setCheckPW = new CheckPassword(); + const setSubmit = new SubmitForm(); From a283c35a20751383a315341269a137a2cfbfbdec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 1 Dec 2023 12:18:58 +0100 Subject: [PATCH 2/3] Add CORS support and update redirect behavior --- src/ui/main.py | 4 +++- src/ui/templates/setup.html | 15 +++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ui/main.py b/src/ui/main.py index a9b207bfe..8b492dae3 100755 --- a/src/ui/main.py +++ b/src/ui/main.py @@ -29,6 +29,7 @@ from docker.errors import ( ) from flask import ( Flask, + Response, flash, jsonify, redirect, @@ -426,6 +427,7 @@ def setup(): "REVERSE_PROXY_URL": request.form["ui_url"] or "/", "AUTO_LETS_ENCRYPT": request.form.get("auto_lets_encrypt", "no"), "INTERCEPTED_ERROR_CODES": "400 404 405 413 429 500 501 502 503 504", + "USE_CORS": "yes", }, request.form["server_name"], request.form["server_name"], @@ -433,7 +435,7 @@ def setup(): kwargs={"operation": "new"}, ).start() - return redirect(url_for("loading", next=url_for("services"), message=f"Creating service {request.form['server_name']} for the web UI")) + return Response(status=200) return render_template( "setup.html", diff --git a/src/ui/templates/setup.html b/src/ui/templates/setup.html index 4e76fc817..ad0578f89 100644 --- a/src/ui/templates/setup.html +++ b/src/ui/templates/setup.html @@ -1693,15 +1693,22 @@ this.sslCheck.getAttribute("aria-checked") === "true" ? "s" : "" }://${this.servInp.value}${this.urlInp.value}`; - fetch(api, { + fetch(window.location.href, { method: "POST", body: new FormData(this.formEl), }) .then((res) => { if (res.status === 200) { - setTimeout(() => { - window.location.href = api; - }, 400); + setInterval(() => { + fetch(api, { + cache: "no-cache", + }) + .then((res) => { + if (res.status === 200 || res.status === 301) { + window.location.replace(api); + } + }); + }, 5000); } }) .catch((err) => { From 589df19c14f8bafeaf0aa02a0e41e7eefeb58708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 1 Dec 2023 15:15:23 +0100 Subject: [PATCH 3/3] Add check endpoint and remove USE_CORS flag --- src/ui/main.py | 9 ++++++++- src/ui/templates/setup.html | 12 ++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ui/main.py b/src/ui/main.py index 8b492dae3..cbc346903 100755 --- a/src/ui/main.py +++ b/src/ui/main.py @@ -353,6 +353,14 @@ def loading(): ) +@app.route("/check", methods=["GET"]) +def check(): + if "Origin" not in request.headers: + return Response(status=403) + + return Response(status=200, headers={"Access-Control-Allow-Origin": "*"}) + + @app.route("/setup", methods=["GET", "POST"]) def setup(): if app.config["USER"]: @@ -427,7 +435,6 @@ def setup(): "REVERSE_PROXY_URL": request.form["ui_url"] or "/", "AUTO_LETS_ENCRYPT": request.form.get("auto_lets_encrypt", "no"), "INTERCEPTED_ERROR_CODES": "400 404 405 413 429 500 501 502 503 504", - "USE_CORS": "yes", }, request.form["server_name"], request.form["server_name"], diff --git a/src/ui/templates/setup.html b/src/ui/templates/setup.html index ad0578f89..c6f910119 100644 --- a/src/ui/templates/setup.html +++ b/src/ui/templates/setup.html @@ -1699,15 +1699,19 @@ }) .then((res) => { if (res.status === 200) { + setTimeout(() => { + window.open(`${api}/login`, "_self"); + }, 60000); setInterval(() => { - fetch(api, { + fetch(`${api}/check`, { cache: "no-cache", }) .then((res) => { - if (res.status === 200 || res.status === 301) { - window.location.replace(api); + if (res.status === 200) { + window.open(`${api}/login`, "_self"); } - }); + }) + .catch((err) => {}); }, 5000); } })