feat: add security headers, update manifest and cache assets
This commit is contained in:
23
public/_headers
Normal file
23
public/_headers
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
X-Content-Type-Options: nosniff
|
||||
X-Frame-Options: DENY
|
||||
X-XSS-Protection: 1; mode=block
|
||||
Referrer-Policy: strict-origin-when-cross-origin
|
||||
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.googleapis.com *.gstatic.com; style-src 'self' 'unsafe-inline' *.googleapis.com; img-src 'self' data: https:; font-src 'self' data: *.googleapis.com *.gstatic.com; connect-src 'self' *.googleapis.com; frame-ancestors 'none';
|
||||
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
||||
|
||||
/*.html
|
||||
Cache-Control: public, max-age=0, must-revalidate
|
||||
|
||||
/assets/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
/images/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
/*.js
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
/*.css
|
||||
Cache-Control: public, max-age=31536000, immutable
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "Jan-Marlon Leibl | Fullstack Developer",
|
||||
"short_name": "JL Portfolio",
|
||||
"description": "Personal website and portfolio of Jan-Marlon Leibl, Fullstack Developer",
|
||||
"name": "Jan-Marlon Leibl - Fullstack Developer",
|
||||
"short_name": "Jan-Marlon Leibl",
|
||||
"description": "Experienced Fullstack Developer specializing in PHP and TypeScript. Creating high-performance web applications and digital experiences with modern technologies.",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#0A0A0A",
|
||||
"theme_color": "#0A0A0A",
|
||||
"orientation": "portrait-primary",
|
||||
"orientation": "portrait",
|
||||
"screenshots": [
|
||||
{
|
||||
"src": "/screenshots/mobile.png",
|
||||
@ -28,22 +28,33 @@
|
||||
"name": "About Me",
|
||||
"short_name": "About",
|
||||
"description": "Learn more about Jan-Marlon Leibl",
|
||||
"url": "/#about",
|
||||
"icons": [{ "src": "/icons/about-icon.png", "sizes": "192x192" }]
|
||||
"url": "/#about"
|
||||
},
|
||||
{
|
||||
"name": "My Work",
|
||||
"short_name": "Work",
|
||||
"description": "View Jan-Marlon's portfolio projects",
|
||||
"url": "/#work",
|
||||
"icons": [{ "src": "/icons/work-icon.png", "sizes": "192x192" }]
|
||||
"url": "/#work"
|
||||
},
|
||||
{
|
||||
"name": "Contact",
|
||||
"short_name": "Contact",
|
||||
"description": "Get in touch with Jan-Marlon",
|
||||
"url": "/#contact",
|
||||
"icons": [{ "src": "/icons/contact-icon.png", "sizes": "192x192" }]
|
||||
"url": "/#contact"
|
||||
}
|
||||
],
|
||||
"icons": [
|
||||
{
|
||||
"src": "/profile-image-futu-style.jpg",
|
||||
"sizes": "192x192",
|
||||
"type": "image/jpeg",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/profile-image-futu-style.jpg",
|
||||
"sizes": "512x512",
|
||||
"type": "image/jpeg",
|
||||
"purpose": "any"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -4,4 +4,7 @@ User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Optimize crawling
|
||||
Crawl-delay: 10
|
||||
Crawl-delay: 10
|
||||
|
||||
# Sitemaps
|
||||
Sitemap: https://jleibl.net/sitemap-index.xml
|
@ -1,21 +1,33 @@
|
||||
const CACHE_NAME = "jleibl-portfolio-v1";
|
||||
|
||||
const PRECACHE_ASSETS = ["/", "/index.html"];
|
||||
|
||||
const AUTH_ASSETS = ["/manifest.json"];
|
||||
|
||||
const STYLE_ASSETS = ["/styles/global.css", "/styles/theme.css"];
|
||||
|
||||
const IMAGE_ASSETS = ["/images/profile-image-futu-style.jpg"];
|
||||
|
||||
const ALL_ASSETS = [...PRECACHE_ASSETS, ...AUTH_ASSETS, ...STYLE_ASSETS, ...IMAGE_ASSETS];
|
||||
const CACHE_NAME = "jleibl-cache-v1";
|
||||
const urlsToCache = [
|
||||
"/",
|
||||
"/index.html",
|
||||
"/manifest.json",
|
||||
"/profile-image-futu-style.jpg",
|
||||
"/styles/global.css",
|
||||
"/styles/theme.css",
|
||||
];
|
||||
|
||||
self.addEventListener("install", (event) => {
|
||||
self.skipWaiting();
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
console.log("Opened cache");
|
||||
return cache.addAll(PRECACHE_ASSETS);
|
||||
event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache)));
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", (event) => {
|
||||
event.respondWith(
|
||||
caches.match(event.request).then((response) => {
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
return fetch(event.request).then((response) => {
|
||||
if (!response || response.status !== 200 || response.type !== "basic") {
|
||||
return response;
|
||||
}
|
||||
const responseToCache = response.clone();
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(event.request, responseToCache);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -110,3 +110,8 @@ const structuredDataWebsite = {
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
<link rel="preload" href="/profile-image-futu-style.jpg" as="image" />
|
||||
|
||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
|
||||
<link rel="dns-prefetch" href="https://fonts.gstatic.com" />
|
||||
|
Reference in New Issue
Block a user