mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
fix: replace deprecated Telegram Login Widget redirect with callback
Telegram deprecated the data-auth-url redirect flow, which returns a blank page with "deprecated" text. Switch both TelegramLinkWidget (account linking) and TelegramLoginButton (legacy login) to use data-onauth callback approach that works client-side without redirects.
This commit is contained in:
@@ -106,6 +106,8 @@ export default function TelegramLoginButton({ referralCode }: TelegramLoginButto
|
|||||||
}, [isOIDC, widgetConfig?.oidc_client_id, widgetConfig?.request_access]);
|
}, [isOIDC, widgetConfig?.oidc_client_id, widgetConfig?.request_access]);
|
||||||
|
|
||||||
// Legacy widget effect (only when NOT OIDC)
|
// Legacy widget effect (only when NOT OIDC)
|
||||||
|
const loginWithTelegramWidget = useAuthStore((s) => s.loginWithTelegramWidget);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOIDC || !containerRef.current || !botUsername || !widgetConfig) return;
|
if (isOIDC || !containerRef.current || !botUsername || !widgetConfig) return;
|
||||||
|
|
||||||
@@ -114,7 +116,25 @@ export default function TelegramLoginButton({ referralCode }: TelegramLoginButto
|
|||||||
container.removeChild(container.firstChild);
|
container.removeChild(container.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
const redirectUrl = `${window.location.origin}/auth/telegram/callback`;
|
const callbackName = '__onTelegramWidgetAuth';
|
||||||
|
(window as unknown as Record<string, unknown>)[callbackName] = async (
|
||||||
|
user: Record<string, unknown>,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
await loginWithTelegramWidget({
|
||||||
|
id: user.id as number,
|
||||||
|
first_name: user.first_name as string,
|
||||||
|
last_name: (user.last_name as string) || undefined,
|
||||||
|
username: (user.username as string) || undefined,
|
||||||
|
photo_url: (user.photo_url as string) || undefined,
|
||||||
|
auth_date: user.auth_date as number,
|
||||||
|
hash: user.hash as string,
|
||||||
|
});
|
||||||
|
navigate('/');
|
||||||
|
} catch {
|
||||||
|
// Error handled by auth store
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.src = 'https://telegram.org/js/telegram-widget.js?23';
|
script.src = 'https://telegram.org/js/telegram-widget.js?23';
|
||||||
@@ -122,7 +142,7 @@ export default function TelegramLoginButton({ referralCode }: TelegramLoginButto
|
|||||||
script.setAttribute('data-size', widgetConfig.size);
|
script.setAttribute('data-size', widgetConfig.size);
|
||||||
script.setAttribute('data-radius', String(widgetConfig.radius));
|
script.setAttribute('data-radius', String(widgetConfig.radius));
|
||||||
script.setAttribute('data-userpic', String(widgetConfig.userpic));
|
script.setAttribute('data-userpic', String(widgetConfig.userpic));
|
||||||
script.setAttribute('data-auth-url', redirectUrl);
|
script.setAttribute('data-onauth', `${callbackName}(user)`);
|
||||||
if (widgetConfig.request_access) {
|
if (widgetConfig.request_access) {
|
||||||
script.setAttribute('data-request-access', 'write');
|
script.setAttribute('data-request-access', 'write');
|
||||||
}
|
}
|
||||||
@@ -131,11 +151,12 @@ export default function TelegramLoginButton({ referralCode }: TelegramLoginButto
|
|||||||
container.appendChild(script);
|
container.appendChild(script);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
delete (window as unknown as Record<string, unknown>)[callbackName];
|
||||||
while (container.firstChild) {
|
while (container.firstChild) {
|
||||||
container.removeChild(container.firstChild);
|
container.removeChild(container.firstChild);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [isOIDC, botUsername, widgetConfig]);
|
}, [isOIDC, botUsername, widgetConfig, loginWithTelegramWidget, navigate]);
|
||||||
|
|
||||||
if (!botUsername || botUsername === 'your_bot') {
|
if (!botUsername || botUsername === 'your_bot') {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ export const LINK_TELEGRAM_STATE_KEY = 'link_telegram_state';
|
|||||||
/** Compact Telegram Login Widget for account linking (browser only). */
|
/** Compact Telegram Login Widget for account linking (browser only). */
|
||||||
function TelegramLinkWidget() {
|
function TelegramLinkWidget() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { showToast } = useToast();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const botUsername = import.meta.env.VITE_TELEGRAM_BOT_USERNAME || '';
|
const botUsername = import.meta.env.VITE_TELEGRAM_BOT_USERNAME || '';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -37,29 +41,53 @@ function TelegramLinkWidget() {
|
|||||||
container.removeChild(container.firstChild);
|
container.removeChild(container.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate CSRF state token and store in sessionStorage
|
// Global callback invoked by the Telegram Login Widget
|
||||||
const csrfState = crypto.randomUUID();
|
const callbackName = '__onTelegramLinkAuth';
|
||||||
sessionStorage.setItem(LINK_TELEGRAM_STATE_KEY, csrfState);
|
(window as unknown as Record<string, unknown>)[callbackName] = async (
|
||||||
|
user: Record<string, unknown>,
|
||||||
const redirectUrl = `${window.location.origin}/auth/link/telegram/callback?csrf_state=${encodeURIComponent(csrfState)}`;
|
) => {
|
||||||
|
try {
|
||||||
|
const response = await authApi.linkTelegram({
|
||||||
|
id: user.id as number,
|
||||||
|
first_name: user.first_name as string,
|
||||||
|
last_name: (user.last_name as string) || undefined,
|
||||||
|
username: (user.username as string) || undefined,
|
||||||
|
photo_url: (user.photo_url as string) || undefined,
|
||||||
|
auth_date: user.auth_date as number,
|
||||||
|
hash: user.hash as string,
|
||||||
|
});
|
||||||
|
if (response.merge_required && response.merge_token) {
|
||||||
|
navigate(`/merge/${response.merge_token}`, { replace: true });
|
||||||
|
} else {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['linked-providers'] });
|
||||||
|
showToast({ type: 'success', message: t('profile.accounts.linkSuccess') });
|
||||||
|
}
|
||||||
|
} catch (err: unknown) {
|
||||||
|
showToast({
|
||||||
|
type: 'error',
|
||||||
|
message: getErrorDetail(err) || t('profile.accounts.linkError'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.src = 'https://telegram.org/js/telegram-widget.js?23';
|
script.src = 'https://telegram.org/js/telegram-widget.js?23';
|
||||||
script.setAttribute('data-telegram-login', botUsername);
|
script.setAttribute('data-telegram-login', botUsername);
|
||||||
script.setAttribute('data-size', 'small');
|
script.setAttribute('data-size', 'small');
|
||||||
script.setAttribute('data-radius', '8');
|
script.setAttribute('data-radius', '8');
|
||||||
script.setAttribute('data-auth-url', redirectUrl);
|
script.setAttribute('data-onauth', `${callbackName}(user)`);
|
||||||
script.setAttribute('data-request-access', 'write');
|
script.setAttribute('data-request-access', 'write');
|
||||||
script.async = true;
|
script.async = true;
|
||||||
|
|
||||||
container.appendChild(script);
|
container.appendChild(script);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
delete (window as unknown as Record<string, unknown>)[callbackName];
|
||||||
while (container.firstChild) {
|
while (container.firstChild) {
|
||||||
container.removeChild(container.firstChild);
|
container.removeChild(container.firstChild);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [botUsername]);
|
}, [botUsername, navigate, showToast, t, queryClient]);
|
||||||
|
|
||||||
if (!botUsername) {
|
if (!botUsername) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user