working authirization

This commit is contained in:
2025-07-07 00:21:13 +05:00
parent b65b9538bb
commit 6f92b2acad
8 changed files with 997 additions and 703 deletions

View File

@ -1,177 +1,94 @@
import { useState } from 'react';
const useAuth = () => {
const [status, setStatus] = useState('');
interface AuthSession {
accessToken: string;
clientToken: string;
selectedProfile: {
id: string;
name: string;
};
}
const validateSession = async (accessToken: string) => {
export default function useAuth() {
const [status, setStatus] = useState('idle');
// Проверка валидности токена
const validateSession = async (accessToken: string): Promise<boolean> => {
try {
const response = await fetch('https://authserver.ely.by/auth/validate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
accessToken: accessToken,
}),
});
return response.ok;
setStatus('validating');
const response = await window.electron.ipcRenderer.invoke(
'validate-token',
accessToken,
);
setStatus('idle');
return response.valid;
} catch (error) {
console.log(`Ошибка при проверке токена: ${error.message}`);
console.error('Ошибка при валидации токена:', error);
setStatus('error');
return false;
}
};
const refreshSession = async (accessToken: string, clientToken: string) => {
// Обновление токена
const refreshSession = async (
accessToken: string,
clientToken: string,
): Promise<AuthSession | null> => {
try {
const refreshData = {
accessToken: accessToken,
clientToken: clientToken,
};
const response = await fetch('https://authserver.ely.by/auth/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(refreshData),
});
if (response.ok) {
const data = await response.json();
const newAccessToken = data.accessToken;
const profile = data.selectedProfile;
const uuid = profile.id;
const name = profile.name;
if (newAccessToken && uuid && name) {
return {
accessToken: newAccessToken,
uuid: uuid,
username: name,
clientToken: clientToken,
};
}
}
return null;
setStatus('refreshing');
const response = await window.electron.ipcRenderer.invoke(
'refresh-token',
{ accessToken, clientToken },
);
setStatus('idle');
return response;
} catch (error) {
console.log(`Ошибка при обновлении сессии: ${error.message}`);
console.error('Ошибка при обновлении токена:', error);
setStatus('error');
return null;
}
};
// Аутентификация в Ely.by
const authenticateWithElyBy = async (
username: string,
password: string,
saveConfig: Function,
) => {
saveConfigFunc: Function,
): Promise<AuthSession | null> => {
try {
const clientToken = crypto.randomUUID();
const authData = {
username: username,
password: password,
clientToken: clientToken,
requestUser: true,
};
console.log(`Аутентификация пользователя ${username} на Ely.by...`);
const response = await fetch(
'https://authserver.ely.by/auth/authenticate',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(authData),
},
setStatus('authenticating');
const response = await window.electron.ipcRenderer.invoke(
'authenticate',
{ username, password },
);
const responseData = await response.json();
if (response.ok) {
const accessToken = responseData.accessToken;
const profile = responseData.selectedProfile;
const uuid = profile.id;
const name = profile.name;
if (response && response.accessToken) {
// Правильно сохраняем данные в конфигурации
saveConfigFunc({
username: response.selectedProfile.name, // Имя игрока как строка
uuid: response.selectedProfile.id,
accessToken: response.accessToken,
clientToken: response.clientToken,
memory: 4096, // Сохраняем значение по умолчанию или из предыдущей конфигурации
});
if (accessToken && uuid && name) {
saveConfig(
username,
4096, // default memory
accessToken,
clientToken,
'',
password,
);
console.log(`Аутентификация успешна: UUID=${uuid}, Username=${name}`);
return {
accessToken: accessToken,
uuid: uuid,
username: name,
clientToken: clientToken,
};
}
} else {
if (responseData.error === 'Account protected with two factor auth') {
const totpToken = prompt(
'Введите код двухфакторной аутентификации:',
'',
);
if (totpToken) {
authData.password = `${password}:${totpToken}`;
const totpResponse = await fetch(
'https://authserver.ely.by/auth/authenticate',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(authData),
},
);
if (totpResponse.ok) {
const totpData = await totpResponse.json();
const newAccessToken = totpData.accessToken;
const newProfile = totpData.selectedProfile;
const newUuid = newProfile.id;
const newName = newProfile.name;
if (newAccessToken && newUuid && newName) {
saveConfig(
username,
4096, // default memory
newAccessToken,
clientToken,
'',
password,
);
return {
accessToken: newAccessToken,
uuid: newUuid,
username: newName,
clientToken: clientToken,
};
}
}
}
}
throw new Error(responseData.error || 'Ошибка авторизации');
setStatus('authenticated');
return response;
}
setStatus('error');
return null;
} catch (error) {
console.log(`Ошибка авторизации: ${error.message}`);
console.error('Ошибка при аутентификации:', error);
setStatus('error');
return null;
}
};
return {
status,
setStatus,
validateSession,
refreshSession,
authenticateWithElyBy,
};
};
export default useAuth;
}

View File

@ -1,7 +1,18 @@
import { useState, useEffect } from 'react';
// Добавляем определение типа Config
interface Config {
username: string;
password: string;
memory: number;
comfortVersion: string;
accessToken: string;
clientToken: string;
uuid?: string; // Добавляем uuid, который используется для авторизации
}
const useConfig = () => {
const [config, setConfig] = useState({
const [config, setConfig] = useState<Config>({
username: '',
password: '',
memory: 4096,
@ -34,28 +45,10 @@ const useConfig = () => {
setConfig(savedConfig);
}, []);
const saveConfig = (
username: string,
memory: number,
accessToken = '',
clientToken = '',
comfortVersion = '',
password = '',
) => {
try {
const newConfig = {
username,
memory,
accessToken: accessToken || config.accessToken,
clientToken: clientToken || config.clientToken,
comfortVersion: comfortVersion || config.comfortVersion,
password: password || config.password,
};
setConfig(newConfig);
localStorage.setItem('launcher_config', JSON.stringify(newConfig));
} catch (error) {
console.log(`Ошибка при сохранении конфигурации: ${error.message}`);
}
const saveConfig = (newConfig: Partial<Config>) => {
const updatedConfig = { ...config, ...newConfig };
setConfig(updatedConfig);
localStorage.setItem('launcher_config', JSON.stringify(updatedConfig));
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {

View File

@ -33,22 +33,6 @@ const LaunchPage = () => {
navigate('/login');
}
window.electron.ipcRenderer.on('download-progress', (progress: any) => {
setDownloadProgress(progress as number);
});
// Добавляем слушатель для статуса установки
window.electron.ipcRenderer.on('installation-progress', (data: any) => {
setInstallStatus((data as { status: string }).status);
});
// Обновляем слушатель для статуса установки
window.electron.ipcRenderer.on('installation-status', (data: any) => {
const { step, message } = data as { step: string; message: string };
setInstallStep(step);
setInstallMessage(message);
});
return () => {
window.electron.ipcRenderer.removeAllListeners('download-progress');
window.electron.ipcRenderer.removeAllListeners('installation-progress');
@ -77,6 +61,11 @@ const LaunchPage = () => {
setIsDownloading(true);
setDownloadProgress(0);
// Загружаем настройки и токены
const savedConfig = JSON.parse(
localStorage.getItem('launcher_config') || '{}',
);
// Сначала проверяем и обновляем файлы
const downloadResult = await window.electron.ipcRenderer.invoke(
'download-and-extract',
@ -95,9 +84,16 @@ const LaunchPage = () => {
);
}
// Затем запускаем Minecraft
const launchResult =
await window.electron.ipcRenderer.invoke('launch-minecraft');
// Затем запускаем Minecraft с данными авторизации
const launchResult = await window.electron.ipcRenderer.invoke(
'launch-minecraft',
{
accessToken: savedConfig.accessToken,
uuid: savedConfig.uuid,
username: savedConfig.username,
memory: savedConfig.memory || 4096,
},
);
if (launchResult?.success) {
showNotification('Minecraft успешно запущен!', 'success');