Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Staging to Main #738

Merged
merged 16 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions api/functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@
const buildId = req.params.buildId;
const runId = newGuid();
const buildDate = new Date();
const unscannableLinks = await getUnscannableLinks();

Check warning on line 233 in api/functions/index.js

View workflow job for this annotation

GitHub Actions / build

'unscannableLinks' is assigned a value but never used

Check warning on line 233 in api/functions/index.js

View workflow job for this annotation

GitHub Actions / build

'unscannableLinks' is assigned a value but never used

const uid = await getUserIdFromApiKey(apikey);
if (!uid) {
Expand Down Expand Up @@ -262,11 +262,11 @@
url,
cloc,
totalBrokenLinks: badUrls.length,
uniqueBrokenLinks: R.uniqBy(R.prop('dst'), badUrls.filter((x) => !unscannableLinks.some(link => x.dst.includes(link)))).length,
pagesWithBrokenLink: R.uniqBy(R.prop('src'), badUrls.filter((x) => !unscannableLinks.some(link => x.dst.includes(link)))).length,
uniqueBrokenLinks: R.uniqBy(R.prop('dst'), badUrls).length,
pagesWithBrokenLink: R.uniqBy(R.prop('src'), badUrls).length,
totalUnique404: R.uniqBy(
R.prop('dst'),
badUrls.filter((x) => x.statuscode === '404' && !unscannableLinks.some(link => x.dst.includes(link)))
badUrls.filter((x) => x.statuscode === '404')
).length,
htmlWarnings: htmlWarnings ? htmlWarnings : 0,
htmlErrors: htmlErrors ? htmlErrors : 0,
Expand Down
2 changes: 1 addition & 1 deletion docker/customHtmlRules.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ exports.addCustomHtmlRule = () => {
"Checks for phone numbers that aren't in hyperlinks with a \"tel:\" prefix.",
init: function (parser, reporter) {
const self = this;
parser.addListener("all", (event) => {
parser.addListener("text", (event) => {
if (event.raw && event.lastEvent && findPhoneNumbersInText(event.raw, "AU").length) {
const pageContent = event.lastEvent.raw;
if (pageContent && event.lastEvent.tagName) {
Expand Down
1 change: 1 addition & 0 deletions docker/sswlinkauditor.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func check(link Link, linkch chan LinkStatus, number int, unscannableLinks []str
}
method := "HEAD"

// get list of links we consider unscannable and use a GET request to get a more accurate result
if isLinkUnscannable(link.url, unscannableLinks) {
method = "GET"
}
Expand Down
19 changes: 18 additions & 1 deletion docker/test/phone-numbers-without-links.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ const phoneNumbers = [
const nonPhoneNumbers = [
"2023.05.31.02",
"123.456.7890",
"1234.567.890"
"1234.567.890",
"20231024.16"
];

describe(`Rules: ${ruleId}`, () => {
Expand All @@ -40,6 +41,14 @@ describe(`Rules: ${ruleId}`, () => {
});
});

phoneNumbers.forEach((phone) => {
it(`text containing "${phone}" in a non-text tag should not error`, () => {
const code = `<style>${phone}</style><script>${phone}</script>`;
const messages = HTMLHint.verify(code, ruleOptions);
expect(messages.length).to.be(0);
});
});

nonPhoneNumbers.forEach((phone) => {
it(`text containing non-phone number "${phone}" without hyperlink should not error`, () => {
const code =
Expand All @@ -51,6 +60,14 @@ describe(`Rules: ${ruleId}`, () => {
});
});

nonPhoneNumbers.forEach((phone) => {
it(`text containing non-phone number "${phone}" in a non-text tag should not error`, () => {
const code = `<style>${phone}</style><script>${phone}</script>`;
const messages = HTMLHint.verify(code, ruleOptions);
expect(messages.length).to.be(0);
});
});

phoneNumbers.forEach((phone) => {
it(`link containing "${phone}" without hyperlink should error`, () => {
const code = `<a>${phone}</a>`;
Expand Down
5 changes: 1 addition & 4 deletions ui/src/components/buildlistcardcomponents/BuildList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@

let groupUrlKey = [];
let groupUrl;

// Remove 'www.' before grouping the scans by the Urls
builds = builds.map(item => ({...item, url: item.url.replace('www.', '')}))


groupUrl = groupBy(props(["url"]))(builds);
groupUrlKey = Object.keys(groupUrl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
cursor-default whitespace-nowrap">
<a
on:click={() => viewSource(page.url, item, error.error)}
href={'#'}
href={"javascript:void(0)"}
title="View source">
{item}
</a>
Expand All @@ -138,7 +138,7 @@
cursor-default whitespace-nowrap">
<a
on:click={() => viewSource(page.url, item, error.error)}
href={'#'}
href={"javascript:void(0)"}
title="View source">
{item}
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
cursor-default whitespace-nowrap">
<a
on:click={() => viewSource(url.url, item, key)}
href={'#'}
href={"javascript:void(0)"}
title="View source">
{item}
</a>
Expand All @@ -128,7 +128,7 @@
cursor-default whitespace-nowrap">
<a
on:click={() => viewSource(url.url, item, key)}
href={'#'}
href={"javascript:void(0)"}
title="View source">
{item}
</a>
Expand Down
4 changes: 0 additions & 4 deletions ui/src/components/misccomponents/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
</script>

<style>
.modal {
transition: opacity 0.2s ease;
z-index: 3000;
}
.fullheight {
height: 90vh;
}
Expand Down
28 changes: 16 additions & 12 deletions ui/src/components/misccomponents/SendAlertModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@

let isLoading;
let emailAddress = "";
let type = "text";
let showErrorPromp = false;
let showErrorPrompt = false;

const dismiss = () => (show = false);

const handleInput = (e) => {
emailAddress = validateEmail(e.target.value) ? e.target.value : null;
if (e.key === "Enter") {
updateEmailAddress();
} else {
showErrorPrompt = false;
}
};

const reloadSharedEmailList = async () => {
Expand Down Expand Up @@ -44,8 +47,8 @@
};

const updateEmailAddress = async () => {
if (emailAddress) {
showErrorPromp = false;
if (emailAddress && validateEmail(emailAddress)) {
showErrorPrompt = false;
isLoading = true;
const res = await fetch(
`${CONSTS.API}/api/${userApiKey}/addalertemailaddresses`,
Expand All @@ -62,12 +65,13 @@

if (res.ok) {
isLoading = false;
emailAddress = "";
reloadSharedEmailList();
} else {
throw new Error("Failed to load");
}
} else {
showErrorPromp = true;
showErrorPrompt = true;
}
};
</script>
Expand Down Expand Up @@ -104,11 +108,11 @@
class="appearance-none block w-full text-gray-700 border border-red-700
rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white
focus:border-red-800"
{type}
value={emailAddress}
type="text"
bind:value={emailAddress}
on:keydown={handleInput}
class:border-red-300={!emailAddress}
class:focus:border-red-500={!emailAddress}
on:input={handleInput}
placeholder="Email address"
/>
</div>
Expand All @@ -119,9 +123,9 @@
on:click={updateEmailAddress}>Add</button
>
</div>
{#if showErrorPromp}
<div class="text-red-700 font-sans">Invalid email input</div>
{/if}
</div>
<div class="{showErrorPrompt ? 'visible' : 'invisible'}">
<span class="text-red-700 font-sans">Invalid email input</span>
</div>
{#if sharedEmailAddresses.length > 0}
<div class="font-sans font-bold mt-5">
Expand Down
98 changes: 56 additions & 42 deletions ui/src/components/summaryitemcomponents/CardSummary.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import { createEventDispatcher } from "svelte";
import { printTimeDiff, convertSpecialCharUrl } from "../../utils/utils";
import SendAlertModal from "../misccomponents/SendAlertModal.svelte";
import { userSession$ } from "../../stores";
import { userSession$, isLoggedIn } from "../../stores";
import { CONSTS } from "../../utils/utils";
import { navigateTo } from "svelte-router-spa";
import { onMount } from "svelte";
import { onDestroy } from "svelte";

export let value;
export let isHtmlHintComp = false;
Expand All @@ -23,28 +23,33 @@
const perfThreshold = () => dispatch("perfThreshold");
const htmlHintThreshold = () => dispatch("htmlHintThreshold");

const emailAlertModal = () => {
userSession$.subscribe(async x => {
userApiKey = x.apiKey;
let fullUrl = convertSpecialCharUrl(value.url)
const res = await fetch(`${CONSTS.API}/api/getalertemailaddresses/${userApiKey}/${fullUrl}`);
sharedEmailAddresses = await res.json();
showShareAlert = true;
});
const emailAlertModal = async () => {
let fullUrl = convertSpecialCharUrl(value.url)
const res = await fetch(`${CONSTS.API}/api/getalertemailaddresses/${userApiKey}/${fullUrl}`);
sharedEmailAddresses = await res.json();
showShareAlert = true;
};

onMount(async () => {
// Check if scan has any previous scans
userSession$.subscribe(async x => {
if (x) {
userApiKey = x.apiKey;
let fullUrl = convertSpecialCharUrl(value.url)
const res = await fetch(`${CONSTS.API}/api/scanSummaryFromUrl/${userApiKey}/${fullUrl}`);
previousScans = await res.json();
}
});
})

const navigateToLatestScan = () => {
navigateTo(`/build/${previousScans[0].runId}`);
// Force reload page otherwise Svelte would not refresh the content
location.reload(true);
}

const getPreviousScans = async () => {
let fullUrl = convertSpecialCharUrl(value.url)
const res = await fetch(`${CONSTS.API}/api/scanSummaryFromUrl/${userApiKey}/${fullUrl}`);
previousScans = await res.json();
};

const userSubscriber = userSession$.subscribe(x => {
if (x) {
userApiKey = x.apiKey;
getPreviousScans();
}
});

onDestroy(userSubscriber);
</script>

<div class="grid grid-cols">
Expand All @@ -56,8 +61,7 @@
class="underline text-xl font-sans font-bold textdark hover:text-red-600">{value.url}</a>
</div>
<div class="text-center">
<span class="text-xl font-sans block lg:inline-block textgrey">Last
scanned:
<span class="text-xl font-sans block lg:inline-block textgrey"> Scanned on:
<strong>{format(new Date(value.buildDate), 'dd MMM yyyy')}</strong>
({formatDistanceToNow(new Date(value.buildDate), { addSuffix: true })} at {format(new Date(value.buildDate), 'hh:mmaaa')})
</span>
Expand All @@ -68,42 +72,52 @@
</span>
</div>
</div>
<div class="text-center mt-3">
<div class="text-center my-3">
{#if previousScans.length > 1}
{#if previousScans[0].runId !== value.runId}
<button
type="button"
class="bg-black hover:bg-gray-800 text-white font-semibold py-2 px-4 border rounded"
on:click={() => navigateToLatestScan()}
>
<i class="fas fa-rocket"></i> Go to latest scan
</button>
{/if}
<button
type="button"
class="bg-black hover:bg-gray-800 text-white font-semibold py-2 px-4 border rounded"
class="bg-white hover:bg-gray-800 hover:text-white font-semibold py-2 px-4 border rounded"
on:click={navigateTo(`/scanCompare/${value.partitionKey}/${convertSpecialCharUrl(value.url.slice(12))}/${value.buildDate}`)}
>
<i class="fas fa-code-compare"></i> Compare to latest scan
<i class="fas fa-code-compare"></i>
{previousScans[0].runId !== value.runId ? "Compare to latest scan" : "Compare to previous scan"}
</button>
{/if}
<button
on:click={emailAlertModal}
class="bg-black hover:bg-gray-800 text-white font-semibold py-2 px-4 border rounded"
>
<i class="fas fa-paper-plane"></i> Send Email Alerts
</button>
{#if value.buildDate && isLighthouseAudit}
<div class="text-center lg:text-right">
{#if $isLoggedIn}
<button
on:click={perfThreshold}
class="bgred hover:bg-red-800 text-white font-semibold py-2 px-4
border hover:border-transparent rounded">
<span>Set Performance Threshold For Next Scan</span>
on:click={emailAlertModal}
class="bg-white hover:bg-gray-800 hover:text-white font-semibold py-2 px-4 border rounded"
>
<i class="fas fa-paper-plane"></i> Send Email Alerts
</button>
</div>
{/if}
</div>
<div class="text-center lg:text-right">
{#if (value.buildDate && isHtmlHintComp)}
{#if (value.buildDate && isHtmlHintComp && $isLoggedIn)}
<button
on:click={htmlHintThreshold}
class="bgred hover:bg-red-800 text-white font-semibold py-2 px-4
border hover:border-transparent rounded">
<span>Enable/Disable Rules</span>
</button>
{/if}
{/if}
{#if value.buildDate && isLighthouseAudit && $isLoggedIn}
<button
on:click={perfThreshold}
class="bgred hover:bg-red-800 text-white font-semibold py-2 px-4
border hover:border-transparent rounded">
<span>Set Performance Threshold For Next Scan</span>
</button>
{/if}
</div>
</div>

Expand Down
11 changes: 3 additions & 8 deletions ui/src/containers/LinkReport.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import LoadingFlat from "../components/misccomponents/LoadingFlat.svelte";
import UpdateIgnoreUrl from "../components/misccomponents/UpdateIgnoreUrl.svelte";
import BuildDetailsSlot from "../components/detailslotcomponents/BuildDetailsSlot.svelte";
import { CONSTS } from "../utils/utils";

export let currentRoute;

Expand All @@ -25,16 +24,12 @@
if (currentRoute.namedParams.id) {
promise = new Promise(async (resolve) => {
const buildDetails = await getBuildDetails(currentRoute.namedParams.id);
const resp = await fetch(`${CONSTS.API}/api/unscannablelinks`);
const unscannableLinks = await resp.json();
resolve({ buildDetails, unscannableLinks });
resolve({ buildDetails });
});
} else {
promise = new Promise(async (resolve) => {
const buildDetails = await getLatestBuildDetails(currentRoute.namedParams.api, currentRoute.namedParams.url);
const resp = await fetch(`${CONSTS.API}/api/unscannablelinks`);
const unscannableLinks = await resp.json();
resolve({ buildDetails, unscannableLinks });
resolve({ buildDetails });
});
}

Expand Down Expand Up @@ -90,7 +85,7 @@
on:ignore={url => showIgnore(data.buildDetails.summary.url, url, $userSession$)}
builds={data.buildDetails ? data.buildDetails.brokenLinks : []}
{currentRoute}
unscannableLinks={data.unscannableLinks}
unscannableLinks={[]}
/>
</BuildDetailsSlot>
{:catch error}
Expand Down
5 changes: 5 additions & 0 deletions ui/src/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,8 @@ button:focus {
width: 100%;
height: 2px;
}

.modal {
transition: opacity 0.2s ease;
z-index: 3000;
}
Loading