forked from mirrors/pronouns.cc
feat: offer fediverse login on login page
This commit is contained in:
parent
cf424d3ae4
commit
c6484ef066
5 changed files with 83 additions and 13 deletions
|
@ -1,7 +1,53 @@
|
||||||
<script lang="ts">
|
<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";
|
import type { PageData } from "./$types";
|
||||||
|
|
||||||
export let data: PageData;
|
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>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@ -11,13 +57,35 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Log in or sign up</h1>
|
<h1>Log in or sign up</h1>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col-md-4">
|
||||||
<p>
|
<ListGroup>
|
||||||
<a class="btn btn-primary" href={data.discord} role="button">Log in with Discord</a>
|
<ListGroupItem tag="button" on:click={toggleModal}>
|
||||||
</p>
|
<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>
|
</div>
|
||||||
<div class="col">
|
{/if}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button color="primary" disabled={fediDisabled || instance === ""} on:click={fediLogin}
|
||||||
|
>Fediverse login</Button
|
||||||
|
>
|
||||||
|
</ModalFooter>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
<div class="col-md">
|
||||||
|
<p>
|
||||||
|
<b>Choose an authentication provider to get started.</b> You can add more providers later.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import { userStore } from "$lib/store";
|
import { userStore } from "$lib/store";
|
||||||
import type { PageData } from "./$types";
|
import type { PageData } from "./$types";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
|
import { addToast } from "$lib/toast";
|
||||||
|
|
||||||
interface SignupResponse {
|
interface SignupResponse {
|
||||||
user: MeUser;
|
user: MeUser;
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
localStorage.setItem("pronouns-token", data.token);
|
localStorage.setItem("pronouns-token", data.token);
|
||||||
localStorage.setItem("pronouns-user", JSON.stringify(data.user));
|
localStorage.setItem("pronouns-user", JSON.stringify(data.user));
|
||||||
userStore.set(data.user);
|
userStore.set(data.user);
|
||||||
|
addToast({ header: "Logged in", body: "Successfully logged in!" });
|
||||||
goto("/");
|
goto("/");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -42,6 +44,7 @@
|
||||||
localStorage.setItem("pronouns-token", resp.token);
|
localStorage.setItem("pronouns-token", resp.token);
|
||||||
localStorage.setItem("pronouns-user", JSON.stringify(resp.user));
|
localStorage.setItem("pronouns-user", JSON.stringify(resp.user));
|
||||||
userStore.set(resp.user);
|
userStore.set(resp.user);
|
||||||
|
addToast({ header: "Welcome!", body: "Signed up successfully!" });
|
||||||
goto("/");
|
goto("/");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
data.error = e as APIError;
|
data.error = e as APIError;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
const MAX_AVATAR_BYTES = 1_000_000;
|
const MAX_AVATAR_BYTES = 1_000_000;
|
||||||
|
|
||||||
if (!$userStore) {
|
if (!$userStore) {
|
||||||
|
addToast({ header: "Error", body: "You are not logged in." });
|
||||||
goto("/");
|
goto("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,16 +56,9 @@
|
||||||
|
|
||||||
let modified = false;
|
let modified = false;
|
||||||
|
|
||||||
$: redirectIfNoAuth($userStore);
|
|
||||||
$: modified = isModified(bio, display_name, links, names, pronouns, fields, avatar);
|
$: modified = isModified(bio, display_name, links, names, pronouns, fields, avatar);
|
||||||
$: getAvatar(avatar_files).then((b64) => (avatar = b64));
|
$: getAvatar(avatar_files).then((b64) => (avatar = b64));
|
||||||
|
|
||||||
const redirectIfNoAuth = (user: MeUser | null) => {
|
|
||||||
if (!user) {
|
|
||||||
goto("/");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isModified = (
|
const isModified = (
|
||||||
bio: string,
|
bio: string,
|
||||||
display_name: string,
|
display_name: string,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { Button, ListGroup, ListGroupItem, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
import { Button, ListGroup, ListGroupItem, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
||||||
import { userStore } from "$lib/store";
|
import { userStore } from "$lib/store";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
|
import { addToast } from "$lib/toast";
|
||||||
|
|
||||||
export let data: LayoutData;
|
export let data: LayoutData;
|
||||||
|
|
||||||
|
@ -15,6 +16,8 @@
|
||||||
localStorage.removeItem("pronouns-token");
|
localStorage.removeItem("pronouns-token");
|
||||||
localStorage.removeItem("pronouns-user");
|
localStorage.removeItem("pronouns-user");
|
||||||
toggle();
|
toggle();
|
||||||
|
|
||||||
|
addToast({ header: "Logged out", body: "Successfully logged out!" });
|
||||||
goto("/");
|
goto("/");
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
||||||
import { userStore } from "$lib/store";
|
import { userStore } from "$lib/store";
|
||||||
|
import { addToast } from "$lib/toast";
|
||||||
import { Button, Icon, Modal, ModalBody, ModalFooter, ModalHeader, Table } from "sveltestrap";
|
import { Button, Icon, Modal, ModalBody, ModalFooter, ModalHeader, Table } from "sveltestrap";
|
||||||
import type { PageData } from "./$types";
|
import type { PageData } from "./$types";
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
localStorage.removeItem("pronouns-token");
|
localStorage.removeItem("pronouns-token");
|
||||||
localStorage.removeItem("pronouns-user");
|
localStorage.removeItem("pronouns-user");
|
||||||
toggleDeleteOpen();
|
toggleDeleteOpen();
|
||||||
|
addToast({ header: "Deleted account", body: "Your account is now pending deletion." });
|
||||||
goto("/");
|
goto("/");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
deleteUsername = "";
|
deleteUsername = "";
|
||||||
|
|
Loading…
Reference in a new issue