Made app more modular.
Fixed some bugs. Added some functionality.
This commit is contained in:
123
services/api.ts
123
services/api.ts
@@ -6,9 +6,7 @@ const API_BASE = '/api';
|
||||
class ApiService {
|
||||
private getHeaders() {
|
||||
const session = localStorage.getItem('hip6_session');
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const headers: HeadersInit = { 'Content-Type': 'application/json' };
|
||||
if (session) {
|
||||
const { token } = JSON.parse(session);
|
||||
if (token) headers['Authorization'] = `Bearer ${token}`;
|
||||
@@ -17,14 +15,9 @@ class ApiService {
|
||||
}
|
||||
|
||||
async getState(): Promise<CTFState> {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/state`);
|
||||
if (!res.ok) throw new Error(`HTTP Error ${res.status}`);
|
||||
return res.json();
|
||||
} catch (err) {
|
||||
console.error('API Error (getState):', err);
|
||||
throw err;
|
||||
}
|
||||
const res = await fetch(`${API_BASE}/state`);
|
||||
if (!res.ok) throw new Error(`HTTP Error ${res.status}`);
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async login(name: string, pass: string): Promise<{ team: Team, token: string }> {
|
||||
@@ -58,46 +51,84 @@ class ApiService {
|
||||
method: 'POST',
|
||||
headers: this.getHeaders(),
|
||||
});
|
||||
if (!res.ok) throw new Error('Unauthorized or failed to toggle CTF');
|
||||
if (!res.ok) throw new Error('Failed to toggle CTF');
|
||||
}
|
||||
|
||||
async resetScores(): Promise<void> {
|
||||
const res = await fetch(`${API_BASE}/admin/reset-scores`, {
|
||||
method: 'POST',
|
||||
headers: this.getHeaders(),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to reset scores');
|
||||
}
|
||||
|
||||
async backupDatabase(): Promise<any> {
|
||||
const res = await fetch(`${API_BASE}/admin/db/export`, {
|
||||
method: 'GET',
|
||||
headers: this.getHeaders(),
|
||||
});
|
||||
if (!res.ok) throw new Error('Backup failed');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async restoreDatabase(file: File): Promise<void> {
|
||||
const formData = new FormData();
|
||||
formData.append('restoreFile', file);
|
||||
const session = localStorage.getItem('hip6_session');
|
||||
const headers: HeadersInit = session ? { 'Authorization': `Bearer ${JSON.parse(session).token}` } : {};
|
||||
const res = await fetch(`${API_BASE}/admin/db/restore`, { method: 'POST', headers, body: formData });
|
||||
if (!res.ok) throw new Error('Restore failed');
|
||||
}
|
||||
|
||||
async exportChallenges(): Promise<{ challenges: any[] }> {
|
||||
const res = await fetch(`${API_BASE}/admin/challenges/export`, {
|
||||
method: 'GET',
|
||||
headers: this.getHeaders(),
|
||||
});
|
||||
if (!res.ok) throw new Error('Export failed');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async importChallenges(file: File): Promise<void> {
|
||||
const formData = new FormData();
|
||||
formData.append('importFile', file);
|
||||
const session = localStorage.getItem('hip6_session');
|
||||
const headers: HeadersInit = session ? { 'Authorization': `Bearer ${JSON.parse(session).token}` } : {};
|
||||
const res = await fetch(`${API_BASE}/admin/challenges/import`, { method: 'POST', headers, body: formData });
|
||||
if (!res.ok) throw new Error('Import failed');
|
||||
}
|
||||
|
||||
async deleteAllChallenges(): Promise<void> {
|
||||
const res = await fetch(`${API_BASE}/admin/challenges/all`, {
|
||||
method: 'DELETE',
|
||||
headers: this.getHeaders(),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to delete all challenges');
|
||||
}
|
||||
|
||||
async updateConfig(formData: FormData): Promise<void> {
|
||||
const session = localStorage.getItem('hip6_session');
|
||||
const headers: HeadersInit = {};
|
||||
if (session) {
|
||||
const { token } = JSON.parse(session);
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
const res = await fetch(`${API_BASE}/admin/config`, {
|
||||
method: 'PUT',
|
||||
headers,
|
||||
body: formData,
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to update configuration');
|
||||
const headers: HeadersInit = session ? { 'Authorization': `Bearer ${JSON.parse(session).token}` } : {};
|
||||
const res = await fetch(`${API_BASE}/admin/config`, { method: 'PUT', headers, body: formData });
|
||||
if (!res.ok) throw new Error('Failed to update config');
|
||||
}
|
||||
|
||||
async updateTeam(id: string, data: { name: string, isDisabled: boolean, isAdmin: boolean, password?: string }): Promise<void> {
|
||||
async updateTeam(id: string, data: any): Promise<void> {
|
||||
const res = await fetch(`${API_BASE}/admin/teams/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json();
|
||||
throw new Error(err.message || 'Failed to update team');
|
||||
}
|
||||
if (!res.ok) throw new Error('Failed to update team');
|
||||
}
|
||||
|
||||
async updateProfile(data: { password?: string }): Promise<void> {
|
||||
async updateProfile(data: any): Promise<void> {
|
||||
const res = await fetch(`${API_BASE}/profile`, {
|
||||
method: 'PUT',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json();
|
||||
throw new Error(err.message || 'Failed to update profile');
|
||||
}
|
||||
if (!res.ok) throw new Error('Failed to update profile');
|
||||
}
|
||||
|
||||
async deleteTeam(id: string): Promise<void> {
|
||||
@@ -114,30 +145,15 @@ class ApiService {
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify({ challengeId, flag }),
|
||||
});
|
||||
if (!res.ok) throw new Error('Submission failed');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async upsertChallenge(formData: FormData, id?: string): Promise<any> {
|
||||
const method = id ? 'PUT' : 'POST';
|
||||
const url = id ? `${API_BASE}/admin/challenges/${id}` : `${API_BASE}/admin/challenges`;
|
||||
|
||||
const session = localStorage.getItem('hip6_session');
|
||||
const headers: HeadersInit = {};
|
||||
if (session) {
|
||||
const { token } = JSON.parse(session);
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers,
|
||||
body: formData,
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({ message: 'Save failed' }));
|
||||
throw new Error(err.message || 'Failed to save challenge');
|
||||
}
|
||||
const headers: HeadersInit = session ? { 'Authorization': `Bearer ${JSON.parse(session).token}` } : {};
|
||||
const res = await fetch(url, { method, headers, body: formData });
|
||||
return res.json();
|
||||
}
|
||||
|
||||
@@ -149,22 +165,20 @@ class ApiService {
|
||||
if (!res.ok) throw new Error('Failed to delete challenge');
|
||||
}
|
||||
|
||||
async createBlogPost(data: { title: string, content: string }): Promise<void> {
|
||||
async createBlogPost(data: any): Promise<void> {
|
||||
const res = await fetch(`${API_BASE}/admin/blogs`, {
|
||||
method: 'POST',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to create blog post');
|
||||
}
|
||||
|
||||
async updateBlogPost(id: string, data: { title: string, content: string }): Promise<void> {
|
||||
async updateBlogPost(id: string, data: any): Promise<void> {
|
||||
const res = await fetch(`${API_BASE}/admin/blogs/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to update blog post');
|
||||
}
|
||||
|
||||
async deleteBlogPost(id: string): Promise<void> {
|
||||
@@ -172,7 +186,6 @@ class ApiService {
|
||||
method: 'DELETE',
|
||||
headers: this.getHeaders(),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to delete blog post');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user