OpenAuth_server/Frontend/src/pages/user/Pages/Security.svelte

150 lines
3.7 KiB
Svelte

<script lang="ts">
import {
type ContactInfo,
type Account,
Gender,
Token,
TwoFactor,
TFAType,
} from "@hibas123/openauth-internalapi";
import InternalAPI from "../../../helper/api";
import Loading from "../Loading.svelte";
import { onMount } from "svelte";
import {
Button,
Card,
Input,
Label,
Select,
Heading,
Spinner,
Helper,
Table,
TableHead,
TableHeadCell,
TableBody,
TableBodyRow,
TableBodyCell,
Accordion,
AccordionItem,
} from "flowbite-svelte";
let tokens: Token[];
let twofactors: TwoFactor[];
let error: string | undefined;
let loading = true;
async function load() {
loading = true;
try {
tokens = await InternalAPI.Security.GetTokens();
twofactors = await InternalAPI.Security.GetTwofactorOptions();
} catch (e) {
error = e.message;
} finally {
loading = false;
}
}
onMount(() => {
load();
});
async function revokeToken(id: string) {
try {
await InternalAPI.Security.RevokeToken(id);
await load();
} catch (e) {
error = e.message;
}
}
const typeToName = {
[TFAType.TOTP]: "TOTP",
[TFAType.WEBAUTHN]: "Security Key (WebAuthn)",
[TFAType.BACKUP_CODE]: "Backup-Code",
[TFAType.APP_ALLOW]: "App-Auth",
};
</script>
<Loading {loading} {error}>
<Card size="xl">
<Heading tag="h5">Active Sessions</Heading>
<hr class="mb-6" />
<Table>
<TableHead>
<TableHeadCell>Browser</TableHeadCell>
<TableHeadCell class="w-full">IP</TableHeadCell>
<TableHeadCell class="material-icons-outlined w-20"
>delete</TableHeadCell
>
</TableHead>
<TableBody>
{#each tokens as token}
<TableBodyRow
class="bg-yellow-50"
color={token.isthis ? "custom" : "default"}
>
<TableBodyCell>{token.browser}</TableBodyCell>
<TableBodyCell>{token.ip}</TableBodyCell>
<TableBodyCell>
<!-- svelte-ignore a11y-missing-attribute -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<a
class="font-medium text-red-600 hover:underline dark:text-blue-500"
on:click={() => revokeToken(token.id)}
>
Revoke
</a>
</TableBodyCell>
</TableBodyRow>
{/each}
</TableBody>
</Table>
</Card>
<Card size="xl" class="mt-4">
<Heading tag="h5">Change Password</Heading>
<hr class="mb-6" />
<div class="mb-6">
<Label for="oldPassword">Old Password</Label>
<Input type="password" id="oldPassword" />
</div>
<div class="mb-6">
<Label for="newPassword">New Password</Label>
<Input type="password" id="newPassword" />
</div>
<div class="mb-6">
<Label for="newPasswordRepeat">Repeat New Password</Label>
<Input type="password" id="newPasswordRepeat" />
</div>
<Button class="mt-4">Change Password</Button>
</Card>
<Card size="xl" class="mt-4">
<Heading tag="h5">Two Factor Auth</Heading>
<hr class="mb-6" />
<Accordion>
{#each twofactors as tfa}
<AccordionItem>
<span slot="header">{tfa.name ?? typeToName[tfa.tfatype]}</span>
</AccordionItem>
{/each}
</Accordion>
<Button class="mt-4">Add Option</Button>
</Card>
<!-- <Card size="xl" class="mt-4">
<Heading tag="h5">Delete Account</Heading>
<hr class="mb-6" />
<div class="mb-6">
<Label for="password">Password</Label>
<Input type="password" id="password" />
</div>
<Button class="mt-4">Delete Account</Button>
</Card> -->
</Loading>