Created
July 24, 2024 14:10
-
-
Save HarleySalas/2116aef5f4896c9053bff74f2aadd66c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AUTH_REDIRECT_COOKIE, COLLECTION_SLUG } from '@/constants' | |
import { lucia } from '@/lib/lucia' | |
import { authProviders } from '@/lib/lucia/providers' | |
import { getPayloadHMR } from '@payloadcms/next/utilities' | |
import config from '@/payload.config' | |
import { OAuth2RequestError } from 'arctic' | |
import { cookies } from 'next/headers' | |
import type { NextRequest } from 'next/server' | |
export async function GET( | |
request: NextRequest, | |
{ params }: { params: { provider: keyof typeof authProviders } }, | |
): Promise<Response> { | |
const url = new URL(request.url) | |
const provider = String(params?.provider) as keyof typeof authProviders | |
const code = url.searchParams.get('code') | |
const state = url.searchParams.get('state') | |
const storedState = cookies().get(authProviders[provider].cookieName)?.value ?? null | |
const providerConfig = authProviders[provider] ?? null | |
if (!code || !state || !storedState || state !== storedState) { | |
return new Response(null, { status: 400, statusText: 'Invalid OAuth State...' }) | |
} | |
try { | |
const payload = await getPayloadHMR({ config }) | |
const { data, email } = await providerConfig.exchangeCodeForUser(request) | |
let user | |
const { docs } = await payload.find({ | |
collection: COLLECTION_SLUG.CUSTOMER, | |
where: { | |
and: [ | |
{ | |
provider: { | |
equals: data.provider, | |
}, | |
}, | |
{ | |
providerAccountId: { | |
equals: data.providerAccountId, | |
}, | |
}, | |
], | |
}, | |
}) | |
user = docs?.at(0) || null | |
if (user) { | |
const updatedUser = await payload.update({ | |
collection: COLLECTION_SLUG.CUSTOMER, | |
id: user.id, | |
data: { | |
email: email, | |
/** @ts-ignore */ | |
metadata: data.metadata, | |
}, | |
}) | |
user = updatedUser | |
} else { | |
user = await payload.create({ | |
collection: COLLECTION_SLUG.CUSTOMER, | |
data: { | |
email: email, | |
password: 'testing123', | |
provider: data.provider, | |
providerAccountId: data.providerAccountId, | |
metadata: data.metadata, | |
}, | |
}) | |
} | |
if (!user) { | |
throw new Error('Failed to create or update user...') | |
} | |
//ignored, because payload incorrectly types the update operation as a bulk update, even when it's a single update | |
/** @ts-ignore */ | |
const session = await lucia.createSession(user.id, {}) | |
const sessionCookie = lucia.createSessionCookie(session.id) | |
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes) | |
const redirectTo = cookies().get(AUTH_REDIRECT_COOKIE)?.value ?? null | |
cookies().delete(AUTH_REDIRECT_COOKIE) | |
return new Response(null, { | |
status: 302, | |
headers: { | |
Location: redirectTo ? decodeURIComponent(redirectTo) : '/', | |
}, | |
}) | |
} catch (error) { | |
console.error(error) | |
if (error instanceof OAuth2RequestError) { | |
return new Response(null, { | |
status: 400, | |
}) | |
} | |
return new Response(null, { | |
status: 500, | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment