diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..c57d4fa --- /dev/null +++ b/.htaccess @@ -0,0 +1,49 @@ +# Example Apache VirtualHost +# for serving tkr as a subdirectory path +# on shared hosting via .htaccess +# +# e.g. http://www.my-domain.com/tkr +# +# This should work without modification if you extract the app +# to /tkr from your web document root + +# Enable mod_rewrite +RewriteEngine On + +# Security headers +Header always set X-Frame-Options "SAMEORIGIN" +Header always set X-XSS-Protection "1; mode=block" +Header always set X-Content-Type-Options "nosniff" + +# Directory index +DirectoryIndex public/index.php + +# Security: Block direct access to .php files (except through rewrites) +RewriteCond %{THE_REQUEST} \s/[^?\s]*\.php[\s?] [NC] +RewriteRule ^.*$ - [R=404,L] + +# Security: Block access to sensitive directories +RewriteRule ^(storage|src|templates|examples|config)(/.*)?$ - [F,L] + +# Security: Block access to hidden files +RewriteRule ^\..*$ - [F,L] + +# Cache CSS files for 1 hour + + Header set Cache-Control "public, max-age=3600" + + +# Serve the one static file that exists: css/tkr.css +# (Pass requests to css/custom/ through to the PHP app) +RewriteCond %{REQUEST_URI} !^/css/custom/ +RewriteRule ^css/tkr\.css$ public/css/tkr.css [L] + +# 404 all other static files (images, js, fonts, etc.) +# so those requests don't hit the PHP app +# (this is to reduce load on the PHP app from bots and scanners) +RewriteRule \.(js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|pdf|zip|mp3|mp4|avi|mov)$ - [R=404,L] + +# Everything else goes to the front controller +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^(.*)$ public/index.php [L] diff --git a/config/.htaccess b/config/.htaccess new file mode 100644 index 0000000..f86ed55 --- /dev/null +++ b/config/.htaccess @@ -0,0 +1,6 @@ +# Deny all access to this directory +Require all denied + +# Fallback for Apache 2.2 +Order deny,allow +Deny from all \ No newline at end of file diff --git a/config/bootstrap.php b/config/bootstrap.php index 372109a..a9ac650 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -41,7 +41,7 @@ function handle_setup_exception(SetupException $e){ // Show error message and exit http_response_code(500); echo "

Configuration Error

"; - echo "

" . htmlspecialchars($setupError['message']) . "

"; + echo "

" . Util::escape_html($setupError['message']) . "

"; exit; case 'table_contents': // Recoverable error. diff --git a/examples/.htaccess b/examples/.htaccess new file mode 100644 index 0000000..f86ed55 --- /dev/null +++ b/examples/.htaccess @@ -0,0 +1,6 @@ +# Deny all access to this directory +Require all denied + +# Fallback for Apache 2.2 +Order deny,allow +Deny from all \ No newline at end of file diff --git a/public/css/tkr.css b/public/css/tkr.css index 76da718..9a81245 100644 --- a/public/css/tkr.css +++ b/public/css/tkr.css @@ -95,7 +95,7 @@ fieldset.emoji-group { } h1.site-description { - font-size: 1.3em; + font-size: 1.5em; } .delete-emoji-fieldset .fieldset-items { @@ -310,19 +310,85 @@ label.description { } .home-sidebar{ + padding-top: 1em; padding-bottom: 1em; } .site-description { font-size: 1.2rem; color: var(--color-text-dark); - margin-bottom: 0.5rem; + margin-bottom: 1.2rem; } -.profile-row { +.profile-data { + display: grid; + gap: 1rem; + margin: 0; + margin-bottom: 1rem; +} + +/* Description list: description */ +.profile-data dd { + margin: 0; +} + +/* Description list: term */ +/* Hidden from visual display - screen reader only class */ +.profile-data dt { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* + Left-justify the greeting text, + right-justify the Change Mood link +*/ + +/* greeting text */ +.profile-greeting { display: flex; - width: 100%; - gap: 0.5em; + justify-content: space-between; + align-items: center; + gap: 0.5rem; +} + +/* add a small gap between the greeting and the mood emoji */ +.greeting-content { + display: flex; + align-items: baseline; + gap: 0.4em; +} + +/* define the profile "greeting" style */ +.greeting-text { + font-weight: 600; + font-size: 1.1em; + color: var(--color-text-primary); +} + +/* Adjust emoji positioning */ +.greeting-emoji { + vertical-align: middle; +} + +/* Style the Change Mood link */ +.change-mood { + font-size: 0.9em; + white-space: nowrap; +} + +/* define the profile "about" style */ +.profile-about { + font-style: italic; + font-size: 0.95em; + color: var(--color-text-muted); } .tick-form { @@ -332,20 +398,13 @@ label.description { gap: 0.5em; } -.mood-bar { - display: flex; - width: 100%; - justify-content: space-between; - align-items: center; - gap: 0.5em; -} - +/* Styling for flash messages */ .flash-messages { - background: white; + background: var(--color-bg-white); margin-top: 10px; padding: 15px; border-radius: 8px; - box-shadow: 0 2px 10px rgba(0,0,0,0.1); + box-shadow: 0 2px 10px var(--shadow-primary); } .flash-message { @@ -436,18 +495,28 @@ label.description { color: var(--color-required); } +.tick-feed { + list-style: none; + padding: 0; + margin: 0; + margin-top: 0.5em; +} + .tick { margin-bottom: 1em; + padding-left: 0.5em; } .tick-time { color: var(--color-text-muted); font-size: 0.8em; + margin-bottom: 0.4em; } .tick-text { color: var(--color-text-black); font-size: 1.0em; + display: block; } .tick-pagination a { diff --git a/src/.htaccess b/src/.htaccess new file mode 100644 index 0000000..f86ed55 --- /dev/null +++ b/src/.htaccess @@ -0,0 +1,6 @@ +# Deny all access to this directory +Require all denied + +# Fallback for Apache 2.2 +Order deny,allow +Deny from all \ No newline at end of file diff --git a/src/Controller/AuthController/AuthController.php b/src/Controller/AuthController/AuthController.php index 15bc901..4efbfcd 100644 --- a/src/Controller/AuthController/AuthController.php +++ b/src/Controller/AuthController/AuthController.php @@ -16,8 +16,6 @@ class AuthController extends Controller { function handleLogin(){ global $config; - $error = ''; - if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; @@ -37,7 +35,10 @@ class AuthController extends Controller { header('Location: ' . $config->basePath); exit; } else { - $error = 'Invalid username or password'; + // Set a flash message and reload the login page + Session::setFlashMessage('error', 'Invalid username or password'); + header('Location: ' . $_SERVER['PHP_SELF']); + exit; } } } diff --git a/src/View/FlashView/FlashView.php b/src/View/FlashView/FlashView.php index cf7e9a0..e657d55 100644 --- a/src/View/FlashView/FlashView.php +++ b/src/View/FlashView/FlashView.php @@ -9,7 +9,7 @@ class FlashView { $messages): ?>
- +
diff --git a/src/View/HomeView/HomeView.php b/src/View/HomeView/HomeView.php index da17826..d49921b 100644 --- a/src/View/HomeView/HomeView.php +++ b/src/View/HomeView/HomeView.php @@ -4,15 +4,14 @@ class HomeView { ob_start(); ?> -
-
+
+
1): ?> « Newer @@ -21,7 +20,6 @@ class HomeView { Older »
-
$emojis): ?> -
+
@@ -31,7 +31,7 @@ class MoodView { ob_start(); ?>
- + render_emoji_groups($emojiGroups, $currentMood) ?>
diff --git a/storage/.htaccess b/storage/.htaccess new file mode 100755 index 0000000..f86ed55 --- /dev/null +++ b/storage/.htaccess @@ -0,0 +1,6 @@ +# Deny all access to this directory +Require all denied + +# Fallback for Apache 2.2 +Order deny,allow +Deny from all \ No newline at end of file diff --git a/templates/.htaccess b/templates/.htaccess new file mode 100644 index 0000000..f86ed55 --- /dev/null +++ b/templates/.htaccess @@ -0,0 +1,6 @@ +# Deny all access to this directory +Require all denied + +# Fallback for Apache 2.2 +Order deny,allow +Deny from all \ No newline at end of file diff --git a/templates/main.php b/templates/main.php index 0e2cfd0..2d96a0c 100644 --- a/templates/main.php +++ b/templates/main.php @@ -10,19 +10,19 @@ + href="basePath) ?>css/tkr.css"> cssId)): ?> + href="basePath) ?>css/custom/customCssFilename()) ?>"> + title="siteTitle) ?> RSS Feed" + href="baseUrl . $config->basePath)?>feed/rss/"> + title="siteTitle) ?> Atom Feed" + href="baseUrl . $config->basePath)?>feed/atom/"> diff --git a/templates/partials/admin.php b/templates/partials/admin.php index bc6d13c..e81a52c 100644 --- a/templates/partials/admin.php +++ b/templates/partials/admin.php @@ -6,28 +6,28 @@ - +
User settings
+ value="about) ?>"> + value="website) ?>">
@@ -36,21 +36,21 @@ + value="siteDescription) ?>"> CSS Management
- +
Manage
@@ -20,13 +20,13 @@ - +
@@ -38,7 +38,7 @@
Upload
- + Emoji Management
- +
Add Emoji
@@ -25,19 +25,19 @@
- +
Delete Emoji
-
diff --git a/templates/partials/home.php b/templates/partials/home.php index 64c674d..3fafdbd 100644 --- a/templates/partials/home.php +++ b/templates/partials/home.php @@ -3,36 +3,50 @@
-
-
- - -
-
+
- +
- - + +
+
+

siteDescription ?>

+
+ +
+
diff --git a/templates/partials/login.php b/templates/partials/login.php index 8920ff7..b06d3ae 100644 --- a/templates/partials/login.php +++ b/templates/partials/login.php @@ -2,12 +2,9 @@

Login

- -

-
- +