sql injection

This commit is contained in:
Vomitblood 2025-01-13 22:05:58 +08:00
parent 9301f7cb9c
commit 0edb234718
6 changed files with 453 additions and 220 deletions

195
client/package-lock.json generated
View file

@ -13,7 +13,7 @@
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.13.0",
"@mui/icons-material": "^6.1.6",
"@mui/lab": "^6.0.0-beta.14",
"@mui/lab": "^6.0.0-beta.22",
"@mui/material": "^6.1.6",
"@tauri-apps/api": "^2.1.0",
"@tauri-apps/plugin-http": "~2",
@ -186,13 +186,14 @@
}
},
"node_modules/@emotion/cache": {
"version": "11.13.1",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz",
"integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==",
"version": "11.14.0",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
"integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
"license": "MIT",
"dependencies": {
"@emotion/memoize": "^0.9.0",
"@emotion/sheet": "^1.4.0",
"@emotion/utils": "^1.4.0",
"@emotion/utils": "^1.4.2",
"@emotion/weak-memoize": "^0.4.0",
"stylis": "4.2.0"
}
@ -239,14 +240,15 @@
}
},
"node_modules/@emotion/serialize": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz",
"integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==",
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
"integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
"license": "MIT",
"dependencies": {
"@emotion/hash": "^0.9.2",
"@emotion/memoize": "^0.9.0",
"@emotion/unitless": "^0.10.0",
"@emotion/utils": "^1.4.1",
"@emotion/utils": "^1.4.2",
"csstype": "^3.0.2"
}
},
@ -310,9 +312,10 @@
}
},
"node_modules/@emotion/utils": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz",
"integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA=="
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
"integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
"license": "MIT"
},
"node_modules/@emotion/weak-memoize": {
"version": "0.4.0",
@ -435,26 +438,29 @@
}
},
"node_modules/@floating-ui/core": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
"version": "1.6.9",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
"integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.8"
"@floating-ui/utils": "^0.2.9"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.12",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
"version": "1.6.13",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
"integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.8"
"@floating-ui/utils": "^0.2.9"
}
},
"node_modules/@floating-ui/react-dom": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz",
"integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.0.0"
},
@ -464,9 +470,10 @@
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
"license": "MIT"
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
@ -915,14 +922,15 @@
}
},
"node_modules/@mui/base": {
"version": "5.0.0-beta.61",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.61.tgz",
"integrity": "sha512-YaMOTXS3ecDNGsPKa6UdlJ8loFLvcL9+VbpCK3hfk71OaNauZRp4Yf7KeXDYr7Ms3M/XBD3SaiR6JMr6vYtfDg==",
"version": "5.0.0-beta.68",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.68.tgz",
"integrity": "sha512-F1JMNeLS9Qhjj3wN86JUQYBtJoXyQvknxlzwNl6eS0ZABo1MiohMONj3/WQzYPSXIKC2bS/ZbyBzdHhi2GnEpA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@floating-ui/react-dom": "^2.1.1",
"@mui/types": "^7.2.19",
"@mui/utils": "^6.1.6",
"@mui/types": "^7.2.20",
"@mui/utils": "^6.3.0",
"@popperjs/core": "^2.11.8",
"clsx": "^2.1.1",
"prop-types": "^15.8.1"
@ -935,9 +943,9 @@
"url": "https://opencollective.com/mui-org"
},
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
@ -946,9 +954,10 @@
}
},
"node_modules/@mui/core-downloads-tracker": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.6.tgz",
"integrity": "sha512-nz1SlR9TdBYYPz4qKoNasMPRiGb4PaIHFkzLzhju0YVYS5QSuFF2+n7CsiHMIDcHv3piPu/xDWI53ruhOqvZwQ==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.3.1.tgz",
"integrity": "sha512-2OmnEyoHpj5//dJJpMuxOeLItCCHdf99pjMFfUFdBteCunAK9jW+PwEo4mtdGcLs7P+IgZ+85ypd52eY4AigoQ==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui-org"
@ -980,15 +989,16 @@
}
},
"node_modules/@mui/lab": {
"version": "6.0.0-beta.14",
"resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.14.tgz",
"integrity": "sha512-l+g8z6QGcr7HdfCXhVaYcEp9TijH/G4h0lNaDaBL+qDFQ087ipNHC+XozE7mXOmBwtEAWmTJB4E5GwDboi9oxA==",
"version": "6.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.22.tgz",
"integrity": "sha512-9nwUfBj+UzoQJOCbqV+JcCSJ74T+gGWrM1FMlXzkahtYUcMN+5Zmh2ArlttW3zv2dZyCzp7K5askcnKF0WzFQg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mui/base": "5.0.0-beta.61",
"@mui/system": "^6.1.6",
"@mui/types": "^7.2.19",
"@mui/utils": "^6.1.6",
"@mui/base": "5.0.0-beta.68",
"@mui/system": "^6.3.1",
"@mui/types": "^7.2.21",
"@mui/utils": "^6.3.1",
"clsx": "^2.1.1",
"prop-types": "^15.8.1"
},
@ -1002,8 +1012,8 @@
"peerDependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@mui/material": "^6.1.6",
"@mui/material-pigment-css": "^6.1.6",
"@mui/material": "^6.3.1",
"@mui/material-pigment-css": "^6.3.1",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
@ -1024,21 +1034,22 @@
}
},
"node_modules/@mui/material": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.6.tgz",
"integrity": "sha512-1yvejiQ/601l5AK3uIdUlAVElyCxoqKnl7QA+2oFB/2qYPWfRwDgavW/MoywS5Y2gZEslcJKhe0s2F3IthgFgw==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-6.3.1.tgz",
"integrity": "sha512-ynG9ayhxgCsHJ/dtDcT1v78/r2GwQyP3E0hPz3GdPRl0uFJz/uUTtI5KFYwadXmbC+Uv3bfB8laZ6+Cpzh03gA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mui/core-downloads-tracker": "^6.1.6",
"@mui/system": "^6.1.6",
"@mui/types": "^7.2.19",
"@mui/utils": "^6.1.6",
"@mui/core-downloads-tracker": "^6.3.1",
"@mui/system": "^6.3.1",
"@mui/types": "^7.2.21",
"@mui/utils": "^6.3.1",
"@popperjs/core": "^2.11.8",
"@types/react-transition-group": "^4.4.11",
"@types/react-transition-group": "^4.4.12",
"clsx": "^2.1.1",
"csstype": "^3.1.3",
"prop-types": "^15.8.1",
"react-is": "^18.3.1",
"react-is": "^19.0.0",
"react-transition-group": "^4.4.5"
},
"engines": {
@ -1051,7 +1062,7 @@
"peerDependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@mui/material-pigment-css": "^6.1.6",
"@mui/material-pigment-css": "^6.3.1",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
@ -1072,12 +1083,13 @@
}
},
"node_modules/@mui/private-theming": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.6.tgz",
"integrity": "sha512-ioAiFckaD/fJSnTrUMWgjl9HYBWt7ixCh7zZw7gDZ+Tae7NuprNV6QJK95EidDT7K0GetR2rU3kAeIR61Myttw==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.3.1.tgz",
"integrity": "sha512-g0u7hIUkmXmmrmmf5gdDYv9zdAig0KoxhIQn1JN8IVqApzf/AyRhH3uDGx5mSvs8+a1zb4+0W6LC260SyTTtdQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mui/utils": "^6.1.6",
"@mui/utils": "^6.3.1",
"prop-types": "^15.8.1"
},
"engines": {
@ -1098,13 +1110,14 @@
}
},
"node_modules/@mui/styled-engine": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.6.tgz",
"integrity": "sha512-I+yS1cSuSvHnZDBO7e7VHxTWpj+R7XlSZvTC4lS/OIbUNJOMMSd3UDP6V2sfwzAdmdDNBi7NGCRv2SZ6O9hGDA==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.3.1.tgz",
"integrity": "sha512-/7CC0d2fIeiUxN5kCCwYu4AWUDd9cCTxWCyo0v/Rnv6s8uk6hWgJC3VLZBoDENBHf/KjqDZuYJ2CR+7hD6QYww==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@emotion/cache": "^11.13.1",
"@emotion/serialize": "^1.3.2",
"@emotion/cache": "^11.13.5",
"@emotion/serialize": "^1.3.3",
"@emotion/sheet": "^1.4.0",
"csstype": "^3.1.3",
"prop-types": "^15.8.1"
@ -1131,15 +1144,16 @@
}
},
"node_modules/@mui/system": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.6.tgz",
"integrity": "sha512-qOf1VUE9wK8syiB0BBCp82oNBAVPYdj4Trh+G1s+L+ImYiKlubWhhqlnvWt3xqMevR+D2h1CXzA1vhX2FvA+VQ==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-6.3.1.tgz",
"integrity": "sha512-AwqQ3EAIT2np85ki+N15fF0lFXX1iFPqenCzVOSl3QXKy2eifZeGd9dGtt7pGMoFw5dzW4dRGGzRpLAq9rkl7A==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mui/private-theming": "^6.1.6",
"@mui/styled-engine": "^6.1.6",
"@mui/types": "^7.2.19",
"@mui/utils": "^6.1.6",
"@mui/private-theming": "^6.3.1",
"@mui/styled-engine": "^6.3.1",
"@mui/types": "^7.2.21",
"@mui/utils": "^6.3.1",
"clsx": "^2.1.1",
"csstype": "^3.1.3",
"prop-types": "^15.8.1"
@ -1170,9 +1184,10 @@
}
},
"node_modules/@mui/types": {
"version": "7.2.19",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.19.tgz",
"integrity": "sha512-6XpZEM/Q3epK9RN8ENoXuygnqUQxE+siN/6rGRi2iwJPgBUR25mphYQ9ZI87plGh58YoZ5pp40bFvKYOCDJ3tA==",
"version": "7.2.21",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz",
"integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==",
"license": "MIT",
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
@ -1183,16 +1198,17 @@
}
},
"node_modules/@mui/utils": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.6.tgz",
"integrity": "sha512-sBS6D9mJECtELASLM+18WUcXF6RH3zNxBRFeyCRg8wad6NbyNrdxLuwK+Ikvc38sTZwBzAz691HmSofLqHd9sQ==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.3.1.tgz",
"integrity": "sha512-sjGjXAngoio6lniQZKJ5zGfjm+LD2wvLwco7FbKe1fu8A7VIFmz2SwkLb+MDPLNX1lE7IscvNNyh1pobtZg2tw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mui/types": "^7.2.19",
"@types/prop-types": "^15.7.13",
"@mui/types": "^7.2.21",
"@types/prop-types": "^15.7.14",
"clsx": "^2.1.1",
"prop-types": "^15.8.1",
"react-is": "^18.3.1"
"react-is": "^19.0.0"
},
"engines": {
"node": ">=14.0.0"
@ -1671,9 +1687,10 @@
}
},
"node_modules/@types/prop-types": {
"version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA=="
"version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.12",
@ -1694,10 +1711,11 @@
}
},
"node_modules/@types/react-transition-group": {
"version": "4.4.11",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz",
"integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==",
"dependencies": {
"version": "4.4.12",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
"integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*"
}
},
@ -4822,9 +4840,10 @@
}
},
"node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz",
"integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==",
"license": "MIT"
},
"node_modules/react-transition-group": {
"version": "4.4.5",

View file

@ -15,7 +15,7 @@
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.13.0",
"@mui/icons-material": "^6.1.6",
"@mui/lab": "^6.0.0-beta.14",
"@mui/lab": "^6.0.0-beta.22",
"@mui/material": "^6.1.6",
"@tauri-apps/api": "^2.1.0",
"@tauri-apps/plugin-http": "~2",

View file

@ -1,72 +1,19 @@
import { Box, LinearProgress, TextField, Typography } from "@mui/material";
import { TabContext, TabList, TabPanel } from "@mui/lab";
import { Box, Divider, Tab, useTheme } from "@mui/material";
import { useState } from "react";
import { useNotification } from "../../../contexts/NotificationContext";
import { HeaderLogo } from "../../Generic/HeaderLogo";
import { SqlInjectionLogin } from "./SqlInjectionLogin";
import { SqlInjectionRegister } from "./SqlInjectionRegister";
export const SqlInjection = () => {
// contexts
const { openNotification } = useNotification();
const theme = useTheme();
// 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");
const [subTabValue, setSubTabValue] = useState("style");
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);
// logic for switching tabs
const subTabChangeEvent = (newTabValue: string) => {
setSubTabValue(newTabValue);
};
return (
@ -82,77 +29,59 @@ export const SqlInjection = () => {
sx={{
border: "solid 1px grey",
borderRadius: 2,
p: 4,
minWidth: "300px",
maxWidth: "400px",
display: "flex",
flexDirection: "column",
maxHeight: "90vh",
width: "400px",
}}
>
<Box
alignItems="center"
display="flex"
flexDirection="row"
sx={{
mb: 2,
}}
>
<HeaderLogo />
<Typography
sx={{
color: "grey",
<TabContext value={subTabValue}>
<TabList
onChange={(e, value) => {
subTabChangeEvent(value);
}}
variant="h6"
scrollButtons={true}
sx={{
borderBottom: "1px solid " + theme.palette.divider,
}}
variant="standard"
>
&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>
<Tab
label="Register"
value="register"
/>
<Tab
label="Login"
value="login"
/>
</TabList>
<Box
sx={{
minHeight: "500px",
display: "flex",
flexDirection: "column",
flexGrow: 1,
overflowY: "auto",
p: 2,
width: "100%",
}}
>
<TabPanel
sx={{ p: 2 }}
value="register"
>
<SqlInjectionRegister />
</TabPanel>
<TabPanel
sx={{ p: 2 }}
value="login"
>
<SqlInjectionLogin />
</TabPanel>
<Divider />
the logged in account details goes here
</Box>
</TabContext>
</Box>
</Box>
);

View file

@ -0,0 +1,64 @@
import { Box, LinearProgress, TextField, Typography } from "@mui/material";
import { useState } from "react";
import { HeaderLogo } from "../../Generic/HeaderLogo";
export const SqlInjectionLogin = () => {
// states
const [emailValueRaw, setEmailValueRaw] = useState<string>("");
const [passwordValueRaw, setPasswordValueRaw] = useState<string>("");
const [passwordErrorMsg, setPasswordErrorMsg] = useState<string>("");
return (
<>
<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
fullWidth
id="email"
label="Email"
onChange={(e: { target: { value: string } }) => setEmailValueRaw(e.target.value)}
size="small"
type="email"
value={emailValueRaw}
sx={{ mb: 2 }}
variant="outlined"
/>
<TextField
error={Boolean(passwordErrorMsg)}
fullWidth
helperText={Boolean(passwordErrorMsg) ? passwordErrorMsg : ""}
id="password"
label="Password"
onChange={(e: { target: { value: string } }) => setPasswordValueRaw(e.target.value)}
size="small"
type="password"
value={passwordValueRaw}
sx={{ mb: 2 }}
variant="outlined"
/>
</Box>
</>
);
};

View file

@ -0,0 +1,223 @@
import { LoadingButton } from "@mui/lab";
import { Box, LinearProgress, TextField, Typography } from "@mui/material";
import { fetch } from "@tauri-apps/plugin-http";
import { useAtom } from "jotai";
import { useState } from "react";
import { serverUrlAtom } from "../../../lib/jotai";
import { sleep } from "../../../lib/utility";
import { HeaderLogo } from "../../Generic/HeaderLogo";
export const SqlInjectionRegister = () => {
// atoms
const [serverUrl, setServerUrl] = useAtom(serverUrlAtom);
// states
const [emailValueRaw, setEmailValueRaw] = useState<string>("");
const [passwordValueRaw, setPasswordValueRaw] = useState<string>("");
const [rePasswordValueRaw, setRePasswordValueRaw] = useState<string>("");
const [passwordErrorMsg, setPasswordErrorMsg] = useState<string>("");
const [passwordStrength, setPasswordStrength] = useState(0);
const [passwordStrengthColor, setPasswordStrengthColor] = useState<"primary" | "error" | "warning" | "success">(
"primary",
);
const [passwordStrengthInfo, setPasswordStrengthInfo] = useState("Enter a password");
const [registerLoading, setRegisterLoading] = useState<boolean>(false);
let newPasswordStrengthInfo = "Enter a password";
const passwordInputEvent = (passwordValueRawInput: string) => {
setPasswordValueRaw(passwordValueRawInput);
// call function to update strength meter
calculatePasswordStrength(passwordValueRawInput);
};
const rePasswordInputEvent = (rePasswordValueRawInput: string) => {
setRePasswordValueRaw(rePasswordValueRawInput);
};
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);
};
const nextClickEvent = async () => {
// make a request to the server
setRegisterLoading(true);
// remove trailing slash
setServerUrl(serverUrl.replace(/\/$/, ""));
try {
const response = await fetch(serverUrl + "/sql-register");
console.log;
} catch (e) {
console.log("failed", e);
await sleep(500);
setRegisterLoading(false);
}
};
return (
<>
<Box
alignItems="center"
display="flex"
flexDirection="row"
sx={{
mb: 2,
}}
>
<HeaderLogo />
<Typography
sx={{
color: "grey",
}}
variant="h6"
>
&nbsp;Register
</Typography>
</Box>
<form
onSubmit={(e) => {
e.preventDefault();
nextClickEvent();
}}
>
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<TextField
fullWidth
id="email"
label="Email"
onChange={(e: { target: { value: string } }) => setEmailValueRaw(e.target.value)}
size="small"
type="email"
value={emailValueRaw}
sx={{ mb: 2 }}
variant="outlined"
/>
<TextField
error={Boolean(passwordErrorMsg)}
fullWidth
helperText={Boolean(passwordErrorMsg) ? passwordErrorMsg : ""}
id="password"
label="Password"
onChange={(e: { target: { value: string } }) => passwordInputEvent(e.target.value)}
size="small"
type="password"
value={passwordValueRaw}
sx={{ mb: 2 }}
variant="outlined"
/>
<TextField
error={Boolean(passwordErrorMsg)}
fullWidth
helperText={Boolean(passwordErrorMsg) ? passwordErrorMsg : ""}
id="re-password"
label="Re-enter password"
onChange={(e: { target: { value: string } }) => rePasswordInputEvent(e.target.value)}
size="small"
type="password"
value={rePasswordValueRaw}
sx={{ mb: 2 }}
variant="outlined"
/>
<LinearProgress
color={passwordStrengthColor}
value={passwordStrength}
variant="determinate"
/>
<Typography
sx={{
color: "lightgrey",
fontSize: "12px",
mt: 0.5,
whiteSpace: "normal",
overflowWrap: "break-word",
}}
>
{passwordStrengthInfo}
</Typography>
<Typography
component="div"
sx={{
color: "lightgrey",
fontSize: "12px",
whiteSpace: "normal",
overflowWrap: "break-word",
}}
>
<ul>
<li>Between 8 and 128 characters</li>
<li>At least one uppercase and lowercase letter</li>
<li>At least one number</li>
<li>At least one special character</li>
</ul>
</Typography>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "end",
}}
>
<LoadingButton
loading={registerLoading}
type="submit"
variant="contained"
>
Next
</LoadingButton>
</Box>
</form>
</>
);
};

View file

@ -10,5 +10,3 @@ services:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data: