diff --git a/public/error.html b/public/error.html
new file mode 100644
index 0000000..c844b96
--- /dev/null
+++ b/public/error.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ WOLITE| ERROR
+
+
+
+
+
+
ERROR | {{errorCode}}
+
{{errorMessage}}
+
+
+
+
+
diff --git a/public/style.css b/public/style.css
index 53b0b70..d563c6b 100644
--- a/public/style.css
+++ b/public/style.css
@@ -27,13 +27,15 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
--text-3xl--line-height: calc(2.25 / 1.875);
--text-4xl: 2.25rem;
--text-4xl--line-height: calc(2.5 / 2.25);
- --text-5xl: 3rem;
- --text-5xl--line-height: 1;
--text-7xl: 4.5rem;
--text-7xl--line-height: 1;
--text-9xl: 8rem;
--text-9xl--line-height: 1;
+ --font-weight-extralight: 200;
+ --font-weight-light: 300;
--font-weight-bold: 700;
+ --default-transition-duration: 150ms;
+ --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
--default-font-family: var(--font-sans);
--default-font-feature-settings: var(--font-sans--font-feature-settings);
--default-font-variation-settings: var(
@@ -249,6 +251,9 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
.mx-auto {
margin-inline: auto;
}
+ .mt-4 {
+ margin-top: calc(var(--spacing) * 4);
+ }
.block {
display: block;
}
@@ -282,6 +287,9 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
.border-collapse {
border-collapse: collapse;
}
+ .transform {
+ transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
+ }
.cursor-pointer {
cursor: pointer;
}
@@ -327,6 +335,9 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
.bg-secondary {
background-color: var(--color-secondary);
}
+ .p-1 {
+ padding: calc(var(--spacing) * 1);
+ }
.p-2 {
padding: calc(var(--spacing) * 2);
}
@@ -360,14 +371,18 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
.font-inter {
font-family: var(--font-inter);
}
+ .text-2xl {
+ font-size: var(--text-2xl);
+ line-height: var(--tw-leading, var(--text-2xl--line-height));
+ }
+ .text-3xl {
+ font-size: var(--text-3xl);
+ line-height: var(--tw-leading, var(--text-3xl--line-height));
+ }
.text-4xl {
font-size: var(--text-4xl);
line-height: var(--tw-leading, var(--text-4xl--line-height));
}
- .text-5xl {
- font-size: var(--text-5xl);
- line-height: var(--tw-leading, var(--text-5xl--line-height));
- }
.text-7xl {
font-size: var(--text-7xl);
line-height: var(--tw-leading, var(--text-7xl--line-height));
@@ -384,12 +399,17 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
}
+ .font-extralight {
+ --tw-font-weight: var(--font-weight-extralight);
+ font-weight: var(--font-weight-extralight);
+ }
+ .font-light {
+ --tw-font-weight: var(--font-weight-light);
+ font-weight: var(--font-weight-light);
+ }
.text-wrap {
text-wrap: wrap;
}
- .text-\[\#5c5c5c\] {
- color: #5c5c5c;
- }
.text-muted {
color: var(--color-muted);
}
@@ -412,6 +432,38 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
+ .backdrop-filter {
+ -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
+ backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
+ }
+ .transition {
+ transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
+ .duration-1 {
+ --tw-duration: 1ms;
+ transition-duration: 1ms;
+ }
+ .duration-75 {
+ --tw-duration: 75ms;
+ transition-duration: 75ms;
+ }
+ .duration-500 {
+ --tw-duration: 500ms;
+ transition-duration: 500ms;
+ }
+ .duration-1000 {
+ --tw-duration: 1000ms;
+ transition-duration: 1000ms;
+ }
+ .hover\:bg-secondary {
+ &:hover {
+ @media (hover: hover) {
+ background-color: var(--color-secondary);
+ }
+ }
+ }
.hover\:bg-white {
&:hover {
@media (hover: hover) {
@@ -419,6 +471,13 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
}
}
}
+ .hover\:text-primary {
+ &:hover {
+ @media (hover: hover) {
+ color: var(--color-primary);
+ }
+ }
+ }
.hover\:text-secondary {
&:hover {
@media (hover: hover) {
@@ -440,23 +499,12 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
}
}
}
- .sm\:text-justify {
- @media (width >= 40rem) {
- text-align: justify;
- }
- }
.sm\:text-2xl {
@media (width >= 40rem) {
font-size: var(--text-2xl);
line-height: var(--tw-leading, var(--text-2xl--line-height));
}
}
- .sm\:text-5xl {
- @media (width >= 40rem) {
- font-size: var(--text-5xl);
- line-height: var(--tw-leading, var(--text-5xl--line-height));
- }
- }
.sm\:text-7xl {
@media (width >= 40rem) {
font-size: var(--text-7xl);
@@ -473,6 +521,42 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
width: calc(1/2 * 100%);
}
}
+ .lg\:space-y-0 {
+ @media (width >= 64rem) {
+ :where(& > :not(:last-child)) {
+ --tw-space-y-reverse: 0;
+ margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));
+ margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));
+ }
+ }
+ }
+ .lg\:space-y-0\.5 {
+ @media (width >= 64rem) {
+ :where(& > :not(:last-child)) {
+ --tw-space-y-reverse: 0;
+ margin-block-start: calc(calc(var(--spacing) * 0.5) * var(--tw-space-y-reverse));
+ margin-block-end: calc(calc(var(--spacing) * 0.5) * calc(1 - var(--tw-space-y-reverse)));
+ }
+ }
+ }
+ .lg\:space-y-1 {
+ @media (width >= 64rem) {
+ :where(& > :not(:last-child)) {
+ --tw-space-y-reverse: 0;
+ margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));
+ margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));
+ }
+ }
+ }
+ .lg\:space-y-2 {
+ @media (width >= 64rem) {
+ :where(& > :not(:last-child)) {
+ --tw-space-y-reverse: 0;
+ margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));
+ margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)));
+ }
+ }
+ }
.lg\:space-y-8 {
@media (width >= 64rem) {
:where(& > :not(:last-child)) {
@@ -493,12 +577,6 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
line-height: var(--tw-leading, var(--text-3xl--line-height));
}
}
- .xl\:text-7xl {
- @media (width >= 80rem) {
- font-size: var(--text-7xl);
- line-height: var(--tw-leading, var(--text-7xl--line-height));
- }
- }
.xl\:text-9xl {
@media (width >= 80rem) {
font-size: var(--text-9xl);
@@ -506,6 +584,31 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
}
}
}
+@property --tw-rotate-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateX(0);
+}
+@property --tw-rotate-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateY(0);
+}
+@property --tw-rotate-z {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateZ(0);
+}
+@property --tw-skew-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: skewX(0);
+}
+@property --tw-skew-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: skewY(0);
+}
@property --tw-space-y-reverse {
syntax: "*";
inherits: false;
@@ -565,3 +668,43 @@ https://youtu.be/K6XO8FTiGIs?si=sH0Fx1ThPbmmWemT [how to add color]
syntax: "*";
inherits: false;
}
+@property --tw-backdrop-blur {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-brightness {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-contrast {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-grayscale {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-hue-rotate {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-invert {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-opacity {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-saturate {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-sepia {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-duration {
+ syntax: "*";
+ inherits: false;
+}
diff --git a/server/middleware/basicIpFilter.js b/server/middleware/basicIpFilter.js
index 9e9f966..60f004e 100644
--- a/server/middleware/basicIpFilter.js
+++ b/server/middleware/basicIpFilter.js
@@ -1,3 +1,4 @@
+const GetErrorPage = require("../utils/error");
const LogConsole = require("../utils/logging");
require("dotenv").config();
@@ -21,7 +22,7 @@ function basicIpAuth(req, res, next) {
// Check if the client's IP is in the allowedIPs list
if (!allowedOrigins.includes(clientIp)) {
LogConsole("warn", "Access denied. IP not allowed.", clientIp);
- return res.status(403).send("Access denied.");
+ return res.status(403).send(GetErrorPage(403, "Access denied. IP not allowed."));
}
LogConsole("info", "IP allowed.", clientIp);
next();
diff --git a/server/routes/auth.js b/server/routes/auth.js
index 740f5a9..f9378e8 100644
--- a/server/routes/auth.js
+++ b/server/routes/auth.js
@@ -4,6 +4,7 @@ const bcrypt = require("bcrypt");
require("dotenv").config();
const createOTP = require("../utils/otp");
const LogConsole = require("../utils/logging");
+const basicIpFilter = require("../middleware/basicIpFilter");
const router = express.Router();
@@ -12,6 +13,8 @@ router.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "..", "..", "public", "login.html"));
});
+router.use(basicIpFilter);
+
// POST /auth - process the login form submission
router.post("/", (req, res) => {
const { username, password, totp } = req.body;
diff --git a/server/utils/error.js b/server/utils/error.js
new file mode 100644
index 0000000..46498f4
--- /dev/null
+++ b/server/utils/error.js
@@ -0,0 +1,13 @@
+const fs = require("fs");
+const path = require("path");
+
+function GetErrorPage(code, message) {
+ const errorFilePath = path.join(__dirname, "..", "..", "public", "error.html");
+ let errorHtml = fs.readFileSync(errorFilePath, "utf8");
+ errorHtml = errorHtml.replace("{{errorCode}}", code);
+ errorHtml = errorHtml.replace("{{errorMessage}}", message);
+
+ return errorHtml;
+}
+
+module.exports = GetErrorPage;