create superform for oauth callback
This commit is contained in:
parent
093b7a8135
commit
b0935402c0
2 changed files with 71 additions and 19 deletions
|
@ -1,4 +1,12 @@
|
|||
import { Google, Discord, GitHub, generateState, generateCodeVerifier } from 'arctic'
|
||||
import {
|
||||
Google,
|
||||
Discord,
|
||||
GitHub,
|
||||
generateState,
|
||||
generateCodeVerifier,
|
||||
type GitHubTokens,
|
||||
type DiscordTokens
|
||||
} from 'arctic'
|
||||
import { error, redirect, type Actions, type RequestHandler, type ServerLoad } from '@sveltejs/kit'
|
||||
import { z } from 'zod'
|
||||
import { db, publicUser } from './db'
|
||||
|
@ -6,8 +14,9 @@ import { env } from '$env/dynamic/private'
|
|||
import { dev } from '$app/environment'
|
||||
import { alphabet, generateRandomString } from 'oslo/crypto'
|
||||
import { decodeJwt } from 'jose'
|
||||
import { superForm, type SuperForm } from 'sveltekit-superforms'
|
||||
import { superValidate, type SuperForm } from 'sveltekit-superforms'
|
||||
import { zod, type ValidationAdapter } from 'sveltekit-superforms/adapters'
|
||||
import { cookieController, createSessionForUser } from './auth'
|
||||
|
||||
const {
|
||||
DISCORD_CLIENT_ID,
|
||||
|
@ -158,24 +167,50 @@ export function oauth_callback(): ServerLoad<
|
|||
) {
|
||||
error(400, 'Invalid request')
|
||||
}
|
||||
let tokens
|
||||
let id
|
||||
let name
|
||||
let id: string
|
||||
let name: string
|
||||
if (provider instanceof Google) {
|
||||
tokens = await provider.validateAuthorizationCode(code, storedCodeVerifier)
|
||||
const tokens = await provider.validateAuthorizationCode(code, storedCodeVerifier)
|
||||
console.log(tokens.idToken)
|
||||
const { sub, name: Uname } = decodeJwt(tokens.idToken)
|
||||
id = sub
|
||||
name = Uname
|
||||
id = sub!
|
||||
name = Uname as string
|
||||
} else {
|
||||
tokens = await provider.validateAuthorizationCode(code)
|
||||
const tokens: GitHubTokens | DiscordTokens = await provider.validateAuthorizationCode(code)
|
||||
if (providerID === 'discord') {
|
||||
const response = await fetch('https://discord.com/api/users/@me', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens.accessToken}`
|
||||
}
|
||||
})
|
||||
if (!response.ok) error(500, 'Unable to contact provider')
|
||||
const { id: userId, username } = await response.json()
|
||||
id = userId
|
||||
name = username
|
||||
} else if (providerID === 'github') {
|
||||
const response = await fetch('https://api.github.com/user', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens.accessToken}`
|
||||
}
|
||||
})
|
||||
if (!response.ok) error(500, 'Unable to contact provider')
|
||||
const { id: userId, login } = await response.json()
|
||||
id = userId
|
||||
name = login
|
||||
}
|
||||
}
|
||||
const existingUser = (await db.user.getOneBySecondaryIndex(`oauth_${providerID}_id`, id))?.flat()
|
||||
if(existingUser) {
|
||||
const session = await createSessionForUser(existingUser.id)
|
||||
const sessionCookie = cookieController.createCookie(session.unwrap().id)
|
||||
cookies.set(sessionCookie.name, sessionCookie.value, {
|
||||
path: '.',
|
||||
...sessionCookie.attributes
|
||||
})
|
||||
redirect(302, '/app')
|
||||
}
|
||||
const formToken = generateRandomString(12, alphabet('0-9', 'a-z'))
|
||||
const form = superForm(
|
||||
zod(z.object({ token: z.string() }), {
|
||||
defaults: { token: formToken }
|
||||
})
|
||||
)
|
||||
const form = await superValidate({ token: formToken }, zod(z.object({ token: z.string() })))
|
||||
if (locals.user) {
|
||||
// the user is already logged in, ask them if they want to link the account to their existing account, or log out and try again
|
||||
await db.saved_oauth_data.set(formToken, {
|
||||
|
@ -207,5 +242,12 @@ export function oauth_callback(): ServerLoad<
|
|||
}
|
||||
|
||||
export function oauth_callback_actions(): Actions<{ provider: string }> {
|
||||
return {}
|
||||
return {
|
||||
link: ({ request, locals, }) => {
|
||||
// get existing account and link it
|
||||
},
|
||||
create: ({ request }) => {
|
||||
// create new account with
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
<script>
|
||||
import { superForm } from 'sveltekit-superforms'
|
||||
|
||||
const { data } = $props()
|
||||
const { enhance } = superForm(data.form)
|
||||
</script>
|
||||
|
||||
<form action="POST" use:enhance>
|
||||
{#if data.type === 'create'}
|
||||
do you want to create a new account using <code class="font-bold">{data.name}</code> from {data.prov}?
|
||||
<button>yes</button> <button>no</button>
|
||||
{:else if data.type === 'link'}{/if}
|
||||
<button formaction="?/create">yes</button> <a href="/">no</a>
|
||||
{:else if data.type === 'link'}
|
||||
do you want to link <code class="font-bold">{data.name}</code> from {data.prov} to your existing
|
||||
account {data.user.displayName}?
|
||||
<button formaction="?/link">yes</button> <a href="/">no</a>
|
||||
<a href="/auth/signout">Sign me out and try again</a>
|
||||
{/if}
|
||||
</form>
|
||||
|
|
Loading…
Reference in a new issue