Nuxt

Nuxt

@orria/tapok/nuxt реэкспортирует browser-клиенты. Запускайте их только на клиенте. Backend helpers импортируются отдельно из @orria/tapok/server в server route.

Hosted

<!-- pages/login.vue -->
<script setup lang="ts">
import { Tapok } from '@orria/tapok/nuxt'

const tapok = new Tapok()

async function login() {
  const result = await tapok.login() // вызывается из click в browser
  await $fetch('/api/session', {
    method: 'POST',
    body: { token: result.token },
  })
}
</script>

<template><button @click="login">Войти через Tapok</button></template>
// server/api/session.post.ts — псевдокод
import { verifyHostedToken } from '@orria/tapok/server'

export default defineEventHandler(async event => {
  const { token } = await readBody(event)
  const verified = await verifyHostedToken(token, {
    origin: 'https://app.example', // доверенная runtime config
  })

  const session = await sessions.create(verified.user.uid)
  setCookie(event, 'session', session, { httpOnly: true, secure: true })
})

Connect

<!-- pages/auth/callback.vue -->
<script setup lang="ts">
import { createTapokConnect } from '@orria/tapok/nuxt'

const connect = createTapokConnect({
  clientId: 'tapok_…',
  redirectUri: 'https://app.example/auth/callback',
  scopes: ['session', 'profile:display_name'],
})

onMounted(async () => {
  const callback = connect.finishSignIn()
  if (callback) await $fetch('/api/connect/exchange', { method: 'POST', body: callback })
})
</script>

<template><p>Завершаем вход…</p></template>
// server/api/connect/exchange.post.ts — псевдокод
import { exchangeConnectCode } from '@orria/tapok/server'

export default defineEventHandler(async event => {
  const callback = await readBody(event)
  const token = await exchangeConnectCode({
    clientId: runtimeConfig.tapokClientId,
    apiKey: runtimeConfig.tapokApiKey,
    code: callback.code,
    codeVerifier: callback.codeVerifier,
    redirectUri: 'https://app.example/auth/callback',
  })

  return createOwnSession(event, token.pairwise_sub)
})

tapokApiKey должен находиться в private runtime config, а не в runtimeConfig.public.