diff options
Diffstat (limited to 'http/public')
| -rw-r--r-- | http/public/do/bcrypt.php | 57 | ||||
| -rw-r--r-- | http/public/scripts/feed-condense-content.js | 67 |
2 files changed, 57 insertions, 67 deletions
diff --git a/http/public/do/bcrypt.php b/http/public/do/bcrypt.php new file mode 100644 index 0000000..a61dd9e --- /dev/null +++ b/http/public/do/bcrypt.php @@ -0,0 +1,57 @@ +<?php + +const BCRYPT_COST = 12; + +$user = $_SERVER['PHP_AUTH_USER'] ?? null; +$pass = $_SERVER['PHP_AUTH_PW'] ?? null; + +// Fallback for CGI / FastCGI SAPIs that don't populate PHP_AUTH_*. +// Apache: add "CGIPassAuth On" (2.4.13+) or a RewriteRule to expose +// HTTP_AUTHORIZATION; nginx+php-fpm passes it through by default. +if ($user === null || $pass === null) { + $header = $_SERVER['HTTP_AUTHORIZATION'] + ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] + ?? null; + + if (is_string($header) && preg_match('/^Basic\s+(.+)$/i', $header, $m) === 1) { + $decoded = base64_decode($m[1], true); + + // Split on the FIRST colon only: passwords may contain colons. + if ($decoded !== false && str_contains($decoded, ':')) { + [$user, $pass] = explode(':', $decoded, 2); + } + } +} + +if (!is_string($user) || $user === '' || !is_string($pass) || $pass === '') { + header('WWW-Authenticate: Basic realm="Restricted", charset="UTF-8"'); + http_response_code(401); + header('Content-Type: text/plain; charset=utf-8'); + header('Cache-Control: no-store'); + echo 'authentication required'; + exit; +} + +if (strlen($pass) > 72) { + http_response_code(422); + header('Content-Type: text/plain; charset=utf-8'); + header('Cache-Control: no-store'); + echo 'password exceeds the 72-byte bcrypt limit'; + exit; +} + +$hash = password_hash($pass, PASSWORD_BCRYPT, ['cost' => BCRYPT_COST]); + +if ($hash === false) { + http_response_code(500); + header('Content-Type: text/plain; charset=utf-8'); + header('Cache-Control: no-store'); + echo 'hashing failed'; + exit; +} + +header('Content-Type: text/plain; charset=utf-8'); +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Pragma: no-cache'); + +echo $user . ':' . $hash; diff --git a/http/public/scripts/feed-condense-content.js b/http/public/scripts/feed-condense-content.js deleted file mode 100644 index 984dbce..0000000 --- a/http/public/scripts/feed-condense-content.js +++ /dev/null @@ -1,67 +0,0 @@ -const expandedClass = "e-content--expanded"; - -export function toggleContentExpanded(id) { - const content = document.querySelector(`.e-content[data-content-id="${id}"]`); - const buttonBefore = document.querySelector( - `button:has(+ .e-content[data-content-id="${id}"])`, - ); - const buttonAfter = document.querySelector( - `.e-content[data-content-id="${id}"] + button`, - ); - - if (!content) { - throw new Error(`No content found with ID: ${id}`); - } - const classes = content.getAttribute("class").split(" "); - const wasExpanded = classes.includes(expandedClass); - if (wasExpanded) { - const newClasses = classes.filter((c) => c != expandedClass); - content.setAttribute("class", newClasses.join(" ")); - } else { - content.setAttribute("class", [...classes, expandedClass].join(" ")); - } - - if (wasExpanded) { - if (!buttonBefore) { - console.warn("Tried to remove 'Read less' button but could not find it"); - } else { - buttonBefore.remove(); - } - if (!buttonAfter) { - console.warn( - "Tried to toggle 'Read less' button to say 'Read more' but could not find it", - ); - } else { - buttonAfter.textContent = "Read more"; - } - } else { - if (!buttonAfter) { - console.warn( - "Tried to toggle 'Read more' button to say 'Read less' but could not find it", - ); - } else { - buttonAfter.textContent = "Read less"; - } - if (buttonBefore) { - buttonBefore.remove(); - } - const newButtonBefore = createExpandCondenseButton(id, "Read less"); - content.insertAdjacentElement("beforebegin", newButtonBefore); - } -} - -export function addExpandItemButtons() { - for (const content of document.querySelectorAll(".e-content")) { - const contentId = crypto.randomUUID(); - content.setAttribute("data-content-id", contentId); - const button = createExpandCondenseButton(contentId, "Read more"); - content.insertAdjacentElement("afterend", button); - } -} - -function createExpandCondenseButton(contentId, initialText) { - const button = document.createElement("button"); - button.textContent = initialText; - button.addEventListener("click", () => toggleContentExpanded(contentId)); - return button; -} |
