This commit is contained in:
Vomitblood 2025-01-13 20:08:15 +08:00
parent f891b486df
commit 9301f7cb9c
12 changed files with 201 additions and 68 deletions

View file

@ -5,7 +5,7 @@
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"jsxBracketSameLine": false,
"jsxSingleQuote": true,
"jsxSingleQuote": false,
"printWidth": 120,
"proseWrap": "preserve",
"quoteProps": "consistent",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

View file

@ -0,0 +1,33 @@
import { Box, Typography } from "@mui/material";
import Image from "next/image";
import { FC } from "react";
interface HeaderLogoProps {
sx?: any;
}
export const HeaderLogo: FC<HeaderLogoProps> = ({ sx }) => {
return (
<Box
alignItems="center"
display="flex"
sx={sx}
>
<Image
alt="Logo"
height={40}
priority
src="images/logo.gif"
width={40}
/>
<Typography
sx={{
ml: 1.5,
}}
variant="h6"
>
<b>CSPJ Application</b>
</Typography>
</Box>
);
};

View file

@ -9,14 +9,6 @@ export const NavigationButtons = () => {
// atoms
const [route, setRoute] = useAtom(routeAtom);
const goBack = () => {
// TODO
};
const goForward = () => {
// TODO
};
const goHome = () => {
setRoute("home");
};
@ -29,29 +21,12 @@ export const NavigationButtons = () => {
flexDirection: "row",
}}
>
<Stack
direction='row'
spacing={1}
<IconButton
onClick={goHome}
size="small"
>
<IconButton
onClick={goBack}
size='small'
>
<ArrowBack fontSize='inherit' />
</IconButton>
<IconButton
onClick={goForward}
size='small'
>
<ArrowForward fontSize='inherit' />
</IconButton>
<IconButton
onClick={goHome}
size='small'
>
<HomeOutlined fontSize='inherit' />
</IconButton>
</Stack>
<HomeOutlined fontSize="inherit" />
</IconButton>
</Box>
);
};

View file

@ -19,9 +19,10 @@ export const AttackItem: FC<AttackItemProps> = ({ attackName, routeTarget }) =>
<Card
sx={{
backgroundColor: theme.palette.background.default,
border: "solid 1px grey",
borderRadius: "8px",
}}
variant='outlined'
variant="outlined"
>
<CardActionArea
onClick={() => {
@ -29,7 +30,7 @@ export const AttackItem: FC<AttackItemProps> = ({ attackName, routeTarget }) =>
}}
>
<CardContent>
<Typography component='div'>{attackName}</Typography>
<Typography component="div">{attackName}</Typography>
</CardContent>
</CardActionArea>
</Card>

View file

@ -25,12 +25,17 @@ export const Home = () => {
sx={{
mb: 2,
}}
variant='h3'
variant="h3"
>
CSPJ Application Attack Simulator
</Typography>
</Box>
<Button href='https://github.com/cspj-nyp/cspj-application'>Need help getting started?</Button>
<Button
href="https://github.com/cspj-nyp/cspj-application"
sx={{ mb: 2 }}
>
Need help getting started?
</Button>
</Box>
<Grid2
container
@ -38,14 +43,14 @@ export const Home = () => {
>
<Grid2 size={3}>
<AttackItem
attackName='SQL Injection'
routeTarget='sql_injection'
attackName="SQL Injection"
routeTarget="sql_injection"
/>
</Grid2>
<Grid2 size={3}>
<AttackItem
attackName='Cross Site Scripting'
routeTarget='xss'
attackName="Cross Site Scripting"
routeTarget="xss"
/>
</Grid2>
</Grid2>

View file

@ -1,15 +0,0 @@
import { Box } from "@mui/material";
export const AttackPage = ({}) => {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "start",
}}
>
asdf
</Box>
);
};

View file

@ -1,21 +1,159 @@
import { Box, Button } from "@mui/material";
import { Box, LinearProgress, TextField, Typography } from "@mui/material";
import { useState } from "react";
import { useNotification } from "../../../contexts/NotificationContext";
import { HeaderLogo } from "../../Generic/HeaderLogo";
export const SqlInjection = () => {
// contexts
const { openNotification } = useNotification();
// states
const [passwordValueRaw, setPasswordValueRaw] = useState<string>("");
const [rePasswordValueRaw, setRePasswordValueRaw] = useState<string>("");
const [passwordErrorMsg, setPasswordErrorMsg] = useState<string>("");
// password strength meter
const [passwordStrength, setPasswordStrength] = useState(0);
const [passwordStrengthColor, setPasswordStrengthColor] = useState<"primary" | "error" | "warning" | "success">(
"primary",
);
const [PasswordStrengthInfo, setPasswordStrengthInfo] = useState("Enter a password");
let newPasswordStrengthInfo = "Enter a password";
const calculatePasswordStrength = (passwordValueRaw: string) => {
let strengthPoints = 0;
// logic for calculating password strength
if (passwordValueRaw.length >= 8 && passwordValueRaw.length <= 128) {
strengthPoints += 20;
}
if (passwordValueRaw.match(/[a-z]/g)) {
strengthPoints += 20;
}
if (passwordValueRaw.match(/[A-Z]/g)) {
strengthPoints += 20;
}
if (passwordValueRaw.match(/[0-9]/g)) {
strengthPoints += 20;
}
if (passwordValueRaw.match(/[^a-zA-Z\d]/g)) {
strengthPoints += 20;
}
// calculate strengthPoints as a percentage
strengthPoints = Math.min(strengthPoints, 100);
// logic for changing color of progress bar
if (strengthPoints === 0) {
setPasswordStrengthColor("primary");
newPasswordStrengthInfo = "Enter a password";
} else if (strengthPoints <= 20) {
setPasswordStrengthColor("error");
newPasswordStrengthInfo = "Password strength is weak";
} else if (strengthPoints <= 40) {
setPasswordStrengthColor("warning");
newPasswordStrengthInfo = "Password strength is decent";
} else if (strengthPoints <= 60) {
setPasswordStrengthColor("warning");
newPasswordStrengthInfo = "Password strength is decent";
} else if (strengthPoints <= 80) {
setPasswordStrengthColor("success");
newPasswordStrengthInfo = "Password strength is good";
} else if (strengthPoints <= 100) {
setPasswordStrengthColor("success");
newPasswordStrengthInfo = "Password strength is strong";
}
// update state
setPasswordStrength(strengthPoints);
setPasswordStrengthInfo(newPasswordStrengthInfo);
};
return (
<Box>
<h1>SQL Injection</h1>
<p>SQL Injection is a code injection technique</p>
<Button
onClick={() => {
openNotification("deez nuts", "", 3000);
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
}}
>
<Box
sx={{
border: "solid 1px grey",
borderRadius: 2,
p: 4,
minWidth: "300px",
maxWidth: "400px",
}}
>
clicky
</Button>
<Box
alignItems="center"
display="flex"
flexDirection="row"
sx={{
mb: 2,
}}
>
<HeaderLogo />
<Typography
sx={{
color: "grey",
}}
variant="h6"
>
&nbsp;Login
</Typography>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<TextField
error={Boolean(passwordErrorMsg)}
fullWidth
helperText={Boolean(passwordErrorMsg) ? passwordErrorMsg : ""}
id="email"
label="Email"
size="small"
type="email"
// value={value}
sx={{ mb: 2 }}
variant="outlined"
/>
<TextField
error={Boolean(passwordErrorMsg)}
fullWidth
helperText={Boolean(passwordErrorMsg) ? passwordErrorMsg : ""}
id="password"
label="Password"
size="small"
type="password"
// value={value}
sx={{ mb: 2 }}
variant="outlined"
/>
<TextField
error={Boolean(passwordErrorMsg)}
fullWidth
helperText={Boolean(passwordErrorMsg) ? passwordErrorMsg : ""}
id="re-password"
label="Re-enter password"
size="small"
type="password"
// value={value}
sx={{ mb: 2 }}
variant="outlined"
/>
<LinearProgress
color={passwordStrengthColor}
value={passwordStrength}
variant="determinate"
/>
</Box>
</Box>
</Box>
);
};

View file

@ -5,7 +5,6 @@ import { Home } from "../components/Pages/Home/Home";
import { SqlInjection } from "../components/Pages/SqlInjection/SqlInjection";
import { Xss } from "../components/Pages/Xss/Xss";
import { routeAtom } from "../lib/jotai";
import { AttackPage } from "../components/Pages/Shared/AttackPage";
export default function Index() {
// contexts
@ -23,9 +22,6 @@ export default function Index() {
return <SqlInjection />;
case "xss":
return <Xss />;
// TODO: remove testing when done
case "testing":
return <AttackPage />;
default:
return <Home />;
}
@ -42,7 +38,7 @@ export default function Index() {
>
<HeaderBar />
<Container
maxWidth='lg'
maxWidth="lg"
sx={{
display: "flex",
flexDirection: "column",