test for telegram

This commit is contained in:
sdarbinyan
2026-06-20 14:12:22 +04:00
parent 9386fbc2f8
commit b9be1ff007
2 changed files with 108 additions and 7 deletions

View File

@@ -19,22 +19,53 @@ export class TelegramLoginComponent implements OnDestroy {
webSessionID = signal('');
qrStatus = signal<'loading' | 'ready' | 'expired' | 'error'>('loading');
encodedQrUrl = computed(() => encodeURIComponent(this.loginUrl()));
awaitingTelegramReturn = signal(false);
private readonly pollIntervalMs = 5000;
private pollTimer?: ReturnType<typeof setInterval>;
private mobileFallbackTimeout?: ReturnType<typeof setTimeout>;
private readonly handleVisibilityChange = () => {
if (document.visibilityState === 'hidden') {
this.clearMobileFallbackTimeout();
return;
}
this.resumeLoginPolling();
};
private readonly handleWindowFocus = () => {
this.resumeLoginPolling();
};
private readonly handlePageShow = () => {
this.resumeLoginPolling();
};
constructor() {
effect(() => {
if (this.showDialog()) {
this.initQrLogin();
} else {
this.awaitingTelegramReturn.set(false);
this.clearMobileFallbackTimeout();
this.stopPolling();
}
});
if (typeof window !== 'undefined') {
document.addEventListener('visibilitychange', this.handleVisibilityChange);
window.addEventListener('focus', this.handleWindowFocus);
window.addEventListener('pageshow', this.handlePageShow);
}
}
ngOnDestroy(): void {
this.clearMobileFallbackTimeout();
this.stopPolling();
if (typeof window !== 'undefined') {
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
window.removeEventListener('focus', this.handleWindowFocus);
window.removeEventListener('pageshow', this.handlePageShow);
}
}
close(): void {
@@ -43,16 +74,21 @@ export class TelegramLoginComponent implements OnDestroy {
}
openTelegramLogin(): void {
const url = this.loginUrl();
if (!url) return;
window.open(url, '_blank');
if (!this.pollTimer) {
const webSessionID = this.webSessionID();
if (webSessionID) {
const url = this.loginUrl();
if (!url || !webSessionID) return;
if (!this.pollTimer) {
this.startPolling(webSessionID);
}
if (this.isMobileBrowser()) {
this.awaitingTelegramReturn.set(true);
this.launchTelegramOnMobile(webSessionID, url);
return;
}
window.open(url, '_blank', 'noopener,noreferrer');
}
refreshQr(): void {
@@ -94,6 +130,8 @@ export class TelegramLoginComponent implements OnDestroy {
this.authService.checkSessionOnce(webSessionID).subscribe({
next: (session) => {
if (session?.active) {
this.awaitingTelegramReturn.set(false);
this.clearMobileFallbackTimeout();
this.stopPolling();
this.authService.onTelegramLoginComplete();
}
@@ -111,4 +149,57 @@ export class TelegramLoginComponent implements OnDestroy {
this.pollTimer = undefined;
}
}
private resumeLoginPolling(): void {
if (!this.showDialog() || !this.awaitingTelegramReturn()) {
return;
}
const webSessionID = this.webSessionID();
if (!webSessionID) {
this.awaitingTelegramReturn.set(false);
return;
}
if (!this.pollTimer) {
this.startPolling(webSessionID);
}
this.authService.checkSessionOnce(webSessionID).subscribe(session => {
if (session?.active) {
this.awaitingTelegramReturn.set(false);
this.stopPolling();
this.authService.onTelegramLoginComplete();
}
});
}
private launchTelegramOnMobile(webSessionID: string, fallbackUrl: string): void {
this.clearMobileFallbackTimeout();
this.mobileFallbackTimeout = setTimeout(() => {
if (typeof document !== 'undefined' && document.visibilityState === 'visible') {
window.location.assign(fallbackUrl);
}
}, 1200);
window.location.assign(this.authService.getTelegramAppLoginUrl(webSessionID));
}
private clearMobileFallbackTimeout(): void {
if (this.mobileFallbackTimeout) {
clearTimeout(this.mobileFallbackTimeout);
this.mobileFallbackTimeout = undefined;
}
}
private isMobileBrowser(): boolean {
if (typeof navigator === 'undefined') {
return false;
}
const userAgent = navigator.userAgent || navigator.vendor;
const isTouchMac = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
return /Android|iPhone|iPad|iPod|IEMobile|Opera Mini/i.test(userAgent) || isTouchMac;
}
}

View File

@@ -84,10 +84,16 @@ export class AuthService {
/** Generate the Telegram login URL for bot-based auth */
getTelegramLoginUrl(webSessionID = this.generateGuid()): string {
const botUsername = (environment as Record<string, unknown>)['telegramBot'] as string || 'DexarSupport_bot';
const botUsername = this.getTelegramBotUsername();
return `https://t.me/${botUsername}?start=${encodeURIComponent(webSessionID)}`;
}
/** Generate the Telegram app deep link for mobile auth handoff. */
getTelegramAppLoginUrl(webSessionID: string): string {
const botUsername = this.getTelegramBotUsername();
return `tg://resolve?domain=${encodeURIComponent(botUsername)}&start=${encodeURIComponent(webSessionID)}`;
}
/** Get QR code data URL for Telegram login */
getTelegramQrUrl(): string {
return this.getTelegramLoginUrl();
@@ -348,4 +354,8 @@ export class AuthService {
document.cookie = `${WEB_SESSION_COOKIE}=; Max-Age=0; Path=/; SameSite=Lax`;
}
private getTelegramBotUsername(): string {
return (environment as Record<string, unknown>)['telegramBot'] as string || 'DexarSupport_bot';
}
}