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"> | ||||
|   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"> | ||||
|       <p> | ||||
|         <a class="btn btn-primary" href={data.discord} role="button">Log in with Discord</a> | ||||
|       </p> | ||||
|     <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"> | ||||
| 
 | ||||
|     <div class="col-md"> | ||||
|       <p> | ||||
|         <b>Choose an authentication provider to get started.</b> You can add more providers later. | ||||
|       </p> | ||||
|     </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…
	
	Add table
		Add a link
		
	
		Reference in a new issue