mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
Enhance TelegramLoginButton component for improved authentication flow
- Updated the message handler to only accept messages from Telegram OAuth, ensuring better security. - Refactored the authentication process to handle Telegram's auth_result more effectively, including parsing the payload and managing session tokens. - Improved error handling during the authentication process, providing clearer error messages for failed operations. - Added a new allowed host in vite.config.ts for the frontend runner. These changes streamline the authentication process with Telegram, enhancing security and user experience.
This commit is contained in:
@@ -63,25 +63,86 @@ const TelegramLoginButton = ({
|
||||
|
||||
let authCompleted = false;
|
||||
|
||||
// Listen for postMessage from the backend success page
|
||||
// Listen for postMessage from Telegram OAuth
|
||||
const messageHandler = async (event: MessageEvent) => {
|
||||
// Verify origin for security
|
||||
const backendOrigin = new URL(BACKEND_URL).origin;
|
||||
if (event.origin !== backendOrigin) {
|
||||
// 1) Only accept messages from Telegram OAuth
|
||||
if (event.origin !== 'https://oauth.telegram.org') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data?.type === 'telegram-auth' && event.data?.token && !authCompleted) {
|
||||
// 2) Parse the payload (Telegram sends a JSON string)
|
||||
let data: any;
|
||||
try {
|
||||
data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3) Handle successful auth_result from Telegram
|
||||
if (data.event === 'auth_result' && data.result && !authCompleted) {
|
||||
authCompleted = true;
|
||||
window.removeEventListener('message', messageHandler);
|
||||
popup.close();
|
||||
|
||||
try {
|
||||
// This token is a JWT token generated by the backend server
|
||||
const jwtToken = event.data.token;
|
||||
const telegramData: TelegramAuthData = {
|
||||
id: data.result.id,
|
||||
first_name: data.result.first_name,
|
||||
last_name: data.result.last_name,
|
||||
username: data.result.username,
|
||||
photo_url: data.result.photo_url,
|
||||
auth_date: data.result.auth_date,
|
||||
hash: data.result.hash,
|
||||
};
|
||||
|
||||
// Store JWT token in store (received from backend server)
|
||||
dispatch(setToken(jwtToken));
|
||||
try {
|
||||
// Send Telegram auth data to backend to verify and exchange for JWT
|
||||
const webCompleteResponse = await fetch(`${BACKEND_URL}/auth/web-complete`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
method: 'telegram',
|
||||
telegramUser: telegramData,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!webCompleteResponse.ok) {
|
||||
const errorData = await webCompleteResponse.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || 'Failed to complete authentication');
|
||||
}
|
||||
|
||||
const { data: completeData } = await webCompleteResponse.json();
|
||||
const { loginToken } = completeData || {};
|
||||
|
||||
if (!loginToken) {
|
||||
throw new Error('No login token received from server');
|
||||
}
|
||||
|
||||
const exchangeResponse = await fetch(`${BACKEND_URL}/auth/desktop-exchange`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
token: loginToken,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!exchangeResponse.ok) {
|
||||
const errorData = await exchangeResponse.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || 'Failed to exchange token');
|
||||
}
|
||||
|
||||
const exchangeData = await exchangeResponse.json();
|
||||
const { sessionToken } = exchangeData.data || {};
|
||||
|
||||
if (!sessionToken) {
|
||||
throw new Error('No JWT token received from server');
|
||||
}
|
||||
|
||||
// Store JWT token in store (this is the JWT from the backend)
|
||||
dispatch(setToken(sessionToken));
|
||||
|
||||
// Call onSuccess callback if provided, otherwise navigate to onboarding
|
||||
if (onSuccess) {
|
||||
@@ -92,8 +153,7 @@ const TelegramLoginButton = ({
|
||||
setIsAuthenticating(false);
|
||||
} catch (error) {
|
||||
setIsAuthenticating(false);
|
||||
console.error('Failed to process authentication token:', error);
|
||||
// alert('Failed to complete authentication. Please try again.');
|
||||
console.error('Failed to complete Telegram authentication:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -28,6 +28,9 @@ export default defineConfig(async () => ({
|
||||
port: 1420,
|
||||
strictPort: true,
|
||||
host: host || false,
|
||||
allowedHosts: [
|
||||
"frontend-runner-alphahuman-git-main-vezuresxyz.vercel.app",
|
||||
],
|
||||
hmr: host
|
||||
? {
|
||||
protocol: "ws",
|
||||
|
||||
Reference in New Issue
Block a user