150 lines
3.7 KiB
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>
|