User Account
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 authenticationtokenanduserobject. It provides methods likesetToken,setUser, andlogout.useUser()Hook: A convenient hook to access the current user's profile data (Usertype) 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:
| Property | Type | Description |
|---|---|---|
id | number | Unique user identifier. |
name | string | User's full display name. |
email | string | Primary email address (immutable). |
role | string | User role (e.g., 'user', 'admin'). |
is_verified | boolean | Verification status badge indicator. |
avatar_url | string | URL to the user's profile image. |
phone_number | string | Optional contact number. |
uuid | string | Universally 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.
- User Action: The user selects "Delete Account" in the Security settings.
- Confirmation: A destructive confirmation dialog (
Dialogcomponent withvariant="danger") is shown. - API Call: The
useDeleteAccountMutationhook sends aDELETErequest to the backend. - 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
ThemeContextandtokenssystem to ensure consistent aesthetics across light and dark modes.
