Compare commits

...

8 Commits

Author SHA1 Message Date
Justin 5b35c52d58 Resolve unresolved merge conflict markers left in main
The merge of claude/nifty-bhaskara-fb3ec2 left three-way conflict
markers committed straight into index.html, _headers, and
.claude/launch.json instead of being resolved. Two branches had
independently fixed the same duplicate-CSP bug; keep the more
thorough fix (single CSP source of truth in _headers, no meta tag
in index.html, local photo path) and drop the now-unneeded
'unsafe-inline'/ki5bhv.com allowances.
2026-08-31 19:37:44 -05:00
Justin c31ba229af Merge branch 'claude/nifty-bhaskara-fb3ec2' of https://git.ki5bhv.com/justin/k5bss.com
# Conflicts:
#	.claude/launch.json
#	_headers
#	index.html
2026-08-31 19:26:10 -05:00
Justin 49856bdefc Merge branch 'claude/scan-report-issues-93c6e9' of https://git.ki5bhv.com/justin/k5bss.com
# Conflicts:
#	_headers
#	index.html
2026-08-31 14:40:01 -05:00
Justin f8b0a8b070 Add local static-server launch config for browser preview
Lets the Browser pane preview the site locally (python -m http.server)
without needing a full deploy to check CSP/console behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 14:26:21 -05:00
Justin 9dd8fae16e Fix CSP violations and font 404 from Cloudflare Radar scan
Two conflicting <meta> CSP tags in index.html (plus a separate _headers
policy) meant the browser enforced their intersection, which blocked
the Cloudflare Insights beacon script and its inline bootstrap. k5bss.html
had the same gap in its own CSP. Consolidated to one consistent policy per
surface that allows static.cloudflareinsights.com / cloudflareinsights.com,
and moved index.html's inline script and onerror handler into js/main.js
so script-src no longer needs 'unsafe-inline' there.

Also added the missing fonts/ibm-plex-mono-400.woff2 that style.css has
referenced since it was wired up, which was 404ing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 14:25:10 -05:00
Justin 8c665ba239 update 2026-08-31 13:57:34 -05:00
Justin bdcc6c1a8f fixed a picture issues 2026-08-30 16:35:48 -05:00
Justin c7a10ae719 Fix CSP violations from Cloudflare Radar scan
Two duplicate <meta> CSP tags in index.html conflicted with the
_headers HTTP header, and browsers enforce the intersection of all
active policies. That blocked the profile photo, the inline nav-
highlight script, and the Cloudflare Insights beacon.

Consolidate to a single CSP in _headers, allow the actual external
resources the page needs (ki5bhv.com image, cloudflareinsights.com
beacon), and move the inline script/onerror handler into js/main.js
so script-src no longer needs 'unsafe-inline'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 16:28:33 -05:00
5 changed files with 27 additions and 22 deletions

View File

@ -1 +1,2 @@
./vs
./.claude

View File

@ -1,5 +1,5 @@
/*
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://static.cloudflareinsights.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://ki5bhv.com data:; connect-src 'self' https://cloudflareinsights.com; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests
Content-Security-Policy: default-src 'self'; script-src 'self' https://static.cloudflareinsights.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://cloudflareinsights.com; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin

23
index.html Executable file → Normal file
View File

@ -6,8 +6,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="referrer" content="strict-origin-when-cross-origin" />
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'unsafe-inline' https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' https://ki5bhv.com data:; connect-src 'self' https://cloudflareinsights.com; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'none'; upgrade-insecure-requests" />
<title>Justin Frasier | Infrastructure Administrator</title>
<link rel="sitemap" type="application/xml" href="/sitemap.xml" />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='4' fill='%230f1218'/%3E%3Ctext x='3' y='11' font-family='IBM Plex Mono,Courier New,monospace' font-size='6' fill='%234a5568'%3E~$%3C/text%3E%3Ctext x='2' y='27' font-family='IBM Plex Mono,Courier New,monospace' font-size='19' font-weight='600' fill='%2322c55e'%3Ejf%3C/text%3E%3C/svg%3E" />
@ -26,8 +24,7 @@
<!-- ── Sidebar ── -->
<aside>
<img class="profile-photo" src="https://ki5bhv.com/photo/justin1.jpg" alt="Justin Frasier"
onerror="this.style.display='none'">
<img class="profile-photo" src="./photo/justin1.jpg" alt="Justin Frasier">
<div class="profile-name">Justin Frasier</div>
<div class="profile-title">Infrastructure Administrator</div>
<div class="profile-loc">📍 Bossier City, LA</div>
@ -369,23 +366,7 @@
</main>
</div>
<script>
// Highlight active nav link on scroll
const sections = document.querySelectorAll('section[id]');
const links = document.querySelectorAll('nav a');
const observer = new IntersectionObserver(entries => {
entries.forEach(e => {
if (e.isIntersecting) {
links.forEach(l => l.classList.remove('active'));
const active = document.querySelector(`nav a[href="#${e.target.id}"]`);
if (active) active.classList.add('active');
}
});
}, { threshold: 0.3 });
sections.forEach(s => observer.observe(s));
</script>
<script src="js/main.js" defer></script>
</body>

23
js/main.js Normal file
View File

@ -0,0 +1,23 @@
// Highlight active nav link on scroll
const sections = document.querySelectorAll('section[id]');
const links = document.querySelectorAll('nav a');
const observer = new IntersectionObserver(entries => {
entries.forEach(e => {
if (e.isIntersecting) {
links.forEach(l => l.classList.remove('active'));
const active = document.querySelector(`nav a[href="#${e.target.id}"]`);
if (active) active.classList.add('active');
}
});
}, { threshold: 0.3 });
sections.forEach(s => observer.observe(s));
// Hide the profile photo if it fails to load
const profilePhoto = document.querySelector('.profile-photo');
if (profilePhoto) {
profilePhoto.addEventListener('error', () => {
profilePhoto.style.display = 'none';
});
}

BIN
photo/justin1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB