|
1 | 1 | /* WiFiChallenge by r4ulcl · copy recovered key off the device */ |
2 | | -function copyFlagToClipboard(flag) { |
3 | | - var e = window.event; |
4 | | - var btn = e && e.target && e.target.closest ? e.target.closest('button') : null; |
5 | 2 |
|
6 | | - function done() { |
7 | | - if (!btn) return; |
8 | | - btn.classList.add('copied'); |
9 | | - setTimeout(function () { btn.classList.remove('copied'); }, 1500); |
| 3 | +/* Fallback for insecure contexts (plain HTTP, where navigator.clipboard is |
| 4 | + undefined). Returns true only if the copy actually succeeded. */ |
| 5 | +function copyLegacy(text) { |
| 6 | + try { |
| 7 | + var ta = document.createElement('textarea'); |
| 8 | + ta.value = text; |
| 9 | + ta.setAttribute('readonly', ''); |
| 10 | + ta.style.position = 'fixed'; |
| 11 | + ta.style.top = '-1000px'; |
| 12 | + ta.style.opacity = '0'; |
| 13 | + document.body.appendChild(ta); |
| 14 | + ta.select(); |
| 15 | + ta.setSelectionRange(0, ta.value.length); |
| 16 | + var ok = document.execCommand('copy'); |
| 17 | + document.body.removeChild(ta); |
| 18 | + return ok; |
| 19 | + } catch (err) { |
| 20 | + return false; |
10 | 21 | } |
| 22 | +} |
11 | 23 |
|
12 | | - /* Fallback for insecure contexts (plain HTTP, where navigator.clipboard |
13 | | - is undefined). Returns true only if the copy actually succeeded. */ |
14 | | - function legacy() { |
15 | | - try { |
16 | | - var ta = document.createElement('textarea'); |
17 | | - ta.value = flag; |
18 | | - ta.setAttribute('readonly', ''); |
19 | | - ta.style.position = 'fixed'; |
20 | | - ta.style.top = '-1000px'; |
21 | | - ta.style.opacity = '0'; |
22 | | - document.body.appendChild(ta); |
23 | | - ta.select(); |
24 | | - ta.setSelectionRange(0, ta.value.length); |
25 | | - var ok = document.execCommand('copy'); |
26 | | - document.body.removeChild(ta); |
27 | | - return ok; |
28 | | - } catch (err) { |
29 | | - return false; |
30 | | - } |
| 24 | +function copyFlagToClipboard(flag, btn) { |
| 25 | + function done(ok) { |
| 26 | + if (!btn) return; |
| 27 | + var label = btn.getAttribute('data-label') || btn.textContent; |
| 28 | + btn.setAttribute('data-label', label); |
| 29 | + btn.classList.remove('copied', 'failed'); |
| 30 | + btn.classList.add(ok ? 'copied' : 'failed'); |
| 31 | + btn.textContent = ok ? 'COPIED' : 'SELECT + CTRL-C'; |
| 32 | + setTimeout(function () { |
| 33 | + btn.classList.remove('copied', 'failed'); |
| 34 | + btn.textContent = label; |
| 35 | + }, 1500); |
31 | 36 | } |
32 | 37 |
|
33 | 38 | if (navigator.clipboard && navigator.clipboard.writeText) { |
34 | | - navigator.clipboard.writeText(flag).then(done, function () { if (legacy()) done(); }); |
35 | | - } else if (legacy()) { |
36 | | - done(); |
| 39 | + navigator.clipboard.writeText(flag).then( |
| 40 | + function () { done(true); }, |
| 41 | + function () { done(copyLegacy(flag)); } |
| 42 | + ); |
| 43 | + } else { |
| 44 | + done(copyLegacy(flag)); |
37 | 45 | } |
38 | 46 | } |
| 47 | + |
| 48 | +/* Delegated: the flag text lives in .flag > .flag-text so it stays selectable |
| 49 | + with the mouse, and the COPY button never carries the key inline. */ |
| 50 | +document.addEventListener('click', function (ev) { |
| 51 | + var btn = ev.target && ev.target.closest ? ev.target.closest('.flag-copy') : null; |
| 52 | + if (!btn) return; |
| 53 | + |
| 54 | + var wrap = btn.closest('.flag'); |
| 55 | + var text = wrap ? wrap.querySelector('.flag-text') : null; |
| 56 | + if (!text) return; |
| 57 | + |
| 58 | + copyFlagToClipboard(text.textContent.trim(), btn); |
| 59 | +}); |
0 commit comments