#Discord oauth

3 messages · Page 1 of 1 (latest)

misty crater
#

Hi guys

I've created a way to login to the site with Discord. Is there anything wrong with my method of doing this?

I've tried to utilise as much as payload auths as I can:

misty crater
#
export const GET = async (request: NextRequest): Promise<NextResponse> => {
  const errorUrl = new URL('/auth/error', request.url)
  const code = request.nextUrl.searchParams.get('code')
  const state = request.nextUrl.searchParams.get('state')
  const storedState = request.cookies.get('discord_oauth_state')?.value

  if (!code || !state || !storedState || state !== storedState) {
    const response = NextResponse.redirect(errorUrl)
    response.cookies.delete('discord_oauth_state')
    return response
  }

  try {
    const accessToken = await exchangeCode(code)
    const discordUser = await fetchDiscordUser(accessToken)
    const payload = await getPayload({ config })

    const { docs } = await payload.find({
      collection: 'users',
      where: { 'connections.discord.userId': { equals: discordUser.id } },
      overrideAccess: true,
      limit: 1,
    })

    const displayName = discordUser.global_name ?? discordUser.username

    const user =
      docs[0] ??
      (await payload.create({
        collection: 'users',
        overrideAccess: true,
        data: {
          name: displayName,
          slug: normaliseSlug(displayName),
          email: `${randomUUID()}@discord.placeholder`,
          password: randomUUID(),
          roles: ['player'],
          connections: {
            discord: { userId: discordUser.id },
          },
        },
      }))

 const collectionConfig = payload.collections['users'].config
    const { auth } = collectionConfig
    const tokenExpiration = auth.tokenExpiration ?? 7200

    // Create session record so Payload's useSessions validation passes
    const sid = randomUUID()
    const now = new Date()
    const expiresAt = new Date(now.getTime() + tokenExpiration * 1000)
    const existingSessions = (user.sessions ?? []).filter((s) => new Date(s.expiresAt) > now)