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;