diff options
| author | mat <github@matdoes.dev> | 2022-03-17 14:27:36 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-03-17 14:27:36 -0500 |
| commit | 557423e887a363d0d1be1dfc6db613f83fd7cec0 (patch) | |
| tree | 08796b7de8bff9a9de1f438c5bb45f2b62d43410 /src/routes | |
| parent | e6be291bd6787199f644b263c28c6d2c8b9b1d74 (diff) | |
| download | skyblock-stats-557423e887a363d0d1be1dfc6db613f83fd7cec0.tar.gz skyblock-stats-557423e887a363d0d1be1dfc6db613f83fd7cec0.tar.bz2 skyblock-stats-557423e887a363d0d1be1dfc6db613f83fd7cec0.zip | |
add logging in
Diffstat (limited to 'src/routes')
| -rw-r--r-- | src/routes/index.svelte | 21 | ||||
| -rw-r--r-- | src/routes/loggedin.ts | 8 | ||||
| -rw-r--r-- | src/routes/logout.ts | 34 | ||||
| -rw-r--r-- | src/routes/player/[player]/[profile].svelte | 2 | ||||
| -rw-r--r-- | src/routes/player/index.ts | 4 | ||||
| -rw-r--r-- | src/routes/profile.svelte | 79 | ||||
| -rw-r--r-- | src/routes/verify.svelte | 63 | ||||
| -rw-r--r-- | src/routes/verify.ts | 104 |
8 files changed, 307 insertions, 8 deletions
diff --git a/src/routes/index.svelte b/src/routes/index.svelte index 6f6bae1..54843bd 100644 --- a/src/routes/index.svelte +++ b/src/routes/index.svelte @@ -1,13 +1,28 @@ +<script lang="ts" context="module"> + import type { Load } from '@sveltejs/kit' + import { API_URL } from '$lib/api' + + export const load: Load = async ({ params, fetch, session }) => { + return { + props: { + loggedIn: session.sid !== undefined, + }, + } + } +</script> + <script lang="ts"> import Username from '$lib/minecraft/Username.svelte' import SearchUser from '$lib/SearchUser.svelte' - import type { CleanUser } from '$lib/APITypes' import donators from '../_donators.json' import Head from '$lib/Head.svelte' import Emoji from '$lib/Emoji.svelte' + import LoginButton from '$lib/LoginButton.svelte' - export const prerender = true + // export const prerender = true export const hydrate = false + + export let loggedIn: boolean </script> <svelte:head> @@ -20,6 +35,7 @@ /> <main> + <LoginButton {loggedIn} /> <section class="title-section"> <h1>SkyBlock Stats</h1> <SearchUser> @@ -56,7 +72,6 @@ <section> <h2>Info</h2> <p>Website made by <a href="https://matdoes.dev">mat</a>.</p> - <p>Join the <a href="https://discord.gg/nWQKpzPCPJ">Forum Sweats</a> Discord server.</p> <p> Resource packs: <a href="//packshq.com">PacksHQ</a> (default), <a href="//hypixel.net/threads/2138599">Furfsky</a>, diff --git a/src/routes/loggedin.ts b/src/routes/loggedin.ts index eb7236d..9eadf67 100644 --- a/src/routes/loggedin.ts +++ b/src/routes/loggedin.ts @@ -2,15 +2,17 @@ import { API_URL } from '$lib/api' import type { RequestHandler } from '@sveltejs/kit' import type { JSONValue } from '@sveltejs/kit/types/internal' -export const get: RequestHandler = async ({ params }) => { - const code = params.code +export const get: RequestHandler = async ({ url }) => { + const code = url.searchParams.get('code') + const redirectUri = `${url.protocol}//${url.host}/loggedin` const response = await fetch(`${API_URL}accounts/createsession`, { method: 'POST', headers: { 'content-type': 'application/json', }, body: JSON.stringify({ - code + code, + redirectUri: redirectUri }), }).then(res => { if (res.status !== 200) diff --git a/src/routes/logout.ts b/src/routes/logout.ts new file mode 100644 index 0000000..f2f5e33 --- /dev/null +++ b/src/routes/logout.ts @@ -0,0 +1,34 @@ +import { API_URL } from '$lib/api' +import type { RequestHandler } from '@sveltejs/kit' + +const DISCORD_CLIENT_ID = process.env.DISCORD_CLIENT_ID +if (!DISCORD_CLIENT_ID) + console.warn('DISCORD_CLIENT_ID is not set as an environment variable. This is required for logging in with Discord to work.') + +export const get: RequestHandler = async ({ request, params, locals, url }) => { + // if the sid is wrong, nothing to do + console.log(url.searchParams.get('sid'), locals.sid) + if (url.searchParams.has('sid') && url.searchParams.get('sid') === locals.sid) { + console.log('ok sent logout') + await fetch(`${API_URL}accounts/session`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + uuid: locals.sid + }), + }).then(res => { + if (res.status !== 200) + throw new Error(res.statusText) + }) + } + return { + status: 303, + headers: { + location: '/', + 'Set-Cookie': 'sid=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;' + } + } + +} diff --git a/src/routes/player/[player]/[profile].svelte b/src/routes/player/[player]/[profile].svelte index b87741c..02c46bb 100644 --- a/src/routes/player/[player]/[profile].svelte +++ b/src/routes/player/[player]/[profile].svelte @@ -39,7 +39,7 @@ pack = (await import('skyblock-assets/matchers/worlds_and_beyond.json')) as any break default: - // packshq is the default pack + // furfsky reborn is the default pack pack = (await import('skyblock-assets/matchers/furfsky_reborn.json')) as any break } diff --git a/src/routes/player/index.ts b/src/routes/player/index.ts index c9d1b90..4644499 100644 --- a/src/routes/player/index.ts +++ b/src/routes/player/index.ts @@ -1,4 +1,6 @@ -export async function post({ request }) { +import type { RequestHandler } from '@sveltejs/kit' + +export const post: RequestHandler = async ({ request }) => { const form = await request.formData() const player = form.get('user-search') diff --git a/src/routes/profile.svelte b/src/routes/profile.svelte new file mode 100644 index 0000000..c88b8fe --- /dev/null +++ b/src/routes/profile.svelte @@ -0,0 +1,79 @@ +<script lang="ts" context="module"> + import type { Load } from '@sveltejs/kit' + import { API_URL } from '$lib/api' + import type { AccountSchema, CleanMemberProfile, CleanUser, SessionSchema } from '$lib/APITypes' + import Head from '$lib/Head.svelte' + import Header from '$lib/Header.svelte' + + export const load: Load = async ({ params, fetch, session }) => { + const sessionResponse: { session: SessionSchema | null; account: AccountSchema | null } | null = + await fetch(`${API_URL}accounts/session`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + uuid: session.sid, + }), + }).then(r => r.json()) + + const playerResponse = sessionResponse?.account + ? await fetch( + `${API_URL}player/${sessionResponse.account.minecraftUuid}?customization=true` + ).then(r => r.json()) + : null + + // redirect to /login if the user is not logged in + if (!sessionResponse?.account) { + return { redirect: '/login', status: 303 } + } + + return { + props: { + session: sessionResponse.session, + account: sessionResponse.account, + player: playerResponse, + }, + } + } +</script> + +<script lang="ts"> + import Emoji from '$lib/Emoji.svelte' + + export let session: SessionSchema | null + export let account: AccountSchema | null + export let player: CleanUser | null +</script> + +<Head title="Customize Profile" /> +<Header /> + +<main> + {#if session && session._id} + <a href="/logout?sid={session._id}" class="logout"><button>Log out</button></a> + {/if} + <h1>Customize Profile</h1> + <noscript> + <p><Emoji value="⚠" /> Please enable JavaScript to use this page.</p> + </noscript> + {#if player && player.player} + <a href="/player/{player.player.username}">View profile</a> + {:else} + <p><Emoji value="⚠" /> No linked Minecraft account</p> + {/if} + <p> + Pack: <select> + <option value="default">Default</option> + <option value="custom">Custom</option> + </select> + </p> +</main> + +<style> + .logout { + position: absolute; + top: 0.5em; + right: 0.5em; + } +</style> diff --git a/src/routes/verify.svelte b/src/routes/verify.svelte new file mode 100644 index 0000000..e900a5f --- /dev/null +++ b/src/routes/verify.svelte @@ -0,0 +1,63 @@ +<script lang="ts" context="module"> + import type { Load } from '@sveltejs/kit' + export const load: Load = async ({ params, fetch, session, url }) => { + if (session.sid === undefined) { + return { redirect: '/login', status: 303 } + } + return { + props: { + errorCode: url.searchParams.get('error'), + current: url.searchParams.get('current'), + correct: url.searchParams.get('correct'), + }, + } + } +</script> + +<script lang="ts"> + import Emoji from '$lib/Emoji.svelte' + import Head from '$lib/Head.svelte' + import Header from '$lib/Header.svelte' + + export let errorCode: string | null + export let current: string | null + export let correct: string | null + + const errorCodes = { + NO_IGN: 'Please enter a valid Minecraft username.', + NOT_LINKED: + 'Please link your Discord in Hypixel by doing /profile -> Social media -> Discord. If you just changed it, wait a few minutes and try again.', + WRONG_NAME: `You're linked to ${current} on Hypixel. Please change this to ${correct} by doing /profile -> Social media -> Discord. If you just changed it, wait a few minutes and try again.`, + NO_KEY: + "This instance of skyblock-stats doesn't have a skyblock-api key set. Please contact the owner of the website if you believe this to be a mistake.", + } +</script> + +<Head title="Verify Account" /> +<Header /> + +<main> + <h1>Verify Minecraft account</h1> + <p>Please enter your Minecraft username to verify that this is your account.</p> + <p>This will check with the Hypixel API that your Discord username matches your Hypixel name.</p> + {#if errorCode && errorCode in errorCodes} + <div class="error"> + <Emoji value="🚫" /> + {errorCodes[errorCode]} + </div> + {/if} + <form method="post" action="/verify"> + <input placeholder="Username or UUID" name="ign" required /> + <input type="submit" value="Enter" /> + </form> +</main> + +<style> + p { + margin: 0; + } + .error { + font-weight: bold; + margin: 1em 0; + } +</style> diff --git a/src/routes/verify.ts b/src/routes/verify.ts new file mode 100644 index 0000000..5951314 --- /dev/null +++ b/src/routes/verify.ts @@ -0,0 +1,104 @@ +import { API_URL } from '$lib/api' +import type { AccountSchema, CleanUser, SessionSchema } from '$lib/APITypes' +import type { RequestHandler } from '@sveltejs/kit' + +function redirect(status: number, location: string) { + return { + status, + headers: { + location, + }, + } +} + +export const post: RequestHandler = async ({ request, locals }) => { + console.log('ok!') + if (!process.env.SKYBLOCK_STATS_API_KEY) { + return redirect(303, `/verify?error=NO_KEY`) + } + console.log('sid check') + if (locals.sid === undefined) { + // return { + // status: 303, + // redirect: '/login', + // } + return redirect(303, '/login') + } + + const form = await request.formData() + + // username or uuid + const playerIdentifier = form.get('ign') + console.log('ign check') + if (!playerIdentifier) { + // return { + // status: 303, + // redirect: '/verify?error=NO_IGN', + // } + return redirect(303, `/verify?error=NO_IGN`) + } + + const playerResponse: CleanUser = await fetch(`${API_URL}player/${playerIdentifier}`).then(res => res.json()) + const sessionResponse: { session: SessionSchema | null, account: AccountSchema | null } = await fetch(`${API_URL}accounts/session`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + uuid: locals.sid, + }), + }).then(r => r.json()) + + console.log('session check') + if (!sessionResponse.session) + // return { + // status: 303, + // redirect: '/login', + // } + return redirect(303, '/login') + + const hypixelDiscordName = playerResponse.player?.socials.discord + + console.log('discord check') + if (!hypixelDiscordName) + // return { + // status: 303, + // redirect: '/verify?error=NOT_LINKED', + // } + return redirect(303, `/verify?error=NOT_LINKED`) + + + const discordUser = sessionResponse.session.discord_user + const actualDiscordName = discordUser.name + // some people link themselves as <id>#<discrim> instead of <name>#<discrim> + const actualDiscordIdDiscrim = `${discordUser.id}#${discordUser.name.split('#')[1]}` + + console.log('name check') + if (!(hypixelDiscordName === actualDiscordName || hypixelDiscordName === actualDiscordIdDiscrim)) + // return { + // status: 303, + // redirect: `/verify?error=WRONG_NAME?current=${hypixelDiscordName}&correct=${actualDiscordName}`, + // } + return redirect(303, `/verify?error=WRONG_NAME¤t=${encodeURIComponent(hypixelDiscordName)}&correct=${encodeURIComponent(actualDiscordName)}`) + + const updatedAccount: AccountSchema = { + discordId: sessionResponse.session.discord_user.id, + minecraftUuid: playerResponse.player?.uuid + } + + await fetch(`${API_URL}accounts/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + key: process.env.SKYBLOCK_STATS_API_KEY + }, + body: JSON.stringify(updatedAccount), + }).then(r => r.json()) + + console.log('epic') + // return { + // status: 303, + // redirect: '/profile' + // } + return redirect(303, '/profile') +}
\ No newline at end of file |
