feat(frontend): discord registration/login/linking

also moves the registration form found on the mastodon callback page
into a component so we're not repeating the same code for every auth method
This commit is contained in:
sam 2024-11-28 21:35:55 +01:00
parent 4780be3019
commit de733a0682
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
19 changed files with 545 additions and 212 deletions

View file

@ -0,0 +1,24 @@
<script lang="ts">
import type { AuthMethod } from "$api/models";
import AuthMethodRow from "./AuthMethodRow.svelte";
type Props = {
methods: AuthMethod[];
canRemove: boolean;
max: number;
buttonLink: string;
buttonText: string;
};
let { methods, canRemove, max, buttonLink, buttonText }: Props = $props();
</script>
{#if methods.length > 0}
<div class="list-group mb-3">
{#each methods as method (method.id)}
<AuthMethodRow {method} {canRemove} />
{/each}
</div>
{/if}
{#if methods.length < max}
<a class="btn btn-primary mb-3" href={buttonLink}>{buttonText}</a>
{/if}

View file

@ -0,0 +1,26 @@
<script lang="ts">
import { t } from "$lib/i18n";
import type { AuthMethod } from "$api/models";
type Props = { method: AuthMethod; canRemove: boolean };
let { method, canRemove }: Props = $props();
let name = $derived(
method.type === "EMAIL" ? method.remote_id : (method.remote_username ?? method.remote_id),
);
let showId = $derived(method.type !== "FEDIVERSE");
</script>
<div class="list-group-item">
<div class="row">
<div class="col">
{name}
{#if showId}({method.remote_id}){/if}
</div>
{#if canRemove}
<div class="col text-end">
<a href="/settings/auth/remove-method/{method.id}">{$t("settings.auth-remove-method")}</a>
</div>
{/if}
</div>
</div>

View file

@ -0,0 +1,34 @@
<script lang="ts">
import type { AuthMethod, PartialUser } from "$api/models";
import { t } from "$lib/i18n";
type Props = { method: AuthMethod; user: PartialUser };
let { method, user }: Props = $props();
let name = $derived(
method.type === "EMAIL" ? method.remote_id : (method.remote_username ?? method.remote_id),
);
let text = $derived.by(() => {
switch (method.type) {
case "DISCORD":
return $t("auth.successful-link-discord");
case "GOOGLE":
return $t("auth.successful-link-google");
case "TUMBLR":
return $t("auth.successful-link-tumblr");
case "FEDIVERSE":
return $t("auth.successful-link-fedi");
default:
return "<you shouldn't see this!>";
}
});
</script>
<h1>{$t("auth.new-auth-method-added")}</h1>
<p>{text} <code>{name}</code></p>
<p>{$t("auth.successful-link-profile-hint")}</p>
<p>
<a class="btn btn-primary" href="/@{user.username}">{$t("auth.successful-link-profile-link")}</a>
</p>

View file

@ -0,0 +1,35 @@
<script lang="ts">
import type { RawApiError } from "$api/error";
import { enhance } from "$app/forms";
import ErrorAlert from "$components/ErrorAlert.svelte";
import { t } from "$lib/i18n";
import { Button, Input, Label } from "@sveltestrap/sveltestrap";
type Props = {
title: string;
remoteLabel: string;
remoteUser: string;
ticket: string;
error?: RawApiError;
};
let { title, remoteLabel, remoteUser, ticket, error }: Props = $props();
</script>
<h1>{title}</h1>
{#if error}
<ErrorAlert {error} />
{/if}
<form method="POST" use:enhance>
<div class="mb-3">
<Label>{remoteLabel}</Label>
<Input type="text" readonly value={remoteUser} />
</div>
<div class="mb-3">
<Label>{$t("auth.register-username-label")}</Label>
<Input type="text" name="username" required />
</div>
<input type="hidden" name="ticket" value={ticket} />
<Button color="primary" type="submit">{$t("auth.register-button")}</Button>
</form>