- Spring Security Basic Auth 인증 도입 (Bypass 데이터 API만) - 계정 신청/승인/거절 백엔드 API 및 프론트엔드 구현 - 계정 관리 (CRUD, 비밀번호 재설정, 상태/기간 수정) - 401 응답에 계정 상태 상세 메시지 포함 - Swagger UI Basic Auth 스킴/환경별 그룹 노출 연동 - 신청 폼 정규식 검증 및 접근기간 프리셋 선택
139 lines
4.4 KiB
TypeScript
139 lines
4.4 KiB
TypeScript
export interface BypassAccountResponse {
|
|
id: number;
|
|
username: string;
|
|
displayName: string;
|
|
organization: string | null;
|
|
email: string | null;
|
|
phone: string | null;
|
|
status: string;
|
|
accessStartDate: string | null;
|
|
accessEndDate: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
plainPassword: string | null;
|
|
}
|
|
|
|
export interface BypassAccountUpdateRequest {
|
|
displayName?: string;
|
|
organization?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
status?: string;
|
|
accessStartDate?: string;
|
|
accessEndDate?: string;
|
|
}
|
|
|
|
export interface BypassRequestResponse {
|
|
id: number;
|
|
applicantName: string;
|
|
organization: string | null;
|
|
purpose: string | null;
|
|
email: string | null;
|
|
phone: string | null;
|
|
requestedAccessPeriod: string | null;
|
|
status: string;
|
|
reviewedBy: string | null;
|
|
reviewedAt: string | null;
|
|
rejectReason: string | null;
|
|
accountId: number | null;
|
|
accountUsername: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface BypassRequestSubmitRequest {
|
|
applicantName: string;
|
|
organization: string;
|
|
purpose: string;
|
|
email: string;
|
|
phone: string;
|
|
requestedAccessPeriod: string;
|
|
}
|
|
|
|
export interface BypassRequestReviewRequest {
|
|
reviewedBy: string;
|
|
rejectReason?: string;
|
|
accessStartDate?: string;
|
|
accessEndDate?: string;
|
|
}
|
|
|
|
export interface PageResponse<T> {
|
|
content: T[];
|
|
totalElements: number;
|
|
totalPages: number;
|
|
number: number;
|
|
size: number;
|
|
}
|
|
|
|
interface ApiResponse<T> {
|
|
success: boolean;
|
|
message: string;
|
|
data: T;
|
|
}
|
|
|
|
// BASE URL
|
|
const BASE = '/snp-api/api/bypass-account';
|
|
|
|
// 헬퍼 함수 (bypassApi.ts 패턴과 동일)
|
|
async function fetchJson<T>(url: string): Promise<T> {
|
|
const res = await fetch(url);
|
|
if (!res.ok) throw new Error(`API Error: ${res.status} ${res.statusText}`);
|
|
return res.json();
|
|
}
|
|
|
|
async function postJson<T>(url: string, body?: unknown): Promise<T> {
|
|
const res = await fetch(url, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: body != null ? JSON.stringify(body) : undefined,
|
|
});
|
|
if (!res.ok) throw new Error(`API Error: ${res.status} ${res.statusText}`);
|
|
return res.json();
|
|
}
|
|
|
|
async function putJson<T>(url: string, body?: unknown): Promise<T> {
|
|
const res = await fetch(url, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: body != null ? JSON.stringify(body) : undefined,
|
|
});
|
|
if (!res.ok) throw new Error(`API Error: ${res.status} ${res.statusText}`);
|
|
return res.json();
|
|
}
|
|
|
|
async function deleteJson<T>(url: string): Promise<T> {
|
|
const res = await fetch(url, { method: 'DELETE' });
|
|
if (!res.ok) throw new Error(`API Error: ${res.status} ${res.statusText}`);
|
|
return res.json();
|
|
}
|
|
|
|
export const bypassAccountApi = {
|
|
// Accounts
|
|
getAccounts: (status?: string, page = 0, size = 20) => {
|
|
const params = new URLSearchParams({ page: String(page), size: String(size) });
|
|
if (status) params.set('status', status);
|
|
return fetchJson<ApiResponse<PageResponse<BypassAccountResponse>>>(`${BASE}/accounts?${params}`);
|
|
},
|
|
getAccount: (id: number) =>
|
|
fetchJson<ApiResponse<BypassAccountResponse>>(`${BASE}/accounts/${id}`),
|
|
updateAccount: (id: number, data: BypassAccountUpdateRequest) =>
|
|
putJson<ApiResponse<BypassAccountResponse>>(`${BASE}/accounts/${id}`, data),
|
|
deleteAccount: (id: number) =>
|
|
deleteJson<ApiResponse<void>>(`${BASE}/accounts/${id}`),
|
|
resetPassword: (id: number) =>
|
|
postJson<ApiResponse<BypassAccountResponse>>(`${BASE}/accounts/${id}/reset-password`, {}),
|
|
|
|
// Requests
|
|
submitRequest: (data: BypassRequestSubmitRequest) =>
|
|
postJson<ApiResponse<BypassRequestResponse>>(`${BASE}/requests`, data),
|
|
getRequests: (status?: string, page = 0, size = 20) => {
|
|
const params = new URLSearchParams({ page: String(page), size: String(size) });
|
|
if (status) params.set('status', status);
|
|
return fetchJson<ApiResponse<PageResponse<BypassRequestResponse>>>(`${BASE}/requests?${params}`);
|
|
},
|
|
approveRequest: (id: number, data: BypassRequestReviewRequest) =>
|
|
postJson<ApiResponse<BypassAccountResponse>>(`${BASE}/requests/${id}/approve`, data),
|
|
rejectRequest: (id: number, data: BypassRequestReviewRequest) =>
|
|
postJson<ApiResponse<BypassRequestResponse>>(`${BASE}/requests/${id}/reject`, data),
|
|
};
|