Raven CMS Preferences
This document explains Raven's user Preferences screen for both panel users and developers/agents.
Maintenance note: keep this file updated whenever Preferences routes, validation/avatar behavior, or Preferences panel views change (private/tpl/panel/preferences.php, PreferencesController::preferences*, or AuthService preference persistence contracts).
1) Panel Guide (Preferences)
Where To Go
- Open panel sidebar:
Welcome->Preferences.
Preferences Screen (/preferences)
Primary action:
Save Preferences
Each account, profile, contact, password, and two-factor setting includes a short inline explanation beside the control.
The Preferences tabs are Account, Profile, Security, and Site; Panel Theme and Timezone are grouped on the Site tab.
Fields/options:
Username(required)Display NameBioEmail Address(required)Change Passwordbutton reveals password-change inputsNew Password(optional, leave blank to keep current)Enter new password again to confirm:helper text under the confirmation fieldPanel Theme(<Default>,Corporate,Ice,Midnight; Site tab)Timezone(Site tab;— Use Site Default —uses the value fromsite.timezonein site configuration)Avatarfile upload (gif/jpg/jpeg/png)Remove current avatarcheckbox (shown only when avatar exists)Cover Imagelocal file upload (gif/jpg/jpeg/png)Remove current cover imagecheckbox (shown only when cover image exists)Two-Factor Methods(Security tab)- section label
Two-Factor Authentication Setup AppSetup TOTP(legacy label)Manual KeyAuthenticator CodeType(Authenticator App (TOTP),Recovery Phrase,Security Key (WebAuthn),Email Code)LabelTOTP Secret / Confirm CodeRecovery PhraseReusableGenerateScan QRProvisioning URICredential IDRequire PIN/Biometric?Pair Security KeyTarget EmailAdd 2FA Method
Behavior notes:
- Password changes require minimum 8 characters.
<Default>theme follows system configured panel default theme.- Avatar upload shows current avatar preview when present.
- TOTP setup now provisions 8-digit codes with SHA-256 metadata and longer app secrets.
- Confirmed TOTP rows show
TOTP Secretwith valueStored securely on server(no confirm-code input, no copy control). - TOTP secrets are encrypted at rest in user preferences (not one-way hashed) so login-time code verification can still run.
- Recovery phrases are generated as 12 words from the BIP39 English wordlist.
- Non-reusable recovery phrases are one-time login methods and are removed after successful use.
2) Developer And Agent Internals
Key Files
- Panel view:
private/tpl/panel/preferences.php- Panel controller:
private/sys/Controller/Panel/PreferencesController.php- Auth service persistence:
private/sys/Gatekeeper.php
Panel Routes
Declared in private/sys/Router/Panel/PreferencesRouter.php:
GET /preferences-> formPOST /preferences/save-> savePOST /preferences/2fa/recovery/generate-> generate one 12-word recovery phrase
Controller Flow
PreferencesController::preferences():
- Requires panel login.
- Loads current user preference payload from
Gatekeeper::userPreferences(...)via$this->context->auth(). - Renders preferences form with theme options.
PreferencesController::preferencesSave():
- Requires panel login.
- Validates CSRF.
- Loads current profile state for safe avatar replacement/removal handling.
- Sanitizes and validates username/display/bio/email/theme/password.
- Validates avatar upload (when present) using
AvatarValidatorand media config limits. - Stores avatar through sanitized re-encode flow (
storeSanitizedAvatarUpload). - Uses deterministic avatar naming:
public/uploads/user/avatar/{user_string}.{extension}. - Generates companion avatar thumbnails as
public/uploads/user/avatar/{user_string}_thumb.jpg.
- avatars above
120x120are center-cropped/resized to120x120JPEG - avatars at or below
120x120are copied as-is from sanitized original
- Stores optional cover uploads at
public/uploads/user/cover/{user_string}.{extension}. - Persists changes through
Preferences::updateUserPreferences(...)+AuthWrite::updatePreferences(...), including optionalcover_image. - Removes superseded avatar and cover files after successful update.
Persistence Contract
Preferences::updateUserPreferences(...) handles:
- unique username/email checks
- optional password hash update
- theme update
- plaintext
bioupdate capped by config keyuser.bio - optional avatar path update
- optional
cover_imagefilename update two_factor_methodsJSON persistence for multi-method 2FA entries
Returned result shape:
{ ok: bool, errors: string[] }
Security/Validation Expectations
- Login required (self-service route).
- CSRF enforced on save.
- Input sanitation via
InputSanitizer. - Avatar validation and sanitized write path enforced before persistence.
- Failed update flows clean up newly written avatar and cover files to avoid orphaned writes.
Update Discipline
When Preferences behavior changes, update this document in the same task. That includes fields, validation rules, avatar handling, and persistence flow.
UI Labels Reference
AccountProfileSecuritySiteContact InformationAdd More Contact InformationTypeValueEmail AddressChange PasswordEnter new password again to confirm:Two-Factor AuthenticationAuthenticator CodeTwo-Factor MethodsSetup TOTPSetup AppFinish SetupManual KeyAdd 2FA MethodTOTP Secret / Confirm CodeTOTP SecretRecovery PhraseReusableGenerateScan QRProvisioning URICredential IDRequire PIN/Biometric?Pair Security KeyTarget Email