|
| 1 | +<script lang="ts"> |
| 2 | + import { browser } from '$app/environment'; |
| 3 | + import { PUBLIC_TWITCH_CLIENT_ID, PUBLIC_TWITCH_REDIRECT_URI } from '$env/static/public'; |
| 4 | + import type { LayoutServerData } from './$types'; |
| 5 | +
|
| 6 | + export let data: LayoutServerData; |
| 7 | +
|
| 8 | + let url = new URL('https://id.twitch.tv/oauth2/authorize'); |
| 9 | +
|
| 10 | + if (browser) { |
| 11 | + const state = generateState(); |
| 12 | + const scopes = ['user:read:email']; |
| 13 | + url.searchParams.set('client_id', PUBLIC_TWITCH_CLIENT_ID); |
| 14 | + url.searchParams.set('redirect_uri', PUBLIC_TWITCH_REDIRECT_URI); |
| 15 | + url.searchParams.set('response_type', 'code'); |
| 16 | + url.searchParams.set('scope', scopes.join('+')); |
| 17 | + url.searchParams.set('state', state); |
| 18 | +
|
| 19 | + window.localStorage.setItem('state', state); |
| 20 | + } |
| 21 | +
|
| 22 | + function generateState() { |
| 23 | + const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
| 24 | +
|
| 25 | + let array = new Uint8Array(43); |
| 26 | +
|
| 27 | + window.crypto.getRandomValues(array); |
| 28 | + array = array.map((x) => validChars.charCodeAt(x % validChars.length)); |
| 29 | +
|
| 30 | + // @ts-ignore |
| 31 | + const randomState = String.fromCharCode.apply(null, array); |
| 32 | +
|
| 33 | + return randomState; |
| 34 | + } |
| 35 | +</script> |
| 36 | + |
| 37 | +<main> |
| 38 | + {#if data.user} |
| 39 | + <h2>Welcome, {data.user.id}!</h2> |
| 40 | + <form action="/logout" method="POST"> |
| 41 | + <button type="submit">Logout</button> |
| 42 | + </form> |
| 43 | + {:else} |
| 44 | + <a href={url.toString()}>Connect with Twitch</a> |
| 45 | + {/if} |
| 46 | + <slot /> |
| 47 | +</main> |
0 commit comments