Our Personal Data Server from scratch! tranquil.farm
pds rust database fun oauth atproto
221
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 143 lines 4.2 kB view raw
1<script lang="ts"> 2 import { getCurrentPath, navigate } from './lib/router.svelte' 3 import { initAuth, getAuthState } from './lib/auth.svelte' 4 import { initServerConfig } from './lib/serverConfig.svelte' 5 import { initI18n } from './lib/i18n' 6 import { isLoading as i18nLoading } from 'svelte-i18n' 7 import Toast from './components/Toast.svelte' 8 import Login from './routes/Login.svelte' 9 import RegisterSso from './routes/RegisterSso.svelte' 10 import Verify from './routes/Verify.svelte' 11 import ResetPassword from './routes/ResetPassword.svelte' 12 import RecoverPasskey from './routes/RecoverPasskey.svelte' 13 import RequestPasskeyRecovery from './routes/RequestPasskeyRecovery.svelte' 14 import Dashboard from './routes/Dashboard.svelte' 15 import OAuthConsent from './routes/OAuthConsent.svelte' 16 import OAuthLogin from './routes/OAuthLogin.svelte' 17 import OAuthAccounts from './routes/OAuthAccounts.svelte' 18 import OAuthVerifyCode from './routes/OAuthVerifyCode.svelte' 19 import OAuthPasskey from './routes/OAuthPasskey.svelte' 20 import OAuthDelegation from './routes/OAuthDelegation.svelte' 21 import OAuthError from './routes/OAuthError.svelte' 22 import SsoRegisterComplete from './routes/SsoRegisterComplete.svelte' 23 import Register from './routes/Register.svelte' 24 25 import ActAs from './routes/ActAs.svelte' 26 import Migration from './routes/Migration.svelte' 27 import { _ } from './lib/i18n' 28 initI18n() 29 30 const auth = $derived(getAuthState()) 31 32 let oauthCallbackPending = $state(hasOAuthCallback()) 33 34 function hasOAuthCallback(): boolean { 35 if (window.location.pathname === '/app/migrate') { 36 return false 37 } 38 const params = new URLSearchParams(window.location.search) 39 return !!(params.get('code') && params.get('state')) 40 } 41 42 $effect(() => { 43 initServerConfig() 44 initAuth().then(({ oauthLoginCompleted }) => { 45 if (oauthLoginCompleted) { 46 navigate('/dashboard', { replace: true }) 47 } 48 oauthCallbackPending = false 49 }) 50 }) 51 52 const isLoading = $derived( 53 auth.kind === 'loading' || $i18nLoading || oauthCallbackPending 54 ) 55 56 $effect(() => { 57 if (auth.kind === 'loading') return 58 const path = getCurrentPath() 59 if (path === '/') { 60 if (auth.kind === 'authenticated') { 61 navigate('/dashboard', { replace: true }) 62 } else { 63 navigate('/login', { replace: true }) 64 } 65 } 66 }) 67 68 const dashboardRoutes = new Set([ 69 '/dashboard', 70 '/settings', 71 '/security', 72 '/sessions', 73 '/app-passwords', 74 '/comms', 75 '/repo', 76 '/controllers', 77 78 '/invite-codes', 79 '/did-document', 80 '/admin', 81 ]) 82 83 function getComponent(path: string) { 84 const pathWithoutQuery = path.split('?')[0] 85 if (dashboardRoutes.has(pathWithoutQuery)) { 86 return Dashboard 87 } 88 switch (pathWithoutQuery) { 89 case '/login': 90 return Login 91 case '/verify': 92 return Verify 93 case '/reset-password': 94 return ResetPassword 95 case '/recover-passkey': 96 return RecoverPasskey 97 case '/request-passkey-recovery': 98 return RequestPasskeyRecovery 99 case '/oauth/consent': 100 return OAuthConsent 101 case '/oauth/login': 102 return OAuthLogin 103 case '/oauth/accounts': 104 return OAuthAccounts 105 case '/oauth/2fa': 106 case '/oauth/totp': 107 return OAuthVerifyCode 108 case '/oauth/passkey': 109 return OAuthPasskey 110 case '/oauth/delegation': 111 return OAuthDelegation 112 case '/oauth/error': 113 return OAuthError 114 case '/oauth/sso-register': 115 return SsoRegisterComplete 116 case '/register': 117 case '/oauth/register': 118 case '/oauth/register-password': 119 return Register 120 case '/oauth/register-sso': 121 return RegisterSso 122 case '/act-as': 123 return ActAs 124 case '/migrate': 125 return Migration 126 default: 127 return Login 128 } 129 } 130 131 let currentPath = $derived(getCurrentPath()) 132 let CurrentComponent = $derived(getComponent(currentPath)) 133 134</script> 135 136<main> 137 {#if isLoading} 138 <div class="loading"></div> 139 {:else} 140 <CurrentComponent /> 141 {/if} 142</main> 143<Toast />