Skip to content

Commit

Permalink
Merge pull request #4647 from b-onc/feat/username-verification
Browse files Browse the repository at this point in the history
Feature: Check username validity on text field return
  • Loading branch information
tonisevener authored Nov 21, 2024
2 parents bb7adfa + b6879eb commit f821a45
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions Wikipedia/Code/WMFAccountCreationViewController.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<connections>
<action selector="textFieldDidBeginEditing:" destination="LsX-JK-bT6" eventType="editingDidBegin" id="VM3-mK-wNB"/>
<action selector="textFieldDidChange:" destination="LsX-JK-bT6" eventType="editingChanged" id="Eys-MQ-tYh"/>
<action selector="textFieldDidEndEditing:reason:" destination="LsX-JK-bT6" eventType="editingDidEnd" id="2Bj-vl-8sb"/>
<outlet property="delegate" destination="LsX-JK-bT6" id="QIw-fL-bzL"/>
</connections>
</textField>
Expand Down
22 changes: 22 additions & 0 deletions Wikipedia/Code/WMFAccountCreationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,28 @@ class WMFAccountCreationViewController: WMFScrollViewController, WMFCaptchaViewC
default: break
}
}

@IBAction func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
guard textField === usernameField, reason == .committed, let username = textField.text else { return }
let siteURL = dataStore.primarySiteURL!
// We can check for username validity in the background
Task {
accountCreator.checkUsername(username, siteURL: siteURL) { canCreate in
if !canCreate {
Task {
await MainActor.run {
self.usernameAlertLabel.text = WMFAccountCreatorError.usernameUnavailable.localizedDescription
self.usernameAlertLabel.isHidden = false
self.usernameField.textColor = self.theme.colors.error
}
}
}
} failure: { error in
// TODO: What to do if this request fails?
}

}
}

fileprivate func createAccount() {
WMFAlertManager.sharedInstance.showAlert(WMFLocalizedString("account-creation-saving", value:"Saving...", comment:"Alert shown when user saves account creation form. {{Identical|Saving}}"), sticky: true, canBeDismissedByUser: false, dismissPreviousAlerts: true, tapCallBack: nil)
Expand Down
67 changes: 67 additions & 0 deletions Wikipedia/Code/WMFAccountCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,73 @@ public struct WMFAccountCreatorResult {
}

public class WMFAccountCreator: Fetcher {

struct CheckUsernameAPIResponse: Codable {
struct Query: Codable {
struct User: Codable {
struct CanCreateError: Codable {
let message: String
let params: [String]
let type: String
let code: String
}

enum CodingKeys: String, CodingKey {
case userId = "userid"
case name
case missing
case canCreate = "cancreate"
case canCreateError = "cancreateerror"
}

let userId: Int?
let name: String
let missing: Bool?
let canCreate: Bool?
let canCreateError: [CanCreateError]?
}

let users: [User]
}

enum CodingKeys: String, CodingKey {
case batchComplete = "batchcomplete"
case query
}

let batchComplete: Bool
let query: Query
}

public func checkUsername(
_ username: String,
siteURL: URL,
success: @escaping (Bool) -> Void,
failure: @escaping WMFErrorHandler
) {
let parameters: [String: String] = [
"action": "query",
"list": "users",
"ususers": username,
"usprop": "cancreate",
"formatversion": "2",
"format": "json"
]

performDecodableMediaWikiAPIGET(
for: siteURL,
with: parameters
) { (result: Result<CheckUsernameAPIResponse, Error>) in
switch result {
case .failure(let error):
failure(error)
case .success(let apiResponse):
let usernameAvailable = apiResponse.query.users.first?.canCreate ?? false
success(usernameAvailable)
}
}
}

public func createAccount(username: String, password: String, retypePassword: String, email: String?, captchaID: String?, captchaWord: String?, siteURL: URL, success: @escaping WMFAccountCreatorResultBlock, failure: @escaping WMFErrorHandler) {
var parameters: [String: String] = [
"action": "createaccount",
Expand Down

0 comments on commit f821a45

Please sign in to comment.