GetAccountInfoResponse.swift 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2023 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import Foundation
  15. /** @var kErrorKey
  16. @brief The key for the "error" value in JSON responses from the server.
  17. */
  18. private let kErrorKey = "error"
  19. /** @class FIRGetAccountInfoResponseProviderUserInfo
  20. @brief Represents the provider user info part of the response from the getAccountInfo endpoint.
  21. @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo
  22. */
  23. @objc(FIRGetAccountInfoResponseProviderUserInfo)
  24. public class GetAccountInfoResponseProviderUserInfo: NSObject {
  25. /** @property providerID
  26. @brief The ID of the identity provider.
  27. */
  28. @objc public let providerID: String?
  29. /** @property displayName
  30. @brief The user's display name at the identity provider.
  31. */
  32. @objc public let displayName: String?
  33. /** @property photoURL
  34. @brief The user's photo URL at the identity provider.
  35. */
  36. @objc public let photoURL: URL?
  37. /** @property federatedID
  38. @brief The user's identifier at the identity provider.
  39. */
  40. @objc public let federatedID: String?
  41. /** @property email
  42. @brief The user's email at the identity provider.
  43. */
  44. @objc public let email: String?
  45. /** @property phoneNumber
  46. @brief A phone number associated with the user.
  47. */
  48. @objc public let phoneNumber: String?
  49. /** @fn initWithAPIKey:
  50. @brief Designated initializer.
  51. @param dictionary The provider user info data from endpoint.
  52. */
  53. @objc public init(dictionary: [String: Any]) {
  54. providerID = dictionary["providerId"] as? String
  55. displayName = dictionary["displayName"] as? String
  56. if let photoURL = dictionary["photoUrl"] as? String {
  57. self.photoURL = URL(string: photoURL)
  58. } else {
  59. photoURL = nil
  60. }
  61. federatedID =
  62. dictionary["federatedId"] as? String
  63. email = dictionary["email"] as? String
  64. phoneNumber = dictionary["phoneNumber"] as? String
  65. }
  66. }
  67. /** @class FIRGetAccountInfoResponseUser
  68. @brief Represents the firebase user info part of the response from the getAccountInfo endpoint.
  69. @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo
  70. */
  71. @objc(FIRGetAccountInfoResponseUser) public class GetAccountInfoResponseUser: NSObject {
  72. /** @property localID
  73. @brief The ID of the user.
  74. */
  75. @objc public let localID: String?
  76. /** @property email
  77. @brief The email or the user.
  78. */
  79. @objc public let email: String?
  80. /** @property emailVerified
  81. @brief Whether the email has been verified.
  82. */
  83. @objc public let emailVerified: Bool
  84. /** @property displayName
  85. @brief The display name of the user.
  86. */
  87. @objc public let displayName: String?
  88. /** @property photoURL
  89. @brief The user's photo URL.
  90. */
  91. @objc public let photoURL: URL?
  92. /** @property creationDate
  93. @brief The user's creation date.
  94. */
  95. @objc public let creationDate: Date?
  96. /** @property lastSignInDate
  97. @brief The user's last login date.
  98. */
  99. @objc public let lastLoginDate: Date?
  100. /** @property providerUserInfo
  101. @brief The user's profiles at the associated identity providers.
  102. */
  103. @objc public let providerUserInfo: [GetAccountInfoResponseProviderUserInfo]?
  104. /** @property passwordHash
  105. @brief Information about user's password.
  106. @remarks This is not necessarily the hash of user's actual password.
  107. */
  108. @objc public let passwordHash: String?
  109. /** @property phoneNumber
  110. @brief A phone number associated with the user.
  111. */
  112. @objc public let phoneNumber: String?
  113. @objc(MFAEnrollments) public let mfaEnrollments: [AuthProtoMFAEnrollment]?
  114. /** @fn initWithAPIKey:
  115. @brief Designated initializer.
  116. @param dictionary The provider user info data from endpoint.
  117. */
  118. init(dictionary: [String: Any]) {
  119. if let providerUserInfoData = dictionary["providerUserInfo"] as? [[String: Any]] {
  120. providerUserInfo = providerUserInfoData.map {
  121. GetAccountInfoResponseProviderUserInfo(dictionary: $0)
  122. }
  123. } else {
  124. providerUserInfo = nil
  125. }
  126. localID = dictionary["localId"] as? String
  127. displayName = dictionary["displayName"] as? String
  128. email = dictionary["email"] as? String
  129. if let photoURL = dictionary["photoUrl"] as? String {
  130. self.photoURL = URL(string: photoURL)
  131. } else {
  132. photoURL = nil
  133. }
  134. if let createdAt = dictionary["createdAt"] as? String,
  135. let timeInterval = Double(createdAt) {
  136. // Divide by 1000 in order to convert milliseconds to seconds.
  137. creationDate = Date(timeIntervalSince1970: timeInterval / 1000)
  138. } else {
  139. creationDate = nil
  140. }
  141. if let lastLoginAt = dictionary["lastLoginAt"] as? String,
  142. let timeInterval = Double(lastLoginAt) {
  143. // Divide by 1000 in order to convert milliseconds to seconds.
  144. lastLoginDate = Date(timeIntervalSince1970: timeInterval / 1000)
  145. } else {
  146. lastLoginDate = nil
  147. }
  148. emailVerified = dictionary["emailVerified"] as? Bool ?? false
  149. passwordHash = dictionary["passwordHash"] as? String
  150. phoneNumber = dictionary["phoneNumber"] as? String
  151. if let mfaEnrollmentData = dictionary["mfaInfo"] as? [[String: AnyHashable]] {
  152. mfaEnrollments = mfaEnrollmentData.map { AuthProtoMFAEnrollment(dictionary: $0)
  153. }
  154. } else {
  155. mfaEnrollments = nil
  156. }
  157. }
  158. }
  159. /** @class FIRGetAccountInfoResponse
  160. @brief Represents the response from the setAccountInfo endpoint.
  161. @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo
  162. */
  163. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  164. class GetAccountInfoResponse: AuthRPCResponse {
  165. public required init() {}
  166. /** @property providerUserInfo
  167. @brief The requested users' profiles.
  168. */
  169. var users: [GetAccountInfoResponseUser]?
  170. func setFields(dictionary: [String: AnyHashable]) throws {
  171. guard let usersData = dictionary["users"] as? [[String: AnyHashable]] else {
  172. throw AuthErrorUtils.unexpectedResponse(deserializedResponse: dictionary)
  173. }
  174. guard usersData.count == 1 else {
  175. throw AuthErrorUtils.unexpectedResponse(deserializedResponse: dictionary)
  176. }
  177. users = [GetAccountInfoResponseUser(dictionary: usersData[0])]
  178. }
  179. }