From d3bbc593a6adfc84e20677d6ea8016e926ff4359 Mon Sep 17 00:00:00 2001 From: smanylov Date: Wed, 7 Jan 2026 19:14:37 +0700 Subject: [PATCH] update vk auth --- src/app/actions/vkAuth.ts | 6 +-- src/app/components/VKLogin.tsx | 38 +++++++++------ src/app/components/upload-section-file.tsx | 55 +--------------------- src/i18n/messages/ru.json | 2 +- 4 files changed, 29 insertions(+), 72 deletions(-) diff --git a/src/app/actions/vkAuth.ts b/src/app/actions/vkAuth.ts index ed41a2e..dd88ae4 100644 --- a/src/app/actions/vkAuth.ts +++ b/src/app/actions/vkAuth.ts @@ -5,14 +5,14 @@ import { createSession } from '@/app/actions/session'; import { redirect } from 'next/navigation'; -export async function vkAuthorization(data : any, codeChallenge: string) { +export async function vkAuthorization(data : any, codeVerifier: string) { console.log(data); - console.log(codeChallenge); + console.log(codeVerifier); const { code, state, device_id } = data try { - const response = await fetch(`${API_BASE_URL}/api/v1/vk/authorization/${code}/${state}/${codeChallenge}/${device_id}`, { + const response = await fetch(`${API_BASE_URL}/api/v1/vk/authorization/${code}/${state}/${codeVerifier}/${device_id}`, { method: 'GET', headers: { "Content-Type": "application/json", diff --git a/src/app/components/VKLogin.tsx b/src/app/components/VKLogin.tsx index 6fef6c9..5d4e094 100644 --- a/src/app/components/VKLogin.tsx +++ b/src/app/components/VKLogin.tsx @@ -7,19 +7,26 @@ import { vkAuthorization } from '@/app/actions/vkAuth'; export default function VKLogin() { const [codeVerifier, setCodeVerifier] = useState(''); const [codeChallenge, setCodeChallenge] = useState(''); + const [state, setState] = useState(''); - async function generateAuthString() { + async function generateAuthString(minLength: number = 43, maxLength: number = 128) { const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'; - const minLength = 43; - const maxLength = 128; - const length = Math.floor(Math.random() * (maxLength - minLength + 1)) + minLength; let result = ''; const charsLength = chars.length; - for (let i = 0; i < length; i++) { - result += chars.charAt(Math.floor(Math.random() * charsLength)); + if (typeof crypto !== 'undefined' && crypto.getRandomValues) { + const randomValues = new Uint32Array(length); + crypto.getRandomValues(randomValues); + + for (let i = 0; i < length; i++) { + result += chars.charAt(randomValues[i] % charsLength); + } + } else { + for (let i = 0; i < length; i++) { + result += chars.charAt(Math.floor(Math.random() * charsLength)); + } } return result; @@ -48,21 +55,18 @@ export default function VKLogin() { console.log('codeChallenge:', codeChallenge); try { - // Если codeVerifier пустой, генерируем новый if (!codeVerifier) { - const newCodeVerifier = await generateAuthString(); + const newCodeVerifier = await generateAuthString(43, 128); const newCodeChallenge = await generateCodeChallenge(newCodeVerifier); setCodeVerifier(newCodeVerifier); setCodeChallenge(newCodeChallenge); - // Обновляем конфигурацию VKID VKID.Config.update({ codeChallenge: newCodeChallenge }); } - // Выполняем авторизацию const data = await VKID.Auth.login(); vkidOnSuccess(data); } catch (error) { @@ -73,11 +77,11 @@ export default function VKLogin() { async function vkidOnSuccess(data: any) { console.log('vkidOnSuccess'); console.log('vk data:', data); - console.log('codeChallenge :', codeChallenge); + console.log('codeVerifier :', codeVerifier); - vkAuthorization(data, codeChallenge); + vkAuthorization(data, codeVerifier); - const newCodeVerifier = await generateAuthString(); + const newCodeVerifier = await generateAuthString(43, 128); const newCodeChallenge = await generateCodeChallenge(newCodeVerifier); setCodeVerifier(newCodeVerifier); @@ -88,13 +92,16 @@ export default function VKLogin() { }); console.log('new codeChallenge:', newCodeChallenge); + console.log('state: ', state) } useEffect(() => { async function initVKID() { try { - const newCodeVerifier = await generateAuthString(); + const newCodeVerifier = await generateAuthString(43, 128); const newCodeChallenge = await generateCodeChallenge(newCodeVerifier); + const newState = await generateAuthString(32, 128); + setState(newState); setCodeVerifier(newCodeVerifier); setCodeChallenge(newCodeChallenge); @@ -105,7 +112,8 @@ export default function VKLogin() { responseMode: VKID.ConfigResponseMode.Callback, source: VKID.ConfigSource.LOWCODE, scope: 'email phone vkid.personal_info', - codeChallenge: newCodeChallenge + codeChallenge: newCodeChallenge, + state: newState }); console.log('Generated codeVerifier:', newCodeVerifier); diff --git a/src/app/components/upload-section-file.tsx b/src/app/components/upload-section-file.tsx index 6243c62..234c62b 100644 --- a/src/app/components/upload-section-file.tsx +++ b/src/app/components/upload-section-file.tsx @@ -43,57 +43,6 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile const isCancelledRef = useRef(false); const t = useTranslations('Global'); - let SUPPORTED_FORMATS: string[] = []; - - switch (fileType) { - case 'image': - SUPPORTED_FORMATS = [ - 'image/jpeg', - 'image/jpg', - 'image/png', - 'image/gif', - 'image/bmp', - 'image/webp', - 'image/svg+xml', - 'image/tiff', - 'image/x-icon' - ]; - break; - case 'video': - SUPPORTED_FORMATS = [ - 'video/mp4', - 'video/mpeg', - 'video/ogg', - 'video/webm', - 'video/quicktime', - 'video/x-msvideo', - 'video/x-matroska', - 'video/x-flv', - 'video/3gpp', - 'video/3gpp2' - ]; - break; - case 'audio': - SUPPORTED_FORMATS = [ - 'audio/mpeg', - 'audio/wav', - 'audio/wave', - 'audio/x-wav', - 'audio/x-pn-wav', - 'audio/ogg', - 'audio/webm', - 'audio/aac', - 'audio/mp4', - 'audio/x-m4a', - 'audio/flac', - 'audio/x-flac', - 'audio/opus' - ]; - break; - - default: - break; - }; const acceptString = useMemo(() => { if (!allowedExtensions || !Array.isArray(allowedExtensions)) { @@ -103,7 +52,7 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile }, [allowedExtensions]); const validateFile = (file: File): { isValid: boolean; errorMessage?: string } => { - if (!SUPPORTED_FORMATS.includes(file.type as string)) { + if (!allowedExtensions.includes(file.type as string)) { const extension = file.name.split('.').pop()?.toLowerCase(); if (!extension || !allowedExtensions.includes(extension as string)) { return { @@ -169,7 +118,7 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile if (fileType === "image") { try { dimensions = await getImageDimensions(file) as { width: number, height: number }; - if (dimensions.width < 150 || dimensions.height < 150 || + if (dimensions.width < 100 || dimensions.height < 100 || dimensions.width > 10000 || dimensions.height > 10000) { setError(`${t('image-size')}: ${dimensions.width}x${dimensions.height}. ${t('acceptable-range')}: 100x100 - 10000x10000 ${t('pixels')}.`); return; diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index 431e70b..0fd543e 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -141,7 +141,7 @@ "the-file-is-too-large": "Файл слишком большой", "cost-of-protection": "Стоимость защиты", "current-balance": "Текущий баланс", - "image-resolution": "Разрешение изображение", + "image-resolution": "Разрешение изображения", "file-size": "Размер файла", "file-format": "Формат файла", "mb": "МБ",