forked from colin/resume
2
0
Fork 0

Fix CSP issues by moving inline script to external file and adding SRI

This commit is contained in:
Your Name 2025-03-31 04:04:47 -04:00
parent 0fbd77f073
commit ac3d30d597
3 changed files with 64 additions and 64 deletions

View File

@ -26,7 +26,7 @@
Cross-Origin-Opener-Policy "same-origin"
# Simplified CSP for static content
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none';"
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'; require-sri-for script;"
}
# Handle 404s

View File

@ -6,6 +6,7 @@
<meta name="description" content="Colin Knapp - Cybersecurity Expert and Software Developer Portfolio">
<title>Colin Knapp Portfolio</title>
<link rel="stylesheet" href="styles.css">
<script src="theme.js" integrity="sha384-UbjhZypK/bO7YAIsVbI8lGTyMauZwXy3snXwqT5jddKFsEt2YIDpSqcvTHn7Fn0e" crossorigin="anonymous"></script>
</head>
<body>
<div class="theme-switch">
@ -182,68 +183,5 @@
<p class="accessibility-notice"><strong>Accessibility:</strong> This website is designed and developed to meet WCAG 2.1 Level AAA standards, ensuring the highest level of accessibility for all users. Features include high contrast ratios, keyboard navigation, screen reader compatibility, and responsive design. The site supports both light and dark modes with automatic system preference detection.</p>
</div>
<script>
const themeToggle = document.getElementById('themeToggle');
const html = document.documentElement;
// Check for saved theme preference, default to auto
const savedTheme = localStorage.getItem('theme') || 'auto';
updateTheme(savedTheme);
function updateTheme(theme) {
// Update button state and labels
const themeLabels = {
light: 'Theme mode: Light',
dark: 'Theme mode: Dark',
auto: 'Theme mode: Auto'
};
themeToggle.setAttribute('aria-label', themeLabels[theme]);
themeToggle.setAttribute('aria-pressed', theme !== 'auto');
// Update button icon
const themeIcons = {
light: '🌞',
dark: '🌙',
auto: '🌓'
};
themeToggle.textContent = themeIcons[theme];
if (theme === 'auto') {
html.removeAttribute('data-theme');
} else {
html.setAttribute('data-theme', theme);
}
}
themeToggle.addEventListener('click', () => {
const currentTheme = html.getAttribute('data-theme') || 'auto';
let newTheme;
switch(currentTheme) {
case 'light':
newTheme = 'dark';
break;
case 'dark':
newTheme = 'auto';
break;
default:
newTheme = 'light';
}
updateTheme(newTheme);
localStorage.setItem('theme', newTheme);
});
// Handle keyboard navigation
themeToggle.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
themeToggle.click();
}
});
</script>
</body>
</html>

62
docker/resume/theme.js Normal file
View File

@ -0,0 +1,62 @@
document.addEventListener('DOMContentLoaded', function() {
const themeToggle = document.getElementById('themeToggle');
const html = document.documentElement;
// Check for saved theme preference, default to auto
const savedTheme = localStorage.getItem('theme') || 'auto';
updateTheme(savedTheme);
function updateTheme(theme) {
// Update button state and labels
const themeLabels = {
light: 'Theme mode: Light',
dark: 'Theme mode: Dark',
auto: 'Theme mode: Auto'
};
themeToggle.setAttribute('aria-label', themeLabels[theme]);
themeToggle.setAttribute('aria-pressed', theme !== 'auto');
// Update button icon
const themeIcons = {
light: '🌞',
dark: '🌙',
auto: '🌓'
};
themeToggle.textContent = themeIcons[theme];
if (theme === 'auto') {
html.removeAttribute('data-theme');
} else {
html.setAttribute('data-theme', theme);
}
}
themeToggle.addEventListener('click', () => {
const currentTheme = html.getAttribute('data-theme') || 'auto';
let newTheme;
switch(currentTheme) {
case 'light':
newTheme = 'dark';
break;
case 'dark':
newTheme = 'auto';
break;
default:
newTheme = 'light';
}
updateTheme(newTheme);
localStorage.setItem('theme', newTheme);
});
// Handle keyboard navigation
themeToggle.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
themeToggle.click();
}
});
});