GetAccountInfoResponse.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. class GetAccountInfoResponseProviderUserInfo: NSObject {
  24. /** @property providerID
  25. @brief The ID of the identity provider.
  26. */
  27. let providerID: String?
  28. /** @property displayName
  29. @brief The user's display name at the identity provider.
  30. */
  31. let displayName: String?
  32. /** @property photoURL
  33. @brief The user's photo URL at the identity provider.
  34. */
  35. let photoURL: URL?
  36. /** @property federatedID
  37. @brief The user's identifier at the identity provider.
  38. */
  39. let federatedID: String?
  40. /** @property email
  41. @brief The user's email at the identity provider.
  42. */
  43. let email: String?
  44. /** @property phoneNumber
  45. @brief A phone number associated with the user.
  46. */
  47. let phoneNumber: String?
  48. /** @fn initWithAPIKey:
  49. @brief Designated initializer.
  50. @param dictionary The provider user info data from endpoint.
  51. */
  52. init(dictionary: [String: Any]) {
  53. providerID = dictionary["providerId"] as? String
  54. displayName = dictionary["displayName"] as? String
  55. if let photoURL = dictionary["photoUrl"] as? String {
  56. self.photoURL = URL(string: photoURL)
  57. } else {
  58. photoURL = nil
  59. }
  60. federatedID =
  61. dictionary["federatedId"] as? String
  62. email = dictionary["email"] as? String
  63. phoneNumber = dictionary["phoneNumber"] as? String
  64. }
  65. }
  66. /** @class FIRGetAccountInfoResponseUser
  67. @brief Represents the firebase user info part of the response from the getAccountInfo endpoint.
  68. @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo
  69. */
  70. class GetAccountInfoResponseUser: NSObject {
  71. /** @property localID
  72. @brief The ID of the user.
  73. */
  74. let localID: String?
  75. /** @property email
  76. @brief The email or the user.
  77. */
  78. let email: String?
  79. /** @property emailVerified
  80. @brief Whether the email has been verified.
  81. */
  82. let emailVerified: Bool
  83. /** @property displayName
  84. @brief The display name of the user.
  85. */
  86. let displayName: String?
  87. /** @property photoURL
  88. @brief The user's photo URL.
  89. */
  90. let photoURL: URL?
  91. /** @property creationDate
  92. @brief The user's creation date.
  93. */
  94. let creationDate: Date?
  95. /** @property lastSignInDate
  96. @brief The user's last login date.
  97. */
  98. let lastLoginDate: Date?
  99. /** @property providerUserInfo
  100. @brief The user's profiles at the associated identity providers.
  101. */
  102. let providerUserInfo: [GetAccountInfoResponseProviderUserInfo]?
  103. /** @property passwordHash
  104. @brief Information about user's password.
  105. @remarks This is not necessarily the hash of user's actual password.
  106. */
  107. let passwordHash: String?
  108. /** @property phoneNumber
  109. @brief A phone number associated with the user.
  110. */
  111. let phoneNumber: String?
  112. let mfaEnrollments: [AuthProtoMFAEnrollment]?
  113. /** @fn initWithAPIKey:
  114. @brief Designated initializer.
  115. @param dictionary The provider user info data from endpoint.
  116. */
  117. init(dictionary: [String: Any]) {
  118. if let providerUserInfoData = dictionary["providerUserInfo"] as? [[String: Any]] {
  119. providerUserInfo = providerUserInfoData.map {
  120. GetAccountInfoResponseProviderUserInfo(dictionary: $0)
  121. }
  122. } else {
  123. providerUserInfo = nil
  124. }
  125. localID = dictionary["localId"] as? String
  126. displayName = dictionary["displayName"] as? String
  127. email = dictionary["email"] as? String
  128. if let photoURL = dictionary["photoUrl"] as? String {
  129. self.photoURL = URL(string: photoURL)
  130. } else {
  131. photoURL = nil
  132. }
  133. if let createdAt = dictionary["createdAt"] as? String,
  134. let timeInterval = Double(createdAt) {
  135. // Divide by 1000 in order to convert milliseconds to seconds.
  136. creationDate = Date(timeIntervalSince1970: timeInterval / 1000)
  137. } else {
  138. creationDate = nil
  139. }
  140. if let lastLoginAt = dictionary["lastLoginAt"] as? String,
  141. let timeInterval = Double(lastLoginAt) {
  142. // Divide by 1000 in order to convert milliseconds to seconds.
  143. lastLoginDate = Date(timeIntervalSince1970: timeInterval / 1000)
  144. } else {
  145. lastLoginDate = nil
  146. }
  147. emailVerified = dictionary["emailVerified"] as? Bool ?? false
  148. passwordHash = dictionary["passwordHash"] as? String
  149. phoneNumber = dictionary["phoneNumber"] as? String
  150. if let mfaEnrollmentData = dictionary["mfaInfo"] as? [[String: AnyHashable]] {
  151. mfaEnrollments = mfaEnrollmentData.map { AuthProtoMFAEnrollment(dictionary: $0)
  152. }
  153. } else {
  154. mfaEnrollments = nil
  155. }
  156. }
  157. }
  158. /** @class FIRGetAccountInfoResponse
  159. @brief Represents the response from the setAccountInfo endpoint.
  160. @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo
  161. */
  162. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  163. class GetAccountInfoResponse: AuthRPCResponse {
  164. required init() {}
  165. /** @property providerUserInfo
  166. @brief The requested users' profiles.
  167. */
  168. var users: [GetAccountInfoResponseUser]?
  169. func setFields(dictionary: [String: AnyHashable]) throws {
  170. guard let usersData = dictionary["users"] as? [[String: AnyHashable]] else {
  171. throw AuthErrorUtils.unexpectedResponse(deserializedResponse: dictionary)
  172. }
  173. guard usersData.count == 1 else {
  174. throw AuthErrorUtils.unexpectedResponse(deserializedResponse: dictionary)
  175. }
  176. users = [GetAccountInfoResponseUser(dictionary: usersData[0])]
  177. }
  178. }