'use client'; import { getOAuthClientId, getOAuthRedirectUri, getPublicApiOrigin } from '@/lib/env'; import { createPKCEPair } from '@/lib/oauth/pkce'; const VERIFIER_KEY = 'smart_oauth_pkce_verifier'; /** 跳转浏览器授权页(与 GET /oauth/authorize 一致);PKCE verifier 写入 sessionStorage,回调页取出换 token。 */ export async function redirectToAuthorize(): Promise { const { verifier, challenge } = await createPKCEPair(); if (typeof window !== 'undefined') { sessionStorage.setItem(VERIFIER_KEY, verifier); } const params = new URLSearchParams({ response_type: 'code', client_id: getOAuthClientId(), redirect_uri: getOAuthRedirectUri(), scope: 'openid', code_challenge: challenge, code_challenge_method: 'S256', state: typeof crypto !== 'undefined' && 'randomUUID' in crypto ? crypto.randomUUID() : String(Date.now()), }); const url = `${getPublicApiOrigin()}/oauth/authorize?${params.toString()}`; window.location.href = url; } export function takeStoredPkceVerifier(): string | null { if (typeof window === 'undefined') { return null; } const v = sessionStorage.getItem(VERIFIER_KEY); if (v) { sessionStorage.removeItem(VERIFIER_KEY); } return v; }