Skip to content

Profile

Every user has a profile — their name, avatar, banner, and location — separate from the account-level concerns like email and password. This page covers self-service account management: updating your profile, changing your password, reviewing connected OAuth providers, and deleting your account.

The profile settings page

Updating your profile

Updates the UserProfile model (first/middle/last name, current country).

php
// Update profile fields and sync avatar/banner media, returning the fresh user...
App\Actions\Profile\UpdateProfile::update(User $user, array $input) : App\Models\User

Changing email clears email_verified_at, so a changed address has to be re-verified.

Avatar and banner

UserProfile registers two Spatie Media Library single-file collections, avatar and banner. Uploads go through the media library's own routes rather than the profile update action. Company logos and banners, and announcement banners, follow the same pattern on their respective models.

Password

Passwords are optional in Reshape — since login is passwordless, a user might never set one.

php
// Whether the user has ever set a password (based on password_updated_at)...
$user->hasPassword() : bool

The frontend uses this to decide whether to show "set a password" or "change your password". The same action handles both the initial set and subsequent changes.

Sessions and connected accounts

  • Sessions — see and revoke active browser sessions. Covered in Authentication.
  • OAuth connections — review and unlink connected Google/GitHub/LinkedIn accounts. See Authentication.
  • Passkeys — manage registered passkeys.
  • Two-factor authentication — enable, confirm, and view recovery codes via Fortify.

The frontend groups all of this under web/src/routes/_dashboard/settings/* — separate route files for profile, password, two-factor, passkeys, sessions, and socials.

Preferences

Beyond the fixed profile fields, users (and companies) can store arbitrary typed preferences through a generic, polymorphic system.

Trait Methods (HasPreferences)

php
// Every stored preference override for this owner...
$user->preferences() : Illuminate\Database\Eloquent\Relations\MorphMany

// All preferences visible to this owner, definitions merged with stored overrides...
$user->getPreferences() : Illuminate\Support\Collection

// Read one preference (or several, by array) by name...
$user->getPreference(string|array $name) : mixed

// Set one preference, or several at once via an associative array...
$user->setPreference(string|array $name, mixed $value = null) : void

// Delete one or more stored overrides, reverting to the definition's default...
$user->forgetPreference(string|array $names) : void

Each preference has a definition (App\Preference, typed via App\Enums\PreferenceType) and an optional stored override (Preferenceable). This is also how appearance (light/dark mode) and theme selection are ultimately persisted per user.

Deleting your account

Logs the user out and soft-deletes their account.

php
// Delete a user's addresses/contacts, purge every company they own, then delete the user...
App\Actions\DeleteUser::delete(User $user) : void