TTMT.ManageWebGUI/src/services/auth.service.ts
2026-05-04 12:22:15 +07:00

172 lines
4.7 KiB
TypeScript

import axios from "@/config/axios";
import { API_ENDPOINTS } from "@/config/api";
import rawAxios from "axios";
import type { LoginResquest, LoginResponse, CreateAccountRequest } from "@/types/auth";
/**
* Đăng nhập
* @param credentials - Thông tin đăng nhập
* @returns Response chứa token, name, username, access, role
*/
export async function login(credentials: LoginResquest): Promise<LoginResponse> {
const response = await axios.post<LoginResponse>(
API_ENDPOINTS.AUTH.LOGIN,
credentials
);
return response.data;
}
/**
* Build OAuth login URL by provider
* @param provider - OAuth provider key (e.g. google, azuread)
* @param returnUrl - FE callback url
*/
export function buildOAuthLoginUrl(provider: string, returnUrl: string): string {
const base = API_ENDPOINTS.AUTH.OAUTH_LOGIN(provider);
const encoded = encodeURIComponent(returnUrl);
return `${base}?returnUrl=${encoded}`;
}
/**
* Build Google OAuth login URL
* @param returnUrl - FE callback url
*/
export function buildGoogleOAuthLoginUrl(returnUrl: string): string {
return buildOAuthLoginUrl("google", returnUrl);
}
/**
* Build Microsoft SSO login URL (legacy endpoint)
* @param returnUrl - FE callback url
*/
export function buildMicrosoftSsoLoginUrl(returnUrl: string): string {
const base = API_ENDPOINTS.AUTH.SSO_LOGIN;
const encoded = encodeURIComponent(returnUrl);
return `${base}?returnUrl=${encoded}`;
}
/**
* Exchange one-time OAuth code for login payload
* @param code - one-time code
*/
export async function exchangeOAuthCode(code: string): Promise<LoginResponse> {
try {
const response = await rawAxios.post<LoginResponse>(
API_ENDPOINTS.AUTH.OAUTH_EXCHANGE,
{ code }
);
return response.data;
} catch (error) {
if (rawAxios.isAxiosError(error)) {
const status = error.response?.status;
if (status === 401 || status === 404 || status === 405) {
const fallbackResponse = await rawAxios.post<LoginResponse>(
API_ENDPOINTS.AUTH.SSO_EXCHANGE,
{ code }
);
return fallbackResponse.data;
}
}
throw error;
}
}
/**
* Legacy AzureAD SSO URL builder kept for backward compatibility.
*/
export function buildSsoLoginUrl(returnUrl: string): string {
return buildOAuthLoginUrl("azuread", returnUrl);
}
/**
* Legacy SSO exchange alias kept for backward compatibility.
*/
export async function exchangeSsoCode(code: string): Promise<LoginResponse> {
return exchangeOAuthCode(code);
}
/**
* Exchange one-time code by provider without breaking existing flows.
* - azuread/microsoft: force legacy SSO exchange endpoint
* - default: use OAuth exchange flow
*/
export async function exchangeCodeByProvider(
code: string,
provider?: string
): Promise<LoginResponse> {
const providerKey = (provider || "").toLowerCase();
if (providerKey === "microsoft" || providerKey === "azuread") {
const response = await rawAxios.post<LoginResponse>(
API_ENDPOINTS.AUTH.SSO_EXCHANGE,
{ code }
);
return response.data;
}
return exchangeOAuthCode(code);
}
/**
* Đăng xuất
*/
export async function logout(): Promise<void> {
await axios.delete(API_ENDPOINTS.AUTH.LOGOUT);
}
/**
* Kiểm tra phiên đăng nhập
* @param token - Access token
* @returns Response kiểm tra phiên
*/
export async function ping(token?: string): Promise<{ message: string; code: number }> {
const response = await axios.get(API_ENDPOINTS.AUTH.PING, {
params: token ? { token } : undefined,
});
return response.data;
}
/**
* Lấy CSRF token
* @returns CSRF token
*/
export async function getCsrfToken(): Promise<{ token: string }> {
const response = await axios.get(API_ENDPOINTS.AUTH.CSRF_TOKEN);
return response.data;
}
/**
* Thay đổi mật khẩu của user hiện tại
* @param data - Dữ liệu thay đổi mật khẩu {currentPassword, newPassword}
*/
export async function changePassword(data: {
currentPassword: string;
newPassword: string;
}): Promise<{ message: string }> {
const response = await axios.put(API_ENDPOINTS.AUTH.CHANGE_PASSWORD, data);
return response.data;
}
/**
* Admin thay đổi mật khẩu của user khác
* @param data - Dữ liệu {username, newPassword}
*/
export async function changePasswordAdmin(data: {
username: string;
newPassword: string;
}): Promise<{ message: string }> {
const response = await axios.put(
API_ENDPOINTS.AUTH.CHANGE_PASSWORD_ADMIN,
data
);
return response.data;
}
/**
* Tạo tài khoản mới
* @param data - Dữ liệu tạo tài khoản (maps to CreateAccountRequest DTO)
*/
export async function createAccount(data: CreateAccountRequest): Promise<{ message: string }> {
const response = await axios.post(API_ENDPOINTS.AUTH.CREATE_ACCOUNT, data);
return response.data;
}