-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
437 lines (406 loc) · 18.9 KB
/
Copy pathscript.js
File metadata and controls
437 lines (406 loc) · 18.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
document.addEventListener("DOMContentLoaded", function() {
// Show the "Press me!" tooltip after 8 seconds if no click occurs
let tipTimeout = setTimeout(() => {
document.getElementById("press-tip").classList.add("show");
}, 8000);
document.getElementById("logo").addEventListener("click", function(event) {
clearTimeout(tipTimeout);
document.getElementById("press-tip").classList.remove("show");
const logoContainer = document.getElementById("logo-container");
// Stop the pulse animation
logoContainer.style.animation = 'none';
// Animate circles from the click position
const circles = document.getElementById("circles");
circles.style.opacity = "1";
const clickX = event.clientX - 13;
const clickY = event.clientY - 13;
const circleElements = document.querySelectorAll(".circle");
circleElements.forEach((circle, index) => {
circle.style.left = `${clickX}px`;
circle.style.top = `${clickY}px`;
const angle = (index * 120) - 60;
const x = Math.cos(angle * (Math.PI / 180)) * 200;
const y = Math.sin(angle * (Math.PI / 180)) * 200;
setTimeout(() => {
circle.style.transform = `translate(${x}px, ${y}px)`;
circle.style.opacity = "0";
}, 10);
});
// Fade out and remove the welcome message
const welcomeMessage = document.getElementById("welcome-message");
welcomeMessage.classList.add("fade-out");
setTimeout(() => {
if (welcomeMessage.parentNode) {
welcomeMessage.parentNode.removeChild(welcomeMessage);
}
}, 2000);
// Smoothly move the logo upward:
// Capture its current position, set it to absolute, then animate.
const rect = logoContainer.getBoundingClientRect();
logoContainer.style.position = "absolute";
logoContainer.style.top = rect.top + "px";
logoContainer.style.left = rect.left + "px";
logoContainer.style.width = rect.width + "px";
// Force reflow to register the new position
void logoContainer.offsetWidth;
// Add the move-top class to animate to the top center
logoContainer.classList.add("move-top");
// Remove circles container after animation completes
setTimeout(() => {
const circlesContainer = document.getElementById("circles");
if (circlesContainer && circlesContainer.parentNode) {
circlesContainer.parentNode.removeChild(circlesContainer);
}
}, 2500);
setTimeout(() => {
const loginPage = document.getElementById("login-page");
if (loginPage) {
loginPage.style.display = "block";
void loginPage.offsetWidth;
loginPage.classList.add("fade-in");
}
}, 2500);
});
document.getElementById("next-btn").addEventListener("click", function(e) {
e.preventDefault(); // Prevent the form from submitting if inside a form
const emailInput = document.getElementById("email-input");
const emailValue = emailInput ? emailInput.value : "";
// Validate that the email contains "zain" in its domain
if (!/@.*zain/i.test(emailValue)) {
alert("Please enter a valid Zain email address.");
return;
}
// Save the email value for later (using localStorage as an example)
localStorage.setItem("userEmail", emailValue);
// Remove the email input container (assumed to be the element with class "login-form")
const loginForm = document.querySelector(".login-form");
if (loginForm) {
loginForm.remove();
setTimeout(() => {
const mainContainer = document.getElementById("main-container");
if (mainContainer) {
mainContainer.style.display = "block";
// Force reflow to trigger the CSS transition
void mainContainer.offsetWidth;
mainContainer.classList.add("show");
}
}, 1000);
}
});
document.getElementById("submit-password").addEventListener("click", function(e) {
e.preventDefault();
// Remove any existing message element
const oldMsg = document.getElementById("password-message");
if(oldMsg) oldMsg.remove();
const password = document.getElementById("password-input").value;
let bruteContainer = document.getElementById('brute-visual');
if (!bruteContainer) {
bruteContainer = document.createElement('div');
bruteContainer.id = 'brute-visual';
bruteContainer.style.fontFamily = 'monospace';
bruteContainer.style.fontSize = '24px';
bruteContainer.style.textAlign = 'center';
bruteContainer.style.margin = '10px auto 0';
document.getElementById("password-tester").appendChild(bruteContainer);
}
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";
const length = password.length;
const isStrong = password.length >= 10 && /[0-9]/.test(password) && /[^A-Za-z0-9]/.test(password);
if(!isStrong) {
const revealed = Array(length).fill(false);
const interval = setInterval(() => {
const notRevealed = [];
for(let i = 0; i < length; i++){
if(!revealed[i]) notRevealed.push(i);
}
if(notRevealed.length > 0) {
const randIndex = notRevealed[Math.floor(Math.random() * notRevealed.length)];
revealed[randIndex] = true;
}
let displayStr = "";
for(let i = 0; i < length; i++){
displayStr += revealed[i] ? password[i] : chars[Math.floor(Math.random()*chars.length)];
}
bruteContainer.textContent = displayStr;
if(revealed.every(v => v)) {
clearInterval(interval);
// Create a new element for the dynamic message below the displayed password:
setTimeout(() => {
let missing = [];
if(password.length < 10) missing.push("10+ characters");
if(!/[0-9]/.test(password)) missing.push("a number");
if(!/[^A-Za-z0-9]/.test(password)) missing.push("a symbol");
const messageEl = document.createElement("div");
messageEl.id = "password-message";
messageEl.style.marginTop = "10px";
messageEl.style.fontSize = "20px";
messageEl.textContent = "Your password needs: " + missing.join(", ") + "!";
document.getElementById("password-tester").appendChild(messageEl);
}, 500);
}
}, 100);
} else {
// Strong password branch:
// Start the visual brute forcer (it runs indefinitely until module transition).
const strongInterval = setInterval(() => {
let displayStr = "";
for (let i = 0; i < length; i++) {
displayStr += chars[Math.floor(Math.random()*chars.length)];
}
bruteContainer.textContent = displayStr;
}, 50);
// After 1 second, show success message and award XP.
setTimeout(() => {
const messageEl = document.createElement("div");
messageEl.id = "password-message";
messageEl.style.marginTop = "10px";
messageEl.style.fontSize = "20px";
messageEl.textContent = "This is a strong password!";
document.getElementById("password-tester").appendChild(messageEl);
// After an additional second, transition to the next module ("Device Secuirty")
setTimeout(() => {
// Fade out the current module (module2)
const module2 = document.getElementById("module2");
module2.classList.add("fade-out");
setTimeout(() => {
module2.remove();
// Show module3 (assumed to be pre-defined with id "module3" and titled "Device Secuirty")
const module3 = document.getElementById("module3");
if(module3) {
module3.style.display = "block";
void module3.offsetWidth;
module3.classList.add("fade-in");
}
clearInterval(strongInterval);
}, 1000);
}, 2000);
}, 1000);
}
});
// Game: Spot the Malware in module4
// Wait until module4 is visible (assume a transition to module4 will occur)
const zipFile = document.getElementById("zip-file");
if(zipFile) {
zipFile.addEventListener("click", function() {
document.getElementById("zip-contents").style.display = "block";
});
}
// Add listeners for the file items in the file container
const fileItems = document.querySelectorAll("#file-container .file-item");
fileItems.forEach(item => {
item.addEventListener("click", function() {
if(this.getAttribute("data-type") !== "zip") {
alert("This file is safe.");
}
});
});
// Add listeners for items inside the zip container
const zipFileItems = document.querySelectorAll(".zip-file-item");
zipFileItems.forEach(item => {
item.addEventListener("click", function() {
if(this.getAttribute("data-type") === "malware") {
alert("Correct! safe.exe is infected!");
// Transition from module3 to module4:
const module3 = document.getElementById("module3");
module3.classList.add("fade-out");
setTimeout(() => {
module3.remove();
// Show module4 (assumed pre-defined with id "module4")
const module4 = document.getElementById("module4");
if(module4) {
module4.style.display = "block";
void module4.offsetWidth;
module4.classList.add("fade-in");
}
}, 1000);
} else {
alert("This file is safe. Try again!");
}
});
});
// Wi-Fi Networks Ordering Game - Module 5
const checkOrderBtn = document.getElementById("check-order-btn");
const wifiList = document.getElementById("wifi-list");
let draggedItem = null;
const wifiItems = document.querySelectorAll(".wifi-item");
wifiItems.forEach(item => {
let longPressTimer;
// New: Start long-press timer to add pop-out animation
item.addEventListener("mousedown", function(e) {
longPressTimer = setTimeout(() => {
this.classList.add("dragged-out");
}, 300);
});
// Cancel long-press on mouseup or mouseleave
item.addEventListener("mouseup", function(e) {
clearTimeout(longPressTimer);
this.classList.remove("dragged-out");
});
item.addEventListener("mouseleave", function(e) {
clearTimeout(longPressTimer);
this.classList.remove("dragged-out");
});
// Existing drag events
item.addEventListener("dragstart", function(e) {
draggedItem = this;
this.classList.add("dragging");
e.dataTransfer.effectAllowed = "move";
});
item.addEventListener("dragend", function(e) {
this.classList.remove("dragging");
// Remove any lingering pop-out animation class
this.classList.remove("dragged-out");
});
item.addEventListener("dragover", function(e) {
e.preventDefault();
e.dataTransfer.dropEffect = "move";
});
item.addEventListener("drop", function(e) {
e.preventDefault();
if (draggedItem && draggedItem !== this) {
// Animate the dragged item out.
draggedItem.classList.add("dragged-out");
// Wait for the "disappear" animation to complete (shorter duration now)
setTimeout(() => {
let allItems = Array.from(wifiList.children);
let draggedIndex = allItems.indexOf(draggedItem);
let dropIndex = allItems.indexOf(this);
if (draggedIndex < dropIndex) {
wifiList.insertBefore(draggedItem, this.nextSibling);
} else {
wifiList.insertBefore(draggedItem, this);
}
draggedItem.classList.remove("dragged-out");
}, 200); // Reduced timeout for faster removal
}
});
});
// Randomize the order of Wi‑Fi items using the Fisher–Yates shuffle
function shuffleWiFiItems() {
const items = Array.from(wifiList.children);
for (let i = items.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
wifiList.insertBefore(items[j], items[i]);
}
}
shuffleWiFiItems();
// Remove previous "Check Order" code and use the Finish button for verification
const finishBtn = document.getElementById("next-module-btn");
finishBtn.innerText = "Finish";
finishBtn.addEventListener("click", function(e) {
e.preventDefault();
// Expected correct order: descending data-security [4, 3, 2, 1]
const items = Array.from(wifiList.querySelectorAll(".wifi-item"));
const currentOrder = items.map(item => parseInt(item.getAttribute("data-security")));
const correctOrder = [4, 3, 2, 1];
let isCorrect = currentOrder.every((val, index) => val === correctOrder[index]);
if (isCorrect) {
// Fade out module4 and then create a full screen congrats page
const module4 = document.getElementById("module4");
module4.classList.add("fade-out");
setTimeout(() => {
module4.remove();
const mainContainer = document.getElementById("main-container");
const congratsPage = document.createElement("div");
congratsPage.id = "congrats-page";
congratsPage.className = "fade-in";
congratsPage.style.position = "fixed";
congratsPage.style.top = "0";
congratsPage.style.left = "0";
congratsPage.style.width = "100%";
congratsPage.style.height = "100%";
congratsPage.style.display = "flex";
congratsPage.style.justifyContent = "center";
congratsPage.style.alignItems = "center";
congratsPage.style.backgroundColor = "#000";
congratsPage.style.zIndex = "2000";
// Show only the "Congratulations!" text with circle images behind it
congratsPage.innerHTML = `
<div style="position: relative; text-align: center;">
<h2 style="font-size:48px; color:#fff; position: relative; z-index:2;">Congratulations!</h2>
<div class="congrats-circles" style="position: absolute; top:0; left:0; width:100%; height:100%; z-index:1;">
<img src="recource/ZN_Active_01-01.png" style="position: absolute; top:0%; left:-15%; width:100px; opacity:0; animation: popCircle 2s forwards 0.5s, rotate 10s linear infinite;">
<img src="recource/ZN_Active_01-02.png" style="position: absolute; top:10%; right:10%; width:60px; opacity:0; animation: popCircle 2s forwards 0.8s, rotate 10s linear infinite;">
<img src="recource/ZN_Active_01-05.png" style="position: absolute; bottom:0%; right:-10%; width:100px; opacity:0; animation: popCircle 2s forwards 1.1s, rotate 10s linear infinite;">
</div>
</div>`;
mainContainer.appendChild(congratsPage);
// Add event listener to heading to show small info message
const congratsHeading = congratsPage.querySelector("h2");
congratsHeading.addEventListener("click", function() {
if (!congratsPage.querySelector(".small-info-text")) {
const infoText = document.createElement("p");
infoText.className = "small-info-text";
// Absolutely position the info text below the heading without affecting layout.
infoText.style.position = "absolute";
infoText.style.top = "calc(100% + 10px)";
infoText.style.left = "50%";
infoText.style.transform = "translateX(-50%)";
infoText.style.fontSize = "14px";
infoText.style.color = "#fff";
infoText.textContent = "Hey there! We conduct regular phishing tests, so keep an eye out for them—and don’t tell IT that I Told you that.";
// Append to the parent container (which is position: relative)
congratsPage.querySelector("div").appendChild(infoText);
}
});
}, 1000);
} else {
finishBtn.style.border = "2px solid red";
finishBtn.classList.add("shake");
setTimeout(() => {
finishBtn.classList.remove("shake");
finishBtn.style.border = "2px solid #fff";
}, 500);
}
});
// Temporary Skip Button for Module 4 (testing only - remove later)
const skipModule4 = document.getElementById("skip-module4");
if(skipModule4) {
skipModule4.addEventListener("click", function() {
// Hide modules 1, 2, and 3 if they exist
const module1 = document.getElementById("module1");
if (module1) { module1.style.display = "none"; }
const module2 = document.getElementById("module2");
if (module2) { module2.style.display = "none"; }
const module3 = document.getElementById("module3");
if (module3) { module3.style.display = "none"; }
// Show module 4
const module4 = document.getElementById("module4");
if(module4) {
module4.style.display = "block";
void module4.offsetWidth;
module4.classList.add("fade-in");
}
});
}
});
document.querySelectorAll("#question-section .option").forEach(btn => {
btn.addEventListener("click", function() {
// Disable all options after selection
document.querySelectorAll("#question-section .option").forEach(b => b.disabled = true);
if (this.getAttribute("data-correct") === "true") {
// Correct answer: turn button green
this.style.backgroundColor = "green";
} else {
// Wrong answer: turn clicked button red
this.style.backgroundColor = "red";
// Highlight the correct button with a green border
const correctBtn = document.querySelector('#question-section .option[data-correct="true"]');
if (correctBtn) {
correctBtn.classList.add("correct");
}
}
// After animations, automatically transition from module1 to module2
setTimeout(() => {
const module1 = document.getElementById("module1");
module1.classList.add("fade-out");
setTimeout(() => {
module1.remove();
const module2 = document.getElementById("module2");
module2.style.display = "block";
void module2.offsetWidth;
module2.classList.add("fade-in");
}, 1000);
}, 1500);
});
});