Initial commit
81
public/.htaccess
Normal file
@@ -0,0 +1,81 @@
|
||||
<FilesMatch "^\.env">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
|
||||
<FilesMatch "\.(log|sql|bak|backup|db|ini)$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
|
||||
Options -Indexes
|
||||
|
||||
AddDefaultCharset UTF-8
|
||||
<IfModule mod_mime.c>
|
||||
AddCharset UTF-8 .html .css .js .json .xml .txt
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
Header set X-Content-Type-Options "nosniff"
|
||||
Header set X-Frame-Options "SAMEORIGIN"
|
||||
Header set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
Header set Permissions-Policy "camera=(), microphone=(), geolocation=(self)"
|
||||
Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: blob:; connect-src 'self'"
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
# Force HTTPS
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
RewriteRule ^api/ - [L]
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
# All SPA routes go through router.php
|
||||
RewriteRule ^ /router.php [L]
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css
|
||||
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
|
||||
AddOutputFilterByType DEFLATE application/javascript application/x-javascript application/json
|
||||
AddOutputFilterByType DEFLATE image/svg+xml application/font-woff2
|
||||
SetEnvIfNoCase Request_URI "\.(jpg|jpeg|png|gif|webp|zip|gz|br|woff2)$" no-gzip
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType image/jpg "access plus 1 year"
|
||||
ExpiresByType image/jpeg "access plus 1 year"
|
||||
ExpiresByType image/gif "access plus 1 year"
|
||||
ExpiresByType image/png "access plus 1 year"
|
||||
ExpiresByType image/svg+xml "access plus 1 year"
|
||||
ExpiresByType text/css "access plus 1 year"
|
||||
ExpiresByType application/javascript "access plus 1 year"
|
||||
ExpiresByType text/javascript "access plus 1 year"
|
||||
ExpiresByType application/font-woff2 "access plus 1 year"
|
||||
ExpiresByType text/html "access plus 0 seconds"
|
||||
</IfModule>
|
||||
|
||||
<FilesMatch "index\.html$">
|
||||
<IfModule mod_headers.c>
|
||||
Header set Cache-Control "no-cache, no-store, must-revalidate"
|
||||
Header set Pragma "no-cache"
|
||||
Header set Expires "0"
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
|
||||
<FilesMatch "\.php$">
|
||||
<IfModule mod_headers.c>
|
||||
Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
|
||||
Header set Pragma "no-cache"
|
||||
Header set Expires "0"
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
BIN
public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
3
public/favicon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" viewBox="0 0 100 100"><image width="100" height="100" xlink:href="data:image/png;base64,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"></image><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
|
||||
@media (prefers-color-scheme: dark) { :root { filter: none; } }
|
||||
</style></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/images/logo-dark.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/images/logo-light.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
2
public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
13
public/router.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* SPA Router - serves index.html for all admin routes
|
||||
*/
|
||||
|
||||
http_response_code(200);
|
||||
|
||||
$indexPath = __DIR__ . '/index.html';
|
||||
if (file_exists($indexPath)) {
|
||||
readfile($indexPath);
|
||||
} else {
|
||||
echo '<!DOCTYPE html><html><body><h1>Application not found</h1></body></html>';
|
||||
}
|
||||
21
public/site.webmanifest
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "BOHA",
|
||||
"short_name": "BOHA",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/web-app-manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/web-app-manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
BIN
public/web-app-manifest-192x192.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/web-app-manifest-512x512.png
Normal file
|
After Width: | Height: | Size: 50 KiB |