feat: offer fediverse login on login page
This commit is contained in:
parent
cf424d3ae4
commit
c6484ef066
|
@ -1,7 +1,53 @@
|
|||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import type { APIError } from "$lib/api/entities";
|
||||
import { apiFetch } from "$lib/api/fetch";
|
||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||
import { userStore } from "$lib/store";
|
||||
import { addToast } from "$lib/toast";
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
Button,
|
||||
Icon,
|
||||
Input,
|
||||
ListGroup,
|
||||
ListGroupItem,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
} from "sveltestrap";
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
let error: APIError | null = null;
|
||||
let instance = "";
|
||||
let fediDisabled = false;
|
||||
|
||||
let modalOpen = false;
|
||||
let toggleModal = () => (modalOpen = !modalOpen);
|
||||
|
||||
onMount(() => {
|
||||
if ($userStore) {
|
||||
addToast({ header: "Error", body: "You are already logged in." });
|
||||
goto("/");
|
||||
}
|
||||
});
|
||||
|
||||
const fediLogin = async () => {
|
||||
fediDisabled = true;
|
||||
try {
|
||||
const resp = await apiFetch<{ url: string }>(
|
||||
`/auth/urls/fediverse?instance=${encodeURIComponent(instance)}`,
|
||||
{},
|
||||
);
|
||||
window.location.assign(resp.url);
|
||||
} catch (e) {
|
||||
error = e as APIError;
|
||||
} finally {
|
||||
fediDisabled = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
@ -11,13 +57,35 @@
|
|||
<div class="container">
|
||||
<h1>Log in or sign up</h1>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="col-md-4">
|
||||
<ListGroup>
|
||||
<ListGroupItem tag="button" on:click={toggleModal}>
|
||||
<Icon name="mastodon" /> Log in with Fediverse
|
||||
</ListGroupItem>
|
||||
<ListGroupItem tag="a" href={data.discord}>
|
||||
<Icon name="discord" /> Log in with Discord
|
||||
</ListGroupItem>
|
||||
</ListGroup>
|
||||
<Modal header="Pick an instance" isOpen={modalOpen} toggle={toggleModal}>
|
||||
<ModalBody>
|
||||
<Input placeholder="Instance (e.g. mastodon.social)" bind:value={instance} />
|
||||
{#if error}
|
||||
<div class="mt-2">
|
||||
<ErrorAlert {error} />
|
||||
</div>
|
||||
{/if}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="primary" disabled={fediDisabled || instance === ""} on:click={fediLogin}
|
||||
>Fediverse login</Button
|
||||
>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<p>
|
||||
<a class="btn btn-primary" href={data.discord} role="button">Log in with Discord</a>
|
||||
<b>Choose an authentication provider to get started.</b> You can add more providers later.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import { userStore } from "$lib/store";
|
||||
import type { PageData } from "./$types";
|
||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||
import { addToast } from "$lib/toast";
|
||||
|
||||
interface SignupResponse {
|
||||
user: MeUser;
|
||||
|
@ -21,6 +22,7 @@
|
|||
localStorage.setItem("pronouns-token", data.token);
|
||||
localStorage.setItem("pronouns-user", JSON.stringify(data.user));
|
||||
userStore.set(data.user);
|
||||
addToast({ header: "Logged in", body: "Successfully logged in!" });
|
||||
goto("/");
|
||||
}
|
||||
});
|
||||
|
@ -42,6 +44,7 @@
|
|||
localStorage.setItem("pronouns-token", resp.token);
|
||||
localStorage.setItem("pronouns-user", JSON.stringify(resp.user));
|
||||
userStore.set(resp.user);
|
||||
addToast({ header: "Welcome!", body: "Signed up successfully!" });
|
||||
goto("/");
|
||||
} catch (e) {
|
||||
data.error = e as APIError;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
const MAX_AVATAR_BYTES = 1_000_000;
|
||||
|
||||
if (!$userStore) {
|
||||
addToast({ header: "Error", body: "You are not logged in." });
|
||||
goto("/");
|
||||
}
|
||||
|
||||
|
@ -55,16 +56,9 @@
|
|||
|
||||
let modified = false;
|
||||
|
||||
$: redirectIfNoAuth($userStore);
|
||||
$: modified = isModified(bio, display_name, links, names, pronouns, fields, avatar);
|
||||
$: getAvatar(avatar_files).then((b64) => (avatar = b64));
|
||||
|
||||
const redirectIfNoAuth = (user: MeUser | null) => {
|
||||
if (!user) {
|
||||
goto("/");
|
||||
}
|
||||
};
|
||||
|
||||
const isModified = (
|
||||
bio: string,
|
||||
display_name: string,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { Button, ListGroup, ListGroupItem, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
||||
import { userStore } from "$lib/store";
|
||||
import { goto } from "$app/navigation";
|
||||
import { addToast } from "$lib/toast";
|
||||
|
||||
export let data: LayoutData;
|
||||
|
||||
|
@ -15,6 +16,8 @@
|
|||
localStorage.removeItem("pronouns-token");
|
||||
localStorage.removeItem("pronouns-user");
|
||||
toggle();
|
||||
|
||||
addToast({ header: "Logged out", body: "Successfully logged out!" });
|
||||
goto("/");
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
||||
import { userStore } from "$lib/store";
|
||||
import { addToast } from "$lib/toast";
|
||||
import { Button, Icon, Modal, ModalBody, ModalFooter, ModalHeader, Table } from "sveltestrap";
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
|
@ -39,6 +40,7 @@
|
|||
localStorage.removeItem("pronouns-token");
|
||||
localStorage.removeItem("pronouns-user");
|
||||
toggleDeleteOpen();
|
||||
addToast({ header: "Deleted account", body: "Your account is now pending deletion." });
|
||||
goto("/");
|
||||
} catch (e) {
|
||||
deleteUsername = "";
|
||||
|
|
Loading…
Reference in New Issue