Merge pull request 'PR Summary' (#1) from dev into main
All checks were successful
Deploy Frontend / deploy (push) Successful in 45s

Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2025-10-10 08:49:18 +08:00
5 changed files with 57 additions and 26 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,4 @@
// src/app/admin/devices/page.tsx
import { cookies } from 'next/headers';
import { requireAuthOrRedirect } from '@/lib/authServer';
import axiosServer from '@/lib/axiosServer';
import DeviceTableSection from '@/components/admin/DeviceTableSection';
@@ -16,17 +15,19 @@ interface DeviceDTO {
export default async function DeviceManagementPage() {
const user = await requireAuthOrRedirect();
const cookieStore = cookies();
// @ts-expect-error cookies() isn't really async
const token = cookieStore.get('authToken')?.value;
const res = await axiosServer.get('/admin/devices', {
headers: {
Authorization: `Bearer ${user.token}`,
},
});
try {
const res = await axiosServer.get('/admin/devices', {
headers: {
Authorization: `Bearer ${user.token}`,
},
});
const devices: DeviceDTO[] = res.data;
const devices: DeviceDTO[] = res.data;
return <DeviceTableSection initialDevices={devices} />;
return <DeviceTableSection initialDevices={devices} />;
} catch (error) {
console.error('Failed to fetch devices:', error);
throw new Error(`Failed to load devices: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}

View File

@@ -1,5 +1,4 @@
// src/app/admin/users/page.tsx
import { cookies } from 'next/headers';
import { requireAuthOrRedirect } from '@/lib/authServer';
import axiosServer from '@/lib/axiosServer';
import UserTableSection from '@/components/admin/UserTableSection';
@@ -19,18 +18,19 @@ interface UserDTO {
export default async function UserManagementPage() {
const user = await requireAuthOrRedirect();
const cookieStore = cookies();
// @ts-expect-error - cookies() is not actually async, type is misleading
const token = cookieStore.get('authToken')?.value;
const res = await axiosServer.get('/admin/users', {
headers: {
Authorization: `Bearer ${user.token}`, // token is guaranteed to exist
},
});
const users: UserDTO[] = res.data;
return <UserTableSection initialUsers={users} />;
try {
const res = await axiosServer.get('/admin/users', {
headers: {
Authorization: `Bearer ${user.token}`,
},
});
const users: UserDTO[] = res.data;
return <UserTableSection initialUsers={users} />;
} catch (error) {
console.error('Failed to fetch users:', error);
throw new Error(`Failed to load users: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}

View File

@@ -225,6 +225,21 @@
}
};
const runCveVerification = async () => {
try {
setLoading(true);
await api.post('/admin/scripts/verify-cve-count');
setCveVisible(true);
setToastMessage('🔍 CVE verification started - check logs for comparison results');
setToastOpen(true);
} catch (err: any) {
setToastMessage("❌ Failed to start CVE verification: " + (err?.response?.data || err.message));
setToastOpen(true);
} finally {
setLoading(false);
}
};
const openDialog = async () => {
await fetchClients();
setDialogOpen(true);
@@ -269,6 +284,16 @@
{loading ? 'Starting Backfill...' : 'Backfill All CVEs (2002-Present)'}
</Button>
<Button
variant="contained"
color="info"
onClick={runCveVerification}
disabled={loading}
sx={{ mt: 2 }}
>
{loading ? 'Verifying...' : 'Verify CVE Count (GitHub API)'}
</Button>
<Button
variant="contained"
onClick={runVulnCacheRefresh}

View File

@@ -1,8 +1,12 @@
// src/lib/axiosServer.ts
import axios from 'axios';
import https from 'https';
const axiosServer = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8080/api',
baseURL: process.env.API_BASE_URL || 'http://localhost:8080/api',
httpsAgent: new https.Agent({
rejectUnauthorized: false, // Accept self-signed certificates
}),
});
export default axiosServer;