All files / src/api auth.ts

87.5% Statements 7/8
25% Branches 1/4
100% Functions 1/1
87.5% Lines 7/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                                                                                                  12x       32x         32x       32x 32x 32x   32x    
/**
 * @file auth.ts
 * @description
 * Authentication API service for user login and JWT token handling.
 *
 * **Responsibilities:**
 * - Handle user login requests to the backend
 * - Extract and decode JWT tokens from responses
 * - Parse user role from JWT payload
 * - Error handling and validation
 *
 * **Security Notes:**
 * - JWT tokens are decoded client-side (payload only, signature verification via backend)
 * - Passwords are never logged or stored locally
 * - Token should be stored securely (HttpOnly cookies preferred, localStorage fallback)
 *
 * @module auth
 * @requires ../services/apiClient
 */
 
import apiClient from '../services/apiClient';
 
/**
 * Login API response structure from backend
 * @interface LoginResponse
 */
interface LoginResponse {
  success: boolean;
  message: string;
  data: string;
}
 
/**
 * Authenticates user with credentials and returns JWT token with role.
 *
 * @async
 * @function login
 * @param {string} username - User's login username
 * @param {string} password - User's login password
 * @returns {Promise<{token: string, role: string}>} JWT token and user role
 * @throws {Error} Authentication failed, invalid credentials, or malformed response
 *
 * **Process:**
 * 1. Send POST request with credentials to /api/auth/login
 * 2. Validate response success flag
 * 3. Extract JWT token from response.data
 * 4. Decode JWT payload to extract user role
 * 5. Return token and role for application storage
 */
export const login = async (
  username: string,
  password: string
): Promise<{ token: string; role: string }> => {
  const response = await apiClient.post<LoginResponse>(
    '/api/auth/login',
    { username, password }
  );
 
  Iif (!response.data.success) {
    throw new Error(response.data.message || 'Login failed');
  }
 
  const token = response.data.data;
  const decodedPayload = JSON.parse(atob(token.split('.')[1]));
  const role = decodedPayload.role;
 
  return { token, role };
};