Project Overview
This repository delivers a self-contained, offline-capable Wi-Fi Hacking Mastery Course website. It combines modular HTML lessons, an interactive quiz, and service-worker–powered offline support into a cohesive training and assessment platform.
Structure
- Landing & Promotion:
index.html
– Course overview, syllabus, enrollment CTA, expandable module list.
- Modular Lessons (
module1.html
…module16.html
):- Introductory theory, practical steps, tools, and ethical guidelines across 16 focused topics (Wi-Fi fundamentals, packet sniffing, injection, Evil Twin, captive portals, WPS, KRACK, firmware exploits, post-exploit, defenses).
- Interactive Quiz:
finalchalleng.html
– 20-question Wi-Fi hacking quiz with hints, answer reveal, scoring, and feedback.
- Offline & Ad-Block Resilience:
sw.js
– Service worker managing offline caching, dynamic script imports, ad-block circumvention hooks.
- UI Styling:
universal.css
– Navigation button styles (layout, spacing, hover effects) for consistent look and feel.
Key Features
- Modular, reusable lesson pages for easy content updates or extensions
- Self-contained quiz widget ready for embedding or standalone use
- Offline caching of HTML, CSS, JS assets for uninterrupted learning
- Dynamic script loading and anti-adblock logic baked into the service worker
- Responsive, accessible navigation styled via a single CSS file
Getting Started
- Clone the repository and serve via any static‐file server:
git clone https://github.com/cicadaa5/factsworld.github.io.git cd factsworld.github.io npx serve . # or python3 -m http.server
- Link CSS and register the service worker in your main HTML:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Wi-Fi Hacking Mastery</title> <link rel="stylesheet" href="universal.css"> </head> <body> <!-- page content --> <script> if ('serviceWorker' in navigator) { navigator.serviceWorker .register('/sw.js') .then(() => console.log('Service worker registered')); } </script> </body> </html>
- Navigate to
index.html
to explore modules or openfinalchalleng.html
for the quiz.
Audience
- Course owners who need a ready-made, modular Wi-Fi security training site
- Web-dev contributors who want to extend lessons, customize the quiz, or tweak offline strategies
Getting Started & Deployment
This section guides you through cloning the repository, running a local web server for development, and publishing the site via GitHub Pages.
Prerequisites
- Git
- Node.js (for
http-server
) or Python 3 - A modern browser (Chrome, Firefox, Edge)
1. Clone the Repository
git clone https://github.com/cicadaa5/factsworld.github.io.git
cd factsworld.github.io
2. Run a Local Web Server
Many browsers block service workers on plain file://
URLs. Use one of these options:
Option A: http-server (Node.js)
npm install -g http-server
http-server . -p 8080
Option B: Python 3
# From project root
python3 -m http.server 8080
3. Preview in Browser
Open http://localhost:8080 in your browser.
The service worker (sw.js
) handles:
- Offline caching of assets
- Dynamic script importing
- Anti-adblock measures
To test offline behavior:
- Load the page at least once online.
- In DevTools → Application → Service Workers, check “Offline”.
- Reload to confirm caching.
4. Configure and Publish via GitHub Pages
A. Using the root of the main
branch
- Commit and push your changes:
git add . git commit -m "Update content" git push origin main
- In GitHub, go to Settings → Pages.
- Under Build and deployment, set:
- Branch:
main
- Folder:
/ (root)
- Branch:
- Save. Your site publishes at
https://cicadaa5.github.io/factsworld.github.io/
B. Using a gh-pages
branch (optional)
- Create and switch to the branch:
git checkout -b gh-pages
- Push and set upstream:
git push -u origin gh-pages
- In Settings → Pages, select:
- Branch:
gh-pages
- Folder:
/ (root)
- Branch:
5. Versioning Service Worker Cache
To force clients to fetch updated assets after deployment, bump the cache name in sw.js
:
// sw.js
const CACHE_NAME = 'fw-cache-v2'; // increment version on each deploy
const ASSETS = [
'/',
'/index.html',
'/styles.css',
'/main.js',
// ...
];
self.addEventListener('install', ev => {
ev.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(ASSETS))
);
});
self.addEventListener('activate', ev => {
ev.waitUntil(
caches.keys().then(keys =>
Promise.all(
keys
.filter(key => key !== CACHE_NAME)
.map(key => caches.delete(key))
)
)
);
});
After updating CACHE_NAME
, redeploy so clients clear old caches.
6. FAQ & Troubleshooting
“Service worker not updating?”
• Ensure you bumpCACHE_NAME
.
• In DevTools → Application → Service Workers, click Update.“Site 404 on custom domain?”
• Verify GitHub Pages settings and repository name.
• Confirmindex.html
exists at repo root.“Changes not reflecting?”
• Hard-refresh (Ctrl+Shift+R) to bypass cache.
• Clear site data under DevTools → Application → Clear storage.
You’re now ready to develop locally and deploy the Wi-Fi Hacking Mastery Course landing page seamlessly.
Repository Structure & Internals
This section maps the key folders and files in factsworld.github.io. Use it to locate, edit, or extend core features: quiz data, rendering logic, styling, and offline support.
Directory Layout
/
•index.html
– Home page and quiz entry point
•_config.yml
– Jekyll/site config (if used)
•manifest.json
– PWA metadata
•sw.js
– Service Worker entry/css/
•universal.css
– Global styles (navigation, typography, components)/js/
•data/quiz.json
– Quiz data model
•quizRenderer.js
– Dynamic quiz builder and logic
•serviceWorkerQueue.js
– Queues SW events before importScripts/images/
– Illustrations, icons, assets
Data Layer: data/quiz.json
Holds the entire quiz in JSON. Each item needs question
, answer
, hint
.
[
{
"question": "What is the capital of France?",
"answer": "Paris",
"hint": "It’s known as the City of Light."
},
{
"question": "Which element has atomic number 6?",
"answer": "Carbon",
"hint": "It’s the backbone of organic chemistry."
}
]
To add a new question: append an object to this array. Maintain alphabetical order if you rely on sorted rendering.
Rendering Logic: js/quizRenderer.js
Reads quiz.json
, builds the UI, and wires events.
import quizData from './data/quiz.json';
const quizContainer = document.getElementById('quiz');
const answeredCorrectly = Array(quizData.length).fill(false);
// Build each question card
quizData.forEach((item, i) => {
const card = document.createElement('div');
card.className = 'question';
card.innerHTML = `
<p><strong>Q${i+1}:</strong> ${item.question}</p>
<input id="answer${i}" placeholder="Your answer" autocomplete="off" />
<button id="submit${i}">Submit</button>
<button id="hintBtn${i}">Hint?</button>
<div id="hint${i}" class="hint">💡 ${item.hint}</div>
<div id="feedback${i}" class="feedback"></div>
`;
quizContainer.appendChild(card);
// Event wiring
document.getElementById(`submit${i}`)
.addEventListener('click', () => checkAnswer(i, item.answer));
document.getElementById(`hintBtn${i}`)
.addEventListener('click', () => {
document.getElementById(`hint${i}`).style.display = 'block';
});
});
To extend:
- Inject timers or score counters by modifying the card template.
- Switch to
addEventListener
for complex handlers.
Styling: css/universal.css
Defines global styles and components like navigation buttons.
.navigation-buttons {
display: flex;
justify-content: space-between;
margin: 60px auto 0;
max-width: 900px;
}
.navigation-buttons a {
width: 150px;
text-align: center;
padding: 12px 0;
background: #4ade80;
color: #0f1117;
font-weight: 700;
border-radius: 6px;
transition: background 0.2s;
}
.navigation-buttons a:hover {
background: #3ecf70;
}
.question { /* quiz card wrapper */
margin-bottom: 24px;
padding: 16px;
border: 1px solid #ddd;
border-radius: 4px;
}
.hint { display: none; color: #555; margin-top: 8px; }
.feedback { margin-top: 8px; font-weight: 600; }
Override colors or container widths with a more specific selector in a separate file if needed.
PWA & Offline Support: sw.js & js/serviceWorkerQueue.js
Use deferred event queueing to capture SW events before your main script loads.
// serviceWorkerQueue.js
const STORE_EVENTS = ['install','activate','push'];
const eventBuffer = {}, listenerMap = {};
const realAdd = self.addEventListener.bind(self);
// Buffer incoming events
STORE_EVENTS.forEach(type => {
realAdd(type, evt => {
eventBuffer[type] = eventBuffer[type] || [];
eventBuffer[type].push(evt);
(listenerMap[type] || []).forEach(fn => { try { fn(evt) } catch{} });
});
});
// Override addEventListener for later handlers
self.addEventListener = (type, fn) => {
if (STORE_EVENTS.includes(type)) {
listenerMap[type] = listenerMap[type] || [];
listenerMap[type].push(fn);
(eventBuffer[type] || []).forEach(evt => fn(evt));
} else {
realAdd(type, fn);
}
};
// In sw.js
importScripts('js/serviceWorkerQueue.js');
// Now import your main SW logic
importScripts('js/main-sw.js');
To extend: add new event types to STORE_EVENTS
, register handlers in main-sw.js
, and ensure queued events replay.
Local Development & Deployment
- Clone the repo.
- Run a static server:
npx http-server -c-1 .
- Test PWA: navigate to
localhost:8080
, open DevTools → Application → Service Workers. - Commit changes and push; GitHub Pages auto-deploys from
main
branch.
Content Authoring & Contribution Guide
This guide helps you add or update lessons, maintain the quiz, tweak styles, and validate changes before pushing to the cicadaa5/factsworld.github.io repo.
1. Adding New Lessons
Follow the pattern in module1.html for any new lesson (e.g., module2.html
).
- Copy
module1.html
→module2.html
- Update page metadata and title:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width,initial-scale=1"/> <title>Module 2: Advanced Wi-Fi Attacks</title> <link rel="stylesheet" href="universal.css"/> </head>
- Edit the content section:
<main> <h1>Advanced Wi-Fi Attacks</h1> <p>In this module, you’ll explore deauthentication, Evil Twin, and more.</p> <!-- Add your lesson content here --> </main>
- Update navigation links at bottom:
<nav> <a class="nav-button" href="module1.html">← Previous</a> <a class="nav-button" href="module3.html">Next →</a> </nav>
- Commit as
module2.html
and open a PR.
2. Updating Existing Content
- Always preview changes in a live server (e.g.,
npx http-server .
). - Use utility CSS classes (
.highlight
,.note
) defined inuniversal.css
. - Preserve semantic HTML for accessibility.
- When altering headings or IDs, ensure any deep links or script selectors remain in sync.
3. Editing the Quiz Interface
All quiz logic lives in finalchalleng.html. Questions are driven by the quizData
array.
- Locate the block:
<script> const quizData = [ { question: "What is WEP’s key length?", answer: "128-bit", hint: "It’s weaker than WPA2." }, // … more entries ];
- Add, remove or reorder entries:
// Add to the end: quizData.push({ question: "Which tool cracks WPA2 handshake offline?", answer: "aircrack-ng", hint: "Look for the ‘–wpa2’ flag in documentation." });
- The page auto-injects DOM nodes—no further HTML changes required.
- To customize button order or add “Skip”, modify the injection template inside the
<script>
at the bottom.
4. Customizing Styles (CSS)
All core styles live in universal.css.
- Navigation buttons:
.nav-button { background: #22c55e; color: #fff; padding: 0.75em 1.5em; border-radius: 4px; text-align: center; display: inline-block; margin: 0.5em; text-decoration: none; } .nav-button:hover { background: #16a34a; }
- Utility classes:
.highlight { background: #4ade80; color: #0f1117; padding: 2px 6px; border-radius: 4px; font-weight: bold; } .note { background: #facc15; color: #1f2937; padding: 12px; border-radius: 6px; margin: 20px 0; font-weight: 600; }
- To override, create a new file (e.g.,
custom.css
), include it afteruniversal.css
, and redefine selectors.
5. Testing & Service Worker
sw.js handles offline caching and script loading.
- Bump cache version when assets change:
const CACHE_NAME = "factsworld-cache-v2";
- Rebuild, then in your browser:
- Open DevTools → Application → Service Workers
- Click Unregister on existing worker
- Hard-reload page to fetch new
sw.js
- Verify:
- Offline: turn off network, reload, ensure pages and quiz still load.
- Adblock: disable extensions to test anti-adblock logic.
6. Committing & Pushing Changes
git checkout -b feature/your-topic
- Stage only relevant files:
git add module2.html finalchalleng.html universal.css sw.js
- Write clear commit messages:
git commit -m "Add Module 2: Advanced Wi-Fi Attacks lesson"
- Push and open a Pull Request against
main
. - Include screenshots (if visual) and testing steps in PR description.
Following these guidelines keeps our content consistent, maintainable, and high quality. Happy contributing!