fix(setup): address PR #714 review — password UX, script token, race, nits
Blockers: - SetupPage now mirrors the server password rule (>=8 with upper/lower/digit) so a green client isn't bounced by the server; server errors carry a `field` (routes/setup.js) that the client maps to a translated key instead of rendering raw English. New i18n: setup.invalidToken, setup.passwordRequirements. - picpeak-setup.sh: the ADMIN_CREDENTIALS.txt block no longer dead-ends on the wizard path — when no legacy admin was seeded it prints the one-time setup token (from data/SETUP_TOKEN / docker compose logs) and points at /setup. Concern: - createInitialAdmin creates the admin + burns the token in ONE transaction, atomically claiming the token (null-if-present, expect 1 row) so a double-submit can't create two super_admins. Cross-DB (whereNotNull, trx-only writes). Added a concurrency test. Nits: - SetupPage redirects to /login when /setup/status errors (no form flash on a configured instance). - Dropped the unused DATABASE_URL from docker-compose.yml. - Documented why secrets are chmod 644 (three different reader users).
This commit is contained in:
@@ -45,7 +45,9 @@ router.post('/admin', [
|
||||
res.status(201).json({ user: result.user });
|
||||
} catch (err) {
|
||||
if (err.statusCode) {
|
||||
return res.status(err.statusCode).json({ error: err.message });
|
||||
// `field` (token/email/password) lets the client show a translated
|
||||
// message instead of rendering the raw English error verbatim.
|
||||
return res.status(err.statusCode).json({ error: err.message, field: err.details || undefined });
|
||||
}
|
||||
logger.error('[setup] createInitialAdmin failed', { error: err.message });
|
||||
return res.status(500).json({ error: 'Setup failed' });
|
||||
|
||||
Reference in New Issue
Block a user