fix(design): Farbwelt und Modus bleiben nach dem Neuladen erhalten
requireAuth hat den Benutzer mit einer ausgeschriebenen Spaltenliste geladen, in der theme und theme_mode fehlten. GET /api/auth/me antwortete deshalb mit null, und der ThemeProvider hat das beim Neuladen als "nichts gewaehlt" gelesen: die Anzeige fiel auf perinco/System zurueck und hat den localStorage-Zwischenspeicher gleich mit ueberschrieben. Direkt nach dem Klick und nach dem Anmelden sah es richtig aus, weil PATCH /me den geaenderten Wert selbst zurueckgibt und der Login SELECT * benutzt - nur das Neuladen nicht. Dazu ein Test, der die Spaltenliste mit den Feldern von publicUser() vergleicht, damit ein neues Benutzerfeld nicht wieder still verloren geht. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
71a8c30b23
commit
a50f5cb4a6
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Prueft, dass die Sitzung alle Felder mitbringt, die die API ausliefert.
|
||||
*
|
||||
* requireAuth() laedt den Benutzer mit einer ausgeschriebenen Spaltenliste
|
||||
* (kein SELECT *, damit das Passwort-Hash nicht am Request haengt). publicUser()
|
||||
* liest daraus. Fehlt dort eine Spalte, antwortet die API stillschweigend mit
|
||||
* null - genau so ist die gespeicherte Designwahl beim Neuladen verloren
|
||||
* gegangen: GET /api/auth/me lieferte theme = null, das Frontend hielt das fuer
|
||||
* "nichts gewaehlt" und ist auf den Standard zurueckgefallen.
|
||||
*/
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
let failures = 0;
|
||||
|
||||
function check(name, condition, detail = '') {
|
||||
if (condition) {
|
||||
console.log(` ok ${name}${detail ? ` - ${detail}` : ''}`);
|
||||
} else {
|
||||
console.log(` FAIL ${name}${detail ? ` - ${detail}` : ''}`);
|
||||
failures += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const middleware = readFileSync(new URL('../src/middleware/auth.js', import.meta.url), 'utf8');
|
||||
const routes = readFileSync(new URL('../src/routes/auth.js', import.meta.url), 'utf8');
|
||||
|
||||
console.log('\nSitzungsbenutzer');
|
||||
|
||||
const select = /`SELECT id,([\s\S]*?)FROM crm_users WHERE id = \?/.exec(middleware);
|
||||
check('Spaltenliste in requireAuth gefunden', Boolean(select));
|
||||
|
||||
const publicUser = /function publicUser\(row\) \{([\s\S]*?)\n\}/.exec(routes);
|
||||
check('publicUser in routes/auth.js gefunden', Boolean(publicUser));
|
||||
|
||||
if (select && publicUser) {
|
||||
const columns = [
|
||||
'id',
|
||||
...select[1]
|
||||
.split(',')
|
||||
.map((entry) => entry.trim())
|
||||
.filter(Boolean),
|
||||
];
|
||||
const used = [...new Set([...publicUser[1].matchAll(/row\.([a-z_]+)/g)].map((m) => m[1]))];
|
||||
const missing = used.filter((field) => !columns.includes(field));
|
||||
|
||||
check(
|
||||
'requireAuth laedt jede Spalte, die publicUser ausliefert',
|
||||
missing.length === 0,
|
||||
missing.length ? `fehlt: ${missing.join(', ')}` : `${used.length} Felder geprueft`
|
||||
);
|
||||
check('theme und theme_mode sind dabei', columns.includes('theme') && columns.includes('theme_mode'));
|
||||
check('Das Passwort-Hash bleibt draussen', !columns.includes('password_hash'));
|
||||
}
|
||||
|
||||
console.log(
|
||||
failures === 0 ? '\nAlle Pruefungen bestanden.' : `\n${failures} Pruefung(en) fehlgeschlagen.`
|
||||
);
|
||||
process.exit(failures === 0 ? 0 : 1);
|
||||
Reference in New Issue
Block a user