org
This commit is contained in:
311
kms/kms-frontend/src/services/apiService.ts
Normal file
311
kms/kms-frontend/src/services/apiService.ts
Normal file
@ -0,0 +1,311 @@
|
||||
import axios, { AxiosInstance, AxiosResponse } from 'axios';
|
||||
|
||||
// Types based on the KMS API
|
||||
export interface Application {
|
||||
app_id: string;
|
||||
app_link: string;
|
||||
type: string[];
|
||||
callback_url: string;
|
||||
hmac_key: string;
|
||||
token_prefix?: string;
|
||||
token_renewal_duration: number;
|
||||
max_token_duration: number;
|
||||
owner: {
|
||||
type: string;
|
||||
name: string;
|
||||
owner: string;
|
||||
};
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface StaticToken {
|
||||
id: string;
|
||||
app_id: string;
|
||||
owner: {
|
||||
type: string;
|
||||
name: string;
|
||||
owner: string;
|
||||
};
|
||||
type: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface CreateApplicationRequest {
|
||||
app_id: string;
|
||||
app_link: string;
|
||||
type: string[];
|
||||
callback_url: string;
|
||||
token_prefix?: string;
|
||||
token_renewal_duration: string;
|
||||
max_token_duration: string;
|
||||
owner: {
|
||||
type: string;
|
||||
name: string;
|
||||
owner: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateTokenRequest {
|
||||
owner: {
|
||||
type: string;
|
||||
name: string;
|
||||
owner: string;
|
||||
};
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
export interface CreateTokenResponse {
|
||||
id: string;
|
||||
token: string;
|
||||
permissions: string[];
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
limit: number;
|
||||
offset: number;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface VerifyRequest {
|
||||
app_id: string;
|
||||
user_id?: string;
|
||||
token: string;
|
||||
permissions?: string[];
|
||||
}
|
||||
|
||||
export interface VerifyResponse {
|
||||
valid: boolean;
|
||||
permitted: boolean;
|
||||
user_id?: string;
|
||||
permissions: string[];
|
||||
permission_results?: Record<string, boolean>;
|
||||
expires_at?: string;
|
||||
max_valid_at?: string;
|
||||
token_type: string;
|
||||
claims?: Record<string, string>;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface AuditEvent {
|
||||
id: string;
|
||||
type: string;
|
||||
status: string;
|
||||
timestamp: string;
|
||||
actor_id?: string;
|
||||
actor_ip?: string;
|
||||
user_agent?: string;
|
||||
resource_id?: string;
|
||||
resource_type?: string;
|
||||
action: string;
|
||||
description: string;
|
||||
details?: Record<string, any>;
|
||||
request_id?: string;
|
||||
session_id?: string;
|
||||
}
|
||||
|
||||
export interface AuditQueryParams {
|
||||
event_types?: string[];
|
||||
statuses?: string[];
|
||||
actor_id?: string;
|
||||
resource_id?: string;
|
||||
resource_type?: string;
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
order_by?: string;
|
||||
order_desc?: boolean;
|
||||
}
|
||||
|
||||
export interface AuditResponse {
|
||||
events: AuditEvent[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface AuditStats {
|
||||
total_events: number;
|
||||
by_type: Record<string, number>;
|
||||
by_severity: Record<string, number>;
|
||||
by_status: Record<string, number>;
|
||||
by_time?: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface AuditStatsParams {
|
||||
event_types?: string[];
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
group_by?: string;
|
||||
}
|
||||
|
||||
class ApiService {
|
||||
private api: AxiosInstance;
|
||||
private baseURL: string;
|
||||
|
||||
constructor() {
|
||||
this.baseURL = process.env.REACT_APP_API_URL || 'http://localhost:8080';
|
||||
|
||||
this.api = axios.create({
|
||||
baseURL: this.baseURL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// Add request interceptor to include user email header
|
||||
this.api.interceptors.request.use((config) => {
|
||||
const user = localStorage.getItem('kms_user');
|
||||
if (user) {
|
||||
try {
|
||||
const userData = JSON.parse(user);
|
||||
config.headers['X-User-Email'] = userData.email;
|
||||
} catch (error) {
|
||||
console.error('Error parsing user data:', error);
|
||||
}
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// Add response interceptor for error handling
|
||||
this.api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
console.error('API Error:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Health Check
|
||||
async healthCheck(): Promise<any> {
|
||||
const response = await this.api.get('/health');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async readinessCheck(): Promise<any> {
|
||||
const response = await this.api.get('/ready');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// Applications
|
||||
async getApplications(limit: number = 50, offset: number = 0): Promise<PaginatedResponse<Application>> {
|
||||
const response = await this.api.get(`/api/applications?limit=${limit}&offset=${offset}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async getApplication(appId: string): Promise<Application> {
|
||||
const response = await this.api.get(`/api/applications/${appId}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async createApplication(data: CreateApplicationRequest): Promise<Application> {
|
||||
const response = await this.api.post('/api/applications', data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async updateApplication(appId: string, data: Partial<CreateApplicationRequest>): Promise<Application> {
|
||||
const response = await this.api.put(`/api/applications/${appId}`, data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async deleteApplication(appId: string): Promise<void> {
|
||||
await this.api.delete(`/api/applications/${appId}`);
|
||||
}
|
||||
|
||||
// Tokens
|
||||
async getTokensForApplication(appId: string, limit: number = 50, offset: number = 0): Promise<PaginatedResponse<StaticToken>> {
|
||||
const response = await this.api.get(`/api/applications/${appId}/tokens?limit=${limit}&offset=${offset}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async createToken(appId: string, data: CreateTokenRequest): Promise<CreateTokenResponse> {
|
||||
const response = await this.api.post(`/api/applications/${appId}/tokens`, data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async deleteToken(tokenId: string): Promise<void> {
|
||||
await this.api.delete(`/api/tokens/${tokenId}`);
|
||||
}
|
||||
|
||||
// Token verification
|
||||
async verifyToken(data: VerifyRequest): Promise<VerifyResponse> {
|
||||
const response = await this.api.post('/api/verify', data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// Authentication
|
||||
async login(appId: string, permissions: string[], redirectUri?: string, tokenDelivery?: string): Promise<any> {
|
||||
const response = await this.api.post('/api/login', {
|
||||
app_id: appId,
|
||||
permissions,
|
||||
redirect_uri: redirectUri,
|
||||
token_delivery: tokenDelivery,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async renewToken(appId: string, userId: string, token: string): Promise<any> {
|
||||
const response = await this.api.post('/api/renew', {
|
||||
app_id: appId,
|
||||
user_id: userId,
|
||||
token,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// Audit endpoints
|
||||
async getAuditEvents(params?: AuditQueryParams): Promise<AuditResponse> {
|
||||
const queryString = new URLSearchParams();
|
||||
|
||||
if (params) {
|
||||
if (params.event_types?.length) {
|
||||
params.event_types.forEach(type => queryString.append('event_types', type));
|
||||
}
|
||||
if (params.statuses?.length) {
|
||||
params.statuses.forEach(status => queryString.append('statuses', status));
|
||||
}
|
||||
if (params.actor_id) queryString.set('actor_id', params.actor_id);
|
||||
if (params.resource_id) queryString.set('resource_id', params.resource_id);
|
||||
if (params.resource_type) queryString.set('resource_type', params.resource_type);
|
||||
if (params.start_time) queryString.set('start_time', params.start_time);
|
||||
if (params.end_time) queryString.set('end_time', params.end_time);
|
||||
if (params.limit) queryString.set('limit', params.limit.toString());
|
||||
if (params.offset) queryString.set('offset', params.offset.toString());
|
||||
if (params.order_by) queryString.set('order_by', params.order_by);
|
||||
if (params.order_desc !== undefined) queryString.set('order_desc', params.order_desc.toString());
|
||||
}
|
||||
|
||||
const url = `/api/audit/events${queryString.toString() ? '?' + queryString.toString() : ''}`;
|
||||
const response = await this.api.get(url);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async getAuditEvent(eventId: string): Promise<AuditEvent> {
|
||||
const response = await this.api.get(`/api/audit/events/${eventId}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async getAuditStats(params?: AuditStatsParams): Promise<AuditStats> {
|
||||
const queryString = new URLSearchParams();
|
||||
|
||||
if (params) {
|
||||
if (params.event_types?.length) {
|
||||
params.event_types.forEach(type => queryString.append('event_types', type));
|
||||
}
|
||||
if (params.start_time) queryString.set('start_time', params.start_time);
|
||||
if (params.end_time) queryString.set('end_time', params.end_time);
|
||||
if (params.group_by) queryString.set('group_by', params.group_by);
|
||||
}
|
||||
|
||||
const url = `/api/audit/stats${queryString.toString() ? '?' + queryString.toString() : ''}`;
|
||||
const response = await this.api.get(url);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const apiService = new ApiService();
|
||||
Reference in New Issue
Block a user