Ctrl K
ComunidadGuías…

src/services/logAs.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { Router } from 'vue-router'
import { toast } from 'vue-sonner'
import { invokeCapgoApi } from '~/services/capgoApi'
import { FunctionsHttpError } from '~/services/consoleClient'
import { getSpoofedAdminJwt, isSpoofed, saveSpoof, useConsole } from './console'

async function getErrorMessage(error: unknown) {
  if (error instanceof FunctionsHttpError && error.context instanceof Response) {
    try {
      const json = await error.context.clone().json() as { error?: string, message?: string }
      if (json.message)
        return json.message
      if (json.error)
        return json.error
    }
    catch {
      // Fall back to the SDK error message below.
    }
  }

  if (error instanceof Error)
    return error.message
  if (typeof error === 'string')
    return error
  const message = typeof error === 'object' && error !== null
    ? (error as { message?: unknown }).message
    : undefined
  if (typeof message === 'string')
    return message
  return 'Cannot log in, see console'
}

export async function logAsUser(identifier: string, router: Router) {
  const toastId = toast.loading('Logging as...')
  try {
    if (!identifier)
      throw new Error('Missing user id, email, or org id')

    const wasSpoofed = isSpoofed()
    const spoofedAdminJwt = wasSpoofed ? await getSpoofedAdminJwt() : null
    if (wasSpoofed && !spoofedAdminJwt)
      throw new Error('Cannot restore admin session, please sign in again')

    const capgo = useConsole()
    const invokeOptions: { body: { identifier: string }, headers?: Record<string, string> } = {
      body: { identifier },
    }
    if (spoofedAdminJwt)
      invokeOptions.headers = { Authorization: `Bearer ${spoofedAdminJwt}` }

    const { data, error } = await invokeCapgoApi<{ jwt?: string, refreshToken?: string }>('private/log_as', invokeOptions)

    if (error)
      throw new Error(await getErrorMessage(error))

    const { jwt: newJwt, refreshToken: newRefreshToken } = data ?? {}

    if (!newJwt || !newRefreshToken)
      throw new Error('Cannot log in, see console')

    let adminSession: { jwt: string, refreshToken: string } | null = null
    if (!wasSpoofed) {
      const { data: currentSession, error: sessionError } = await capgo.auth.getSession()
      if (sessionError || !currentSession?.session)
        throw new Error('No current session')

      const { access_token: currentJwt, refresh_token: currentRefreshToken } = currentSession.session
      adminSession = { jwt: currentJwt, refreshToken: currentRefreshToken }
    }

    const { error: authError } = await capgo.auth.setSession({ access_token: newJwt, refresh_token: newRefreshToken })
    if (authError)
      throw authError

    if (adminSession)
      saveSpoof(adminSession.jwt, adminSession.refreshToken)

    toast.dismiss(toastId)
    toast.success('Spoofed, will reload')
    setTimeout(() => {
      router.replace('/dashboard').then(() => {
        globalThis.location.reload()
      })
    }, 1000)
  }
  catch (error) {
    toast.dismiss(toastId)
    const message = await getErrorMessage(error)
    toast.error(message)
    console.error(error)
    throw error
  }
}