2025-07-22 13:46:05 +02:00
|
|
|
// frontend/src/api/services/authService.ts - UPDATED TO HANDLE TOKENS FROM REGISTRATION
|
2025-07-22 08:50:18 +02:00
|
|
|
import { tokenManager } from '../auth/tokenManager';
|
2025-07-22 07:37:51 +02:00
|
|
|
import { apiClient } from '../base/apiClient';
|
|
|
|
|
|
|
|
|
|
export interface LoginCredentials {
|
|
|
|
|
email: string;
|
|
|
|
|
password: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RegisterData {
|
|
|
|
|
email: string;
|
|
|
|
|
password: string;
|
|
|
|
|
full_name: string;
|
|
|
|
|
tenant_name?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UserProfile {
|
|
|
|
|
id: string;
|
|
|
|
|
email: string;
|
|
|
|
|
full_name: string;
|
2025-07-22 13:46:05 +02:00
|
|
|
tenant_id?: string;
|
|
|
|
|
role?: string;
|
2025-07-22 07:37:51 +02:00
|
|
|
is_active: boolean;
|
2025-07-22 13:46:05 +02:00
|
|
|
is_verified?: boolean;
|
2025-07-22 07:37:51 +02:00
|
|
|
created_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 13:46:05 +02:00
|
|
|
export interface TokenResponse {
|
|
|
|
|
access_token: string;
|
|
|
|
|
refresh_token?: string;
|
|
|
|
|
token_type: string;
|
|
|
|
|
expires_in?: number;
|
|
|
|
|
user?: UserProfile;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 07:37:51 +02:00
|
|
|
class AuthService {
|
2025-07-22 13:46:05 +02:00
|
|
|
async register(data: RegisterData): Promise<UserProfile> {
|
|
|
|
|
// NEW: Registration now returns tokens directly - no auto-login needed!
|
|
|
|
|
const response: TokenResponse = await apiClient.post('/api/v1/auth/register', data);
|
2025-07-22 12:58:32 +02:00
|
|
|
|
2025-07-22 13:46:05 +02:00
|
|
|
// Store tokens immediately from registration response
|
2025-07-22 12:58:32 +02:00
|
|
|
await tokenManager.storeTokens(response);
|
2025-07-22 13:46:05 +02:00
|
|
|
|
|
|
|
|
// Return user profile from registration response
|
2025-07-22 12:58:32 +02:00
|
|
|
if (response.user) {
|
|
|
|
|
return response.user;
|
|
|
|
|
} else {
|
2025-07-22 13:46:05 +02:00
|
|
|
// Fallback: get user profile if not included in response
|
2025-07-22 12:58:32 +02:00
|
|
|
return this.getCurrentUser();
|
2025-07-22 07:37:51 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 13:46:05 +02:00
|
|
|
async login(credentials: LoginCredentials): Promise<UserProfile> {
|
|
|
|
|
// UPDATED: Use correct endpoint and unified response handling
|
|
|
|
|
const response: TokenResponse = await apiClient.post('/api/v1/auth/login', credentials);
|
2025-07-22 07:37:51 +02:00
|
|
|
|
2025-07-22 13:46:05 +02:00
|
|
|
// Store tokens from login response
|
|
|
|
|
await tokenManager.storeTokens(response);
|
2025-07-22 12:58:32 +02:00
|
|
|
|
2025-07-22 13:46:05 +02:00
|
|
|
// Return user profile from login response
|
|
|
|
|
if (response.user) {
|
|
|
|
|
return response.user;
|
|
|
|
|
} else {
|
|
|
|
|
// Fallback: get user profile if not included in response
|
|
|
|
|
return this.getCurrentUser();
|
|
|
|
|
}
|
2025-07-22 07:37:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async logout(): Promise<void> {
|
|
|
|
|
try {
|
2025-07-22 13:46:05 +02:00
|
|
|
// Get refresh token for logout request
|
|
|
|
|
const refreshToken = tokenManager.getRefreshToken();
|
|
|
|
|
if (refreshToken) {
|
|
|
|
|
await apiClient.post('/api/v1/auth/logout', {
|
|
|
|
|
refresh_token: refreshToken
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Logout API call failed:', error);
|
|
|
|
|
// Continue with local cleanup even if API fails
|
2025-07-22 07:37:51 +02:00
|
|
|
} finally {
|
|
|
|
|
tokenManager.clearTokens();
|
|
|
|
|
window.location.href = '/login';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getCurrentUser(): Promise<UserProfile> {
|
2025-07-22 12:58:32 +02:00
|
|
|
return apiClient.get('/api/v1/auth/me');
|
2025-07-22 07:37:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async updateProfile(updates: Partial<UserProfile>): Promise<UserProfile> {
|
2025-07-22 12:58:32 +02:00
|
|
|
return apiClient.patch('/api/v1/auth/profile', updates);
|
2025-07-22 07:37:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async changePassword(currentPassword: string, newPassword: string): Promise<void> {
|
2025-07-22 12:58:32 +02:00
|
|
|
await apiClient.post('/api/v1/auth/change-password', {
|
2025-07-22 07:37:51 +02:00
|
|
|
current_password: currentPassword,
|
|
|
|
|
new_password: newPassword
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 13:46:05 +02:00
|
|
|
async refreshToken(): Promise<void> {
|
|
|
|
|
await tokenManager.refreshAccessToken();
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 07:37:51 +02:00
|
|
|
isAuthenticated(): boolean {
|
|
|
|
|
return tokenManager.isAuthenticated();
|
|
|
|
|
}
|
2025-07-22 13:46:05 +02:00
|
|
|
|
|
|
|
|
getUser(): UserProfile | null {
|
|
|
|
|
// This method would need to be implemented to return cached user data
|
|
|
|
|
// For now, it returns null and components should use getCurrentUser()
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-07-22 07:37:51 +02:00
|
|
|
}
|
|
|
|
|
|
2025-07-22 12:58:32 +02:00
|
|
|
export const authService = new AuthService();
|