'use client'; import { Suspense, useCallback, useEffect, useMemo, useState } from 'react'; import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; import { Loader2, ShieldCheck } from 'lucide-react'; import { BrandLogo } from '@/components/id/brand-logo'; import { useAuth } from '@/components/id/auth-provider'; import { Button } from '@/components/ui/button'; function OAuthAuthorizeContent() { const searchParams = useSearchParams(); const router = useRouter(); const { user, token, isPinLocked, isLoading } = useAuth(); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const oauthQuery = useMemo(() => { const params = new URLSearchParams(); searchParams.forEach((value, key) => params.set(key, value)); return params; }, [searchParams]); const clientId = searchParams.get('client_id') ?? searchParams.get('clientId'); const redirectUri = searchParams.get('redirect_uri') ?? searchParams.get('redirectUri'); const scope = searchParams.get('scope') ?? 'openid profile'; useEffect(() => { if (isLoading) return; if (!clientId || !redirectUri) return; if (user && token && !isPinLocked) return; const returnUrl = `/auth/oauth/authorize?${oauthQuery.toString()}`; router.replace(`/auth/login?redirect=${encodeURIComponent(returnUrl)}`); }, [clientId, isLoading, isPinLocked, oauthQuery, redirectUri, router, token, user]); const approve = useCallback(async () => { if (!token || !user) return; setSubmitting(true); setError(null); try { const apiBase = (process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:3000').replace(/\/$/, ''); const url = new URL(`${apiBase}/oauth/authorize`); oauthQuery.forEach((value, key) => url.searchParams.set(key, value)); url.searchParams.set('userId', user.id); const response = await fetch(url.toString(), { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } }); if (!response.ok) { const payload = (await response.json().catch(() => null)) as { message?: string | string[] } | null; const message = Array.isArray(payload?.message) ? payload.message.join(', ') : payload?.message; throw new Error(message || 'Не удалось подтвердить доступ'); } const data = (await response.json()) as { redirectUrl?: string }; if (!data.redirectUrl) { throw new Error('Сервер не вернул redirect URL'); } window.location.href = data.redirectUrl; } catch (err) { setError(err instanceof Error ? err.message : 'Ошибка OAuth авторизации'); } finally { setSubmitting(false); } }, [oauthQuery, token, user]); if (isLoading) { return (
); } if (!clientId || !redirectUri) { return (

Некорректный OAuth запрос

Отсутствуют обязательные параметры client_id и redirect_uri.

На главную
); } if (!user || !token || isPinLocked) { return (
); } return (

Разрешить доступ?

Приложение {clientId} запрашивает доступ к вашему аккаунту Lendry ID.

Пользователь: {user.displayName}

Scopes: {scope}

Redirect URI: {redirectUri}

{error ?

{error}

: null}
); } export default function OAuthAuthorizePage() { return ( } > ); }