diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/apache/root/.htaccess b/examples/apache/root/.htaccess new file mode 100644 index 0000000..12c567c --- /dev/null +++ b/examples/apache/root/.htaccess @@ -0,0 +1,59 @@ +# Enable mod_rewrite +RewriteEngine On + +# Security headers +# The first rule is to prevent including in a frame on a different domain. +# Remove it if you want to do that. +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 +# (Not actually used because everything gets handled by a rewrite rule +# , but I'm keeping it for clarity about what's going on.) +DirectoryIndex index.php + +# Deny access to hidden files (e.g. .htaccess) + + Require all denied + + +# Cache static files (excluding css/custom which goes through PHP) +# Note that I don't actually serve most of this (just css) +# but this prevents requests for static content from getting to the PHP handler. +# +# The /css/custom directory is excluded from this in a RewriteCond below: +# RewriteCond %{REQUEST_URI} !^/tkr/css/custom/ +# +# Those requests are handled by the PHP app to serve custom css + + ExpiresActive On + ExpiresDefault "access plus 1 year" + Header set Cache-Control "public, max-age=31536000, immutable" + + +# Process PHP files + + SetHandler application/x-httpd-php + + +# Skip rewriting if already in /tkr/public/ (prevents infinite loops) +RewriteRule ^tkr/public/ - [L] + +# Block direct access to all .php files +# but allow internal rewrites to index.php +RewriteCond %{THE_REQUEST} \.php [NC] +RewriteRule ^.*\.php$ - [R=404,L] + +# Block access to sensitive directories +RewriteRule ^(storage|src|templates|uploads|config)(/.*)?$ - [F,L] + +# If it's a static file that exists in /tkr/public, serve it directly +# (but exclude css/custom which should go through PHP) +RewriteCond %{REQUEST_URI} !^/css/custom/ +RewriteCond %{DOCUMENT_ROOT}/tkr/public%{REQUEST_URI} -f +RewriteRule ^(.*)$ /tkr/public/$1 [L] + +# Send everything else to the front controller +# (/tkr/public/index.php) +RewriteRule ^.*$ /tkr/public/index.php [L] diff --git a/examples/apache/subfolder/.htaccess b/examples/apache/subfolder/.htaccess new file mode 100644 index 0000000..740a389 --- /dev/null +++ b/examples/apache/subfolder/.htaccess @@ -0,0 +1,61 @@ +# Enable mod_rewrite +RewriteEngine On + +# Security headers +# The first rule is to prevent including in a frame on a different domain. +# Remove it if you want to do that. +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 index.php + +# Deny access to hidden files (e.g. .htaccess) + + Require all denied + + +# Cache static files (excluding css/custom which goes through PHP) +# Note that I don't actually serve most of this (just css) +# but this prevents requests for static content from getting to the PHP handler. +# +# The /css/custom directory is excluded from this in a RewriteCond below: +# RewriteCond %{REQUEST_URI} !^/tkr/css/custom/ +# +# Those requests are handled by the PHP app to serve custom css + + ExpiresActive On + ExpiresDefault "access plus 1 year" + Header set Cache-Control "public, max-age=31536000, immutable" + + +# Process PHP files + + SetHandler application/x-httpd-php + + +# Skip rewriting if already in /tkr/public/ (prevents infinite loops) +RewriteRule ^tkr/public/ - [L] + +# Block direct access to all .php files +# but allow internal rewrites to index.php +RewriteCond %{THE_REQUEST} \.php [NC] +RewriteRule ^.*\.php$ - [R=404,L] + +# Block access to sensitive directories under /tkr +RewriteRule ^tkr/(storage|src|templates|uploads|config)(/.*)?$ - [F,L] + +# Handle /tkr requests +# (keep the path after /tkr for the next directive) +RewriteCond %{REQUEST_URI} ^/tkr(/.*)?$ + +# If it's a static file that exists in /tkr/public, serve it directly +# (e.g. /tkr/public/css/tkr.css) +RewriteCond %{REQUEST_URI} !^/tkr/css/custom/ +RewriteCond %{DOCUMENT_ROOT}/tkr/public%1 -f +RewriteRule ^tkr(/.*)?$ /tkr/public$1 [L] + +# Send everything else to the front controller +# (/tkr/public/index.php) +RewriteRule ^tkr(/.*)?$ /tkr/public/index.php [L] diff --git a/examples/nginx/docker-compose.yml b/examples/nginx/docker-compose.yml deleted file mode 100644 index 0122879..0000000 --- a/examples/nginx/docker-compose.yml +++ /dev/null @@ -1,33 +0,0 @@ -services: - nginx: - image: nginx:alpine - container_name: nginx-server - ports: - - "80:80" - volumes: - - ./public:/var/www/html/tkr/public - - ./examples/nginx/folder.conf:/etc/nginx/conf.d/default.conf - depends_on: - - php - restart: unless-stopped - - php: - image: php:8.2-fpm-alpine - container_name: php-fpm - volumes: - - ./config:/var/www/html/tkr/config - - ./public:/var/www/html/tkr/public - - ./src:/var/www/html/tkr/src - - ./storage:/var/www/html/tkr/storage - - ./templates:/var/www/html/tkr/templates - command: > - sh -c " - chown -R www-data:www-data /var/www/html/tkr/storage && - chmod -R 775 /var/www/html/tkr/storage && - php-fpm - " - restart: unless-stopped - -volumes: - src: - driver: local \ No newline at end of file diff --git a/examples/nginx/root.conf b/examples/nginx/root.conf deleted file mode 100644 index 6f7f869..0000000 --- a/examples/nginx/root.conf +++ /dev/null @@ -1,36 +0,0 @@ -server { - #listen 80 default_server; - listen 80; - root /app/public; - - index index.php; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - - # Deny access to hidden files - location ~ /\. { - deny all; - access_log off; - log_not_found off; - } - - location ~ \.php$ { - fastcgi_pass php:9000; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param REQUEST_METHOD $request_method; - fastcgi_param CONTENT_TYPE $content_type; - fastcgi_param CONTENT_LENGTH $content_length; - include fastcgi_params; - } - - location / { - try_files $uri $uri/ =404; - } - - location ~* \.(htaccess|env|ini|log|bak)$ { - deny all; - } -} \ No newline at end of file diff --git a/examples/nginx/root/nginx.conf b/examples/nginx/root/nginx.conf new file mode 100644 index 0000000..2bc476f --- /dev/null +++ b/examples/nginx/root/nginx.conf @@ -0,0 +1,78 @@ +server { + listen 80; + server_name localhost; + + root /var/www/html/tkr/public; + index index.php; + + # Security headers + # The first rule is to prevent including in a frame on a different domain. + # Remove it if you want to do that. + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + + # Deny access to hidden files + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + # PHP routing - everything goes through index.php + location / { + # Cache static files + # Note that I don't actually serve most of this (just css) + # but this prevents requests for static content from getting to the PHP handler. + # + # I've excluded /css/custom so that requests for uploaded css can be handled by the PHP app. + # That lets me store uploaded content outside of the document root, + # so it isn't served directly. + location ~* ^/(?!css/custom/).+\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # index.php is the entry point + # It needs to be sent to php-fpm + # But if someone tries to directly access index.php, that file will throw a 404 + # so bots and scanners can't tell this is a php app + location = /index.php { + fastcgi_pass php:9000; + fastcgi_param SCRIPT_FILENAME /var/www/html/tkr/public/index.php; + include fastcgi_params; + + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + } + + # Block attempts to access all other .php files directly + # (these are bots and scanners) + location ~ ^/.+\.php$ { + return 404; + } + + # forward other requests to the fallback block, + # which sends them to php-fpm for handling + try_files $uri $uri/ @tkr_fallback; + } + + # Fallback for /tkr routing - all non-file requests (e.g. /login) go to index.php + location @tkr_fallback { + fastcgi_pass php:9000; + fastcgi_param SCRIPT_FILENAME /var/www/html/tkr/public/index.php; + include fastcgi_params; + + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + } + + # Deny access to sensitive directories + location ~ ^/(storage|src|templates|uploads|config) { + deny all; + return 404; + } +} diff --git a/examples/nginx/folder.conf b/examples/nginx/subfolder/nginx.conf similarity index 93% rename from examples/nginx/folder.conf rename to examples/nginx/subfolder/nginx.conf index 9416cf8..d48d4dd 100644 --- a/examples/nginx/folder.conf +++ b/examples/nginx/subfolder/nginx.conf @@ -6,6 +6,8 @@ server { index index.html; # Security headers + # The first rule is to prevent including in a frame on a different domain. + # Remove it if you want to do that. add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; @@ -44,7 +46,6 @@ server { fastcgi_param SCRIPT_FILENAME /var/www/html/tkr/public/index.php; include fastcgi_params; - # Additional FastCGI params fastcgi_param REQUEST_METHOD $request_method; fastcgi_param REQUEST_URI $request_uri; fastcgi_param QUERY_STRING $query_string; @@ -67,14 +68,13 @@ server { fastcgi_param SCRIPT_FILENAME /var/www/html/tkr/public/index.php; include fastcgi_params; - # Additional FastCGI params fastcgi_param REQUEST_METHOD $request_method; fastcgi_param REQUEST_URI $request_uri; fastcgi_param QUERY_STRING $query_string; } # Deny access to sensitive directories - location ~ ^/tkr/(storage|src|templates|vendor|uploads|config) { + location ~ ^/tkr/(storage|src|templates|uploads|config) { deny all; return 404; } diff --git a/templates/partials/tick.php b/templates/partials/tick.php new file mode 100644 index 0000000..e85ecc3 --- /dev/null +++ b/templates/partials/tick.php @@ -0,0 +1,5 @@ + + + +

Tick from format('Y-m-d H:i:s'); ?>

+

\ No newline at end of file diff --git a/templates/tick.php b/templates/tick.php deleted file mode 100644 index 1a20d62..0000000 --- a/templates/tick.php +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - -

Tick from format('Y-m-d H:i:s'); ?>

-

- - \ No newline at end of file