Files
2026-09-09 13:53:51 +02:00

3.6 KiB

Administrator recovery

Run tools/remote backend prepare-admin-recovery explicitly when the last administrator has been deleted. It refuses recovery while any administrator exists, including an inactive administrator. It is never run by CI or automatically at startup.

The command uses the configured BACKEND_SSH (default mih04-werkjournal@mih04.hostsharing.net) and the managed Hostsharing layout. It acquires the deployment lock, checks service/database paths, refuses pending deployment or existing maintenance, enables the public maintenance page, stops the service and checks that its process has exited. The installed JDK runs the current JAR in a dedicated offline mode against the existing ~/opt/werkjournal/data/werkjournal H2 database with IFEXISTS=TRUE. This mode does not start Spring, run migrations or send mail.

The database transaction changes only the admission-control row: it permanently consumes the original bootstrap authorization and stores a digest of a new random 256-bit recovery code with a 24-hour expiry. Repeating the command replaces the previous recovery code. Existing accounts and tracking data remain intact. H2's file lock prevents opening the live application database concurrently.

The plaintext code is captured into ~/.config/werkjournal/admin-recovery-code with mode 0600 in a private directory. It is not printed in command output or sent as a process argument. Read this file privately via SSH; do not paste it into build logs or tickets. Select Setup / recovery on the login page and enter the code with your email address. Complete the normal email proof (code or alternative link, valid for two hours). Only then is the administrator created, or an existing active account promoted while retaining its identity and data. Admission is serialized and eligibility is rechecked at redemption; the recovery authorization is cleared atomically. Remove the plaintext server file after successful use; leaving it does not extend its validity or permit reuse.

After the offline command the wrapper starts the service and checks application/Flow readiness before removing maintenance. A refused recovery also restarts the unchanged application. Failed readiness leaves maintenance enabled. No snapshot rollback is used for this operation: restoring old data could reactivate deleted accounts or lose recent records.

If the SSH process is interrupted, inspect the service and maintenance state. Start werkjournal-backend.service with systemctl --user start, verify local application readiness and logs, then remove ~/doms/werkjournal.javagil.de/htdocs-ssl/maintenance.flag. Do not remove maintenance while a deployment is pending; use the existing deployment recovery procedure in that case. If no code file was written, repeat the recovery command after restoring service operation; the new authorization supersedes any inaccessible code.

Validation uses isolated databases and controlled service/mail implementations, never a production administrator reset or real email delivery. Tests cover email proof, replacement, expiry at redemption, the consumed original bootstrap, refusal with active/inactive administrators, existing-account data retention, service restart after refusal, maintenance retention on readiness failure, private code storage and refusal of conflicting maintenance or symlinks.

Full local CI passed at 0.1.12-SNAPSHOT: 131 JVM tests executed, one separate browser harness skipped, 26 operations tests and 17 frontend tests. Production smoke passed and ran the actual packaged offline command twice against its migrated H2 file, verifying successful code rotation without emitting secrets. No schema migration was needed.