8.8 KiB
type, title, description, tags, timestamp
| type | title | description | tags | timestamp | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| guide | Admin — System (Backup, Restore, Danger Zone) | How an admin navigates to /admin/system, creates a backup, stages and commits a restore, resets all scores, and wipes challenges — including the re-authentication confirmation, progress, and side effects. |
|
2026-07-23T12:04:50Z |
Navigation
- Sign in as an admin and open the admin side-nav (see the Admin Shell guide).
- Click System in the side-nav. The route resolves to
/admin/systemand lazily loads theAdminSystemComponentstandalone component. - The page renders two panels side by side: Database (left) and Danger Zone (right). On narrow screens they stack vertically.
Database panel
Create a backup
- Click Create backup (data-testid
admin-system-create-backup). A spinner appears inside the button while the request is in flight. - The browser receives a JSON file via
Content-Disposition: attachment; filename="hipctf-backup-YYYY-MM-DD.json"and the browser download UI saves it to disk. - On success the panel shows a green Backup ready. status line
(data-testid
admin-system-backup-success). - On failure the panel shows a red error message under the buttons
(data-testid
admin-system-backup-error). The friendly message comes fromsystem.pure.tsand resolvesSYSTEM_BACKUP_FAILED,SYSTEM_FILE_READ_FAILED,UNAUTHORIZED,FORBIDDEN, etc.
Restore a backup
- Click Restore backup (data-testid
admin-system-restore-backup). A hidden file picker opens restricted toapplication/json/.json. - Pick a backup JSON file. The progress line shows
Reading selected backup…, then Validating backup
server-side… (data-testid
admin-system-restore-progress). - The server validates the JSON, decodes uploads, and verifies
sizes/checksums. On success a summary card appears
(data-testid
admin-system-restore-summary) showing:- Tables detected
- Uploaded files
- Total bytes
- Stage expiry (ISO timestamp)
- From the summary card, the admin has two options:
- Discard staged backup (data-testid
admin-system-discard-restore) — drops the staged state and resumes from a clean panel. - Continue to destructive restore… (data-testid
admin-system-confirm-restore) — opens the confirmation modal.
- Discard staged backup (data-testid
Confirmation modal (restore-backup)
- The modal title is Restore database?.
- The detail paragraph explains that the entire database and uploads
will be replaced (the modal's
preservedline says Nothing is preserved). - The stage banner explicitly warns: You will be logged out after restore completes.
- The admin must enter their current password and type
RESTORE BACKUPexactly into the confirmation phrase field. - Click Confirm. The modal swaps the input fields for a Working… spinner.
- The frontend calls
POST /confirmationswith{ operation: 'restore-backup', password, stagingId }to receive a single-use token, then immediately callsPOST /restore/commitwith that token and the staging id. - On success the SPA calls
AuthService.forceServerInvalidation(), resets theUserStore, and navigates to/login. TheChallengesStoreandScoreboardStoreinvalidate themselves via theSystemDataChangeService'restore-completed'event. - On failure the modal stays open and shows the resolved error
(e.g.
SYSTEM_TOKEN_MISMATCH,SYSTEM_RESTORE_ROLLED_BACK). The database panel also reflects the error inline.
Danger Zone panel
The danger zone panel is outlined by a dashed red border and contains two red buttons:
| Button | Operation |
|---|---|
admin-system-reset-scores |
reset-scores |
admin-system-wipe-challenges |
wipe-challenges |
Each button opens the same confirmation modal with operation-specific copy:
- Reset all scores? — detail lists what is removed
(every solve and award), preserved (users, sessions, roles,
challenges, categories, etc.). Confirmation phrase:
RESET SCORES. - Wipe all challenges? — detail explains that every challenge, its
attached files, every solve, and every award are removed, and that
every uploaded challenge file on disk is deleted. Preserved:
users, sessions, roles, categories, settings, blog posts, and
root-level uploads (e.g. the site logo). Confirmation phrase:
WIPE CHALLENGES.
After the admin enters their password and types the confirmation
phrase, the SPA re-authenticates to issue a token and then commits the
operation. The panel shows a green summary
(N solve record(s) removed. or N challenge(s), M file(s) wiped.)
and a toast notification. The corresponding stores
(ChallengesStore, ScoreboardStore) automatically reset themselves
via the SystemDataChangeService scores-reset and challenges-wiped
events so every open tab sees fresh data.
Cross-tab invalidation
After any of the destructive operations, the
SystemDataChangeService notifies all subscribers in the same tab via
an Angular signal. The injected effects in ChallengesStore and
ScoreboardStore reset their cached board/matrix/event-log/graph
data. For a restore, the SPA additionally forces a cross-tab
invalidation by calling AuthService.forceServerInvalidation(),
which clears the access token and notifies peer tabs via
BroadcastChannel + the storage-event fallback so they redirect to
/login as well.
Error mapping
The pure helper friendlySystemErrorMessage(op, err) in
system.pure.ts converts the backend error codes into user-facing
messages. Notable mappings:
| Backend code | UI message |
|---|---|
SYSTEM_REAUTH_REQUIRED |
"Your session is no longer valid. Please log in again." |
SYSTEM_INVALID_CREDENTIALS |
"The current password is incorrect." |
SYSTEM_TOKEN_INVALID / _EXPIRED |
"Confirmation token is invalid / expired. Re-authenticate and try again." |
SYSTEM_TOKEN_REUSED |
"Confirmation token was already used. Re-authenticate to get a fresh token." |
SYSTEM_TOKEN_MISMATCH |
"Confirmation token does not match this operation." |
SYSTEM_RESTORE_VALIDATION_FAILED |
"Backup validation failed. No data was changed." |
SYSTEM_RESTORE_PAYLOAD_TOO_LARGE |
"The backup is larger than the configured upload limit." |
SYSTEM_RESTORE_STAGE_EXPIRED |
"The backup staging window expired. Re-upload and validate again." |
SYSTEM_RESTORE_ROLLED_BACK |
"Restore failed and was rolled back. Your data is unchanged." |
SYSTEM_DANGER_ROLLED_BACK |
"Operation failed and was rolled back. Nothing was changed." |
SYSTEM_BACKUP_FAILED |
"Backup could not be generated. No data was changed." |
SYSTEM_DANGER_FAILED |
"Operation could not complete. No data was changed." |
SYSTEM_OPERATION_IN_PROGRESS |
"Another destructive operation is currently running." |
Examples
Manual restore happy path
- Download the backup from a known-good environment.
- Sign in as the admin on the target environment.
- Navigate to
/admin/system, click Restore backup, select the downloaded file. - Verify the summary matches the expected table counts and file counts.
- Click Continue to destructive restore…, enter the admin
password, type
RESTORE BACKUP, click Confirm. - The modal closes, the page shows a brief Restore complete.
Logging out… toast, and the SPA navigates to
/login. - Sign in again with the same admin credentials. The data on the target environment now matches the source backup.
Manual reset happy path
- Navigate to
/admin/system. - Click Reset all scores, enter the password, type
RESET SCORES, click Confirm. - The danger zone panel shows the number of solve records removed and a toast notifies the operation completed. Refresh the Scoreboard page — every player is back at zero.
Manual wipe happy path
- Navigate to
/admin/system. - Click Wipe challenges, enter the password, type
WIPE CHALLENGES, click Confirm. - The danger zone panel shows counts of challenges, files, and
solves removed. The Challenges page becomes empty and the
/admin/challengeslist is empty. Thechallenges/folder on disk is also gone.