fix: resolve WireGuard server tab crash and enforce client creation server prerequisite

This commit is contained in:
xtcnet 2026-03-08 09:47:20 +07:00
parent 54d1623551
commit 36acc3ea65
3 changed files with 34 additions and 23 deletions

View file

@ -357,20 +357,27 @@ const internalWireguard = {
},
/**
* Get the WireGuard interface info
* Get the WireGuard interfaces info
*/
async getInterfaceInfo(knex) {
const iface = await this.getOrCreateInterface(knex);
return {
id: iface.id,
name: iface.name,
public_key: iface.public_key,
ipv4_cidr: iface.ipv4_cidr,
listen_port: iface.listen_port,
mtu: iface.mtu,
dns: iface.dns,
host: iface.host,
};
async getInterfacesInfo(knex) {
const ifaces = await knex("wg_interface").select("*");
const allLinks = await knex("wg_server_link").select("*");
return ifaces.map((i) => {
const links = allLinks.filter(l => l.interface_id_1 === i.id || l.interface_id_2 === i.id);
return {
id: i.id,
name: i.name,
public_key: i.public_key,
ipv4_cidr: i.ipv4_cidr,
listen_port: i.listen_port,
mtu: i.mtu,
dns: i.dns,
host: i.host,
isolate_clients: i.isolate_clients,
linked_servers: links.map(l => l.interface_id_1 === i.id ? l.interface_id_2 : l.interface_id_1),
};
});
},
/**

View file

@ -10,13 +10,13 @@ const router = express.Router({
/**
* GET /api/wireguard
* Get WireGuard interface info
* Get WireGuard interfaces info
*/
router.get("/", async (_req, res, next) => {
try {
const knex = db();
const iface = await internalWireguard.getInterfaceInfo(knex);
res.status(200).json(iface);
const ifaces = await internalWireguard.getInterfacesInfo(knex);
res.status(200).json(ifaces);
} catch (err) {
next(err);
}

View file

@ -48,7 +48,7 @@ function timeAgo(date: string | null): string {
}
function WireGuard() {
const [activeTab, setActiveTab] = useState<"servers" | "clients">("clients");
const [activeTab, setActiveTab] = useState<"servers" | "clients">("servers");
const { data: clients, isLoading: clientsLoading } = useWgClients();
const { data: interfaces, isLoading: ifacesLoading } = useWgInterfaces();
@ -107,6 +107,10 @@ function WireGuard() {
// Client Handlers
const handleNewClient = async () => {
if (!interfaces || interfaces.length === 0) {
alert("Bạn phải tạo một WireGuard Server trước khi tạo Client.");
return;
}
const result = (await EasyModal.show(WireGuardClientModal, { interfaces: interfaces || [] })) as any;
if (result && result.name && result.interface_id) {
createClient.mutate({ name: result.name, interface_id: result.interface_id });
@ -174,18 +178,18 @@ function WireGuard() {
<div className="card">
<div className="card-header">
<ul className="nav nav-tabs card-header-tabs" data-bs-toggle="tabs">
<li className="nav-item cursor-pointer">
<a className={`nav-link ${activeTab === "clients" ? "active" : ""}`} onClick={() => setActiveTab("clients")}>
<IconNetwork className="me-1" size={16}/> Clients
<span className="badge bg-green ms-2">{clients?.length || 0}</span>
</a>
</li>
<li className="nav-item cursor-pointer">
<a className={`nav-link ${activeTab === "servers" ? "active" : ""}`} onClick={() => setActiveTab("servers")}>
<IconServer className="me-1" size={16}/> Servers
<span className="badge bg-blue ms-2">{interfaces?.length || 0}</span>
</a>
</li>
<li className="nav-item cursor-pointer">
<a className={`nav-link ${activeTab === "clients" ? "active" : ""}`} onClick={() => setActiveTab("clients")}>
<IconNetwork className="me-1" size={16}/> Clients
<span className="badge bg-green ms-2">{clients?.length || 0}</span>
</a>
</li>
</ul>
</div>