@govtechsg/oobee 0.10.84 → 0.10.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/image.yml +3 -2
- package/.github/workflows/publish.yml +10 -0
- package/DETAILS.md +29 -0
- package/dist/cli.js +7 -6
- package/dist/combine.js +1 -1
- package/dist/constants/common.js +15 -4
- package/dist/constants/constants.js +604 -1
- package/dist/crawlers/commonCrawlerFunc.js +3 -2
- package/dist/crawlers/crawlSitemap.js +98 -80
- package/dist/crawlers/custom/utils.js +218 -71
- package/dist/crawlers/guards/urlGuard.js +8 -15
- package/dist/crawlers/runCustom.js +24 -15
- package/dist/generateOobeeClientScanner.js +570 -0
- package/dist/mergeAxeResults.js +49 -29
- package/dist/npmIndex.js +10 -2
- package/dist/proxyService.js +18 -3
- package/dist/services/s3Uploader.js +21 -10
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/ScanConfiguration.ejs +2 -2
- package/dist/static/ejs/partials/scripts/ruleModal/constants.ejs +1 -761
- package/dist/static/ejs/summary.ejs +10 -5
- package/oobee-client-scanner.js +34992 -0
- package/package.json +3 -3
- package/src/cli.ts +20 -15
- package/src/combine.ts +3 -1
- package/src/constants/common.ts +22 -10
- package/src/constants/constants.ts +602 -1
- package/src/crawlers/commonCrawlerFunc.ts +4 -3
- package/src/crawlers/crawlSitemap.ts +116 -98
- package/src/crawlers/custom/utils.ts +244 -84
- package/src/crawlers/guards/urlGuard.ts +24 -31
- package/src/crawlers/runCustom.ts +38 -15
- package/src/generateOobeeClientScanner.ts +591 -0
- package/src/mergeAxeResults.ts +48 -29
- package/src/npmIndex.ts +12 -2
- package/src/proxyService.ts +25 -4
- package/src/services/s3Uploader.ts +23 -11
- package/src/static/ejs/partials/scripts/header/aboutScanModal/ScanConfiguration.ejs +2 -2
- package/src/static/ejs/partials/scripts/ruleModal/constants.ejs +1 -761
- package/src/static/ejs/summary.ejs +10 -5
- package/testStaticJSScanner.html +534 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/* eslint-disable no-shadow */
|
|
2
1
|
/* eslint-disable no-alert */
|
|
3
2
|
/* eslint-disable no-param-reassign */
|
|
4
3
|
/* eslint-env browser */
|
|
5
4
|
import path from 'path';
|
|
5
|
+
import { getDomain } from 'tldts';
|
|
6
6
|
import { runAxeScript } from '../commonCrawlerFunc.js';
|
|
7
7
|
import { consoleLogger, guiInfoLog, silentLogger } from '../../logs.js';
|
|
8
8
|
import { guiInfoStatusTypes } from '../../constants/constants.js';
|
|
@@ -19,6 +19,44 @@ declare global {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
const sameRegistrableDomain = (hostA: string, hostB: string) => {
|
|
23
|
+
const domainA = getDomain(hostA);
|
|
24
|
+
const domainB = getDomain(hostB);
|
|
25
|
+
|
|
26
|
+
if (!domainA || !domainB) return hostA === hostB;
|
|
27
|
+
|
|
28
|
+
return domainA === domainB;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const parseBoolEnv = (val: string | undefined, defaultVal: boolean) => {
|
|
32
|
+
if (val == null) return defaultVal;
|
|
33
|
+
const v = String(val).trim().toLowerCase();
|
|
34
|
+
if (['1', 'true', 'yes', 'y', 'on'].includes(v)) return true;
|
|
35
|
+
if (['0', 'false', 'no', 'n', 'off'].includes(v)) return false;
|
|
36
|
+
return defaultVal;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const RESTRICT_OVERLAY_TO_ENTRY_DOMAIN = parseBoolEnv(
|
|
40
|
+
process.env.RESTRICT_OVERLAY_TO_ENTRY_DOMAIN,
|
|
41
|
+
false,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const isOverlayAllowed = (currentUrl: string, entryUrl: string) => {
|
|
45
|
+
try {
|
|
46
|
+
const cur = new URL(currentUrl);
|
|
47
|
+
|
|
48
|
+
if (cur.protocol !== 'http:' && cur.protocol !== 'https:') return false;
|
|
49
|
+
|
|
50
|
+
if (!RESTRICT_OVERLAY_TO_ENTRY_DOMAIN) return true;
|
|
51
|
+
|
|
52
|
+
const base = new URL(entryUrl);
|
|
53
|
+
|
|
54
|
+
return sameRegistrableDomain(cur.hostname, base.hostname);
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
22
60
|
//! For Cypress Test
|
|
23
61
|
// env to check if Cypress test is running
|
|
24
62
|
const isCypressTest = process.env.IS_CYPRESS_TEST === 'true';
|
|
@@ -62,20 +100,17 @@ export const screenshotFullPage = async (page, screenshotsDir: string, screensho
|
|
|
62
100
|
window.scrollTo(0, document.body.scrollHeight);
|
|
63
101
|
});
|
|
64
102
|
|
|
65
|
-
const isLoadMoreContent = async () =>
|
|
66
|
-
new Promise(resolve =>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
resolve(result);
|
|
77
|
-
}, 2500);
|
|
78
|
-
});
|
|
103
|
+
const isLoadMoreContent = async () => {
|
|
104
|
+
await new Promise(resolve => setTimeout(resolve, 2500));
|
|
105
|
+
if (page.isClosed()) return false;
|
|
106
|
+
try {
|
|
107
|
+
await page.waitForLoadState('domcontentloaded');
|
|
108
|
+
const newHeight = await page.evaluate(() => document.body.scrollHeight);
|
|
109
|
+
return newHeight > prevHeight;
|
|
110
|
+
} catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
79
114
|
|
|
80
115
|
const result = await isLoadMoreContent();
|
|
81
116
|
return result;
|
|
@@ -248,7 +283,7 @@ export const updateMenu = async (page, urlsCrawled) => {
|
|
|
248
283
|
log(`Overlay menu: updating: ${page.url()}`);
|
|
249
284
|
await page.evaluate(
|
|
250
285
|
vars => {
|
|
251
|
-
const shadowHost = document.querySelector('#
|
|
286
|
+
const shadowHost = document.querySelector('#oobeeShadowHost');
|
|
252
287
|
if (shadowHost) {
|
|
253
288
|
const p = shadowHost.shadowRoot.querySelector('#oobee-p-pages-scanned');
|
|
254
289
|
if (p) {
|
|
@@ -262,7 +297,6 @@ export const updateMenu = async (page, urlsCrawled) => {
|
|
|
262
297
|
consoleLogger.info(`Overlay menu updated`);
|
|
263
298
|
};
|
|
264
299
|
|
|
265
|
-
|
|
266
300
|
export const addOverlayMenu = async (
|
|
267
301
|
page,
|
|
268
302
|
urlsCrawled,
|
|
@@ -307,7 +341,7 @@ export const addOverlayMenu = async (
|
|
|
307
341
|
`;
|
|
308
342
|
minBtn.innerHTML = MINBTN_SVG;
|
|
309
343
|
|
|
310
|
-
let currentPos: 'LEFT' | 'RIGHT' =
|
|
344
|
+
let currentPos: 'LEFT' | 'RIGHT' = vars.menuPos || 'RIGHT';
|
|
311
345
|
const isCollapsed = () => panel.classList.contains('collapsed');
|
|
312
346
|
|
|
313
347
|
const setPosClass = (pos: 'LEFT' | 'RIGHT') => {
|
|
@@ -325,7 +359,7 @@ export const addOverlayMenu = async (
|
|
|
325
359
|
};
|
|
326
360
|
|
|
327
361
|
const toggleCollapsed = (force?: boolean) => {
|
|
328
|
-
const willCollapse =
|
|
362
|
+
const willCollapse = typeof force === 'boolean' ? force : !isCollapsed();
|
|
329
363
|
if (willCollapse) {
|
|
330
364
|
panel.classList.add('collapsed');
|
|
331
365
|
localStorage.setItem('oobee:overlay-collapsed', '1');
|
|
@@ -375,25 +409,72 @@ export const addOverlayMenu = async (
|
|
|
375
409
|
const h2 = document.createElement('h2');
|
|
376
410
|
h2.id = 'oobeeHPagesScanned';
|
|
377
411
|
h2.className = 'oobee-section-title';
|
|
378
|
-
h2.textContent =
|
|
379
|
-
|
|
412
|
+
h2.textContent = `Pages Scanned (${vars.urlsCrawled.scanned.length || 0})`;
|
|
413
|
+
|
|
414
|
+
const scanIcon = document.createElement('span');
|
|
415
|
+
scanIcon.className = 'oobee-btn-icon';
|
|
416
|
+
|
|
417
|
+
const SCAN_SVG = `
|
|
418
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
419
|
+
<g clip-path="url(#clip0_1421_431)">
|
|
420
|
+
<path d="M12.5763 11.5472L12.2958 11.2857L12.1037 11.1005C12.776 10.3183 12.9194 9.56432 12.9194 8.45969C12.9194 5.99657 10.9228 4 8.45969 4C5.99657 4 4 5.99657 4 8.45969C4 10.9228 5.99657 12.9194 8.45969 12.9194C9.56432 12.9194 10.3183 12.776 11.1005 12.1037L11.2857 12.2958L11.5472 12.5763L14.9777 16L16 14.9777L12.5763 11.5472ZM8.45969 11.5472C6.75129 11.5472 5.37221 10.1681 5.37221 8.45969C5.37221 6.75129 6.75129 5.37221 8.45969 5.37221C10.1681 5.37221 11.5472 6.75129 11.5472 8.45969C11.5472 10.1681 10.1681 11.5472 8.45969 11.5472Z" fill="white"/>
|
|
421
|
+
<path d="M18.5 0H19.5C19.7761 0 20 0.223858 20 0.5V5H18.5V0Z" fill="white"/>
|
|
422
|
+
<path d="M19.5 2.18552e-08L19.5 1.5L15 1.5L15 -2.18556e-07L19.5 2.18552e-08Z" fill="white"/>
|
|
423
|
+
<path d="M1.5 0H0.5C0.223858 0 0 0.223858 0 0.5V5H1.5V0Z" fill="white"/>
|
|
424
|
+
<path d="M0.5 2.18552e-08L0.5 1.5L5 1.5L5 -2.18556e-07L0.5 2.18552e-08Z" fill="white"/>
|
|
425
|
+
<path d="M1.5 20H0.5C0.223858 20 0 19.7761 0 19.5V15H1.5V20Z" fill="white"/>
|
|
426
|
+
<path d="M0.5 20L0.5 18.5L5 18.5L5 20L0.5 20Z" fill="white"/>
|
|
427
|
+
<path d="M18.5 20H19.5C19.7761 20 20 19.7761 20 19.5V15H18.5V20Z" fill="white"/>
|
|
428
|
+
<path d="M19.5 20L19.5 18.5L15 18.5L15 20L19.5 20Z" fill="white"/>
|
|
429
|
+
</g>
|
|
430
|
+
<defs>
|
|
431
|
+
<clipPath id="clip0_1421_431">
|
|
432
|
+
<rect width="20" height="20" fill="white"/>
|
|
433
|
+
</clipPath>
|
|
434
|
+
</defs>
|
|
435
|
+
</svg>
|
|
436
|
+
`;
|
|
437
|
+
|
|
438
|
+
scanIcon.innerHTML = SCAN_SVG;
|
|
380
439
|
const scanBtn = document.createElement('button');
|
|
381
440
|
scanBtn.id = 'oobeeBtnScan';
|
|
382
441
|
scanBtn.className = 'oobee-btn oobee-btn-primary';
|
|
383
|
-
scanBtn.innerText = 'Scan this page';
|
|
384
442
|
scanBtn.disabled = inProgress;
|
|
443
|
+
scanBtn.appendChild(scanIcon);
|
|
444
|
+
|
|
445
|
+
const scanText = document.createElement('span');
|
|
446
|
+
scanText.className = 'oobee-btn-text';
|
|
447
|
+
scanText.innerText = 'Scan page';
|
|
448
|
+
scanBtn.appendChild(scanText);
|
|
449
|
+
|
|
385
450
|
scanBtn.addEventListener('click', async () => customWindow.handleOnScanClick?.());
|
|
386
451
|
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
452
|
+
const endScanIcon = document.createElement('span');
|
|
453
|
+
endScanIcon.className = 'oobee-btn-icon';
|
|
454
|
+
|
|
455
|
+
const ENDSCAN_SVG =
|
|
456
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
457
|
+
<path d="M10 0C4.47 0 0 4.47 0 10C0 15.53 4.47 20 10 20C15.53 20 20 15.53 20 10C20 4.47 15.53 0 10 0ZM10 18C5.59 18 2 14.41 2 10C2 5.59 5.59 2 10 2C14.41 2 18 5.59 18 10C18 14.41 14.41 18 10 18ZM13.59 5L10 8.59L6.41 5L5 6.41L8.59 10L5 13.59L6.41 15L10 11.41L13.59 15L15 13.59L11.41 10L15 6.41L13.59 5Z" fill="#9021A6"/>
|
|
458
|
+
</svg>
|
|
459
|
+
`;
|
|
460
|
+
|
|
461
|
+
endScanIcon.innerHTML = ENDSCAN_SVG;
|
|
462
|
+
const endScanBtn = document.createElement('button');
|
|
463
|
+
endScanBtn.id = 'oobeeBtnEndScan';
|
|
464
|
+
endScanBtn.className = 'oobee-btn oobee-btn-secondary';
|
|
465
|
+
endScanBtn.appendChild(endScanIcon);
|
|
466
|
+
|
|
467
|
+
const endScanText = document.createElement('span');
|
|
468
|
+
endScanText.className = 'oobee-btn-text';
|
|
469
|
+
endScanText.innerText = 'End scan';
|
|
470
|
+
endScanBtn.appendChild(endScanText);
|
|
471
|
+
|
|
472
|
+
endScanBtn.addEventListener('click', async () => customWindow.handleOnStopClick?.());
|
|
392
473
|
|
|
393
474
|
const btnGroup = document.createElement('div');
|
|
394
475
|
btnGroup.className = 'oobee-actions';
|
|
395
476
|
btnGroup.appendChild(scanBtn);
|
|
396
|
-
btnGroup.appendChild(
|
|
477
|
+
btnGroup.appendChild(endScanBtn);
|
|
397
478
|
|
|
398
479
|
const listWrap = document.createElement('div');
|
|
399
480
|
listWrap.id = 'oobeeList';
|
|
@@ -414,13 +495,13 @@ export const addOverlayMenu = async (
|
|
|
414
495
|
const ol = document.createElement('ol');
|
|
415
496
|
ol.className = 'oobee-ol';
|
|
416
497
|
|
|
417
|
-
scanned.forEach(
|
|
498
|
+
scanned.forEach(item => {
|
|
418
499
|
const li = document.createElement('li');
|
|
419
500
|
li.className = 'oobee-li';
|
|
420
501
|
|
|
421
502
|
const title = document.createElement('div');
|
|
422
503
|
title.className = 'oobee-item-title';
|
|
423
|
-
title.textContent =
|
|
504
|
+
title.textContent = item.pageTitle && item.pageTitle.trim() ? item.pageTitle : item.url;
|
|
424
505
|
|
|
425
506
|
const url = document.createElement('div');
|
|
426
507
|
url.className = 'oobee-item-url';
|
|
@@ -469,7 +550,7 @@ export const addOverlayMenu = async (
|
|
|
469
550
|
border-right: 1px solid rgba(0,0,0,.08)
|
|
470
551
|
}
|
|
471
552
|
.oobee-panel.collapsed {
|
|
472
|
-
width:
|
|
553
|
+
width: 58px;
|
|
473
554
|
overflow: hidden
|
|
474
555
|
}
|
|
475
556
|
|
|
@@ -546,6 +627,12 @@ export const addOverlayMenu = async (
|
|
|
546
627
|
padding: 1rem;
|
|
547
628
|
}
|
|
548
629
|
|
|
630
|
+
.oobee-panel.collapsed .oobee-actions {
|
|
631
|
+
display: flex;
|
|
632
|
+
justify-content: center;
|
|
633
|
+
padding: 1rem 0.7rem;
|
|
634
|
+
}
|
|
635
|
+
|
|
549
636
|
/* Base button */
|
|
550
637
|
.oobee-btn {
|
|
551
638
|
width: 100%;
|
|
@@ -556,6 +643,10 @@ export const addOverlayMenu = async (
|
|
|
556
643
|
line-height: 1.2;
|
|
557
644
|
font-weight: 400;
|
|
558
645
|
cursor: pointer;
|
|
646
|
+
display: flex;
|
|
647
|
+
align-items: center;
|
|
648
|
+
justify-content: center;
|
|
649
|
+
gap: 10px;
|
|
559
650
|
transition: {
|
|
560
651
|
box-shadow .12s ease,
|
|
561
652
|
transform .02s ease,
|
|
@@ -569,6 +660,19 @@ export const addOverlayMenu = async (
|
|
|
569
660
|
cursor:not-allowed
|
|
570
661
|
}
|
|
571
662
|
|
|
663
|
+
.oobee-panel.collapsed .oobee-btn {
|
|
664
|
+
width: 44px !important;
|
|
665
|
+
height: 44px !important;
|
|
666
|
+
min-width: 44px !important;
|
|
667
|
+
min-height: 44px !important;
|
|
668
|
+
max-width: 44px !important;
|
|
669
|
+
max-height: 44px !important;
|
|
670
|
+
border-radius: 50% !important;
|
|
671
|
+
padding: 0 !important;
|
|
672
|
+
justify-content: center;
|
|
673
|
+
gap: 0;
|
|
674
|
+
}
|
|
675
|
+
|
|
572
676
|
/* Primary (filled) */
|
|
573
677
|
.oobee-btn-primary {
|
|
574
678
|
background: #9021a6;
|
|
@@ -624,6 +728,25 @@ export const addOverlayMenu = async (
|
|
|
624
728
|
display: none;
|
|
625
729
|
}
|
|
626
730
|
|
|
731
|
+
.oobee-btn-icon {
|
|
732
|
+
display: inline-flex;
|
|
733
|
+
align-items: center;
|
|
734
|
+
justify-content: center;
|
|
735
|
+
width: 20px;
|
|
736
|
+
height: 20px;
|
|
737
|
+
vertical-align: middle;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.oobee-btn-text {
|
|
741
|
+
display: inline;
|
|
742
|
+
white-space: nowrap;
|
|
743
|
+
vertical-align: middle;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.oobee-panel.collapsed .oobee-btn-text {
|
|
747
|
+
display: none;
|
|
748
|
+
}
|
|
749
|
+
|
|
627
750
|
#oobeeStopOverlay[hidden] {
|
|
628
751
|
display:none !important;
|
|
629
752
|
}
|
|
@@ -641,7 +764,10 @@ export const addOverlayMenu = async (
|
|
|
641
764
|
}
|
|
642
765
|
|
|
643
766
|
.oobee-panel.collapsed .oobee-section-title {
|
|
644
|
-
|
|
767
|
+
font-size: 14px;
|
|
768
|
+
display: flex;
|
|
769
|
+
justify-content: center;
|
|
770
|
+
text-align: center;
|
|
645
771
|
}
|
|
646
772
|
|
|
647
773
|
.oobee-ol {
|
|
@@ -730,8 +856,7 @@ export const addOverlayMenu = async (
|
|
|
730
856
|
|
|
731
857
|
const closed = isCollapsed();
|
|
732
858
|
const arrowPointsRight =
|
|
733
|
-
(currentPos === 'RIGHT' && !closed) ||
|
|
734
|
-
(currentPos === 'LEFT' && closed);
|
|
859
|
+
(currentPos === 'RIGHT' && !closed) || (currentPos === 'LEFT' && closed);
|
|
735
860
|
|
|
736
861
|
icon.classList.toggle('is-left', !arrowPointsRight);
|
|
737
862
|
minBtn.setAttribute('aria-label', closed ? 'Expand panel' : 'Collapse panel');
|
|
@@ -761,11 +886,11 @@ export const addOverlayMenu = async (
|
|
|
761
886
|
|
|
762
887
|
grip.addEventListener('pointerdown', (e: PointerEvent) => {
|
|
763
888
|
startX = e.clientX;
|
|
764
|
-
grip.setPointerCapture(e.pointerId);
|
|
889
|
+
grip.setPointerCapture(e.pointerId); // <-- use the button
|
|
765
890
|
});
|
|
766
891
|
|
|
767
892
|
grip.addEventListener('pointermove', (e: PointerEvent) => {
|
|
768
|
-
if (!grip.hasPointerCapture?.(e.pointerId)) return;
|
|
893
|
+
if (!grip.hasPointerCapture?.(e.pointerId)) return; // <-- check the button
|
|
769
894
|
const dx = e.clientX - startX;
|
|
770
895
|
if (Math.abs(dx) >= THRESH) {
|
|
771
896
|
const nextPos: 'LEFT' | 'RIGHT' = dx < 0 ? 'LEFT' : 'RIGHT';
|
|
@@ -779,7 +904,9 @@ export const addOverlayMenu = async (
|
|
|
779
904
|
});
|
|
780
905
|
|
|
781
906
|
grip.addEventListener('pointerup', (e: PointerEvent) => {
|
|
782
|
-
try {
|
|
907
|
+
try {
|
|
908
|
+
grip.releasePointerCapture(e.pointerId);
|
|
909
|
+
} catch {}
|
|
783
910
|
});
|
|
784
911
|
|
|
785
912
|
const stopDialog = document.createElement('dialog');
|
|
@@ -791,7 +918,7 @@ export const addOverlayMenu = async (
|
|
|
791
918
|
borderRadius: '16px',
|
|
792
919
|
overflow: 'hidden',
|
|
793
920
|
boxShadow: '0 10px 40px rgba(0,0,0,.35)',
|
|
794
|
-
fontFamily: 'system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif'
|
|
921
|
+
fontFamily: 'system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif',
|
|
795
922
|
});
|
|
796
923
|
const dialogSheet = new CSSStyleSheet();
|
|
797
924
|
dialogSheet.replaceSync(`
|
|
@@ -829,13 +956,18 @@ export const addOverlayMenu = async (
|
|
|
829
956
|
display: 'flex',
|
|
830
957
|
alignItems: 'center',
|
|
831
958
|
justifyContent: 'space-between',
|
|
832
|
-
gap: '8px'
|
|
959
|
+
gap: '8px',
|
|
833
960
|
});
|
|
834
961
|
|
|
835
962
|
const title = document.createElement('h2');
|
|
836
963
|
title.id = 'oobee-stop-title';
|
|
837
964
|
title.textContent = 'Are you sure you want to stop this scan?';
|
|
838
|
-
Object.assign(title.style, {
|
|
965
|
+
Object.assign(title.style, {
|
|
966
|
+
margin: '0',
|
|
967
|
+
fontSize: '22px',
|
|
968
|
+
fontWeight: '700',
|
|
969
|
+
lineHeight: '1.25',
|
|
970
|
+
});
|
|
839
971
|
|
|
840
972
|
const closeX = document.createElement('button');
|
|
841
973
|
closeX.type = 'button';
|
|
@@ -853,14 +985,14 @@ export const addOverlayMenu = async (
|
|
|
853
985
|
height: '36px',
|
|
854
986
|
borderRadius: '12px',
|
|
855
987
|
display: 'grid',
|
|
856
|
-
placeItems: 'center'
|
|
988
|
+
placeItems: 'center',
|
|
857
989
|
});
|
|
858
990
|
head.appendChild(title);
|
|
859
991
|
head.appendChild(closeX);
|
|
860
992
|
|
|
861
993
|
const bodyWrap = document.createElement('div');
|
|
862
994
|
Object.assign(bodyWrap.style, {
|
|
863
|
-
padding: '12px 20px 20px 20px'
|
|
995
|
+
padding: '12px 20px 20px 20px',
|
|
864
996
|
});
|
|
865
997
|
|
|
866
998
|
const form = document.createElement('form');
|
|
@@ -869,7 +1001,7 @@ export const addOverlayMenu = async (
|
|
|
869
1001
|
Object.assign(form.style, {
|
|
870
1002
|
display: 'grid',
|
|
871
1003
|
gridTemplateColumns: '1fr',
|
|
872
|
-
rowGap: '12px'
|
|
1004
|
+
rowGap: '12px',
|
|
873
1005
|
});
|
|
874
1006
|
|
|
875
1007
|
const label = document.createElement('label');
|
|
@@ -887,7 +1019,7 @@ export const addOverlayMenu = async (
|
|
|
887
1019
|
padding: '12px 14px',
|
|
888
1020
|
fontSize: '14px',
|
|
889
1021
|
outline: 'none',
|
|
890
|
-
boxSizing: 'border-box'
|
|
1022
|
+
boxSizing: 'border-box',
|
|
891
1023
|
});
|
|
892
1024
|
input.addEventListener('focus', () => {
|
|
893
1025
|
input.style.borderColor = '#7b4dff';
|
|
@@ -913,7 +1045,7 @@ export const addOverlayMenu = async (
|
|
|
913
1045
|
fontWeight: '600',
|
|
914
1046
|
color: '#fff',
|
|
915
1047
|
background: '#9021A6',
|
|
916
|
-
cursor: 'pointer'
|
|
1048
|
+
cursor: 'pointer',
|
|
917
1049
|
});
|
|
918
1050
|
|
|
919
1051
|
const cancel = document.createElement('button');
|
|
@@ -926,7 +1058,7 @@ export const addOverlayMenu = async (
|
|
|
926
1058
|
fontSize: '14px',
|
|
927
1059
|
justifySelf: 'center',
|
|
928
1060
|
cursor: 'pointer',
|
|
929
|
-
padding: '6px'
|
|
1061
|
+
padding: '6px',
|
|
930
1062
|
});
|
|
931
1063
|
|
|
932
1064
|
actions.appendChild(primary);
|
|
@@ -936,7 +1068,7 @@ export const addOverlayMenu = async (
|
|
|
936
1068
|
form.appendChild(label);
|
|
937
1069
|
form.appendChild(input);
|
|
938
1070
|
}
|
|
939
|
-
|
|
1071
|
+
form.appendChild(actions);
|
|
940
1072
|
bodyWrap.appendChild(form);
|
|
941
1073
|
|
|
942
1074
|
stopDialog.appendChild(head);
|
|
@@ -944,17 +1076,27 @@ export const addOverlayMenu = async (
|
|
|
944
1076
|
shadowRoot.appendChild(stopDialog);
|
|
945
1077
|
|
|
946
1078
|
let stopResolver: null | ((v: { confirmed: boolean; label: string }) => void) = null;
|
|
947
|
-
const hideStop = () => {
|
|
1079
|
+
const hideStop = () => {
|
|
1080
|
+
try {
|
|
1081
|
+
stopDialog.close();
|
|
1082
|
+
} catch {}
|
|
1083
|
+
stopResolver = null;
|
|
1084
|
+
};
|
|
948
1085
|
const showStop = () => {
|
|
949
1086
|
if (!shouldHideInput) input.value = '';
|
|
950
|
-
try {
|
|
1087
|
+
try {
|
|
1088
|
+
stopDialog.showModal();
|
|
1089
|
+
} catch {}
|
|
951
1090
|
if (!shouldHideInput) {
|
|
952
1091
|
requestAnimationFrame(() => {
|
|
953
|
-
try {
|
|
1092
|
+
try {
|
|
1093
|
+
input.focus({ preventScroll: true });
|
|
1094
|
+
input.select();
|
|
1095
|
+
} catch {}
|
|
954
1096
|
});
|
|
955
1097
|
}
|
|
956
1098
|
};
|
|
957
|
-
form.addEventListener('submit',
|
|
1099
|
+
form.addEventListener('submit', e => {
|
|
958
1100
|
e.preventDefault();
|
|
959
1101
|
const v = (input.value || '').trim();
|
|
960
1102
|
if (stopResolver) stopResolver({ confirmed: true, label: v });
|
|
@@ -968,13 +1110,13 @@ export const addOverlayMenu = async (
|
|
|
968
1110
|
if (stopResolver) stopResolver({ confirmed: false, label: '' });
|
|
969
1111
|
hideStop();
|
|
970
1112
|
});
|
|
971
|
-
stopDialog.addEventListener('cancel',
|
|
1113
|
+
stopDialog.addEventListener('cancel', e => {
|
|
972
1114
|
e.preventDefault();
|
|
973
1115
|
if (stopResolver) stopResolver({ confirmed: false, label: '' });
|
|
974
1116
|
hideStop();
|
|
975
1117
|
});
|
|
976
1118
|
(customWindow as Window).oobeeShowStopModal = () =>
|
|
977
|
-
new Promise<{ confirmed: boolean; label: string }>(
|
|
1119
|
+
new Promise<{ confirmed: boolean; label: string }>(resolve => {
|
|
978
1120
|
stopResolver = resolve;
|
|
979
1121
|
showStop();
|
|
980
1122
|
});
|
|
@@ -1000,7 +1142,7 @@ export const addOverlayMenu = async (
|
|
|
1000
1142
|
log('Overlay menu: successfully added');
|
|
1001
1143
|
})
|
|
1002
1144
|
.catch(error => {
|
|
1003
|
-
error('Overlay menu: failed to add', error);
|
|
1145
|
+
consoleLogger.error('Overlay menu: failed to add', error);
|
|
1004
1146
|
});
|
|
1005
1147
|
};
|
|
1006
1148
|
|
|
@@ -1027,7 +1169,13 @@ export const initNewPage = async (page, pageClosePromises, processPageParams, pa
|
|
|
1027
1169
|
// eslint-disable-next-line no-underscore-dangle
|
|
1028
1170
|
const pageId = page._guid;
|
|
1029
1171
|
|
|
1030
|
-
page.on('dialog',
|
|
1172
|
+
page.on('dialog', async dialog => {
|
|
1173
|
+
try {
|
|
1174
|
+
await dialog.dismiss();
|
|
1175
|
+
} catch {
|
|
1176
|
+
// dialog may already be closed
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1031
1179
|
|
|
1032
1180
|
const pageClosePromise = new Promise(resolve => {
|
|
1033
1181
|
page.on('close', () => {
|
|
@@ -1058,11 +1206,19 @@ export const initNewPage = async (page, pageClosePromises, processPageParams, pa
|
|
|
1058
1206
|
await processPage(page, processPageParams);
|
|
1059
1207
|
log('Scan: success');
|
|
1060
1208
|
pagesDict[pageId].isScanning = false;
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1209
|
+
|
|
1210
|
+
if (page.isClosed()) return;
|
|
1211
|
+
const allowed = isOverlayAllowed(page.url(), processPageParams.entryUrl);
|
|
1212
|
+
|
|
1213
|
+
if (allowed) {
|
|
1214
|
+
await addOverlayMenu(page, processPageParams.urlsCrawled, menuPos, {
|
|
1215
|
+
inProgress: false,
|
|
1216
|
+
collapsed: !!pagesDict[pageId]?.collapsed,
|
|
1217
|
+
hideStopInput: !!processPageParams.customFlowLabel,
|
|
1218
|
+
});
|
|
1219
|
+
} else {
|
|
1220
|
+
await removeOverlayMenu(page);
|
|
1221
|
+
}
|
|
1066
1222
|
} catch (error) {
|
|
1067
1223
|
log(`Scan failed ${error}`);
|
|
1068
1224
|
}
|
|
@@ -1093,10 +1249,10 @@ export const initNewPage = async (page, pageClosePromises, processPageParams, pa
|
|
|
1093
1249
|
|
|
1094
1250
|
if (!inputValue?.confirmed) {
|
|
1095
1251
|
await page.evaluate(() => {
|
|
1096
|
-
const
|
|
1097
|
-
if (
|
|
1098
|
-
|
|
1099
|
-
|
|
1252
|
+
const endScanBtn = document.getElementById('oobeeBtnEndScan') as HTMLButtonElement | null;
|
|
1253
|
+
if (endScanBtn) {
|
|
1254
|
+
endScanBtn.disabled = false;
|
|
1255
|
+
endScanBtn.textContent = 'Stop';
|
|
1100
1256
|
}
|
|
1101
1257
|
});
|
|
1102
1258
|
return;
|
|
@@ -1125,7 +1281,15 @@ export const initNewPage = async (page, pageClosePromises, processPageParams, pa
|
|
|
1125
1281
|
};
|
|
1126
1282
|
|
|
1127
1283
|
page.on('domcontentloaded', async () => {
|
|
1284
|
+
if (page.isClosed()) return;
|
|
1128
1285
|
try {
|
|
1286
|
+
const allowed = isOverlayAllowed(page.url(), processPageParams.entryUrl);
|
|
1287
|
+
|
|
1288
|
+
if (!allowed) {
|
|
1289
|
+
await removeOverlayMenu(page);
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1129
1293
|
const existingOverlay = await page.evaluate(() => {
|
|
1130
1294
|
return document.querySelector('#oobeeShadowHost');
|
|
1131
1295
|
});
|
|
@@ -1141,12 +1305,6 @@ export const initNewPage = async (page, pageClosePromises, processPageParams, pa
|
|
|
1141
1305
|
});
|
|
1142
1306
|
}
|
|
1143
1307
|
|
|
1144
|
-
setTimeout(() => {
|
|
1145
|
-
// Timeout here to slow things down a little
|
|
1146
|
-
}, 1000);
|
|
1147
|
-
|
|
1148
|
-
//! For Cypress Test
|
|
1149
|
-
// Auto-clicks 'Scan this page' button only once
|
|
1150
1308
|
if (isCypressTest) {
|
|
1151
1309
|
try {
|
|
1152
1310
|
await handleOnScanClick();
|
|
@@ -1155,27 +1313,29 @@ export const initNewPage = async (page, pageClosePromises, processPageParams, pa
|
|
|
1155
1313
|
consoleLogger.info(`Error in calling handleOnScanClick, isCypressTest: ${isCypressTest}`);
|
|
1156
1314
|
}
|
|
1157
1315
|
}
|
|
1158
|
-
|
|
1159
|
-
consoleLogger.info(`Overlay state: ${existingOverlay}`);
|
|
1160
1316
|
} catch {
|
|
1161
1317
|
consoleLogger.info('Error in adding overlay menu to page');
|
|
1162
|
-
consoleLogger.info('Error in adding overlay menu to page');
|
|
1163
1318
|
}
|
|
1164
1319
|
});
|
|
1165
1320
|
|
|
1166
|
-
|
|
1167
|
-
|
|
1321
|
+
try {
|
|
1322
|
+
if (page.isClosed()) return page;
|
|
1323
|
+
await page.exposeFunction('handleOnScanClick', handleOnScanClick);
|
|
1324
|
+
await page.exposeFunction('handleOnStopClick', handleOnStopClick);
|
|
1168
1325
|
|
|
1169
|
-
|
|
1326
|
+
type UpdateMenuPosFunction = (newPos: any) => void;
|
|
1170
1327
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1328
|
+
// Define the updateMenuPos function
|
|
1329
|
+
const updateMenuPos: UpdateMenuPosFunction = newPos => {
|
|
1330
|
+
const prevPos = menuPos;
|
|
1331
|
+
if (prevPos !== newPos) {
|
|
1332
|
+
menuPos = newPos;
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1335
|
+
await page.exposeFunction('updateMenuPos', updateMenuPos);
|
|
1336
|
+
} catch (e) {
|
|
1337
|
+
log(`Error exposing functions on page: ${e}`);
|
|
1338
|
+
}
|
|
1179
1339
|
|
|
1180
1340
|
return page;
|
|
1181
1341
|
};
|