VerifyAssertionResponse.swift 7.6 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. /// Represents the response from the verifyAssertion endpoint.
  16. /// See https: // developers.google.com/identity/toolkit/web/reference/relyingparty/verifyAssertion
  17. struct VerifyAssertionResponse: AuthRPCResponse, AuthMFAResponse {
  18. var federatedID: String?
  19. /// The IdP ID. For white listed IdPs it's a short domain name e.g. google.com, aol.com,
  20. /// live.net and yahoo.com.If the "providerId" param is set to OpenID OP identifier other than
  21. /// the white listed IdPs the OP identifier is returned.If the "identifier" param is federated
  22. /// ID in the createAuthUri request.The domain part of the federated ID is returned.
  23. var providerID: String?
  24. /// The RP local ID if it's already been mapped to the IdP account identified by the federated ID.
  25. var localID: String?
  26. /// The email returned by the IdP. NOTE: The federated login user may not own the email.
  27. var email: String?
  28. /// It's the identifier param in the createAuthUri request if the identifier is an email. It
  29. /// can be used to check whether the user input email is different from the asserted email.
  30. var inputEmail: String?
  31. /// The original email stored in the mapping storage. It's returned when the federated ID is
  32. /// associated to a different email.
  33. var originalEmail: String?
  34. /// The user approved request token for the OpenID OAuth extension.
  35. var oauthRequestToken: String?
  36. /// The scope for the OpenID OAuth extension.
  37. var oauthScope: String?
  38. /// The first name of the user.
  39. var firstName: String?
  40. /// The last name of the user.
  41. var lastName: String?
  42. /// The full name of the user.
  43. var fullName: String?
  44. /// The nickname of the user.
  45. var nickName: String?
  46. /// The display name of the user.
  47. var displayName: String?
  48. /// Either an authorization code suitable for performing an STS token exchange, or the
  49. /// access token from Secure Token Service, depending on whether `returnSecureToken` is set
  50. /// on the request.
  51. private(set) var idToken: String?
  52. /// The approximate expiration date of the access token.
  53. var approximateExpirationDate: Date?
  54. /// The refresh token from Secure Token Service.
  55. var refreshToken: String?
  56. /// The action code.
  57. var action: String?
  58. /// The language preference of the user.
  59. var language: String?
  60. /// The timezone of the user.
  61. var timeZone: String?
  62. /// The URI of the accessible profile picture.
  63. var photoURL: URL?
  64. /// The birth date of the IdP account.
  65. var dateOfBirth: String?
  66. /// The opaque value used by the client to maintain context info between the authentication
  67. /// request and the IDP callback.
  68. var context: String?
  69. /// When action is 'map', contains the idps which can be used for confirmation.
  70. var verifiedProvider: [String]?
  71. /// Whether the assertion is from a non-trusted IDP and need account linking confirmation.
  72. var needConfirmation: Bool = false
  73. /// It's true if the email is recycled.
  74. var emailRecycled: Bool = false
  75. /// The value is true if the IDP is also the email provider. It means the user owns the email.
  76. var emailVerified: Bool = false
  77. /// Flag indicating that the user signing in is a new user and not a returning user.
  78. var isNewUser: Bool = false
  79. /// Dictionary containing the additional IdP specific information.
  80. var profile: [String: Sendable]?
  81. /// The name of the user.
  82. var username: String?
  83. /// The ID token for the OpenID OAuth extension.
  84. var oauthIDToken: String?
  85. /// The approximate expiration date of the oauth access token.
  86. var oauthExpirationDate: Date?
  87. /// The access token for the OpenID OAuth extension.
  88. var oauthAccessToken: String?
  89. /// The secret for the OpenID OAuth extension.
  90. var oauthSecretToken: String?
  91. /// The pending ID Token string.
  92. var pendingToken: String?
  93. // MARK: - AuthMFAResponse
  94. private(set) var mfaPendingCredential: String?
  95. private(set) var mfaInfo: [AuthProtoMFAEnrollment]?
  96. init(dictionary: [String: AnyHashable]) throws {
  97. federatedID = dictionary["federatedId"] as? String
  98. providerID = dictionary["providerId"] as? String
  99. localID = dictionary["localId"] as? String
  100. emailRecycled = dictionary["emailRecycled"] as? Bool ?? false
  101. emailVerified = dictionary["emailVerified"] as? Bool ?? false
  102. email = dictionary["email"] as? String
  103. inputEmail = dictionary["inputEmail"] as? String
  104. originalEmail = dictionary["originalEmail"] as? String
  105. oauthRequestToken = dictionary["oauthRequestToken"] as? String
  106. oauthScope = dictionary["oauthScope"] as? String
  107. firstName = dictionary["firstName"] as? String
  108. lastName = dictionary["lastName"] as? String
  109. fullName = dictionary["fullName"] as? String
  110. nickName = dictionary["nickName"] as? String
  111. displayName = dictionary["displayName"] as? String
  112. idToken = dictionary["idToken"] as? String
  113. if let expiresIn = dictionary["expiresIn"] as? String {
  114. approximateExpirationDate = Date(timeIntervalSinceNow: (expiresIn as NSString)
  115. .doubleValue)
  116. }
  117. refreshToken = dictionary["refreshToken"] as? String
  118. isNewUser = dictionary["isNewUser"] as? Bool ?? false
  119. if let rawUserInfo = dictionary["rawUserInfo"] as? String,
  120. let data = rawUserInfo.data(using: .utf8) {
  121. if let info = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves),
  122. let profile = info as? [String: any Sendable] {
  123. self.profile = profile
  124. }
  125. } else if let profile = dictionary["rawUserInfo"] as? [String: any Sendable] {
  126. self.profile = profile
  127. }
  128. username = dictionary["username"] as? String
  129. action = dictionary["action"] as? String
  130. language = dictionary["language"] as? String
  131. timeZone = dictionary["timeZone"] as? String
  132. photoURL = URL(string: dictionary["photoUrl"] as? String ?? "")
  133. dateOfBirth = dictionary["dateOfBirth"] as? String
  134. context = dictionary["context"] as? String
  135. needConfirmation = dictionary["needConfirmation"] as? Bool ?? false
  136. if let verifiedProvider = dictionary["verifiedProvider"] as? String,
  137. let data = verifiedProvider.data(using: .utf8) {
  138. if let decoded = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves),
  139. let provider = decoded as? [String] {
  140. self.verifiedProvider = provider
  141. }
  142. } else if let verifiedProvider = dictionary["verifiedProvider"] as? [String] {
  143. self.verifiedProvider = verifiedProvider
  144. }
  145. oauthIDToken = dictionary["oauthIdToken"] as? String
  146. if let oauthExpirationDate = dictionary["oauthExpireIn"] as? String {
  147. self
  148. .oauthExpirationDate = Date(timeIntervalSinceNow: (oauthExpirationDate as NSString)
  149. .doubleValue)
  150. }
  151. oauthAccessToken = dictionary["oauthAccessToken"] as? String
  152. oauthSecretToken = dictionary["oauthTokenSecret"] as? String
  153. pendingToken = dictionary["pendingToken"] as? String
  154. if let mfaInfoDicts = dictionary["mfaInfo"] as? [[String: AnyHashable]] {
  155. mfaInfo = mfaInfoDicts.map {
  156. AuthProtoMFAEnrollment(dictionary: $0)
  157. }
  158. }
  159. mfaPendingCredential = dictionary["mfaPendingCredential"] as? String
  160. }
  161. }