Sketch out CAPTCHA onboarding view.

pull/2/head
Matthew Chen 6 years ago
parent df12f71b74
commit 58abf76244

@ -485,10 +485,11 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
dispatch_async(dispatch_get_main_queue(), ^{
OnboardingController *onboardingController = [OnboardingController new];
[onboardingController
updateWithPhoneNumber:[[OnboardingPhoneNumber alloc] initWithE164:@"+13213214321" userInput:@"3213214321"]];
OnboardingCaptchaViewController *view =
[[OnboardingCaptchaViewController alloc] initWithOnboardingController:onboardingController];
// OnboardingPermissionsViewController *view =
// [[OnboardingPermissionsViewController alloc] initWithOnboardingController:onboardingController];
OWSNavigationController *navigationController =
[[OWSNavigationController alloc] initWithRootViewController:view];
[self presentViewController:navigationController animated:YES completion:nil];

@ -340,8 +340,8 @@ NS_ASSUME_NONNULL_BEGIN
[_requestCodeAgainSpinner startAnimating];
__weak CodeVerificationViewController *weakSelf = self;
[self.tsAccountManager
rerequestSMSWithSuccess:^{
[self.tsAccountManager rerequestSMSWithCaptchaToken:nil
success:^{
OWSLogInfo(@"Successfully requested SMS code");
[weakSelf enableServerActions:YES];
[weakSelf.requestCodeAgainSpinner stopAnimating];
@ -363,8 +363,8 @@ NS_ASSUME_NONNULL_BEGIN
[_requestCallSpinner startAnimating];
__weak CodeVerificationViewController *weakSelf = self;
[self.tsAccountManager
rerequestVoiceWithSuccess:^{
[self.tsAccountManager rerequestVoiceWithCaptchaToken:nil
success:^{
OWSLogInfo(@"Successfully requested voice code");
[weakSelf enableServerActions:YES];

@ -7,6 +7,15 @@ import PromiseKit
@objc
public class OnboardingBaseViewController: OWSViewController {
// MARK: - Dependencies
private var tsAccountManager: TSAccountManager {
return TSAccountManager.sharedInstance()
}
// MARK: -
// Unlike a delegate, we can and should retain a strong reference to the OnboardingController.
let onboardingController: OnboardingController
@ -82,6 +91,65 @@ public class OnboardingBaseViewController: OWSViewController {
}
}
// MARK: - Registration
func tryToRegister(smsVerification: Bool) {
guard let phoneNumber = onboardingController.phoneNumber else {
owsFailDebug("Missing phoneNumber.")
return
}
// We eagerly update this state, regardless of whether or not the
// registration request succeeds.
OnboardingController.setLastRegisteredCountryCode(value: onboardingController.countryState.countryCode)
OnboardingController.setLastRegisteredPhoneNumber(value: phoneNumber.userInput)
let captchaToken = onboardingController.captchaToken
ModalActivityIndicatorViewController.present(fromViewController: self,
canCancel: true) { (modal) in
self.tsAccountManager.register(withPhoneNumber: phoneNumber.e164,
captchaToken: captchaToken,
success: {
DispatchQueue.main.async {
modal.dismiss(completion: {
self.registrationSucceeded()
})
}
}, failure: { (error) in
Logger.error("Error: \(error)")
DispatchQueue.main.async {
modal.dismiss(completion: {
self.registrationFailed(error: error as NSError)
})
}
}, smsVerification: smsVerification)
}
}
private func registrationSucceeded() {
self.onboardingController.onboardingRegistrationSucceeded(viewController: self)
}
private func registrationFailed(error: NSError) {
if error.code == 402 {
Logger.info("Captcha requested.")
self.onboardingController.onboardingDidRequireCaptcha(viewController: self)
return
} else if error.code == 400 {
OWSAlerts.showAlert(title: NSLocalizedString("REGISTRATION_ERROR", comment: ""),
message: NSLocalizedString("REGISTRATION_NON_VALID_NUMBER", comment: ""))
} else {
OWSAlerts.showAlert(title: error.localizedDescription,
message: error.localizedRecoverySuggestion)
}
}
// MARK: - Orientation
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {

@ -14,7 +14,6 @@ public class OnboardingCaptchaViewController: OnboardingBaseViewController {
super.loadView()
view.backgroundColor = Theme.backgroundColor
view.backgroundColor = .orange
view.layoutMargins = .zero
// TODO:
@ -45,8 +44,8 @@ public class OnboardingCaptchaViewController: OnboardingBaseViewController {
webView.allowsBackForwardNavigationGestures = false
webView.customUserAgent = "Signal iOS (+https://signal.org/download)"
webView.allowsLinkPreview = false
// webView.scrollView.contentInset = .zero
// webView.layoutMargins = .zero
webView.scrollView.contentInset = .zero
webView.layoutMargins = .zero
let stackView = UIStackView(arrangedSubviews: [
titleRow,
@ -108,46 +107,36 @@ public class OnboardingCaptchaViewController: OnboardingBaseViewController {
loadContent()
}
// MARK: - Events
// MARK: -
private func didComplete(url: URL) {
private func parseCaptchaAndTryToRegister(url: URL) {
Logger.info("")
guard let captchaToken = parseCaptcha(url: url) else {
owsFailDebug("Could not parse captcha token: \(url)")
// TODO: Alert?
//
// Reload content so user can try again.
loadContent()
return
}
onboardingController.update(captchaToken: captchaToken)
tryToRegister(smsVerification: false)
}
private func parseCaptcha(url: URL) -> String? {
Logger.info("")
// signalcaptcha://03AF6jDqXgf1PocNNrWRJEENZ9l6RAMIsUoESi2dFKkxTgE2qjdZGVjEW6SZNFQqeRRTgGqOii6zHGG--uLyC1HnhSmRt8wHeKxHcg1hsK4ucTusANIeFXVB8wPPiV7U_0w2jUFVak5clMCvW9_JBfbfzj51_e9sou8DYfwc_R6THuTBTdpSV8Nh0yJalgget-nSukCxh6FPA6hRVbw7lP3r-me1QCykHOfh-V29UVaQ4Fs5upHvwB5rtiViqT_HN8WuGmdIdGcaWxaqy1lQTgFSs2Shdj593wZiXfhJnCWAw9rMn3jSgIZhkFxdXwKOmslQ2E_I8iWkm6
guard let host = url.host,
host.count > 0 else {
owsFailDebug("Missing host.")
return
return nil
}
onboardingController.
return host
}
//
// @objc func countryRowTapped(sender: UIGestureRecognizer) {
// guard sender.state == .recognized else {
// return
// }
// showCountryPicker()
// }
//
// @objc func countryCodeTapped(sender: UIGestureRecognizer) {
// guard sender.state == .recognized else {
// return
// }
// showCountryPicker()
// }
//
// @objc func nextPressed() {
// Logger.info("")
//
// parseAndTryToRegister()
// }
//
// // MARK: -
//
// private func registrationSucceeded() {
// self.onboardingController.onboardingPhoneNumberDidComplete(viewController: self)
// }
}
// MARK: -
@ -164,7 +153,7 @@ extension OnboardingCaptchaViewController: WKNavigationDelegate {
if url.scheme == "signalcaptcha" {
decisionHandler(.cancel)
DispatchQueue.main.async {
didComplete(url: url)
self.parseCaptchaAndTryToRegister(url: url)
}
return
}
@ -202,8 +191,6 @@ extension OnboardingCaptchaViewController: WKNavigationDelegate {
Logger.verbose("navigation: \(String(describing: navigation)), error: \(error)")
}
// public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
Logger.verbose("")
}

@ -5,7 +5,7 @@
import UIKit
@objc
public class OnboardingState: NSObject {
public class OnboardingCountryState: NSObject {
public let countryName: String
public let callingCode: String
public let countryCode: String
@ -19,7 +19,7 @@ public class OnboardingState: NSObject {
self.countryCode = countryCode
}
public static var defaultValue: OnboardingState {
public static var defaultValue: OnboardingCountryState {
AssertIsOnMainThread()
var countryCode: String = PhoneNumber.defaultCountryCode()
@ -36,13 +36,35 @@ public class OnboardingState: NSObject {
countryName = countryNameDerived
}
return OnboardingState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
return OnboardingCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
}
}
// MARK: -
@objc
public class OnboardingPhoneNumber: NSObject {
public let e164: String
public let userInput: String
@objc
public init(e164: String,
userInput: String) {
self.e164 = e164
self.userInput = userInput
}
}
// MARK: -
@objc
public class OnboardingController: NSObject {
@objc
public override init() {
super.init()
}
// MARK: - Factory Methods
@objc
@ -58,6 +80,8 @@ public class OnboardingController: NSObject {
public func onboardingSplashDidComplete(viewController: UIViewController) {
AssertIsOnMainThread()
Logger.info("")
let view = OnboardingPermissionsViewController(onboardingController: self)
viewController.navigationController?.pushViewController(view, animated: true)
}
@ -65,12 +89,16 @@ public class OnboardingController: NSObject {
public func onboardingPermissionsWasSkipped(viewController: UIViewController) {
AssertIsOnMainThread()
Logger.info("")
pushPhoneNumberView(viewController: viewController)
}
public func onboardingPermissionsDidComplete(viewController: UIViewController) {
AssertIsOnMainThread()
Logger.info("")
pushPhoneNumberView(viewController: viewController)
}
@ -81,53 +109,64 @@ public class OnboardingController: NSObject {
viewController.navigationController?.pushViewController(view, animated: true)
}
public func onboardingPhoneNumberDidComplete(viewController: UIViewController) {
public func onboardingRegistrationSucceeded(viewController: UIViewController) {
AssertIsOnMainThread()
Logger.info("")
// CodeVerificationViewController *vc = [CodeVerificationViewController new];
// [weakSelf.navigationController pushViewController:vc animated:YES];
}
public func onboardingPhoneNumberDidRequireCaptcha(viewController: UIViewController) {
public func onboardingDidRequireCaptcha(viewController: UIViewController) {
AssertIsOnMainThread()
let view = OnboardingCaptchaViewController(onboardingController: self)
viewController.navigationController?.pushViewController(view, animated: true)
}
Logger.info("")
public func onboardingCaptchaDidComplete(viewController: UIViewController,
captchaToken: String) {
AssertIsOnMainThread()
guard let navigationController = viewController.navigationController else {
owsFailDebug("Missing navigationController.")
return
}
self.captchaToken = captchaToken
// The service could demand CAPTCHA from the "phone number" view or later
// from the "code verification" view. The "Captcha" view should always appear
// immediately after the "phone number" view.
while navigationController.viewControllers.count > 1 &&
!(navigationController.topViewController is OnboardingPhoneNumberViewController) {
navigationController.popViewController(animated: false)
}
// let view = OnboardingCaptchaViewController(onboardingController: self)
// viewController.navigationController?.pushViewController(view, animated: true)
let view = OnboardingCaptchaViewController(onboardingController: self)
navigationController.pushViewController(view, animated: true)
}
// MARK: - State
public private(set) var state: OnboardingState = .defaultValue
public private(set) var countryState: OnboardingCountryState = .defaultValue
private var captchaToken: String
public private(set) var phoneNumber: OnboardingPhoneNumber?
public func update(withCountryName countryName: String, callingCode: String, countryCode: String) {
public private(set) var captchaToken: String?
@objc
public func update(countryState: OnboardingCountryState) {
AssertIsOnMainThread()
guard countryCode.count > 0 else {
owsFailDebug("Invalid country code.")
return
}
guard countryName.count > 0 else {
owsFailDebug("Invalid country name.")
return
}
guard callingCode.count > 0 else {
owsFailDebug("Invalid calling code.")
return
}
self.countryState = countryState
}
@objc
public func update(phoneNumber: OnboardingPhoneNumber) {
AssertIsOnMainThread()
self.phoneNumber = phoneNumber
}
state = OnboardingState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
@objc
public func update(captchaToken: String) {
AssertIsOnMainThread()
self.captchaToken = captchaToken
}
// MARK: - Debug

@ -165,13 +165,13 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
owsFailDebug("Could not resume re-registration; couldn't parse phoneNumberE164.")
return
}
guard let callingCode = parsedPhoneNumber.getCountryCode() else {
guard let callingCodeNumeric = parsedPhoneNumber.getCountryCode() else {
owsFailDebug("Could not resume re-registration; missing callingCode.")
return
}
let callingCodeText = "\(COUNTRY_CODE_PREFIX)\(callingCode)"
let callingCode = "\(COUNTRY_CODE_PREFIX)\(callingCodeNumeric)"
let countryCodes: [String] =
PhoneNumberUtil.sharedThreadLocal().countryCodes(fromCallingCode: callingCodeText)
PhoneNumberUtil.sharedThreadLocal().countryCodes(fromCallingCode: callingCode)
guard let countryCode = countryCodes.first else {
owsFailDebug("Could not resume re-registration; unknown countryCode.")
return
@ -180,13 +180,28 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
owsFailDebug("Could not resume re-registration; unknown countryName.")
return
}
if !phoneNumberE164.hasPrefix(callingCodeText) {
if !phoneNumberE164.hasPrefix(callingCode) {
owsFailDebug("Could not resume re-registration; non-matching calling code.")
return
}
let phoneNumberWithoutCallingCode = phoneNumberE164.substring(from: callingCodeText.count)
let phoneNumberWithoutCallingCode = phoneNumberE164.substring(from: callingCode.count)
guard countryCode.count > 0 else {
owsFailDebug("Invalid country code.")
return
}
guard countryName.count > 0 else {
owsFailDebug("Invalid country name.")
return
}
guard callingCode.count > 0 else {
owsFailDebug("Invalid calling code.")
return
}
let countryState = OnboardingCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
onboardingController.update(countryState: countryState)
onboardingController.update(withCountryName: countryName, callingCode: callingCodeText, countryCode: countryCode)
updateState()
phoneNumberTextField.text = phoneNumberWithoutCallingCode
@ -198,21 +213,21 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
private var countryName: String {
get {
return onboardingController.state.countryName
return onboardingController.countryState.countryName
}
}
private var callingCode: String {
get {
AssertIsOnMainThread()
return onboardingController.state.callingCode
return onboardingController.countryState.callingCode
}
}
private var countryCode: String {
get {
AssertIsOnMainThread()
return onboardingController.state.countryCode
return onboardingController.countryState.countryCode
}
}
@ -297,10 +312,11 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
comment: "Message of alert indicating that users needs to enter a valid phone number to register."))
return
}
let parsedPhoneNumber = localNumber.toE164()
let e164PhoneNumber = localNumber.toE164()
onboardingController.update(phoneNumber: OnboardingPhoneNumber(e164: e164PhoneNumber, userInput: phoneNumberText))
if UIDevice.current.isIPad {
let countryCode = self.countryCode
OWSAlerts.showConfirmationAlert(title: NSLocalizedString("REGISTRATION_IPAD_CONFIRM_TITLE",
comment: "alert title when registering an iPad"),
message: NSLocalizedString("REGISTRATION_IPAD_CONFIRM_BODY",
@ -308,65 +324,12 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
proceedTitle: NSLocalizedString("REGISTRATION_IPAD_CONFIRM_BUTTON",
comment: "button text to proceed with registration when on an iPad"),
proceedAction: { (_) in
self.tryToRegister(parsedPhoneNumber: parsedPhoneNumber,
phoneNumberText: phoneNumberText,
countryCode: countryCode)
self.tryToRegister(smsVerification: false)
})
} else {
tryToRegister(parsedPhoneNumber: parsedPhoneNumber,
phoneNumberText: phoneNumberText,
countryCode: countryCode)
tryToRegister(smsVerification: false)
}
}
private func tryToRegister(parsedPhoneNumber: String,
phoneNumberText: String,
countryCode: String) {
ModalActivityIndicatorViewController.present(fromViewController: self,
canCancel: true) { (modal) in
OnboardingController.setLastRegisteredCountryCode(value: countryCode)
OnboardingController.setLastRegisteredPhoneNumber(value: phoneNumberText)
self.tsAccountManager.register(withPhoneNumber: parsedPhoneNumber,
success: {
DispatchQueue.main.async {
modal.dismiss(completion: {
self.registrationSucceeded()
})
}
}, failure: { (error) in
Logger.error("Error: \(error)")
DispatchQueue.main.async {
modal.dismiss(completion: {
self.registrationFailed(error: error as NSError)
})
}
}, smsVerification: true)
}
}
private func registrationSucceeded() {
self.onboardingController.onboardingPhoneNumberDidComplete(viewController: self)
}
private func registrationFailed(error: NSError) {
if error.code == 402 {
Logger.info("Captcha requested.")
self.onboardingController.onboardingPhoneNumberDidRequireCaptcha(viewController: self)
return
} else if error.code == 400 {
OWSAlerts.showAlert(title: NSLocalizedString("REGISTRATION_ERROR", comment: ""),
message: NSLocalizedString("REGISTRATION_NON_VALID_NUMBER", comment: ""))
} else {
OWSAlerts.showAlert(title: error.localizedDescription,
message: error.localizedRecoverySuggestion)
}
phoneNumberTextField.becomeFirstResponder()
}
}
// MARK: -
@ -382,7 +345,6 @@ extension OnboardingPhoneNumberViewController: UITextFieldDelegate {
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
parseAndTryToRegister()
textField.resignFirstResponder()
return false
}
}
@ -404,7 +366,10 @@ extension OnboardingPhoneNumberViewController: CountryCodeViewControllerDelegate
return
}
onboardingController.update(withCountryName: countryName, callingCode: callingCode, countryCode: countryCode)
let countryState = OnboardingCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
onboardingController.update(countryState: countryState)
updateState()
// Trigger the formatting logic with a no-op edit.

@ -448,6 +448,7 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
__weak RegistrationViewController *weakSelf = self;
[self.tsAccountManager registerWithPhoneNumber:parsedPhoneNumber
captchaToken:nil
success:^{
OWSProdInfo([OWSAnalyticsEvents registrationRegisteredPhoneNumber]);

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "RegistrationUtils.h"
@ -59,8 +59,8 @@ NS_ASSUME_NONNULL_BEGIN
presentFromViewController:fromViewController
canCancel:NO
backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
[self.tsAccountManager
registerWithPhoneNumber:self.tsAccountManager.reregisterationPhoneNumber
[self.tsAccountManager registerWithPhoneNumber:self.tsAccountManager.reregisterationPhoneNumber
captchaToken:nil
success:^{
OWSLogInfo(@"re-registering: send verification code succeeded.");

@ -90,13 +90,18 @@ typedef NS_ENUM(NSUInteger, OWSRegistrationState) {
#pragma mark - Register with phone number
- (void)registerWithPhoneNumber:(NSString *)phoneNumber
captchaToken:(nullable NSString *)captchaToken
success:(void (^)(void))successBlock
failure:(void (^)(NSError *error))failureBlock
smsVerification:(BOOL)isSMS;
- (void)rerequestSMSWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock;
- (void)rerequestSMSWithCaptchaToken:(nullable NSString *)captchaToken
success:(void (^)(void))successBlock
failure:(void (^)(NSError *error))failureBlock;
- (void)rerequestVoiceWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock;
- (void)rerequestVoiceWithCaptchaToken:(nullable NSString *)captchaToken
success:(void (^)(void))successBlock
failure:(void (^)(NSError *error))failureBlock;
- (void)verifyAccountWithCode:(NSString *)verificationCode
pin:(nullable NSString *)pin

@ -322,6 +322,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa
}
- (void)registerWithPhoneNumber:(NSString *)phoneNumber
captchaToken:(nullable NSString *)captchaToken
success:(void (^)(void))successBlock
failure:(void (^)(NSError *error))failureBlock
smsVerification:(BOOL)isSMS
@ -339,6 +340,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa
TSRequest *request =
[OWSRequestFactory requestVerificationCodeRequestWithPhoneNumber:phoneNumber
captchaToken:captchaToken
transport:(isSMS ? TSVerificationTransportSMS
: TSVerificationTransportVoice)];
[[TSNetworkManager sharedManager] makeRequest:request
@ -357,20 +359,33 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa
}];
}
- (void)rerequestSMSWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock
- (void)rerequestSMSWithCaptchaToken:(nullable NSString *)captchaToken
success:(void (^)(void))successBlock
failure:(void (^)(NSError *error))failureBlock
{
// TODO: Can we remove phoneNumberAwaitingVerification?
NSString *number = self.phoneNumberAwaitingVerification;
OWSAssertDebug(number);
[self registerWithPhoneNumber:number success:successBlock failure:failureBlock smsVerification:YES];
[self registerWithPhoneNumber:number
captchaToken:captchaToken
success:successBlock
failure:failureBlock
smsVerification:YES];
}
- (void)rerequestVoiceWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock
- (void)rerequestVoiceWithCaptchaToken:(nullable NSString *)captchaToken
success:(void (^)(void))successBlock
failure:(void (^)(NSError *error))failureBlock
{
NSString *number = self.phoneNumberAwaitingVerification;
OWSAssertDebug(number);
[self registerWithPhoneNumber:number success:successBlock failure:failureBlock smsVerification:NO];
[self registerWithPhoneNumber:number
captchaToken:captchaToken
success:successBlock
failure:failureBlock
smsVerification:NO];
}
- (void)verifyAccountWithCode:(NSString *)verificationCode

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@ -56,6 +56,7 @@ typedef NS_ENUM(NSUInteger, TSVerificationTransport) { TSVerificationTransportVo
+ (TSRequest *)unregisterAccountRequest;
+ (TSRequest *)requestVerificationCodeRequestWithPhoneNumber:(NSString *)phoneNumber
captchaToken:(nullable NSString *)captchaToken
transport:(TSVerificationTransport)transport;
+ (TSRequest *)submitMessageRequestWithRecipient:(NSString *)recipientId

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "OWSRequestFactory.h"
@ -235,13 +235,21 @@ NS_ASSUME_NONNULL_BEGIN
}
+ (TSRequest *)requestVerificationCodeRequestWithPhoneNumber:(NSString *)phoneNumber
captchaToken:(nullable NSString *)captchaToken
transport:(TSVerificationTransport)transport
{
OWSAssertDebug(phoneNumber.length > 0);
NSString *path = [NSString stringWithFormat:@"%@/%@/code/%@?client=ios",
NSString *querystring = @"client=ios";
if (captchaToken.length > 0) {
querystring = [NSString stringWithFormat:@"%@&captcha=%@", querystring, captchaToken];
}
NSString *path = [NSString stringWithFormat:@"%@/%@/code/%@?%@",
textSecureAccountsAPI,
[self stringForTransport:transport],
phoneNumber];
phoneNumber,
querystring];
TSRequest *request = [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"GET" parameters:@{}];
request.shouldHaveAuthorizationHeaders = NO;

Loading…
Cancel
Save