Add server status check

This commit is contained in:
olcxja 2026-04-30 21:05:30 +02:00
commit e908702025
3 changed files with 105 additions and 21 deletions

View file

@ -176,7 +176,8 @@
<form id="form-login"> <form id="form-login">
<div class="input-group"> <div class="input-group">
<label for="login-host">Server Host</label> <label for="login-host">Server Host</label>
<input type="text" id="login-host" placeholder="example.com" autocomplete="url"> <input type="text" id="login-host" placeholder="example.com" autocomplete="url" onchange="loginHostChanged()">
<p class="mininote serverstatus">Connecting...</p>
</div> </div>
<div class="input-group"> <div class="input-group">
@ -210,7 +211,8 @@
<form id="form-register"> <form id="form-register">
<div class="input-group"> <div class="input-group">
<label for="reg-host">Server Host</label> <label for="reg-host">Server Host</label>
<input type="text" id="reg-host" placeholder="example.com" autocomplete="url"> <input type="text" id="reg-host" placeholder="example.com" autocomplete="url" onchange="regHostChanged()">
<p class="mininote serverstatus">Connecting...</p>
</div> </div>
<div class="input-group"> <div class="input-group">
@ -229,7 +231,7 @@
<input type="password" id="reg-confirm" placeholder="Repeat password" autocomplete="new-password"> <input type="password" id="reg-confirm" placeholder="Repeat password" autocomplete="new-password">
</div> </div>
<button type="submit" class="submit-button"> <button type="submit" class="submit-button" id="register-button">
Sign Up Sign Up
</button> </button>
</form> </form>
@ -255,7 +257,7 @@
<input type="text" id="captcha-input" placeholder="Captcha code" autocomplete="off"> <input type="text" id="captcha-input" placeholder="Captcha code" autocomplete="off">
</div> </div>
<div class="input-group"> <div class="input-group" id="regkey-group">
<label for="regkey-input">Invitation code</label> <label for="regkey-input">Invitation code</label>
<input type="text" id="regkey-input" placeholder="Invitation code" autocomplete="off"> <input type="text" id="regkey-input" placeholder="Invitation code" autocomplete="off">
</div> </div>
@ -299,6 +301,9 @@
const loginPassword = document.getElementById("login-password"); const loginPassword = document.getElementById("login-password");
const captchaCode = document.getElementById("captcha-input"); const captchaCode = document.getElementById("captcha-input");
const regKeyInput = document.getElementById("regkey-input"); const regKeyInput = document.getElementById("regkey-input");
const registerButton = document.getElementById("register-button");
const regKeyGroup = document.getElementById("regkey-group");
toRegister.addEventListener('click', () => { toRegister.addEventListener('click', () => {
container.className = 'auth-container show-register'; container.className = 'auth-container show-register';
@ -345,6 +350,9 @@
formRegister.addEventListener('submit', async (e) => { formRegister.addEventListener('submit', async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
captchaCode.value = "";
regKeyInput.value = "";
url = `${window.location.protocol}//${registerHost.value}/_larpix`; url = `${window.location.protocol}//${registerHost.value}/_larpix`;
if (!registerUsername.value || registerUsername.value.trim() === '') { if (!registerUsername.value || registerUsername.value.trim() === '') {
@ -357,6 +365,11 @@
container.className = 'auth-container show-register'; container.className = 'auth-container show-register';
return; return;
} }
if (registerPassword.value != registerPasswordConfirm.value) {
showNotification("Passwords do not match", "error");
container.className = 'auth-container show-register';
return;
}
let dataarray = keyDataFromServerJson(await fetchAsync(`${url}/createaccount?step=init`)); let dataarray = keyDataFromServerJson(await fetchAsync(`${url}/createaccount?step=init`));
var sharedkey = await calcCommunicationKeyClient(dataarray[0], dataarray[1], dataarray[2]); var sharedkey = await calcCommunicationKeyClient(dataarray[0], dataarray[1], dataarray[2]);
sharedpvkey = sharedkey[1]; sharedpvkey = sharedkey[1];
@ -401,7 +414,7 @@
try { try {
const captchaValue = document.getElementById('captcha-input').value; const captchaValue = captchaCode.value;
if (captchaValue) { if (captchaValue) {
let res = await fetchPost(`${url}/createaccount?step=finish`, JSON.stringify({ let res = await fetchPost(`${url}/createaccount?step=finish`, JSON.stringify({
idKey: createId, idKey: createId,
@ -433,6 +446,53 @@
container.className = 'auth-container show-register'; container.className = 'auth-container show-register';
} }
}); });
async function regHostChanged()
{
loginHost.value = registerHost.value;
await updateLoginForm(registerHost.value);
}
async function loginHostChanged()
{
registerHost.value = loginHost.value;
await updateLoginForm(loginHost.value);
}
async function updateLoginForm(host)
{
try {
let serverInfo = await getServerInfo(host);
if (serverInfo["registration"] == "disabled")
{
registerButton.innerHTML = "Registration disabled";
}
else if (serverInfo["registration"] == "enabled")
{
registerButton.innerHTML = "Sign up";
regKeyGroup.style.display = "";
}
else if (serverInfo["registration"] == "code")
{
regKeyGroup.style.display = "none";
}
setServerStatus("Server pinged", "green");
}
catch(error)
{
console.log(error);
setServerStatus("Can't ping this server", "red");
}
}
function setServerStatus(status, color)
{
let elements = document.getElementsByClassName("serverstatus");
for (let i = 0;i < elements.length;i++) {
elements[i].className = `mininote serverstatus ${status} ${color}`;
elements[i].innerHTML = status;
}
}
loginHostChanged();
</script> </script>
</body> </body>
</html> </html>

26
main.js
View file

@ -26,7 +26,7 @@ async function getNonce(username, key) {
let nonce; let nonce;
let fetchRes = await (await fetch(`${url}/nextnonce?u=${username}`)).text(); let fetchRes = await (await fetch(`${url}/nextnonce?u=${username}`)).text();
console.log(key, fetchRes);
try { try {
nonce = await decryptString(fetchRes, key); nonce = await decryptString(fetchRes, key);
} }
@ -229,20 +229,34 @@ async function fetchPostEnc(url, value) {
async function fetchAsync(url) { async function fetchAsync(url) {
let response = await fetch(url, { let response = await fetch(url, {
method: "GET", method: "GET",
credentials: "omit", credentials: "omit"
headers: {
"secret": await encryptWithNonce(passwordHash, passwordHash, await getNonce(username, passwordHash))
}
}); });
let data = await response.text(); let data = await response.text();
return data; return data;
} }
async function fetchAsyncWAuth(url) {
let response = await fetch(url, {
method: "GET",
credentials: "omit",
headers: {
"secret": await encryptWithNonce(passwordHash, passwordHash, await getNonce(username, passwordHash))
}
});
let data = await response.text();
return data;
}
async function getServerInfo(host){
console.log(`${window.location.protocol}//${host}/_larpix/serverinfo`)
return JSON.parse(await fetchAsync(`${window.location.protocol}//${host}/_larpix/serverinfo`));
}
async function Auth(username, password) { async function Auth(username, password) {
let passwordHash = await hashSHA3_512(password); let passwordHash = await hashSHA3_512(password);
console.log(username, password, passwordHash);
let response = await fetch(`${url}/auth?u=${username}`, { let response = await fetch(`${url}/auth?u=${username}`, {
method: "GET", method: "GET",
credentials: "omit", credentials: "omit",

View file

@ -20,8 +20,12 @@
.red { .red {
color: var(--big-red); color: var(--big-red);
} }
.green {
color: var(--big-green);
}
.mininote { .mininote {
font-size: 80%; font-size: 80%;
padding: 0 0.5rem;
} }
html { html {
font-size: max(16px, calc(100vw / 120)); font-size: max(16px, calc(100vw / 120));
@ -162,35 +166,41 @@ hr {
} }
#notification-container { #notification-container {
position: fixed; position: fixed;
top: 2vw; top: 1.5rem;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
z-index: 1500; z-index: 1500;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1vw; gap: 0.8rem;
pointer-events: none; pointer-events: none;
align-items: center; align-items: center;
} }
.notification { .notification {
background: rgba(10, 10, 14, 0.7); background: rgba(255, 255, 255, 0.015);
backdrop-filter: blur(1rem); backdrop-filter: blur(1.2rem);
-webkit-backdrop-filter: blur(1rem); -webkit-backdrop-filter: blur(1.2rem);
border: 0.1rem solid var(--light-border-color);
border-radius: 0.8rem; border: var(--border-width) solid var(--light-border-color);
padding: 1rem 2rem; border-radius: 0.9rem;
padding: 0.8rem 1.3rem;
color: var(--text-color); color: var(--text-color);
font-size: 1.1rem; font-size: 1rem;
font-weight: 500;
text-align: center; text-align: center;
box-shadow: 0 0.25rem 1.875rem rgba(0, 0, 0, 0.5);
box-shadow: 0 0.5rem 2rem rgba(0, 0, 0, 0.4);
opacity: 0; opacity: 0;
transform: translateY(-5vw); transform: translateY(-1rem);
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); transition:
opacity 0.3s ease,
transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275),
background-color 0.2s ease;
} }
.notification.show { .notification.show {