BowlerKit
Features

User Account

1/22/2026

Detailed guide on how user accounts, profile management, and account security work in the Expo boilerplate.

User Account

The user account system in the Expo boilerplate is designed to be secure, responsive, and robust. It follows modern React Native patterns, using Zustand for state management and React Query for server state synchronization.

How User Accounts Work

Account management is centered around the authStore, which maintains the authentication state and provides hooks for accessing user data throughout the application.

Key Logic & Stores

  • authStore: The central Zustand store that holds the authentication token and user object. It provides methods like setToken, setUser, and logout.
  • useUser() Hook: A convenient hook to access the current user's profile data (User type) anywhere in the app.
  • useToken() Hook: Provides access to the current JWT token for authenticated requests.
  • Session Persistence: User tokens are persisted locally using secure storage (via services/storage.ts), ensuring the user remains logged in after app restarts.

Data Models

The User model defines the profile structure used across the application:

PropertyTypeDescription
idnumberUnique user identifier.
namestringUser's full display name.
emailstringPrimary email address (immutable).
rolestringUser role (e.g., 'user', 'admin').
is_verifiedbooleanVerification status badge indicator.
avatar_urlstringURL to the user's profile image.
phone_numberstringOptional contact number.
uuidstringUniversally unique identifier for API requests.

Edit Profile

The profile editing feature allows users to update their personal information. This is handled by the EditProfileScreen located at app/profile/edit.tsx.

Functionality

  • Display Name: Users can update their full name.
  • Phone Number: An optional field for user contact information.
  • Email (Read-Only): For security and identity consistency, the email address cannot be changed from the mobile app.
  • Avatar Management: Users can see their current avatar (using UI Avatars as a fallback) and trigger an image picker to update it.
  • Bio: Users can add a short biography to their profile.

Implementation Example

Profile updates are performed using the useUpdateProfileMutation hook which communicates with the Laravel backend.

const updateProfileMutation = useUpdateProfileMutation();

const handleSave = async () => {
  try {
    await updateProfileMutation.mutateAsync({
      name: fullName,
      phone_number: phone,
    });
    toast.success("Profile updated successfully");
    router.back();
  } catch (error: any) {
    // Validation errors from Laravel are automatically handled
    if (error?.data?.errors) {
       // Display field-specific errors
    }
  }
};

Account Security & Management

The Security section within Settings (app/settings/security.tsx) provides a comprehensive suite of features to keep user accounts safe.

Security Features

  • Change Password: A dedicated flow for users to update their credentials securely.
  • Biometric Login: A toggle to enable/disable FaceID or TouchID for faster access.
  • Two-Factor Authentication (2FA): Support for second-layer security.
  • Active Sessions: Users can see all devices currently logged into their account, including device type, IP address, and last active timestamp.
  • Session Revocation: Remote sign-out capabilities for specific devices or "Revoke All Sessions" to secure the account immediately.
  • Login History: A 성공/실패 (Success/Fail) audit log of recent login attempts.

Deleting an Account (Danger Zone)

The "Danger Zone" allows for permanent account deletion. This process is irreversible and complies with privacy regulations by ensuring all user data is removed.

  1. User Action: The user selects "Delete Account" in the Security settings.
  2. Confirmation: A destructive confirmation dialog (Dialog component with variant="danger") is shown.
  3. API Call: The useDeleteAccountMutation hook sends a DELETE request to the backend.
  4. Local Cleanup: Upon success, the store is cleared, and the user is redirected to the login screen.
const deleteAccount = useDeleteAccountMutation();

const handleDeleteAccount = () => {
  deleteAccount.mutate();
  setShowDeleteDialog(false);
};

Best Practices

  • Optimistic Updates: User state is updated in Zustand to provide an instant UI response, while the backend syncs in the background.
  • Validation Handling: Server-side validation errors (e.g., from Laravel) are parsed and mapped back to form fields for clear user feedback.
  • Design Tokens: All account-related screens use the global ThemeContext and tokens system to ensure consistent aesthetics across light and dark modes.