Fix iptables internet forwarding bug. Update UI errors.
This commit is contained in:
@@ -88,7 +88,7 @@ export default function HostWgIpField({
|
|||||||
<Stack className="w-full gap-2">
|
<Stack className="w-full gap-2">
|
||||||
<Row className="w-full flex-nowrap">
|
<Row className="w-full flex-nowrap">
|
||||||
<Input
|
<Input
|
||||||
value={value}
|
defaultValue={value}
|
||||||
changeHandler={(v) => {
|
changeHandler={(v) => {
|
||||||
onChange?.(v);
|
onChange?.(v);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -25,13 +25,6 @@ export default function SetupMainHostButton({ button_props }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack className="w-full items-stretch gap-3">
|
<Stack className="w-full items-stretch gap-3">
|
||||||
{/* <HostWgIpField
|
|
||||||
value={wgIP}
|
|
||||||
onChange={setWgIP}
|
|
||||||
onStatus={setIpStatus}
|
|
||||||
autoFocus
|
|
||||||
/> */}
|
|
||||||
|
|
||||||
{status?.error && status.msg ? (
|
{status?.error && status.msg ? (
|
||||||
<Tag
|
<Tag
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|||||||
@@ -19,5 +19,5 @@ export const AppData = {
|
|||||||
|
|
||||||
WireguardMainHostID: 0,
|
WireguardMainHostID: 0,
|
||||||
DefaultPrivateIP: `10.1.0.1`,
|
DefaultPrivateIP: `10.1.0.1`,
|
||||||
DefaultWGListenPort: 51820,
|
DefaultWGListenPort: 51821,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ export default function buildHostIptablesScripts({
|
|||||||
if (scoped_subnet) {
|
if (scoped_subnet) {
|
||||||
accept_lines.push(
|
accept_lines.push(
|
||||||
`iptables -A ${forward} -s ${source} -d ${scoped_subnet} -j ACCEPT`,
|
`iptables -A ${forward} -s ${source} -d ${scoped_subnet} -j ACCEPT`,
|
||||||
|
`iptables -A ${forward} -s ${source} -o ${target_interface} -j ACCEPT`,
|
||||||
`iptables -A ${input} -s ${source} -j ACCEPT`,
|
`iptables -A ${input} -s ${source} -j ACCEPT`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ export default function AddClientFormAllowedIps({
|
|||||||
allowed_ips: e.target.value,
|
allowed_ips: e.target.value,
|
||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
value={form.allowed_ips}
|
defaultValue={form.allowed_ips}
|
||||||
showLabel
|
showLabel
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||||
|
import fetchApi from "@/src/components/twui/utils/fetch/fetchApi";
|
||||||
|
import type useFormInit from "@/src/hooks/use-form-init";
|
||||||
|
import type { ApiReqParams } from "@/src/types";
|
||||||
|
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
||||||
|
import type { Dispatch, SetStateAction } from "react";
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
iface: string;
|
||||||
|
local: boolean;
|
||||||
|
setLoading: Dispatch<SetStateAction<boolean>>;
|
||||||
|
setForm: Dispatch<SetStateAction<BUN_SQLITE_WGUI_HOSTS>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function clientFetchIP({
|
||||||
|
iface,
|
||||||
|
local,
|
||||||
|
setLoading,
|
||||||
|
setForm,
|
||||||
|
}: Params) {
|
||||||
|
if (!iface) return;
|
||||||
|
|
||||||
|
const endpoint = local
|
||||||
|
? `/api/admin/interface-local-ip?interface=${iface}`
|
||||||
|
: `/api/admin/public-ip?interface=${iface}`;
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
fetchApi<ApiReqParams, APIResponseObject>(endpoint, {
|
||||||
|
method: "GET",
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.success && res.stringRes) {
|
||||||
|
setForm((prev) => ({
|
||||||
|
...prev,
|
||||||
|
public_ip_address: res.stringRes!,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -13,7 +13,9 @@ export default async function submitAddHostForm({
|
|||||||
existing_full,
|
existing_full,
|
||||||
}: ReturnType<typeof useFormInit<BUN_SQLITE_WGUI_HOSTS>>) {
|
}: ReturnType<typeof useFormInit<BUN_SQLITE_WGUI_HOSTS>>) {
|
||||||
try {
|
try {
|
||||||
const confirm_msg = existing_full?.id
|
const is_updating_host = typeof existing_full?.id == "number";
|
||||||
|
|
||||||
|
const confirm_msg = is_updating_host
|
||||||
? `Update this host?`
|
? `Update this host?`
|
||||||
: `Create this new host?`;
|
: `Create this new host?`;
|
||||||
|
|
||||||
@@ -24,12 +26,10 @@ export default async function submitAddHostForm({
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
const res = await fetchApi<ApiReqParams, APIResponseObject>(
|
const res = await fetchApi<ApiReqParams, APIResponseObject>(
|
||||||
existing_full?.id
|
is_updating_host ? `/api/admin/update-host` : `/api/admin/add-host`,
|
||||||
? `/api/admin/update-host`
|
|
||||||
: `/api/admin/add-host`,
|
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: existing_full?.id
|
body: is_updating_host
|
||||||
? {
|
? {
|
||||||
host_id: existing_full.id,
|
host_id: existing_full.id,
|
||||||
update_data: form,
|
update_data: form,
|
||||||
@@ -49,10 +49,7 @@ export default async function submitAddHostForm({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const host_id =
|
const host_id = is_updating_host ? existing_full.id : res.numberRes;
|
||||||
typeof existing_full?.id == "number"
|
|
||||||
? existing_full.id
|
|
||||||
: res.numberRes;
|
|
||||||
|
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
clearLocalForm();
|
clearLocalForm();
|
||||||
|
|||||||
@@ -16,13 +16,15 @@ export default function AddHostFormAction({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const is_updating_host = typeof existing_full?.id == "number";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
title="Create Host"
|
title="Create Host"
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={existing_full?.id ? false : ipStatus !== "available"}
|
disabled={is_updating_host ? false : ipStatus !== "available"}
|
||||||
>
|
>
|
||||||
{existing_full?.id ? "Update Host" : "Create Host"}
|
{is_updating_host ? "Update Host" : "Create Host"}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default function AddHostFormInterface({
|
|||||||
if (existing_full?.interface) {
|
if (existing_full?.interface) {
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
value={existing_full.interface || "N/A"}
|
defaultValue={existing_full.interface || "N/A"}
|
||||||
title="Network Interface"
|
title="Network Interface"
|
||||||
readOnly
|
readOnly
|
||||||
showLabel
|
showLabel
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default function AddHostFormListenPort({
|
|||||||
if (existing_full?.listen_port) {
|
if (existing_full?.listen_port) {
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
value={existing_full.listen_port || "N/A"}
|
defaultValue={existing_full.listen_port || "N/A"}
|
||||||
title="Listen Port"
|
title="Listen Port"
|
||||||
readOnly
|
readOnly
|
||||||
showLabel
|
showLabel
|
||||||
@@ -57,7 +57,7 @@ export default function AddHostFormListenPort({
|
|||||||
label="Listen Port"
|
label="Listen Port"
|
||||||
showLabel
|
showLabel
|
||||||
placeholder={String(AppData["DefaultWGListenPort"])}
|
placeholder={String(AppData["DefaultWGListenPort"])}
|
||||||
value={
|
defaultValue={
|
||||||
form.listen_port != null ? String(form.listen_port) : ""
|
form.listen_port != null ? String(form.listen_port) : ""
|
||||||
}
|
}
|
||||||
numberText
|
numberText
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import Checkbox from "@/src/components/twui/form/Checkbox";
|
|||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import useStatus from "@/src/components/twui/hooks/useStatus";
|
import useStatus from "@/src/components/twui/hooks/useStatus";
|
||||||
import LoadingOverlay from "@/src/components/twui/elements/LoadingOverlay";
|
import LoadingOverlay from "@/src/components/twui/elements/LoadingOverlay";
|
||||||
|
import LoadingRectangleBlock from "@/src/components/twui/layout/LoadingRectangleBlock";
|
||||||
|
import clientFetchIP from "../../(functions)/fetch-ip";
|
||||||
|
import isLocalIPAddress from "../../../../../../utils/is-local-ip-address";
|
||||||
|
|
||||||
type Props = ReturnType<typeof useFormInit<BUN_SQLITE_WGUI_HOSTS>>;
|
type Props = ReturnType<typeof useFormInit<BUN_SQLITE_WGUI_HOSTS>>;
|
||||||
|
|
||||||
@@ -19,64 +22,55 @@ export default function AddHostFormPublicIP({
|
|||||||
app_context,
|
app_context,
|
||||||
existing_full,
|
existing_full,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [useLocalIP, setUseLocalIP] = useState(false);
|
const is_existing_local_ip = isLocalIPAddress(
|
||||||
|
existing_full?.public_ip_address,
|
||||||
|
)
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
|
||||||
|
const [useLocalIP, setUseLocalIP] = useState(is_existing_local_ip);
|
||||||
|
|
||||||
const { loading, setLoading } = useStatus({
|
const { loading, setLoading } = useStatus({
|
||||||
initialLoading: existing_full?.id ? false : true,
|
initialLoading: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
function fetchIP(iface: string, local: boolean) {
|
|
||||||
if (!iface) return;
|
|
||||||
|
|
||||||
const endpoint = local
|
|
||||||
? `/api/admin/interface-local-ip?interface=${iface}`
|
|
||||||
: `/api/admin/public-ip?interface=${iface}`;
|
|
||||||
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
fetchApi<ApiReqParams, APIResponseObject>(endpoint, {
|
|
||||||
method: "GET",
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.success && res.stringRes) {
|
|
||||||
setForm((prev) => ({
|
|
||||||
...prev,
|
|
||||||
public_ip_address: res.stringRes!,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
setLoading(false);
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!form.interface) return;
|
if (!form.interface) {
|
||||||
fetchIP(form.interface, useLocalIP);
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clientFetchIP({
|
||||||
|
iface: form.interface,
|
||||||
|
local: useLocalIP,
|
||||||
|
setForm,
|
||||||
|
setLoading,
|
||||||
|
});
|
||||||
}, [form.interface, useLocalIP]);
|
}, [form.interface, useLocalIP]);
|
||||||
|
|
||||||
if (existing_full?.public_ip_address) {
|
// if (existing_full?.public_ip_address) {
|
||||||
return (
|
// return (
|
||||||
<Input
|
// <Input
|
||||||
value={existing_full.public_ip_address || "N/A"}
|
// defaultValue={existing_full.public_ip_address || "N/A"}
|
||||||
title="IP Address"
|
// title="IP Address"
|
||||||
readOnly
|
// readOnly
|
||||||
showLabel
|
// showLabel
|
||||||
/>
|
// />
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack className={twMerge("w-full gap-2 relative")}>
|
<Stack className={twMerge("w-full gap-2 relative")}>
|
||||||
{loading ? <LoadingOverlay /> : null}
|
{loading ? (
|
||||||
|
<LoadingRectangleBlock className="h-[70px]" />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
<Input
|
<Input
|
||||||
name="public_ip_address"
|
name="public_ip_address"
|
||||||
label="IP Address"
|
label="IP Address"
|
||||||
showLabel
|
showLabel
|
||||||
placeholder="e.g. 203.0.113.10 or 192.168.1.10"
|
placeholder="e.g. 203.0.113.10 or 192.168.1.10"
|
||||||
value={form.public_ip_address || ""}
|
defaultValue={form.public_ip_address || ""}
|
||||||
changeHandler={(v) => {
|
changeHandler={(v) => {
|
||||||
setForm((prev) => ({
|
setForm((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
@@ -89,12 +83,17 @@ export default function AddHostFormPublicIP({
|
|||||||
setUseLocalIP(checked);
|
setUseLocalIP(checked);
|
||||||
}}
|
}}
|
||||||
label={
|
label={
|
||||||
<span className="text-base opacity-80">Use Local IP?</span>
|
<span className="text-base opacity-80">
|
||||||
|
Use Local IP?
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
defaultChecked={
|
defaultChecked={
|
||||||
useLocalIP || Boolean(app_context.pageProps?.is_local_ip)
|
useLocalIP ||
|
||||||
|
isLocalIPAddress(form.public_ip_address)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function AddHostFormWgIpAddress({
|
|||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
placeholder="WG IP address"
|
placeholder="WG IP address"
|
||||||
value={props.existing_full.wg_ip_address}
|
defaultValue={props.existing_full.wg_ip_address}
|
||||||
readOnly
|
readOnly
|
||||||
showLabel
|
showLabel
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default function ChangePasswordSection() {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setNewPassword(e.target.value);
|
setNewPassword(e.target.value);
|
||||||
}}
|
}}
|
||||||
value={new_password}
|
defaultValue={new_password}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="password"
|
type="password"
|
||||||
@@ -97,7 +97,7 @@ export default function ChangePasswordSection() {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setConfirmPassword(e.target.value);
|
setConfirmPassword(e.target.value);
|
||||||
}}
|
}}
|
||||||
value={confirm_password}
|
defaultValue={confirm_password}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{status?.error && status.msg ? (
|
{status?.error && status.msg ? (
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export default function SetupUpdateWgUiAction({ setup }: Props) {
|
|||||||
<Input<"repo_url">
|
<Input<"repo_url">
|
||||||
label="Repository URL"
|
label="Repository URL"
|
||||||
placeholder={SiteData["RepoURL"]}
|
placeholder={SiteData["RepoURL"]}
|
||||||
value={repoUrl}
|
defaultValue={repoUrl}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setRepoUrl(e.target.value);
|
setRepoUrl(e.target.value);
|
||||||
}}
|
}}
|
||||||
@@ -88,7 +88,7 @@ export default function SetupUpdateWgUiAction({ setup }: Props) {
|
|||||||
<Input<"branch">
|
<Input<"branch">
|
||||||
label="Branch"
|
label="Branch"
|
||||||
placeholder="main"
|
placeholder="main"
|
||||||
value={branch}
|
defaultValue={branch}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setBranch(e.target.value);
|
setBranch(e.target.value);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||||
import checkUserAccess from "@/src/functions/backend/auth/check-user-access";
|
import checkUserAccess from "@/src/functions/backend/auth/check-user-access";
|
||||||
import userAuth from "@/src/functions/backend/auth/user-auth";
|
import userAuth from "@/src/functions/backend/auth/user-auth";
|
||||||
import createWireguardHost from "@/src/functions/backend/setup/create-wireguard-host";
|
|
||||||
import setupWireguardHost from "@/src/functions/backend/setup/setup-wireguard-host";
|
import setupWireguardHost from "@/src/functions/backend/setup/setup-wireguard-host";
|
||||||
import type { ApiReqParams, TableType } from "@/src/types";
|
import type { ApiReqParams, TableType } from "@/src/types";
|
||||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export default function isLocalIPAddress(ip: string | undefined) {
|
||||||
|
return Boolean(ip?.match(/^(192|10)\./));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user