added setup page

This commit is contained in:
Vomitblood 2025-02-13 02:43:35 +08:00
parent 43510fb367
commit b2250966fb
7 changed files with 165 additions and 92 deletions

View file

@ -2,7 +2,6 @@ import { Box, Stack } from "@mui/material";
import { WindowButtons } from "./WindowButtons";
import { NavigationButtons } from "./NavigationButtons";
import { RouteDisplay } from "./RouteDisplay";
import { Testing } from "../Testing/Testing";
import { ServerStatus } from "./ServerStatus";
export const HeaderBar = () => {
@ -73,7 +72,6 @@ export const HeaderBar = () => {
}}
>
<ServerStatus />
<Testing />
<WindowButtons />
</Stack>
</Box>

View file

@ -1,7 +1,7 @@
import { Box, Button, Chip, CircularProgress, Popover, Stack } from "@mui/material";
import { fetch } from "@tauri-apps/plugin-http";
import { useAtom } from "jotai";
import { MouseEvent, useEffect, useState } from "react";
import { MouseEvent, useCallback, useEffect, useState } from "react";
import { serverConnectionAtom, serverUrlAtom } from "../../lib/jotai";
import { defaultSettings } from "../../lib/settings";
import { ServerUrlInput } from "./ServerUrlInput";
@ -24,7 +24,7 @@ export const ServerStatus = () => {
};
// function to check server health
const checkServerConnection = async () => {
const checkServerConnection = useCallback(async () => {
setServerConnection("connecting");
// remove trailing slash
@ -42,7 +42,7 @@ export const ServerStatus = () => {
await sleep(500);
setServerConnection("disconnected");
}
};
}, [serverUrl, setServerConnection, setServerUrl]);
const chipProps = {
color: serverConnection === "connected" ? "success" : serverConnection === "disconnected" ? "error" : "warning",
@ -64,7 +64,7 @@ export const ServerStatus = () => {
clearInterval(intervalId);
};
}
}, [serverConnection, serverUrl]);
}, [checkServerConnection, serverConnection, serverUrl]);
return (
<Box

View file

@ -0,0 +1,28 @@
import { Grid2 } from "@mui/material";
import { FC } from "react";
type SetupLogItemProps = {
children?: string;
};
export const SetupLogItem: FC<SetupLogItemProps> = ({ children }) => {
return (
<Grid2
color="lightgreen"
container
fontFamily="JetBrainsMono"
fontSize="0.9rem"
spacing={1}
>
<Grid2 size="auto">&gt;</Grid2>
<Grid2
size="grow"
sx={{
wordBreak: "break-word",
}}
>
{children}
</Grid2>
</Grid2>
);
};

View file

@ -3,13 +3,14 @@ import { Box, Divider, Tab, useTheme } from "@mui/material";
import { useState } from "react";
import { SqlInjectionLogin } from "./SqlInjectionLogin";
import { SqlInjectionRegister } from "./SqlInjectionRegister";
import { SqlInjectionSetup } from "./SqlInjectionSetup";
export const SqlInjection = () => {
// contexts
const theme = useTheme();
// states
const [subTabValue, setSubTabValue] = useState("register");
const [subTabValue, setSubTabValue] = useState("setup");
// logic for switching tabs
const subTabChangeEvent = (newTabValue: string) => {
@ -37,7 +38,7 @@ export const SqlInjection = () => {
>
<TabContext value={subTabValue}>
<TabList
onChange={(e, value) => {
onChange={(_, value) => {
subTabChangeEvent(value);
}}
scrollButtons={true}
@ -46,6 +47,10 @@ export const SqlInjection = () => {
}}
variant="standard"
>
<Tab
label="Setup"
value="setup"
/>
<Tab
label="Register"
value="register"
@ -66,6 +71,12 @@ export const SqlInjection = () => {
width: "100%",
}}
>
<TabPanel
sx={{ p: 2 }}
value="setup"
>
<SqlInjectionSetup />
</TabPanel>
<TabPanel
sx={{ p: 2 }}
value="register"

View file

@ -0,0 +1,120 @@
import { LoadingButton } from "@mui/lab";
import { Box, FormControlLabel, Grid, Grid2, Switch, TextField, Typography } from "@mui/material";
import { fetch } from "@tauri-apps/plugin-http";
import { useAtom } from "jotai";
import { useState } from "react";
import { useNotification } from "../../../contexts/NotificationContext";
import { serverUrlAtom } from "../../../lib/jotai";
import { HeaderLogo } from "../../Generic/HeaderLogo";
import { SetupLogItem } from "./SetupLogItem";
export const SqlInjectionSetup = () => {
// contexts
const { openNotification } = useNotification();
// atoms
const [serverUrl, setServerUrl] = useAtom(serverUrlAtom);
// states
const [logs, setLogs] = useState<string[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const setupClickEvent = async () => {
setLoading(true);
try {
const response = await fetch(serverUrl + "/nuke-db", {
method: "POST",
});
const responseText = await response.text();
if (!response.ok) {
openNotification("Nuke failed: " + responseText);
} else {
openNotification("Nuke successful");
}
setLogs((prevLogs) => [...prevLogs.slice(-5), responseText]);
const response2 = await fetch(serverUrl + "/setup-demo-db", {
method: "POST",
});
const responseText2 = await response2.text();
if (!response.ok) {
openNotification("Setup demo DB failed: " + responseText2);
} else {
openNotification("Demo database setup successful");
}
setLogs((prevLogs) => [...prevLogs.slice(-5), responseText2]);
} catch (e) {
// log the error and handle failure
console.log("Request failed", e);
} finally {
// stop loading indicator regardless of success/failure
setLoading(false);
}
};
return (
<>
<Box
alignItems="center"
display="flex"
flexDirection="row"
sx={{
mb: 2,
}}
>
<HeaderLogo />
<Typography
sx={{
color: "grey",
}}
variant="h6"
>
&nbsp;Setup
</Typography>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
maxHeight: "100%",
}}
>
<Typography variant="body2">
Click on the &apos;Setup/reset DB&apos; button below to initialize or reset your database.
</Typography>
<Typography variant="body2">
If you get an error, make sure you have set the correct server URL (check the chip at the top right).
</Typography>
<Typography variant="body2">
Demo email:{" "}
<b>
<code style={{ fontFamily: "JetBrainsMono" }}>asdf@gmail.com</code>
</b>
</Typography>
<Typography variant="body2">
Demo password:{" "}
<b>
<code style={{ fontFamily: "JetBrainsMono" }}>asdf</code>
</b>
</Typography>
<LoadingButton
loading={loading}
onClick={setupClickEvent}
size="small"
sx={{
my: 2,
}}
variant="contained"
>
Setup/reset DB
</LoadingButton>
{logs.map((log, index) => (
<SetupLogItem key={index}>{log}</SetupLogItem>
))}
</Box>
</>
);
};

View file

@ -1,10 +0,0 @@
import { Box } from "@mui/material";
export const Xss = () => {
return (
<Box>
<h1>XSS</h1>
<p>Cross-site scripting (XSS) is a type of security vulnerability</p>
</Box>
);
};

View file

@ -1,74 +0,0 @@
import { BugReportOutlined } from "@mui/icons-material";
import { Box, Button, IconButton, useTheme } from "@mui/material";
import { fetch } from "@tauri-apps/plugin-http";
import { useAtom } from "jotai";
import { useState } from "react";
import { serverUrlAtom } from "../../lib/jotai";
import { defaultSettings } from "../../lib/settings";
import { FloatingDialog } from "../Generic/FloatingDialog";
export const Testing = () => {
// contexts
const theme = useTheme();
// atoms
const [serverUrl, setServerUrl] = useAtom(serverUrlAtom);
// states
const [openState, setOpenState] = useState(false);
const [maximisedState, setMaximisedState] = useState(false);
// functions
const close = () => setOpenState(false);
const testing = () => {
fetch(serverUrl + "/nuke-db").then((response) => {
console.log(response);
});
fetch(serverUrl + "/setup-demo-db").then((response) => {
console.log(response);
});
};
return (
<FloatingDialog
body={
<Box
sx={{
border: "1px solid " + theme.palette.grey[700],
borderRadius: defaultSettings.style.radius + "px",
display: "flex",
flexDirection: "column",
flexGrow: 1,
my: 2,
overflow: "hidden",
p: 0,
}}
>
<Box>
<Button
onClick={() => {
testing();
}}
>
test
</Button>
</Box>
</Box>
}
close={close}
maximisedState={maximisedState}
openButton={
<IconButton
onClick={() => setOpenState(true)}
size="small"
>
<BugReportOutlined />
</IconButton>
}
openState={openState}
setMaximisedState={setMaximisedState}
title="Testing"
/>
);
};