Content-Length: 646755 | pFad | https://github.com/sebadob/rauthy/commit/c76c20871a303cbf6cfc587483113cd544d65424

37 Merge pull request #104 from sebadob/ui-ip-blacklist-component · sebadob/rauthy@c76c208 · GitHub
Skip to content

Commit

Permalink
Merge pull request #104 from sebadob/ui-ip-blacklist-component
Browse files Browse the repository at this point in the history
UI ip blacklist component
  • Loading branch information
sebadob authored Oct 27, 2023
2 parents aea7794 + 12c43a2 commit c76c208
Show file tree
Hide file tree
Showing 21 changed files with 555 additions and 111 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ edition = "2021"
authors = ["Sebastian Dobe <sebastiandobe@mailbox.org>"]
license = "AGPLv3"

[profile.dev]
panic = "abort"

[profile.release]
codegen-units = 1
lto = true
Expand Down
225 changes: 202 additions & 23 deletions frontend/src/components/admin/blacklist/Blacklist.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,200 @@
import {onMount} from "svelte";
import OrderSearchBar from "$lib/search/OrderSearchBar.svelte";
import Pagination from "$lib/Pagination.svelte";
import {deleteBlacklistedIp, getBlacklist, postBlacklist} from "../../../utils/dataFetchingAdmin.js";
import Button from "$lib/Button.svelte";
import {slide} from "svelte/transition";
import Input from "$lib/inputs/Input.svelte";
import {REGEX_IP_V4} from "../../../utils/constants.js";
import * as yup from "yup";
import {extractFormErrors, formatDateFromTs, formatUtcTsFromDateInput} from "../../../utils/helpers.js";
import IconStop from "$lib/icons/IconStop.svelte";
import Tooltip from "$lib/Tooltip.svelte";
let err = '';
let errSave = '';
let blacklist = [];
let resBlacklist = [];
let resBlacklistPaginated = [];
let refresh;
let showInputs = false;
let formValues = {
ip: '',
exp: new Date().toLocaleString(),
}
let formErrors = {};
const schema = yup.object().shape({
ip: yup.string()
.required(true)
.matches(REGEX_IP_V4, 'Invalid IPv4'),
});
const minDate = new Date().toISOString().split('.')[0];
const searchOptions = [
{
label: 'IP',
callback: (item, search) => item.ip.includes(search),
},
];
let orderOptions = [
{
label: 'IP',
callback: (a, b) => a.ip.localeCompare(b.ip),
},
];
$: if (showInputs) {
errSave = '';
formValues.exp = new Date().toISOString().split('.')[0];
}
onMount(() => {
fetchBlacklist();
});
async function fetchBlacklist() {
// let res = await getScopes();
// let body = await res.json();
// if (res.ok) {
// scopes = [...body];
// } else {
// err = body.message;
// }
let res = await getBlacklist();
let body = await res.json();
if (res.ok) {
blacklist = body.ips;
} else {
err = body.message;
}
}
function onSave() {
fetchBlacklist();
async function onSubmit() {
errSave = '';
const isValid = await validateForm();
if (!isValid) {
return;
}
let exp = formatUtcTsFromDateInput(formValues.exp);
if (!exp) {
errSave = 'Invalid Date Input: User Expires';
return;
}
let data = {
ip: formValues.ip,
exp,
};
let res = await postBlacklist(data);
if (res.ok) {
showInputs = false;
formValues.ip = '';
await fetchBlacklist();
} else {
let body = await res.json();
errSave = body.message;
}
}
async function deleteIp(ip) {
let res = await deleteBlacklistedIp(ip);
if (res.ok) {
await fetchBlacklist();
}
}
async function validateForm() {
try {
await schema.validate(formValues, {abortEarly: false});
formErrors = {};
return true;
} catch (err) {
formErrors = extractFormErrors(err);
return false;
}
}
</script>

{err}

<div class="content">
<OrderSearchBar
items={blacklist}
bind:resItems={resBlacklist}
searchOptions={searchOptions}
/>
<div class="top">
<OrderSearchBar
items={blacklist}
bind:resItems={resBlacklist}
searchOptions={searchOptions}
orderOptions={orderOptions}
/>

<!-- <ScopeTileAddNew onSave={onSave}/>-->
<div class="addNew">
<Button on:click={() => showInputs = !showInputs} level={3}>BLACKLIST IP</Button>
</div>
</div>
{#if showInputs}
<div transition:slide class="addNewInputs">
<Input
width="9.5rem"
bind:value={formValues.ip}
bind:error={formErrors.ip}
autocomplete="off"
placeholder="IP"
>
IP
</Input>
<Input
type="datetime-local"
step="60"
width="18rem"
bind:value={formValues.exp}
min={minDate}
max="2099-01-01T00:00"
>
EXPIRES
</Input>
<div class="saveBtn">
<Button on:click={onSubmit} level={1}>SAVE</Button>
</div>
<div class="err">
{errSave}
</div>
</div>
{/if}

<div id="blacklist">
{#each resBlacklistPaginated as entry (entry.ip)}
{#if blacklist.length === 0}
<div>
{entry.ip}
<!-- <ScopeTile bind:attrs bind:scope onSave={onSave}/>-->
No blacklisted IPs
</div>
{/each}
{:else}
{#each resBlacklistPaginated as entry (entry.ip)}
<div class="blacklisted">
<div class="ip">
{entry.ip}
</div>
<div class="exp">
{formatDateFromTs(entry.exp)}
</div>
<Tooltip text="Delete IP">
<div
role="button"
tabindex="0"
class="delete"
on:click={() => deleteIp(entry.ip)}
on:keypress={() => deleteIp(entry.ip)}
>
<IconStop color="var(--col-err)"/>
</div>
</Tooltip>
</div>
{/each}
{/if}
</div>

<Pagination
bind:items={resBlacklist}
bind:resItems={resBlacklistPaginated}
/>
{#if blacklist.length > 0}
<Pagination
bind:items={resBlacklist}
bind:resItems={resBlacklistPaginated}
/>
{/if}

<div style="height: 20px"></div>
</div>
Expand All @@ -68,4 +204,47 @@
#blacklist div:nth-of-type(2n + 1) {
background: linear-gradient(90deg, var(--col-ghigh) 35rem, var(--col-bg) 50rem);
}
.addNew {
margin-bottom: .6rem;
}
.addNewInputs {
margin: 0 0 1rem -.25rem;
display: flex;
flex-direction: row;
align-items: center;
}
.blacklisted {
display: flex;
flex-direction: row;
margin: .25rem .5rem;
}
.delete {
cursor: pointer;
}
.err {
color: var(--col-err);
}
.exp {
width: 10rem;
}
.ip {
width: 9rem;
}
.saveBtn {
margin-top: .25rem;
}
.top {
display: inline-flex;
align-items: center;
gap: 1rem;
}
</style>
53 changes: 53 additions & 0 deletions frontend/src/components/admin/blacklist/BlacklistNew.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script>
import Button from "$lib/Button.svelte";
import Input from "$lib/inputs/Input.svelte";
export let onSave = () => {};
let err = '';
let showInputs = true;
let formValues = {
ip: '',
exp: new Date(),
}
let formErrors = {};
</script>


{#if showInputs}
<div class="inpt">
<Input
width="9.5rem"
bind:value={formValues.ip}
bind:error={formErrors.ip}
autocomplete="off"
placeholder="IP"
>
IP
</Input>
<Input
type="datetime-local"
step="60"
width="18rem"
bind:value={formValues.exp}
min={new Date().toISOString().split('.')[0]}
max="2099-01-01T00:00"
>
EXPIRES
</Input>
</div>
{:else}
<Button on:click={() => showInputs = true}>BLACKLIST IP</Button>
{/if}

{err}

<style>
.inpt {
display: inline-flex;
margin-top: -1rem;
border: 1px solid red;
}
</style>
19 changes: 15 additions & 4 deletions frontend/src/lib/search/OrderSearchBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,30 @@

<div class="container">
<div>
<OrderBy items={searchItems} bind:resItems={resItems} options={orderOptions} firstDirReverse={firstDirReverse}/>
<OrderBy
items={searchItems}
bind:resItems={resItems}
options={orderOptions}
firstDirReverse={firstDirReverse}
/>
</div>

<div class="divider"></div>
{#if orderOptions.length > 0}
<div class="divider"></div>
{/if}

<div>
<SearchBar items={items} bind:resItems={searchItems} options={searchOptions}/>
<SearchBar
items={items}
bind:resItems={searchItems}
options={searchOptions}
/>
</div>
</div>

<style>
.divider {
margin: 0 17px;
margin: 0 1rem;
}
.container {
Expand Down
10 changes: 0 additions & 10 deletions frontend/src/utils/auth.js

This file was deleted.

3 changes: 1 addition & 2 deletions frontend/src/utils/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { base } from "$app/paths";

export const PKCE_VERIFIER = 'pkce_verifier';
export const CSRF_TOKEN = 'csrf_token';
export const ACCESS_TOKEN = 'access_token';
Expand All @@ -21,6 +19,7 @@ export const REGEX_CLIENT_ID = /^[a-zA-Z0-9\-_/]{2,128}$/gm;
export const REGEX_CLIENT_NAME = /^[a-zA-Z0-9À-ÿ\-\s]{0,128}$/gm;
export const REGEX_ROLES = /^[a-z0-9\-_/]{2,128}$/gm;
export const REGEX_URI = /^[a-zA-Z0-9,.:/_\-&?=~#!$'()*+%]+$/gm;
export const REGEX_IP_V4 = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm;

// https://gist.github.com/olmokramer/82ccce673f86db7cda5e
export const REGEX_CSS_COLOR = /(#(?:[0-9a-f]{2}){2,4}$|(#[0-9a-f]{3}$)|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\)$|black$|silver$|gray$|whitesmoke$|maroon$|red$|purple$|fuchsia$|green$|lime$|olivedrab$|yellow$|navy$|blue$|teal$|aquamarine$|orange$|aliceblue$|antiquewhite$|aqua$|azure$|beige$|bisque$|blanchedalmond$|blueviolet$|brown$|burlywood$|cadetblue$|chartreuse$|chocolate$|coral$|cornflowerblue$|cornsilk$|crimson$|currentcolor$|darkblue$|darkcyan$|darkgoldenrod$|darkgray$|darkgreen$|darkgrey$|darkkhaki$|darkmagenta$|darkolivegreen$|darkorange$|darkorchid$|darkred$|darksalmon$|darkseagreen$|darkslateblue$|darkslategray$|darkslategrey$|darkturquoise$|darkviolet$|deeppink$|deepskyblue$|dimgray$|dimgrey$|dodgerblue$|firebrick$|floralwhite$|forestgreen$|gainsboro$|ghostwhite$|goldenrod$|gold$|greenyellow$|grey$|honeydew$|hotpink$|indianred$|indigo$|ivory$|khaki$|lavenderblush$|lavender$|lawngreen$|lemonchiffon$|lightblue$|lightcoral$|lightcyan$|lightgoldenrodyellow$|lightgray$|lightgreen$|lightgrey$|lightpink$|lightsalmon$|lightseagreen$|lightskyblue$|lightslategray$|lightslategrey$|lightsteelblue$|lightyellow$|limegreen$|linen$|mediumaquamarine$|mediumblue$|mediumorchid$|mediumpurple$|mediumseagreen$|mediumslateblue$|mediumspringgreen$|mediumturquoise$|mediumvioletred$|midnightblue$|mintcream$|mistyrose$|moccasin$|navajowhite$|oldlace$|olive$|orangered$|orchid$|palegoldenrod$|palegreen$|paleturquoise$|palevioletred$|papayawhip$|peachpuff$|peru$|pink$|plum$|powderblue$|rosybrown$|royalblue$|saddlebrown$|salmon$|sandybrown$|seagreen$|seashell$|sienna$|skyblue$|slateblue$|slategray$|slategrey$|snow$|springgreen$|steelblue$|tan$|thistle$|tomato$|transparent$|turquoise$|violet$|wheat$|white$|yellowgreen$|rebeccapurple$)/i;
Expand Down
Loading

0 comments on commit c76c208

Please sign in to comment.








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/sebadob/rauthy/commit/c76c20871a303cbf6cfc587483113cd544d65424

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy