167 lines
4.4 KiB
JavaScript
167 lines
4.4 KiB
JavaScript
import sha from "sha512";
|
|
import { setCookie, getCookie } from "cookie";
|
|
import "inputs";
|
|
|
|
const loader = document.getElementById("loader");
|
|
const container = document.getElementById("container");
|
|
const usernameinput = document.getElementById("username");
|
|
const usernamegroup = document.getElementById("usernamegroup");
|
|
const uerrorfield = document.getElementById("uerrorfield");
|
|
const passwordinput = document.getElementById("password");
|
|
const passwordgroup = document.getElementById("passwordgroup");
|
|
const perrorfield = document.getElementById("perrorfield");
|
|
const nextbutton = document.getElementById("nextbutton");
|
|
const loginbutton = document.getElementById("loginbutton");
|
|
|
|
let username;
|
|
let salt;
|
|
|
|
usernameinput.focus();
|
|
|
|
const loading = () => {
|
|
container.style.filter = "blur(2px)";
|
|
loader.style.display = "";
|
|
};
|
|
|
|
const loading_fin = () => {
|
|
container.style.filter = "";
|
|
loader.style.display = "none";
|
|
};
|
|
loading_fin();
|
|
|
|
usernameinput.onkeydown = (e) => {
|
|
var keycode = e.keyCode ? e.keyCode : e.which;
|
|
if (keycode === 13) nextbutton.click();
|
|
clearError(uerrorfield);
|
|
};
|
|
|
|
nextbutton.onclick = async () => {
|
|
loading();
|
|
username = usernameinput.value;
|
|
try {
|
|
let res = await fetch(
|
|
"/api/user/login?type=username&username=" + username,
|
|
{
|
|
method: "POST",
|
|
}
|
|
)
|
|
.then((e) => {
|
|
if (e.status !== 200) throw new Error(e.statusText);
|
|
return e.json();
|
|
})
|
|
.then((data) => {
|
|
if (data.error) {
|
|
return Promise.reject(new Error(data.error));
|
|
}
|
|
return data;
|
|
});
|
|
salt = res.salt;
|
|
usernamegroup.classList.add("invisible");
|
|
passwordgroup.classList.remove("invisible");
|
|
passwordinput.focus();
|
|
} catch (e) {
|
|
showError(uerrorfield, e.message);
|
|
}
|
|
loading_fin();
|
|
};
|
|
|
|
passwordinput.onkeydown = (e) => {
|
|
var keycode = e.keyCode ? e.keyCode : e.which;
|
|
if (keycode === 13) loginbutton.click();
|
|
clearError(perrorfield);
|
|
};
|
|
|
|
loginbutton.onclick = async () => {
|
|
loading();
|
|
let pw = sha(salt + passwordinput.value);
|
|
try {
|
|
let { login, special, tfa } = await fetch(
|
|
"/api/user/login?type=password",
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
username: usernameinput.value,
|
|
password: pw,
|
|
}),
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
}
|
|
)
|
|
.then((e) => {
|
|
if (e.status !== 200) throw new Error(e.statusText);
|
|
return e.json();
|
|
})
|
|
.then((data) => {
|
|
if (data.error) {
|
|
return Promise.reject(new Error(data.error));
|
|
}
|
|
return data;
|
|
});
|
|
|
|
setCookie("login", login.token, new Date(login.expires).toUTCString());
|
|
setCookie(
|
|
"special",
|
|
special.token,
|
|
new Date(special.expires).toUTCString()
|
|
);
|
|
let d = new Date();
|
|
d.setTime(d.getTime() + 30 * 24 * 60 * 60 * 1000); //Keep the username 30 days
|
|
setCookie("username", username, d.toUTCString());
|
|
let url = new URL(window.location.href);
|
|
let state = url.searchParams.get("state");
|
|
let red = "/";
|
|
|
|
if (tfa) twofactor(tfa);
|
|
else {
|
|
if (state) {
|
|
let base64 = url.searchParams.get("base64");
|
|
if (base64) red = atob(state);
|
|
else red = state;
|
|
}
|
|
window.location.href = red;
|
|
}
|
|
} catch (e) {
|
|
passwordinput.value = "";
|
|
showError(perrorfield, e.message);
|
|
}
|
|
loading_fin();
|
|
};
|
|
|
|
function clearError(field) {
|
|
field.innerText = "";
|
|
field.classList.add("invisible");
|
|
}
|
|
|
|
function showError(field, error) {
|
|
field.innerText = error;
|
|
field.classList.remove("invisible");
|
|
}
|
|
|
|
username = getCookie("username");
|
|
if (username) {
|
|
usernameinput.value = username;
|
|
|
|
var evt = document.createEvent("HTMLEvents");
|
|
evt.initEvent("change", false, true);
|
|
usernameinput.dispatchEvent(evt);
|
|
}
|
|
|
|
function twofactor(tfa) {
|
|
let list = tfa
|
|
.map((entry) => {
|
|
switch (entry) {
|
|
case 0: // OTC
|
|
return "Authenticator App";
|
|
case 1: // BACKUP
|
|
return "Backup Key";
|
|
}
|
|
return undefined;
|
|
})
|
|
.filter((e) => e !== undefined)
|
|
.reduce((p, c) => p + `<li>${c}</li>`, "");
|
|
|
|
let tfl = document.getElementById("tflist");
|
|
tfl.innerHTML = list;
|
|
}
|