Compare commits

..

8 Commits

Author SHA1 Message Date
74f6e1ab69 Oprava parsování Sladovnická
Opravena chyba, kdy docházelo k posunu nabídky o den, pokud nabídka nezačínala pondělím.
2024-01-03 14:03:38 +01:00
fcad338921 Oprava parsování U Motlíků
Nyní je počítáno s případy, kdy neexistuje nabídka pro první den v daném týdnu.
2024-01-03 14:01:45 +01:00
aca4055d57 Přidání trusted headers do .env.template 2023-12-02 21:07:15 +01:00
4991b813bf Umožnit zadání trusted IPs s bílými znaky 2023-12-02 20:54:39 +01:00
515d4bb47e Opravy překlepů 2023-12-02 20:50:19 +01:00
b9b2492cb4 Odstranění zbytečné proměnné 2023-12-02 20:47:38 +01:00
4ff5d70331 tohle prepsalo muj list ip adres 2023-12-02 19:09:12 +01:00
44de01f6eb doufam ze jsem to hodne rozjebal lol 2023-12-02 17:45:56 +01:00
4 changed files with 72 additions and 32 deletions

View File

@ -360,7 +360,8 @@ function App() {
<Alert variant={'primary'}>
Poslední změny:
<ul>
<li>Tolerance existence menu na více týdnů pro restauraci U Motlíků</li>
<li>Oprava parsování restaurace U Motlíků, pokud neexistuje nabídka pro první den v týdnu</li>
<li>Oprava parsování restaurace Sladovnická, pokud nabídka nezačíná pondělím</li>
</ul>
</Alert>
{dayIndex != null &&

View File

@ -28,3 +28,13 @@
#NTFY_HOST = "http://192.168.0.113:80"
#NTFY_USERNAME="username"
#NTFY_PASSWD="password"
# Zapne přihlašování pomocí důvěryhodných hlaviček (trusted headers). Výchozí hodnota je false.
# V případě zapnutí je nutno vyplnit také HTTP_REMOTE_TRUSTED_IPS.
# HTTP_REMOTE_USER_ENABLED=true
# Seznam IP adres nebo rozsahů oddělených čárkou, ze kterých budou akceptovány důvěryhodné hlavičky.
# HTTP_REMOTE_TRUSTED_IPS=127.0.0.1,192.168.1.0/24
# Název důvěryhodné hlavičky obsahující login uživatele. Výchozí hodnota je 'remote-user'.
# HTTP_REMOTE_USER_HEADER_NAME=remote-user

View File

@ -31,26 +31,46 @@ app.use(cors({
origin: '*'
}));
// Zapínatelný login přes hlavičky - pokud je zapnutý nepovolí "basicauth"
const HTTP_REMOTE_USER_ENABLED = process.env.HTTP_REMOTE_USER_ENABLED || false;
const HTTP_REMOTE_USER_HEADER_NAME = process.env.HTTP_REMOTE_USER_HEADER_NAME || 'remote-user';
if (HTTP_REMOTE_USER_ENABLED) {
if (!process.env.HTTP_REMOTE_TRUSTED_IPS) {
throw new Error('Je zapnutý login z hlaviček, ale není nastaven rozsah adres ze kterých hlavička může přijít.');
}
const HTTP_REMOTE_TRUSTED_IPS = process.env.HTTP_REMOTE_TRUSTED_IPS.split(',').map(ip => ip.trim());
//TODO: nevim jak udelat console.log pouze pro "debug"
//console.log("Budu věřit hlavičkám z: " + HTTP_REMOTE_TRUSTED_IPS);
app.set('trust proxy', HTTP_REMOTE_TRUSTED_IPS);
console.log('Zapnutý login přes hlavičky z proxy.');
}
// ----------- Metody nevyžadující token --------------
app.get("/api/whoami", (req, res) => {
res.send(req.header('remote-user'));
if (!HTTP_REMOTE_USER_ENABLED) {
res.status(403).json({ error: 'Není zapnuté přihlášení z hlaviček' });
}
res.send(req.header(HTTP_REMOTE_USER_HEADER_NAME));
})
app.post("/api/login", (req, res) => {
// Autentizace pomocí trusted headers
const remoteUser = req.header('remote-user');
const remoteName = req.header('remote-name');
if (remoteUser && remoteUser.length > 0 && remoteName && remoteName.length > 0) {
res.status(200).json(generateToken(Buffer.from(remoteName, 'latin1').toString(), true));
return;
if (HTTP_REMOTE_USER_ENABLED) { // je rovno app.enabled('trust proxy')
// Autentizace pomocí trusted headers
const remoteUser = req.header(HTTP_REMOTE_USER_HEADER_NAME);
const remoteName = req.header('remote-name');
if (remoteUser && remoteUser.length > 0 && remoteName && remoteName.length > 0) {
res.status(200).json(generateToken(Buffer.from(remoteName, 'latin1').toString(), true));
}
} else {
// Klasická autentizace loginem
if (!req.body?.login || req.body.login.trim().length === 0) {
throw Error("Nebyl předán login");
}
// TODO zavést podmínky pro délku loginu (min i max)
res.status(200).json(generateToken(req.body.login, false));
}
// Klasická autentizace loginem
if (!req.body?.login || req.body.login.trim().length === 0) {
throw Error("Nebyl předán login");
}
// TODO zavést podmínky pro délku loginu (min i max)
res.status(200).json(generateToken(req.body.login, false));
});
// TODO dočasné řešení - QR se zobrazuje přes <img>, nemáme sem jak dostat token
@ -71,12 +91,14 @@ app.get("/api/qr", (req, res) => {
/** Middleware ověřující JWT token */
app.use("/api/", (req, res, next) => {
const userHeader = req.header('remote-user');
const nameHeader = req.header('remote-name');
const emailHeader = req.header('remote-email');
if (userHeader !== undefined && nameHeader !== undefined) {
const remoteName = Buffer.from(nameHeader, 'latin1').toString();
console.log("Tvuj username, name a email: %s, %s, %s.", userHeader, remoteName, emailHeader);
if (HTTP_REMOTE_USER_ENABLED) {
const userHeader = req.header(HTTP_REMOTE_USER_HEADER_NAME);
const nameHeader = req.header('remote-name');
const emailHeader = req.header('remote-email');
if (userHeader !== undefined && nameHeader !== undefined) {
const remoteName = Buffer.from(nameHeader, 'latin1').toString();
console.log("Tvuj username, name a email: %s, %s, %s.", userHeader, remoteName, emailHeader);
}
}
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Nebyl předán autentizační token' });

View File

@ -137,7 +137,7 @@ export const getMenuSladovnicka = async (firstDayOfWeek: Date, mock: boolean = f
isSoup: false,
});
})
result[index] = currentDayFood;
result[dayIndex] = currentDayFood;
}
return result;
}
@ -157,23 +157,30 @@ export const getMenuUMotliku = async (firstDayOfWeek: Date, mock: boolean = fals
const html = await getHtml(U_MOTLIKU_URL);
const $ = load(html);
// Najdeme první tabulku, nad kterou je v H3 datum začínající prvním dnem aktuálního týdne
// To může selhat mnoha způsoby, ale ty nemá cenu řešit dokud nenastanou
// Najdeme první tabulku, nad kterou je v H3 datum začínající co nejdřívějším dnem v aktuálním týdnu
const tables = $('table.table.table-hover.Xtable-striped');
let usedTable;
const firstDayOfWeekString = `${firstDayOfWeek.getDate()}.${firstDayOfWeek.getMonth() + 1}.`;
for (const tableNode of tables) {
const table = $(tableNode);
const h3 = table.parent().prev();
const s1 = h3.text().split("-")[0].split(".");
const foundFirstDayString = `${s1[0]}.${s1[1]}.`;
if (foundFirstDayString === firstDayOfWeekString) {
usedTable = table;
let usedDate = new Date(firstDayOfWeek.getTime());
for (let i = 0; i < 4; i++) {
const dayOfWeekString = `${usedDate.getDate()}.${usedDate.getMonth() + 1}.`;
for (const tableNode of tables) {
const table = $(tableNode);
const h3 = table.parent().prev();
const s1 = h3.text().split("-")[0].split(".");
const foundFirstDayString = `${s1[0]}.${s1[1]}.`;
if (foundFirstDayString === dayOfWeekString) {
usedTable = table;
}
}
if (usedTable != null) {
break;
}
usedDate.setDate(usedDate.getDate() + 1);
}
if (usedTable == null) {
throw Error(`Nepodařilo se najít tabulku pro datum ${firstDayOfWeekString}`);
const firstDayOfWeekString = `${firstDayOfWeek.getDate()}.${firstDayOfWeek.getMonth() + 1}.`;
throw Error(`Nepodařilo se najít tabulku pro týden začínající ${firstDayOfWeekString}`);
}
const body = usedTable.children().first();