Auth API
XetaSuite uses Laravel Sanctum in stateful mode (cookies) for SPA authentication.
Authentication endpoints
Section titled “Authentication endpoints”Get CSRF cookie
Section titled “Get CSRF cookie”GET /sanctum/csrf-cookieResponse: XSRF-TOKEN cookie set
POST /api/v1/auth/loginHeaders:
Content-Type: application/jsonAccept: application/jsonX-XSRF-TOKEN: {token from cookie}Body:
{ "email": "user@example.com", "password": "password", "remember": true}Response 200:
{ "two_factor": false}Response 422 (Validation):
{ "message": "The provided credentials are incorrect.", "errors": { "email": ["The provided credentials are incorrect."] }}Two-Factor Challenge
Section titled “Two-Factor Challenge”If two_factor: true in the login response:
POST /api/v1/auth/two-factor-challengeBody:
{ "code": "123456"}Or with a recovery code:
{ "recovery_code": "abcd-efgh-ijkl"}Logout
Section titled “Logout”POST /api/v1/auth/logoutResponse 204: No Content
Get current user
Section titled “Get current user”GET /api/v1/userResponse:
{ "data": { "id": 1, "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "email": "john@example.com", "username": "jdoe", "locale": "en", "current_site_id": 1, "roles": ["admin"], "permissions": ["company.viewAny", "company.view", "..."], "sites": [ { "id": 1, "name": "Headquarters", "is_headquarters": true } ] }}Switch current site
Section titled “Switch current site”PATCH /api/v1/user/siteBody:
{ "site_id": 2}Response: Updated user with new permissions for the selected site.
Update locale
Section titled “Update locale”PATCH /api/v1/user/localeBody:
{ "locale": "fr"}React client implementation
Section titled “React client implementation”const httpClient = axios.create({ baseURL: import.meta.env.VITE_API_URL || '', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest', }, withCredentials: true, // Required for Sanctum cookies withXSRFToken: true, // Auto-include XSRF-TOKEN header});
// AuthRepository.tsexport const AuthRepository = { login: async (credentials: LoginCredentials): Promise<void> => { await httpClient.get('/sanctum/csrf-cookie'); await httpClient.post('/api/v1/auth/login', credentials); }, logout: async (): Promise<void> => { await httpClient.get('/sanctum/csrf-cookie'); await httpClient.post('/api/v1/auth/logout'); },};