Villa Buena uses Auth0 for secure user authentication, providing a seamless login experience with automatic profile data integration.
Overview
User account features include:
Secure authentication via Auth0
Automatic profile data hydration
Persistent user preferences
Order history tracking
Shipping and payment information storage
Authentication with Auth0
Integration
The application uses the Auth0 React SDK for authentication:
import { useAuth0 } from "@auth0/auth0-react" ;
const { isAuthenticated , user , loginWithRedirect , logout } = useAuth0 ();
Auth0 handles all authentication flows, including login, signup, password reset, and social authentication.
User Store Architecture
The user store manages all user-related data with persistence:
src/store/useUserStore.js
import { create } from "zustand" ;
import { persist } from "zustand/middleware" ;
export const useUserStore = create (
persist (
( set ) => ({
shipping: {
fullName: "" ,
address: "" ,
city: "" ,
},
payment: {
cardNumber: "" ,
expiryDate: "" ,
cvc: "" ,
},
orders: [],
setShipping : ( data ) =>
set (( state ) => ({
shipping: { ... state . shipping , ... data },
})),
setPayment : ( data ) =>
set (( state ) => ({
payment: { ... state . payment , ... data },
})),
hydrateFromAuth0 : ( user ) =>
set (( state ) => ({
shipping: {
... state . shipping ,
fullName: state . shipping . fullName || user ?. name || "" ,
},
})),
addOrder : ( order ) =>
set (( state ) => ({
orders: [ ... state . orders , order ],
})),
}),
{
name: "user-checkout-storage" ,
},
),
);
All user data is stored in localStorage with the key user-checkout-storage, persisting across sessions.
Profile Data Hydration
Automatic Population
When a user logs in, their Auth0 profile data automatically populates relevant fields:
src/pages/checkoutShipping/CheckoutShipping.jsx
import { useAuth0 } from "@auth0/auth0-react" ;
import { useUserStore } from "../../store/useUserStore" ;
const { user } = useAuth0 ();
const hydrateFromAuth0 = useUserStore (( state ) => state . hydrateFromAuth0 );
useEffect (() => {
if ( user ) {
hydrateFromAuth0 ( user );
}
}, [ user ]);
Hydration Logic
Check Authentication
Verify user is authenticated via Auth0
Extract Profile Data
Get user name and other details from Auth0 user object
Populate Fields
Pre-fill shipping form with user’s name if not already set
Preserve Existing Data
Only hydrate empty fields - don’t overwrite user input
src/store/useUserStore.js
hydrateFromAuth0 : ( user ) =>
set (( state ) => ({
shipping: {
... state . shipping ,
fullName: state . shipping . fullName || user ?. name || "" ,
},
}))
The hydration logic uses a fallback pattern: existing value → Auth0 value → empty string, ensuring user input is never lost.
User Data Management
Users’ shipping information is stored and managed through the store:
Full Name Auto-populated from Auth0 profile
Address Manually entered by user
City Manually entered by user
src/store/useUserStore.js
shipping : {
fullName : "" ,
address : "" ,
city : "" ,
},
setShipping : ( data ) =>
set (( state ) => ({
shipping: { ... state . shipping , ... data },
}))
Payment information is stored in localStorage for user convenience during the session but should be cleared after order completion in a production environment.
src/store/useUserStore.js
payment : {
cardNumber : "" ,
expiryDate : "" ,
cvc : "" ,
},
setPayment : ( data ) =>
set (( state ) => ({
payment: { ... state . payment , ... data },
}))
Order History Management
Order Storage
Completed orders are added to the user’s order history:
src/store/useUserStore.js
orders : [],
addOrder : ( order ) =>
set (( state ) => ({
orders: [ ... state . orders , order ],
}))
Order Object Structure
Each order contains complete purchase information:
{
id : "ABC12345" , // Unique 8-character order ID
date : "2026-03-09T..." , // ISO timestamp
items : [ // Array of purchased products
{
id: 1 ,
title: "Product Name" ,
price: 29.99 ,
thumbnail: "https://..." ,
qty: 2
}
],
total : 59.98 // Total order amount
}
Adding Orders
Orders are created during checkout payment processing:
src/pages/checkoutpayment/CheckoutPayment.jsx
const orderId = Math . random (). toString ( 36 ). substring ( 2 , 10 ). toUpperCase ();
addOrder ({
id: orderId ,
date: new Date (). toISOString (),
items: [ ... cart ],
total: cart . reduce (( acc , item ) => acc + item . price * item . qty , 0 ),
});
Authentication Flow
Login Process
User Clicks Login
User initiates login from navigation or protected page
Redirect to Auth0
Application redirects to Auth0 login page
Authenticate
User enters credentials or uses social login
Return to App
Auth0 redirects back with authentication token
Hydrate Profile
Application automatically populates user data
Protected Routes
Payment page requires authentication before access:
src/pages/checkoutpayment/CheckoutPayment.jsx
const { isAuthenticated , loginWithRedirect } = useAuth0 ();
const handlePayment = ( e ) => {
e . preventDefault ();
if ( ! isAuthenticated ) {
loginWithRedirect ({
appState: { returnTo: "/checkout/payment" },
});
return ;
}
// Process payment...
};
The returnTo parameter ensures users are redirected back to the payment page after logging in, maintaining their checkout flow.
Logout Process
Users can log out through the Auth0 SDK:
import { useAuth0 } from "@auth0/auth0-react" ;
const { logout } = useAuth0 ();
const handleLogout = () => {
logout ({ returnTo: window . location . origin });
};
Logging out clears Auth0 session but does NOT automatically clear localStorage data. Cart and order history persist across sessions.
User State Across Sessions
What Persists
Persisted Data
Shopping cart items
Order history
Shipping information
Payment form data
Session Only
Auth0 authentication token
Active login state
User profile from Auth0
Data Flow Diagram
Privacy and Security Considerations
Authentication
Auth0 handles all password security and encryption
OAuth tokens are managed by Auth0 SDK
No passwords are stored in application code
Data Storage
Shipping and order data persisted in localStorage
Payment information should be considered sensitive
Consider clearing payment data after order completion
Production Recommendations
Implement server-side order storage
Use tokenized payment methods
Encrypt sensitive data in localStorage
Add session timeouts for payment pages
Integration Points
Components Using User Data
Checkout Shipping Uses shipping information and Auth0 profile
Checkout Payment Requires authentication and uses payment data
Order History Displays all user orders from store
Navigation Shows login/logout based on auth state
Best Practices
Always check authentication state before accessing protected features, and provide clear login prompts when needed.
Development Guidelines
State Management : Use the user store for all user-related data
Hydration : Call hydrateFromAuth0 on every auth state change
Validation : Validate all user input before storing
Privacy : Be mindful of what data persists across sessions
UX : Provide clear feedback for authentication state changes
Testing Authentication
const { isAuthenticated , isLoading , user } = useAuth0 ();
if ( isLoading ) {
return < div > Loading... </ div > ;
}
if ( ! isAuthenticated ) {
return < div > Please log in </ div > ;
}
return < div > Welcome, { user . name } ! </ div > ;