public void SignInAsync(TLString phoneNumber, TLString phoneCodeHash, TLString phoneCode, Action <TLAuthorization> callback, Action <TLRPCError> faultCallback = null)
        {
            var obj = new TLSignIn {
                PhoneNumber = phoneNumber, PhoneCodeHash = phoneCodeHash, PhoneCode = phoneCode
            };

            SendInformativeMessage <TLAuthorization>("auth.signIn", obj,
                                                     auth =>
            {
                _cacheService.SyncUser(auth.User, result => { });
                callback(auth);
            },
                                                     faultCallback);
        }
示例#2
0
 public void OpenMediaContact(TLInt userId, TLUserBase user, TLString phoneNumber)
 {
     if (user == null)
     {
         MTProtoService.GetFullUserAsync(new TLInputUserContact {
             UserId = userId
         },
                                         userFull => OpenContactInternal(userFull.User, phoneNumber));
     }
     else
     {
         OpenContactInternal(user, phoneNumber);
     }
 }
示例#3
0
        private string GetChatSubtitle3()
        {
            var channel = CurrentItem as TLChannel;

            if (channel != null)
            {
                if (!TLString.IsNullOrEmpty(channel.About))
                {
                    return(channel.About.ToString());
                }
            }

            return(string.Empty);
        }
示例#4
0
        private DownloadableItem GetDownloadableItem(TLString fileName, TLInt dcId, TLInputDocumentFileLocation location, TLObject owner, TLInt fileSize)
        {
            var item = new DownloadableItem
            {
                DCId     = dcId,
                FileName = fileName,
                Owner    = owner,
                InputDocumentLocation = location
            };

            item.Parts = GetItemParts(fileSize, item);

            return(item);
        }
        private static void AddSecureSecret(
            TLPasswordSettings passwordSettings, TLPassword passwordBase, TLString password,
            TLAuthorizationForm authorizationForm, IList <TLSecureValue> secureValues,
            IMTProtoService mtProtoService, IStateService stateService, INavigationService navigationService)
        {
            var passwordSettings83 = passwordSettings as TLPasswordSettings83;

            if (passwordSettings83 == null)
            {
                return;
            }

            var password84 = passwordBase as TLPassword84;

            if (password84 == null)
            {
                return;
            }

            var newSettings = new TLPasswordInputSettings83 {
                Flags = new TLInt(0)
            };

            Utils.Password.AddRandomSecureSecret(newSettings, password84, password);

            mtProtoService.GetPasswordAsync(
                resul1 =>
            {
                var srpParams = resul1 as IPasswordSRPParams;
                if (srpParams == null)
                {
                    return;
                }

                var currentPasswordHash = passwordBase.CurrentPasswordHash ?? TLString.Empty;
                mtProtoService.UpdatePasswordSettingsAsync(SRP.GetCheck(currentPasswordHash, srpParams.SRPId, srpParams.SRPB, srpParams.CurrentAlgo), newSettings,
                                                           result2 =>
                {
                    passwordSettings83.SecureSettings = newSettings.NewSecureSettings;

                    NavigateToPassportCommon(
                        passwordSettings83, passwordBase, password,
                        authorizationForm, secureValues,
                        mtProtoService, stateService, navigationService);
                },
                                                           error2 => { });
            },
                error1 => { });
        }
示例#6
0
        private void Rekey()
        {
            var chat = Chat as TLEncryptedChat20;

            if (chat == null)
            {
                return;
            }
            if (chat.PFS_ExchangeId != null)
            {
                return;
            }

            var layer = chat.Layer;

            if (layer.Value < 20)
            {
                return;
            }

            var aBytes = new byte[256];
            var random = new SecureRandom();

            random.NextBytes(aBytes);
            var p = chat.P;
            var g = chat.G;

            var gaBytes = Telegram.Api.Services.MTProtoService.GetGB(aBytes, g, p);
            var ga      = TLString.FromBigEndianData(gaBytes);

            var randomId = TLLong.Random();

            chat.PFS_A          = TLString.FromBigEndianData(aBytes);
            chat.PFS_ExchangeId = randomId;
            var actionRequestKey = new TLDecryptedMessageActionRequestKey {
                ExchangeId = randomId, GA = ga
            };
            var decryptedTuple = GetDecryptedServiceMessageAndObject(actionRequestKey, chat, MTProtoService.CurrentUserId, CacheService);

            decryptedTuple.Item1.Unread = TLBool.False;
#if DEBUG
            Items.Insert(0, decryptedTuple.Item1);
#endif

            SendEncryptedService(chat, decryptedTuple.Item2, MTProtoService, CacheService,
                                 result =>
            {
            });
        }
        private static byte[] ComposeSendMessageRequest(TLInputPeerBase peerBase, TLString message, TLLong randomId)
        {
            //#4cde0aab
            var signature = new byte[] { 0xab, 0x0a, 0xde, 0x4c };

            TLUtils.WriteLine("Peer: " + peerBase);
            TLUtils.WriteLine("Message: " + message);
            TLUtils.WriteLine("RandomId: " + randomId);

            return(signature
                   .Concat(peerBase.ToBytes())
                   .Concat(message.ToBytes())
                   .Concat(randomId.ToBytes())
                   .ToArray());
        }
示例#8
0
        public static TLString GetOldHash(TLPasswordKdfAlgoBase kdfAlgoBase, TLString password)
        {
            var algo = kdfAlgoBase as TLPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow;

            if (algo != null)
            {
                var salt1 = algo.Salt1;

                var hash1 = GetHash(salt1, password);

                return(hash1);
            }

            return(null);
        }
示例#9
0
        private DownloadableItem GetDownloadableItem(TLString fileName, TLInt dcId, TLInputFileLocationBase location, TLObject owner, TLInt fileSize, Action <DownloadableItem> callback)
        {
            var item = new DownloadableItem
            {
                DCId          = dcId,
                FileName      = fileName,
                Owner         = owner,
                InputLocation = location,
                Callback      = callback
            };

            item.Parts = GetItemParts(fileSize, item);

            return(item);
        }
        public void Open(TLUserBase user, TLChatBase chat, Action <AddChatParticipantBoxResult> callback)
        {
            var userName = user.FirstName;

            if (TLString.IsNullOrEmpty(userName))
            {
                userName = user.LastName;
            }

            AddUserToTheGroupString = string.Format(AppResources.AddUserToTheGroup, userName, chat.FullName);
            NotifyOfPropertyChange(() => AddUserToTheGroupString);

            IsOpen    = true;
            _callback = callback;
        }
示例#11
0
        public void UploadFile(TLLong fileId, TLObject owner, StorageFile file, TLString key, TLString iv)
        {
            FileUtils.SwitchIdleDetectionMode(false);
            var item = FileUtils.GetUploadableItem(fileId, owner, file, key, iv);

            //if (item)
            //{
            //    item.IsSmallFile = false;   // to void auto convert small video documents to videos on server side
            //}
            lock (_itemsSyncRoot)
            {
                _items.Add(item);
            }

            StartAwaitingWorkers();
        }
        public EncryptionKeyViewModel(IStateService stateService)
        {
            _key = stateService.CurrentKey;
            stateService.CurrentKey = null;

            _contact = stateService.CurrentContact;
            stateService.CurrentContact = null;

            _chat = stateService.CurrentEncryptedChat;
            stateService.CurrentEncryptedChat = null;

            var timer = Stopwatch.StartNew();

            Bitmap            = CreateKeyBitmap(_chat);
            VisualizationTime = timer.Elapsed.ToString();
        }
        public static string Convert(TLString phone)
        {
//#if WP8
//            var phoneUtil = PhoneNumberUtil.GetInstance();
//            try
//            {
//                return phoneUtil.Format(phoneUtil.Parse("+" + phone.Value, ""), PhoneNumberFormat.INTERNATIONAL).Replace('-', ' ');
//            }
//            catch (Exception e)
//            {
//                return "+" + phone.Value;
//            }

//#endif
            return("+" + phone.Value);
        }
示例#14
0
        private string GetChatSubtitle3()
        {
            var user = CurrentItem as TLUser;

            if (user != null && user.IsBot)
            {
                var botInfo = user.BotInfo as TLBotInfo;
                if (botInfo != null &&
                    !TLString.IsNullOrEmpty(botInfo.Description))
                {
                    return(botInfo.Description.ToString());
                }
            }

            return(string.Empty);
        }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var message = value as TLMessage;

            if (message == null)
            {
                return(Visibility.Collapsed);
            }

            if (TLString.IsNullOrEmpty(message.Message))
            {
                return(Visibility.Collapsed);
            }

            return(Visibility.Visible);
        }
示例#16
0
        private static string GetWavFileName(object dataContext)
        {
            var attachment = dataContext as TLMessageMediaAudio;

            if (attachment != null)
            {
                var audio = attachment.Audio as TLAudio;
                if (audio != null)
                {
                    if (TLString.Equals(audio.MimeType, new TLString("audio/mpeg"), StringComparison.OrdinalIgnoreCase))
                    {
                        Execute.BeginOnThreadPool(async() =>
                        {
                            var audioFileName = audio.GetFileName();
#if WP81
                            try
                            {
                                var documentFile = await ApplicationData.Current.LocalFolder.GetFileAsync(audioFileName);
                                Launcher.LaunchFileAsync(documentFile);
                            }
                            catch (Exception ex)
                            {
                                Execute.ShowDebugMessage("LocalFolder.GetFileAsync docLocal exception \n" + ex);
                            }
#elif WP8
                            var file = await ApplicationData.Current.LocalFolder.GetFileAsync(audioFileName);
                            Launcher.LaunchFileAsync(file);
                            return;
#endif
                        });
                    }
                    return(string.Format("audio{0}_{1}.wav", audio.Id, audio.AccessHash));
                }
            }

            var decryptedMediaAudio = dataContext as TLDecryptedMessageMediaAudio;
            if (decryptedMediaAudio != null)
            {
                var file = decryptedMediaAudio.File as TLEncryptedFile;
                if (file != null)
                {
                    return(string.Format("audio{0}_{1}.wav", file.Id, file.AccessHash));
                }
            }

            return(null);
        }
        public ShippingInfoViewModel(ICacheService cacheService, ICommonErrorHandler errorHandler, IStateService stateService, INavigationService navigationService, IMTProtoService mtProtoService, ITelegramEventAggregator eventAggregator)
            : base(cacheService, errorHandler, stateService, navigationService, mtProtoService, eventAggregator)
        {
            if (PaymentInfo != null && PaymentInfo.Form != null)
            {
                var savedInfo = PaymentInfo.Form.SavedInfo;
                if (savedInfo != null)
                {
                    Name = savedInfo.Name != null?savedInfo.Name.ToString() : null;

                    var phone = TLString.IsNullOrEmpty(savedInfo.Phone) ? string.Empty : savedInfo.Phone.ToString();
                    if (!string.IsNullOrEmpty(phone))
                    {
                        var codeCounty = CountryUtils.CountriesSource.FirstOrDefault(x => phone.StartsWith(x.PhoneCode, StringComparison.OrdinalIgnoreCase));
                        if (codeCounty != null)
                        {
                            PhoneCode = codeCounty.PhoneCode;
                            var index       = phone.IndexOf(PhoneCode, StringComparison.OrdinalIgnoreCase);
                            var phoneNumber = (index < 0)
                                ? phone
                                : phone.Remove(index, PhoneCode.Length);
                            PhoneNumber = phoneNumber;
                        }
                        else
                        {
                            PhoneNumber = phone;
                        }
                    }
                    Email = savedInfo.Email != null?savedInfo.Email.ToString() : null;

                    if (savedInfo.ShippingAddress != null)
                    {
                        var country = CountryUtils.CountriesSource.FirstOrDefault(x => string.Equals(savedInfo.ShippingAddress.CountryIso2.ToString(), x.Code, StringComparison.OrdinalIgnoreCase));

                        StreetLine1      = savedInfo.ShippingAddress.StreetLine1.ToString();
                        StreetLine2      = savedInfo.ShippingAddress.StreetLine2.ToString();
                        City             = savedInfo.ShippingAddress.City.ToString();
                        State            = savedInfo.ShippingAddress.State.ToString();
                        _selectedCountry = country;
                        PostCode         = savedInfo.ShippingAddress.PostCode.ToString();
                    }
                }
            }

            SaveShippingInformation = true;
        }
示例#18
0
        private static byte[] ComposeSendCallRequest(TLString phone, TLString phoneCodeHash)
        {
            TLUtils.WriteLine("--Compose SendCallAsync request--");

            var signature = new byte[] { 0x64, 0x15, 0xc5, 0x03 };

            TLUtils.WriteLine("Phone: " + phone);
            TLUtils.WriteLine("Phone serialized: " + BitConverter.ToString(phone.ToBytes()));

            TLUtils.WriteLine("PhoneCodeHash: " + phoneCodeHash.ToString());
            TLUtils.WriteLine("PhoneCodeHash serialized: " + BitConverter.ToString(phoneCodeHash.ToBytes()));

            return(signature
                   .Concat(phone.ToBytes())
                   .Concat(phoneCodeHash.ToBytes())
                   .ToArray());
        }
        public void GetAuthorizationFormAsync(TLInt botId, TLString scope, TLString publicKey, Action <TLAuthorizationForm> callback, Action <TLRPCError> faultCallback = null)
        {
            var obj = new TLGetAuthorizationForm {
                BotId = botId, Scope = scope, PublicKey = publicKey
            };

            SendInformativeMessage <TLAuthorizationForm>("account.getAuthorizationForm", obj,
                                                         result =>
            {
                _cacheService.SyncUsers(result.Users, users =>
                {
                    result.Users = users;
                    callback.SafeInvoke(result);
                });
            },
                                                         faultCallback);
        }
        public void AddContact()
        {
            if (CurrentContact == null)
            {
                return;
            }
            if (!HasPhone)
            {
                return;
            }

            var userPhone = new TLString(Phone);

            if (TLString.IsNullOrEmpty(userPhone))
            {
                return;
            }

            IsWorking = true;
            ImportContactAsync(CurrentContact, userPhone, MTProtoService,
                               result =>
            {
                IsWorking = false;

                if (result.Users.Count > 0)
                {
                    EventAggregator.Publish(result.Users[0]);
                    RaiseImportStatusChanged(new ImportEventArgs {
                        Imported = true
                    });
                    var contact = result.Users[0] as TLUserContact;
                    if (contact != null)
                    {
                        EventAggregator.Publish(new AddedToContactsEventArgs {
                            Contact = contact
                        });
                        ContactsHelper.CreateContactAsync(_fileManager, StateService, contact);
                    }
                }
            },
                               error =>
            {
                IsWorking = false;
                Execute.ShowDebugMessage("contacts.importContacts error " + error);
            });
        }
示例#21
0
        public WebViewModel(IStateService stateService, INavigationService navigationService, IMTProtoService mtProtoService)
        {
            _stateService      = stateService;
            _navigationService = navigationService;
            _mtProtoService    = mtProtoService;

            _sharedContact             = stateService.SharedContact as TLUser;
            stateService.SharedContact = null;

            var userName = _sharedContact as IUserName;

            if (userName != null && !TLString.IsNullOrEmpty(userName.UserName))
            {
                Subtitle = "@" + userName.UserName;
            }

            _botCallbackAnswer             = stateService.BotCallbackAnswer;
            stateService.BotCallbackAnswer = null;

            _forwardMessages             = stateService.ForwardMessages;
            stateService.ForwardMessages = null;

            var botCallbackAnswer54 = _botCallbackAnswer as TLBotCallbackAnswer54;

            if (botCallbackAnswer54 != null)
            {
                Url = new Uri(botCallbackAnswer54.Url.ToString(), UriKind.RelativeOrAbsolute);
#if DEBUG
                Clipboard.SetText(botCallbackAnswer54.Url.ToString());
                MessageBox.Show(botCallbackAnswer54.Url.ToString());
#endif
            }

            _game             = stateService.Game;
            stateService.Game = null;

            if (_game != null)
            {
                GameTitle = _game.Title.ToString();
            }

            _inputPeer             = stateService.InputPeer;
            stateService.InputPeer = null;

            _timer = new Timer(OnTimerTick);
        }
        private void OpenContactInternal(TLUserBase user, TLString phoneNumber)
        {
            if (user == null)
            {
                return;
            }

            if (View != null)
            {
                View.CreateBitmapCache(() => BeginOnUIThread(() =>
                {
                    StateService.CurrentContact      = user;
                    StateService.CurrentContactPhone = phoneNumber;
                    NavigationService.UriFor <ContactViewModel>().Navigate();
                }));
            }
        }
示例#23
0
        public void Passport()
        {
            if (IsWorking)
            {
                return;
            }

            var passportConfig     = StateService.GetPassportConfig();
            var passportConfigHash = passportConfig != null ? passportConfig.Hash : new TLInt(0);

            MTProtoService.GetPassportDataAsync(
                (result1, result2) => BeginOnUIThread(() =>
            {
                IsWorking = false;
                if (result1.HasPassword)
                {
                    StateService.Password     = result1;
                    StateService.SecureValues = result2;
                    NavigationService.UriFor <Passport.EnterPasswordViewModel>().Navigate();
                    return;
                }

                if (!result1.HasPassword)
                {
                    if (!TLString.IsNullOrEmpty(result1.EmailUnconfirmedPattern))
                    {
                        StateService.Password     = result1;
                        StateService.SecureValues = result2;
                        NavigationService.UriFor <PasswordViewModel>().Navigate();
                    }
                    else
                    {
                        StateService.Password     = result1;
                        StateService.SecureValues = result2;
                        NavigationService.UriFor <PasswordIntroViewModel>().Navigate();
                    }
                    return;
                }
            }),
                error => BeginOnUIThread(() =>
            {
                IsWorking = false;
                Execute.ShowDebugMessage("passport.container error " + error);
            }));
        }
示例#24
0
        public void GetDHConfig()
        {
            _isGettingConfig = true;
            MTProtoService.GetDHConfigAsync(new TLInt(0), new TLInt(0),
                                            result =>
            {
                var dhConfig = result as TLDHConfig;
                if (dhConfig == null)
                {
                    return;
                }
                if (!TLUtils.CheckPrime(dhConfig.P.Data, dhConfig.G.Value))
                {
                    return;
                }

                var aBytes = new byte[256];
                var random = new SecureRandom();
                random.NextBytes(aBytes);
                var gaBytes = Telegram.Api.Services.MTProtoService.GetGB(aBytes, dhConfig.G, dhConfig.P);

                dhConfig.A  = TLString.FromBigEndianData(aBytes);
                dhConfig.GA = TLString.FromBigEndianData(gaBytes);

                _isGettingConfig = false;

                Execute.BeginOnUIThread(() =>
                {
                    _dhConfig = dhConfig;

                    if (_contact != null)
                    {
                        UserAction(_contact);
                    }
                });
            },
                                            error =>
            {
                _isGettingConfig = false;
                IsWorking        = false;
                NotifyOfPropertyChange(() => IsNotWorking);
                NotifyOfPropertyChange(() => ProgressVisibility);
                Execute.ShowDebugMessage("messages.getDhConfig error: " + error);
            });
        }
        public void StartEditMessage(TLString text, TLMessage message)
        {
            if (text == null)
            {
                return;
            }
            if (message == null)
            {
                return;
            }

            _editedMessage = message;
            var config    = CacheService.GetConfig() as TLConfig48;
            var editUntil = config != null ? message.DateIndex + config.EditTimeLimit.Value + 5 * 60 : 0;

            if (message.FromId != null &&
                message.ToId is TLPeerUser &&
                message.FromId.Value == message.ToId.Id.Value)
            {
                editUntil = 0;
            }

            Reply = new TLMessagesContainter {
                EditMessage = _editedMessage as TLMessage25, EditUntil = editUntil
            };

            if (_editMessageTimer == null)
            {
                _editMessageTimer          = new DispatcherTimer();
                _editMessageTimer.Tick    += OnEditMessageTimerTick;
                _editMessageTimer.Interval = TimeSpan.FromSeconds(1.0);
            }

            _editMessageTimer.Start();

            IsEditingEnabled = true;
            Text             = text.ToString();

            CurrentInlineBot = null;
            ClearStickerHints();
            ClearInlineBotResults();
            ClearUsernameHints();
            ClearHashtagHints();
            ClearCommandHints();
        }
示例#26
0
        public void CopyLink()
        {
            if (_sharedContact == null || TLString.IsNullOrEmpty(_sharedContact.UserName))
            {
                return;
            }

            var link = string.Format(Constants.UsernameLinkPlaceholder, _sharedContact.UserName);

            if (_game != null &&
                !TLString.IsNullOrEmpty(_game.ShortName))
            {
                link += "?game=" + _game.ShortName;
            }

            Clipboard.SetText(link);
            MessageBox.Show(AppResources.CopyLinkHint);
        }
示例#27
0
        public static TLString GetHash(TLPasswordBase passwordBase, TLString pwd)
        {
            var password83 = passwordBase as TLPassword83;

            if (password83 != null)
            {
                return(GetNewHash(password83.CurrentAlgo, pwd));
            }

            var password = passwordBase as TLPassword;

            if (password != null)
            {
                return(GetHash(password.CurrentSalt, pwd));
            }

            return(null);
        }
示例#28
0
        private static TLPQInnerData GetInnerData(TLInt dcId, TLResPQ resPQ, TLInt256 newNonce, out TimeSpan calcTime, out WindowsPhone.Tuple <ulong, ulong> pqPair)
        {
            var pq = BitConverter.ToUInt64(resPQ.PQ.Data.Reverse().ToArray(), 0);

            TLUtils.WriteLine("pq: " + pq);

            var pqCalcTime = Stopwatch.StartNew();

            try
            {
                pqPair = Utils.GetFastPQ(pq);
                pqCalcTime.Stop();
                calcTime = pqCalcTime.Elapsed;
                TLUtils.WriteLineAtBegin("Pq Fast calculation time: " + pqCalcTime.Elapsed);
                TLUtils.WriteLine("p: " + pqPair.Item1);
                TLUtils.WriteLine("q: " + pqPair.Item2);
            }
            catch (Exception e)
            {
                pqCalcTime = Stopwatch.StartNew();
                pqPair     = Utils.GetPQPollard(pq);
                pqCalcTime.Stop();
                calcTime = pqCalcTime.Elapsed;
                TLUtils.WriteLineAtBegin("Pq Pollard calculation time: " + pqCalcTime.Elapsed);
                TLUtils.WriteLine("p: " + pqPair.Item1);
                TLUtils.WriteLine("q: " + pqPair.Item2);
            }

            var p = TLString.FromUInt64(pqPair.Item1);
            var q = TLString.FromUInt64(pqPair.Item2);

            var innerData1 = new TLPQInnerDataDC
            {
                NewNonce    = newNonce,
                Nonce       = resPQ.Nonce,
                P           = p,
                Q           = q,
                PQ          = resPQ.PQ,
                ServerNonce = resPQ.ServerNonce,
                DCId        = dcId
            };

            return(innerData1);
        }
示例#29
0
        protected override void OnActivate()
        {
            StartTimer();

            if (StateService.RemoveBackEntry)
            {
                StateService.RemoveBackEntry = false;
                NavigationService.RemoveBackEntry();
            }

            if (StateService.Password == null)
            {
                _suppressPasswordEnabled = true;
                if (_password != null)
                {
                    PasswordEnabled = _password.IsAvailable;
                    RecoveryEmailUnconfirmedVisibility = !TLString.IsNullOrEmpty(_password.EmailUnconfirmedPattern) || (_password is TLPassword && ((TLPassword)_password).HasRecovery.Value)
                        ? Visibility.Visible
                        : Visibility.Collapsed;
                    NotifyOfPropertyChange(() => RecoveryEmailLabel);
                    NotifyOfPropertyChange(() => CompletePasswordLabel);
                    NotifyOfPropertyChange(() => ChangePasswordVisibility);
                    NotifyOfPropertyChange(() => CompletePasswordVisibility);
                }
                _suppressPasswordEnabled = false;
            }
            else
            {
                _password             = StateService.Password;
                StateService.Password = null;

                StartTimer();

                RecoveryEmailUnconfirmedVisibility = !TLString.IsNullOrEmpty(_password.EmailUnconfirmedPattern) || (_password is TLPassword && ((TLPassword)_password).HasRecovery.Value)
                     ? Visibility.Visible
                     : Visibility.Collapsed;
                NotifyOfPropertyChange(() => RecoveryEmailLabel);
                NotifyOfPropertyChange(() => CompletePasswordLabel);
                NotifyOfPropertyChange(() => ChangePasswordVisibility);
                NotifyOfPropertyChange(() => CompletePasswordVisibility);
            }

            base.OnActivate();
        }
        public void GetAuthorizationFormAndPassportConfigAsync(TLInt botId, TLString scope, TLString publicKey, TLInt passportConfigHash, Action <TLAuthorizationForm, TLPassportConfigBase> callback, Action <TLRPCError> faultCallback = null)
        {
            var requests = new TLObject[]
            {
                new TLGetAuthorizationForm
                {
                    BotId     = botId,
                    Scope     = scope,
                    PublicKey = publicKey
                },
                new TLGetPassportConfig
                {
                    Hash = passportConfigHash
                }
            };

            var returnValue = new TLObject[2];

            GetPassportRequestsInternal(
                requests,
                result =>
            {
                bool completed;
                lock (returnValue)
                {
                    if (result is TLAuthorizationForm)
                    {
                        returnValue[0] = result;
                    }
                    if (result is TLPassportConfigBase)
                    {
                        returnValue[1] = result;
                    }
                    completed = returnValue[0] != null && returnValue[1] != null;
                }

                if (completed)
                {
                    callback.SafeInvoke(returnValue[0] as TLAuthorizationForm, returnValue[1] as TLPassportConfigBase);
                }
            },
                faultCallback.SafeInvoke);
        }