- Updated `next.config.js` in both web-admin and web-client to enable React strict mode, set output to standalone, and expose environment variables for API URL. - Enhanced `auth-sdk` with detailed comments for JWT verification, decoding, and token management functions. - Improved `http-client` with comprehensive documentation for HTTP client configuration and methods. - Expanded `logger` functionality with detailed configuration options and logging formats. - Enhanced `tracing` setup with detailed comments for distributed tracing configuration. - Updated `types` definitions for authentication and user data transfer objects with comprehensive comments. - Improved `auth-service` with detailed comments in controllers, services, and middlewares for better clarity and maintainability. - Added health check endpoints in `health.controller.ts` for service monitoring. - Enhanced error handling and logging throughout the application for better debugging and user feedback.
220 lines
7.7 KiB
TypeScript
220 lines
7.7 KiB
TypeScript
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
|
|
import { ApiResponse } from '@goodgo/types';
|
|
|
|
/**
|
|
* EN: Configuration interface for HTTP client setup
|
|
* VI: Interface cấu hình cho việc thiết lập HTTP client
|
|
*/
|
|
export interface HttpClientConfig extends AxiosRequestConfig {
|
|
/** EN: Base URL for all API requests / VI: Base URL cho tất cả API requests */
|
|
baseURL: string;
|
|
/** EN: Request timeout in milliseconds / VI: Timeout request tính bằng milliseconds */
|
|
timeout?: number;
|
|
/** EN: Default headers for all requests / VI: Headers mặc định cho tất cả requests */
|
|
headers?: Record<string, string>;
|
|
}
|
|
|
|
/**
|
|
* EN: HTTP client wrapper around Axios with authentication and error handling
|
|
* VI: HTTP client wrapper xung quanh Axios với authentication và xử lý lỗi
|
|
*/
|
|
export class HttpClient {
|
|
/** EN: Axios instance for making HTTP requests / VI: Axios instance để thực hiện HTTP requests */
|
|
private client: AxiosInstance;
|
|
|
|
/**
|
|
* EN: Initialize HTTP client with configuration
|
|
* VI: Khởi tạo HTTP client với cấu hình
|
|
*
|
|
* @param config - HTTP client configuration / Cấu hình HTTP client
|
|
*/
|
|
constructor(config: HttpClientConfig) {
|
|
// EN: Create Axios instance with base configuration
|
|
// VI: Tạo Axios instance với cấu hình cơ bản
|
|
this.client = axios.create({
|
|
baseURL: config.baseURL,
|
|
timeout: config.timeout || 30000,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...config.headers,
|
|
},
|
|
});
|
|
|
|
// EN: Setup request/response interceptors
|
|
// VI: Thiết lập interceptors cho request/response
|
|
this.setupInterceptors();
|
|
}
|
|
|
|
/**
|
|
* EN: Setup Axios interceptors for authentication and error handling
|
|
* VI: Thiết lập Axios interceptors cho authentication và xử lý lỗi
|
|
*/
|
|
private setupInterceptors() {
|
|
// EN: Request interceptor to add authentication token
|
|
// VI: Request interceptor để thêm authentication token
|
|
this.client.interceptors.request.use(
|
|
(config) => {
|
|
// EN: Add auth token if available in localStorage
|
|
// VI: Thêm auth token nếu có trong localStorage
|
|
const token = this.getAuthToken();
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
}
|
|
return config;
|
|
},
|
|
(error) => Promise.reject(error)
|
|
);
|
|
|
|
// EN: Response interceptor for error handling
|
|
// VI: Response interceptor để xử lý lỗi
|
|
this.client.interceptors.response.use(
|
|
(response: AxiosResponse<ApiResponse>) => {
|
|
return response;
|
|
},
|
|
(error: AxiosError<ApiResponse>) => {
|
|
// EN: Handle common HTTP errors
|
|
// VI: Xử lý các lỗi HTTP phổ biến
|
|
if (error.response?.status === 401) {
|
|
// EN: Handle unauthorized - clear tokens and redirect to login
|
|
// VI: Xử lý unauthorized - xóa tokens và chuyển hướng đến login
|
|
this.clearAuthToken();
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* EN: Get authentication token from localStorage
|
|
* VI: Lấy authentication token từ localStorage
|
|
*
|
|
* @returns Access token or null if not found / Access token hoặc null nếu không tìm thấy
|
|
*/
|
|
private getAuthToken(): string | null {
|
|
// EN: Check if running in browser environment
|
|
// VI: Kiểm tra có đang chạy trong môi trường browser không
|
|
if (typeof window !== 'undefined') {
|
|
return localStorage.getItem('accessToken');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* EN: Clear authentication tokens from localStorage
|
|
* VI: Xóa authentication tokens khỏi localStorage
|
|
*/
|
|
private clearAuthToken(): void {
|
|
// EN: Remove both access and refresh tokens
|
|
// VI: Xóa cả access và refresh tokens
|
|
if (typeof window !== 'undefined') {
|
|
localStorage.removeItem('accessToken');
|
|
localStorage.removeItem('refreshToken');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* EN: Make GET request to API endpoint
|
|
* VI: Thực hiện GET request tới API endpoint
|
|
*
|
|
* @param url - API endpoint URL / URL endpoint API
|
|
* @param config - Additional Axios config / Cấu hình Axios bổ sung
|
|
* @returns API response data / Dữ liệu phản hồi API
|
|
*/
|
|
async get<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
|
|
const response = await this.client.get<ApiResponse<T>>(url, config);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* EN: Make POST request to API endpoint
|
|
* VI: Thực hiện POST request tới API endpoint
|
|
*
|
|
* @param url - API endpoint URL / URL endpoint API
|
|
* @param data - Request payload / Payload request
|
|
* @param config - Additional Axios config / Cấu hình Axios bổ sung
|
|
* @returns API response data / Dữ liệu phản hồi API
|
|
*/
|
|
async post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
|
|
const response = await this.client.post<ApiResponse<T>>(url, data, config);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* EN: Make PUT request to API endpoint
|
|
* VI: Thực hiện PUT request tới API endpoint
|
|
*
|
|
* @param url - API endpoint URL / URL endpoint API
|
|
* @param data - Request payload / Payload request
|
|
* @param config - Additional Axios config / Cấu hình Axios bổ sung
|
|
* @returns API response data / Dữ liệu phản hồi API
|
|
*/
|
|
async put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
|
|
const response = await this.client.put<ApiResponse<T>>(url, data, config);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* EN: Make PATCH request to API endpoint
|
|
* VI: Thực hiện PATCH request tới API endpoint
|
|
*
|
|
* @param url - API endpoint URL / URL endpoint API
|
|
* @param data - Request payload / Payload request
|
|
* @param config - Additional Axios config / Cấu hình Axios bổ sung
|
|
* @returns API response data / Dữ liệu phản hồi API
|
|
*/
|
|
async patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
|
|
const response = await this.client.patch<ApiResponse<T>>(url, data, config);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* EN: Make DELETE request to API endpoint
|
|
* VI: Thực hiện DELETE request tới API endpoint
|
|
*
|
|
* @param url - API endpoint URL / URL endpoint API
|
|
* @param config - Additional Axios config / Cấu hình Axios bổ sung
|
|
* @returns API response data / Dữ liệu phản hồi API
|
|
*/
|
|
async delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
|
|
const response = await this.client.delete<ApiResponse<T>>(url, config);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* EN: Set authentication token in localStorage
|
|
* VI: Đặt authentication token trong localStorage
|
|
*
|
|
* @param token - JWT access token / JWT access token
|
|
*/
|
|
setAuthToken(token: string): void {
|
|
// EN: Store token in browser localStorage
|
|
// VI: Lưu token trong localStorage của browser
|
|
if (typeof window !== 'undefined') {
|
|
localStorage.setItem('accessToken', token);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* EN: Remove authentication token from localStorage
|
|
* VI: Xóa authentication token khỏi localStorage
|
|
*/
|
|
removeAuthToken(): void {
|
|
this.clearAuthToken();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* EN: Factory function to create HttpClient instance
|
|
* VI: Hàm factory để tạo HttpClient instance
|
|
*
|
|
* @param config - HTTP client configuration / Cấu hình HTTP client
|
|
* @returns HttpClient instance / Instance HttpClient
|
|
*/
|
|
export const createHttpClient = (config: HttpClientConfig): HttpClient => {
|
|
return new HttpClient(config);
|
|
};
|
|
|
|
// EN: Default export for the HttpClient class
|
|
// VI: Export default cho HttpClient class
|
|
export default HttpClient;
|