Server API

Backend-проверка Hosted token и Connect code exchange.

Server API

@orria/tapok/server и @orria/tapok/auth экспортируют одинаковые backend-функции. Не импортируйте эти entrypoints в browser bundle.

Hosted — verifyHostedToken()

import { verifyHostedToken } from '@orria/tapok/server'
// Эквивалентный путь: @orria/tapok/auth

async function createHostedSession(request) {
  const { token } = await request.json()

  const verified = await verifyHostedToken(token, {
    // Значение из доверенной конфигурации, не из request body.
    origin: 'https://app.example',
    baseUrl: 'https://tapok.orria.space',
  })

  // Псевдокод: привяжите собственные данные к pairwise UID.
  const sessionId = await sessions.create({ userId: verified.user.uid })
  return setHttpOnlySessionCookie(sessionId)
}

Helper проверяет ES256-подпись через JWKS, issuer, exact-origin audience, срок действия, Hosted mode, UID и origin hash. Browser decode не заменяет эту проверку.

Connect — exchangeConnectCode()

Frontend сначала передаёт своему backend результат connect.finishSignIn(). Backend сверяет clientId и redirectUri со своей конфигурацией и выполняет exchange:

import { exchangeConnectCode } from '@orria/tapok/server'

async function exchangeConnectCallback(request) {
  const callback = await request.json()

  const token = await exchangeConnectCode({
    baseUrl: 'https://tapok.orria.space',
    clientId: process.env.TAPOK_CLIENT_ID,
    apiKey: process.env.TAPOK_API_KEY,
    code: callback.code,
    codeVerifier: callback.codeVerifier,
    redirectUri: 'https://app.example/auth/callback',
  })

  // Псевдокод: access token остаётся на backend.
  await tokenStore.save(token.pairwise_sub, token.access_token)
  return createOwnHttpOnlySession(token.pairwise_sub)
}

API key хранится только в backend secret storage. Не передавайте его во frontend, query string, browser storage или логи.