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

Add help and allow editing for ignored URLs #686

Merged
merged 4 commits into from
Oct 6, 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
3 changes: 2 additions & 1 deletion ui/src/components/linkauditorcomponents/DetailsByDest.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { createEventDispatcher } from "svelte";
import LoadingCircle from "../misccomponents/LoadingCircle.svelte";
import Toastr from "../misccomponents/Toastr.svelte";
import { tooltip } from '../misccomponents/tooltip';
const dispatch = createEventDispatcher();

export let builds = [];
Expand Down Expand Up @@ -89,7 +90,7 @@
{#if !hiddenRows[url]}
<div class="font-bold textgrey ml-2">
<i class="fas fa-ban"></i>
Ignore:
<span title="Ignore URL in future scans" use:tooltip>Ignore: </span>
{#if loadingChecks[url]}
<LoadingCircle />
{:else}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import Icon from "../misccomponents/Icon.svelte";
import LoadingCircle from "../misccomponents/LoadingCircle.svelte";
import Toastr from "../misccomponents/Toastr.svelte";
import { tooltip } from '../misccomponents/tooltip';
export let builds = [];
const dispatch = createEventDispatcher();
const ignore = url => dispatch("ignore", url);
Expand Down Expand Up @@ -95,7 +96,7 @@
<th class="w-2/12 px-2 py-2">Anchor Text</th>
<th class="w-1/12 px-2 py-2 text-right">Status</th>
<th class="w-1/12 px-2 py-2 text-right">Days Unfixed</th>
<th class="hidden md:table-cell w-1/12 px-2 py-2">Ignore</th>
<th class="hidden md:table-cell w-1/12 px-2 py-2" title="Ignore URL in future scans" use:tooltip>Ignore</th>
</tr>
</thead>
<tbody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import Icon from "../misccomponents/Icon.svelte";
import LoadingCircle from "../misccomponents/LoadingCircle.svelte";
import Toastr from "../misccomponents/Toastr.svelte";
import { tooltip } from '../misccomponents/tooltip';
export let builds = [];
const dispatch = createEventDispatcher();
const ignore = url => dispatch("ignore", url);
Expand Down Expand Up @@ -93,7 +94,7 @@
<th class="w-1/12 px-2 py-2 text-right">Status</th>
<th class="hidden md:table-cell w-2/12 px-2 py-2 text-right">Message</th>
<th class="hidden md:table-cell w-1/12 px-2 py-2 text-right">Days Unfixed</th>
<th class="hidden md:table-cell w-1/12 px-2 py-2">Ignore</th>
<th class="hidden md:table-cell w-1/12 px-2 py-2" title="Ignore URL in future scans" use:tooltip>Ignore</th>
</tr>
</thead>
<tbody>
Expand Down Expand Up @@ -122,7 +123,7 @@
{#if loadingChecks[val.dst]}
<LoadingCircle />
{:else}
<input type="checkbox" on:click={() => toggleIgnore(val.dst)} bind:checked={ignoredChecks[val.dst]} />
<input type="checkbox" on:click={() => toggleIgnore(val.dst)} bind:checked={ignoredChecks[val.dst]} />
{/if}
</td>
</tr>
Expand Down
29 changes: 19 additions & 10 deletions ui/src/components/misccomponents/IgnoreLists.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import LoadingCircle from "./LoadingCircle.svelte";
import Icon from "./Icon.svelte";
import { userSession$, deleteIgnoreUrl } from "../../stores";
import { createEventDispatcher } from 'svelte';

export let builds = [];

const dispatch = createEventDispatcher();

$: numberOfIgnored = builds.length;

let addedFailedToast;
Expand Down Expand Up @@ -76,16 +79,22 @@
{#if loading && val.urlToIgnore === deleteUrl}
<LoadingCircle />
{:else}
<a
href={'#'}
on:click={() => deleteIgnore(val, $userSession$)}>
<Icon>
<path
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0
01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0
00-1 1v3M4 7h16" />
</Icon>
</a>
<div class="flex gap-2">
<a href={null} on:click={() => dispatch('editIgnore', val)}>
<i class="fa-solid fa-pen-to-square fa-lg cursor-pointer"></i>
</a>
<a
href={null}
class="cursor-pointer"
on:click={() => deleteIgnore(val, $userSession$)}>
<Icon>
<path
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0
01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0
00-1 1v3M4 7h16" />
</Icon>
</a>
</div>
{/if}
</td>
</tr>
Expand Down
6 changes: 3 additions & 3 deletions ui/src/components/misccomponents/Modal.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import LoadingCirle from "./LoadingCircle.svelte";
import LoadingCircle from "./LoadingCircle.svelte";
import { createEventDispatcher } from "svelte";
export let show;
export let header;
Expand Down Expand Up @@ -50,7 +50,7 @@
class="modal-content py-4 text-left px-6"
class:fullheight={full === true}>
<!--Title-->
<div class="flex justify-between items-center">
<div class="flex justify-between items-center mb-4">
<p class="text-2xl font-bold">{header}</p>
</div>

Expand All @@ -69,7 +69,7 @@
border hover:border-transparent rounded">
{mainAction}
{#if loading}
<LoadingCirle />
<LoadingCircle />
{/if}
</button>
{/if}
Expand Down
2 changes: 2 additions & 0 deletions ui/src/components/misccomponents/TextField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
export let autocomplete = "";
export let required = true;
export let placeholder = "";
export let disabled = false;

const enterKey = key => key.code === "Enter" && dispatch("enterKey");
const handleInput = e => {
Expand Down Expand Up @@ -117,6 +118,7 @@
{placeholder}
{autocomplete}
{value}
{disabled}
class:border-red-300={(required && !value) || errorMsg}
class:focus:border-red-500={(required && !value) || errorMsg}
on:input={handleInput}
Expand Down
69 changes: 51 additions & 18 deletions ui/src/components/misccomponents/UpdateIgnoreUrl.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
export let scanUrl;
export let show;
export let user;
export let duration;
export let editing = false;

let ignoredUrls = [];

Expand Down Expand Up @@ -52,8 +54,12 @@
};

$: if (show) {
ignoreOn = "all";
ignoreDuration = 3;
if (scanUrl === "all") {
scanUrl = null;
}

ignoreOn = editing && scanUrl ? scanUrl : "all";
ignoreDuration = duration || 3;
}
</script>

Expand All @@ -62,19 +68,38 @@
transition: background 0.2s, transform 0.2s;
}

input[type="radio"] + label span:hover,
input[type="radio"] + label:hover span {
input[type="radio"] + label:not(.disabled) span:hover,
input[type="radio"] + label:hover:not(.disabled) span {
transform: scale(1.2);
cursor: pointer;
}

input[type="radio"] + label:hover:not(.disabled) {
cursor: pointer;
}

input[type="radio"]:checked + label span {
background-color: black;
box-shadow: 0px 0px 0px 2px white inset;
}

input[type="radio"]:checked + label.disabled span {
background-color: #ccc;
border-color: #ccc;
}

input[type="radio"] + label.disabled span {
background-color: white;
border-color: #ccc;
}

input[type="radio"]:checked + label {
color: #414141;
}

input[type="radio"] + label.disabled {
color: #ccc;
}
</style>

<Modal
Expand All @@ -84,48 +109,56 @@
mainAction="Save"
on:action={updateIgnore}
on:dismiss={dismiss}>
<div class="ml-5">
<TextField bind:value={url} placeholder="" label="URL" type="text" />
<div class="text-sm text-grey-400 py-3">
<div>
<div class="text-md text-grey-400 mb-4">
Ignoring a URL here will prevent CodeAuditor from scanning it for future scans. A URL can be ignored
for a specified period of time, for either all sites or just the current site.
</div>
<TextField bind:value={url} disabled={editing} placeholder="" label="URL" type="text" />
<div class="text-sm text-grey-400 mb-2">
You can use glob matching, e.g. https://twitter.com/** will match with
https://twitter.com/users/john or https://twitter.com/login
</div>
<div class="text-sm text-grey-400">
<div class="text-sm text-grey-400 mb-4">
To see more supported Glob patterns, check out
<a class="link hover:text-red-600" href="https://github.com/SSWConsulting/SSW.CodeAuditor/wiki/SSW-CodeAuditor-Knowledge-Base-(KB)#supported-glob-patterns-when-adding-ignored-urls">CodeAuditor KB</a>
</div>
<label for="radio1" class="block uppercase text-xs mb-2 py-2">For</label>
<ul>
<label for="radio1" class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2">For</label>
<ul class="mb-4">
<li class="pb-3">
<div class="flex items-center mr-4 mb-4">
<div class="flex items-center ml-2 mr-4">
<input
id="radio1"
type="radio"
class="hidden"
value={'all'}
bind:group={ignoreOn} />
bind:group={ignoreOn}
disabled={editing}
/>

<label for="radio1" class="flex items-center cursor-pointer">
<label for="radio1" class:disabled={editing} class="flex items-center">
<span
class="w-5 h-5 inline-block mr-2 rounded-full border-black
border-solid border flex-no-shrink" />
border-solid border shrink-0" />
All new builds
</label>
</div>
</li>
{#if scanUrl}
<li>
<div class="flex items-center mr-4 mb-4">
<div class="flex items-center ml-2 mr-4">
<input
type="radio"
class="hidden"
id="radio2"
bind:group={ignoreOn}
value={url} />
<label for="radio2" class="flex items-center cursor-pointer">
value={url}
disabled={editing}
/>
<label for="radio2" class:disabled={editing} class="flex items-center">
<span
class="w-5 h-5 inline-block mr-2 rounded-full border-black
border-solid border flex-no-shrink" />
border-solid border shrink-0" />
Only when {scanUrl} is scanned
</label>
</div>
Expand Down
62 changes: 43 additions & 19 deletions ui/src/components/misccomponents/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,55 @@ import Tooltip from './TooltipFromAction.svelte';

export function tooltip(element) {
let title;
let x;
let y;
let tooltipComponent;
let timer;
let delay = 500;

function mouseOver(event) {
// NOTE: remove the `title` attribute, to prevent showing the default browser tooltip
// remember to set it back on `mouseleave`
title = element.getAttribute('title');
element.removeAttribute('title');
x = event.pageX;
y = event.pageY;
timer = setTimeout(() => {
if (!tooltipComponent) {
// NOTE: remove the `title` attribute, to prevent showing the default browser tooltip
// remember to set it back on `mouseleave`
title = element.getAttribute('title');
element.removeAttribute('title');

tooltipComponent = new Tooltip({
props: {
title: title,
x: event.pageX,
y: event.pageY,
},
target: document.body,
});
tooltipComponent = new Tooltip({
props: {
title: title,
x,
y,
},
target: document.body,
});
}
}, delay);
}
function mouseMove(event) {
tooltipComponent.$set({
x: event.pageX,
y: event.pageY,
})
x = event.pageX;
y = event.pageY;
tooltipComponent && tooltipComponent.$set({
x,
y,
});
}
function mouseLeave() {
tooltipComponent.$destroy();
// NOTE: restore the `title` attribute
element.setAttribute('title', title);
timer && clearTimeout(timer);
destroy();
if (title) {
// NOTE: restore the `title` attribute
element.setAttribute('title', title);
}
}

function destroy() {
if (tooltipComponent) {
tooltipComponent.$destroy();
tooltipComponent = null;
}
}

element.addEventListener('mouseover', mouseOver);
Expand All @@ -39,6 +62,7 @@ export function tooltip(element) {
element.removeEventListener('mouseover', mouseOver);
element.removeEventListener('mouseleave', mouseLeave);
element.removeEventListener('mousemove', mouseMove);
destroy();
}
}
}
Loading
Loading