access: Add token auth support for access-multiple.js
This commit is contained in:
@ -1,85 +1,58 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
window.CLIENTS = window.CLIENTS || [];
|
window.CLIENT = window.CLIENT || null;
|
||||||
|
window.CLIENTS = window.CLIENTS || {};
|
||||||
|
|
||||||
function getCredentialsUsername(client) {
|
function getStoredUsername(client) {
|
||||||
return window.localStorage.getItem(`${CLIENT}/${client}/username`);
|
return window.localStorage.getItem(`${CLIENT}/${client}/username`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCredentialsPassword(client) {
|
function getStoredToken(client) {
|
||||||
return window.localStorage.getItem(`${CLIENT}/${client}/password`);
|
return window.localStorage.getItem(`${CLIENT}/${client}/token`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBasicAuth(client) {
|
function getAuthorizationHeader(client) {
|
||||||
return {
|
return {
|
||||||
'Authorization': 'Basic ' + btoa(getCredentialsUsername(client) + ':' + getCredentialsPassword(client)),
|
'Authorization': 'Bearer ' + window.localStorage.getItem(`${CLIENT}/${client}/token`),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _get(client, path) {
|
async function authenticate(client, username, password) {
|
||||||
|
const res = await fetch(`${CLIENTS[client]['api']}/auth`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {'Authorization': 'Basic ' + btoa(username + ':' + password)},
|
||||||
|
});
|
||||||
|
const json = await res.json();
|
||||||
|
if (!res.ok) throw new ApiError(res.status, json['message']);
|
||||||
|
return json['token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function get(client, path) {
|
||||||
const res = await fetch(`${CLIENTS[client]['api']}${path}`, {
|
const res = await fetch(`${CLIENTS[client]['api']}${path}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {...getBasicAuth(client)},
|
headers: {...getAuthorizationHeader(client)},
|
||||||
});
|
});
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
if (!res.ok) throw new ApiError(res.status, json['message']);
|
if (!res.ok) throw new ApiError(res.status, json['message']);
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function get(client, path) {
|
|
||||||
return (await _get(client, path))['data'];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getWineVarieties(client) {
|
|
||||||
return Object.fromEntries((await get(client, '/wine/varieties')).map(item => [item['sortid'], item]));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getWineQualityLevels(client) {
|
|
||||||
return Object.fromEntries((await get(client, '/wine/quality_levels')).map(item => [item['qualid'], item]));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getDeliverySchedules(client, filters, limit, offset) {
|
async function getDeliverySchedules(client, filters, limit, offset) {
|
||||||
const query = [];
|
const query = [];
|
||||||
if (!!filters) query.push(`filters=${filters.join(',')}`);
|
if (!!filters) query.push(`filters=${filters.join(',')}`);
|
||||||
if (!!limit) query.push(`limit=${limit}`);
|
if (!!limit) query.push(`limit=${limit}`);
|
||||||
if (!!offset) query.push(`offset=${offset}`);
|
if (!!offset) query.push(`offset=${offset}`);
|
||||||
return await _get(client, `/delivery_schedules${!!query ? '?' : ''}${query.join('&')}`);
|
return await get(client, `/delivery_schedules${!!query ? '?' : ''}${query.join('&')}`);
|
||||||
}
|
|
||||||
|
|
||||||
async function load(client) {
|
|
||||||
const main = document.getElementById("access");
|
|
||||||
const form = main.getElementsByTagName("form")[0];
|
|
||||||
if (form) {
|
|
||||||
const elements = form.getElementsByClassName('error');
|
|
||||||
for (const e of elements) form.removeChild(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
window.WINE_VARIETIES = await getWineVarieties(client);
|
|
||||||
window.WINE_QUALITY_LEVELS = await getWineQualityLevels(client);
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
if (form) {
|
|
||||||
window.localStorage.removeItem(`${CLIENT}/${client}/password`);
|
|
||||||
const error = document.createElement('div');
|
|
||||||
error.className = 'error';
|
|
||||||
error.innerText = e.localizedMessage ?? ERROR_MESSAGES[e.message] ?? 'Unbekannter Fehler';
|
|
||||||
form.insertBefore(error, form.lastChild.previousSibling);
|
|
||||||
} else {
|
|
||||||
window.location.hash = `#/${client}/login`;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
//await load();
|
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateOverview(client) {
|
async function updateOverview(client) {
|
||||||
const [schedules] = await Promise.all([getDeliverySchedules(client, [`year=${getCurrentLastSeason()}`])]);
|
const [schedules] = await Promise.all([getDeliverySchedules(client, [`year=${getCurrentLastSeason()}`])]);
|
||||||
const rows = [];
|
const rows = [];
|
||||||
const days = groupBy(schedules.data, 'date');
|
const days = groupBy(schedules['data'], 'date');
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
for (const [dateString, day] of Object.entries(days)) {
|
for (const [dateString, day] of Object.entries(days)) {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
@ -132,12 +105,12 @@ function render() {
|
|||||||
|
|
||||||
const client = Object.keys(CLIENTS).find(id => hash.startsWith(`#/${id}/`) || hash === `#/${id}`);
|
const client = Object.keys(CLIENTS).find(id => hash.startsWith(`#/${id}/`) || hash === `#/${id}`);
|
||||||
if (client === undefined) {
|
if (client === undefined) {
|
||||||
window.location.hash = `#/${Object.keys(CLIENTS).find(id => !!getCredentialsUsername(id) && !!getCredentialsPassword(id)) || Object.keys(CLIENTS)[0]}`;
|
window.location.hash = `#/${Object.keys(CLIENTS).find(id => !!getStoredUsername(id) && !!getStoredToken(id)) || Object.keys(CLIENTS)[0]}`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nav.children[Object.keys(CLIENTS).indexOf(client)].className = 'active';
|
nav.children[Object.keys(CLIENTS).indexOf(client)].className = 'active';
|
||||||
|
|
||||||
if ((!getCredentialsUsername(client) || !getCredentialsPassword(client)) && window.location.hash !== `#/${client}/login`) {
|
if ((!getStoredUsername(client) || !getStoredToken(client)) && window.location.hash !== `#/${client}/login`) {
|
||||||
window.location.hash = `#/${client}/login`;
|
window.location.hash = `#/${client}/login`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -147,7 +120,7 @@ function render() {
|
|||||||
main.innerHTML = `
|
main.innerHTML = `
|
||||||
<form onsubmit="return actionLogin(this);">
|
<form onsubmit="return actionLogin(this);">
|
||||||
<h1>Anmelden</h1>
|
<h1>Anmelden</h1>
|
||||||
<input type="text" name="username" placeholder="Benutzername" value="${getCredentialsUsername(client) ?? ''}"/>
|
<input type="text" name="username" placeholder="Benutzername" value="${getStoredUsername(client) ?? ''}"/>
|
||||||
<input type="password" name="password" placeholder="Kennwort"/>
|
<input type="password" name="password" placeholder="Kennwort"/>
|
||||||
<input type="hidden" name="client" value="${client}"/>
|
<input type="hidden" name="client" value="${client}"/>
|
||||||
<button type="submit">Anmelden</button>
|
<button type="submit">Anmelden</button>
|
||||||
@ -179,19 +152,29 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
setInterval(update, 60_000);
|
setInterval(update, 60_000);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('hashchange', () => {
|
window.addEventListener('hashchange', render);
|
||||||
render();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener('pageshow', update)
|
window.addEventListener('pageshow', update)
|
||||||
|
|
||||||
document.addEventListener('visibilitychange', update);
|
document.addEventListener('visibilitychange', update);
|
||||||
|
|
||||||
function actionLogin(form) {
|
function actionLogin(form) {
|
||||||
window.localStorage.setItem(`${CLIENT}/${form.client.value}/username`, form.username.value);
|
const elements = form.getElementsByClassName('error');
|
||||||
window.localStorage.setItem(`${CLIENT}/${form.client.value}/password`, form.password.value);
|
for (const e of elements) form.removeChild(e);
|
||||||
load(form.client.value).then(success => {
|
|
||||||
if (success) window.location.hash = `#/${form.client.value}`;
|
const client = form['client'].value;
|
||||||
});
|
window.localStorage.setItem(`${CLIENT}/${client}/username`, form['username'].value);
|
||||||
|
|
||||||
|
authenticate(client, form['username'].value, form['password'].value)
|
||||||
|
.then(token => {
|
||||||
|
window.localStorage.setItem(`${CLIENT}/${client}/token`, token);
|
||||||
|
window.location.hash = `#/${client}`;
|
||||||
|
}).catch(e => {
|
||||||
|
const error = document.createElement('div');
|
||||||
|
error.className = 'error';
|
||||||
|
error.innerText = e.localizedMessage ?? ERROR_MESSAGES[e.message] ?? 'Unbekannter Fehler';
|
||||||
|
form.insertBefore(error, form.lastChild.previousSibling);
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
window.CLIENT = window.CLIENT || null;
|
||||||
window.ELWIG_API = window.ELWIG_API || null;
|
window.ELWIG_API = window.ELWIG_API || null;
|
||||||
|
|
||||||
function getCredentialsUsername() {
|
function getCredentialsUsername() {
|
||||||
|
Reference in New Issue
Block a user