This commit is contained in:
2025-08-26 19:16:41 -04:00
parent 7ca61eb712
commit 6725529b01
113 changed files with 0 additions and 337 deletions

View 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();