VerifyPasswordTests.swift 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. import XCTest
  16. @testable import FirebaseAuth
  17. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  18. class VerifyPasswordTests: RPCBaseTests {
  19. let kTestOOBCode = "OOBCode"
  20. let kTestEmail = "testEmail."
  21. let kTestPassword = "testPassword"
  22. func testVerifyPasswordRequest() async throws {
  23. let kEmailKey = "email"
  24. let kPasswordKey = "password"
  25. let kCaptchaChallengeKey = "captchaChallenge"
  26. let kCaptchaResponseKey = "captchaResponse"
  27. let kSecureTokenKey = "returnSecureToken"
  28. let kExpectedAPIURL =
  29. "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=APIKey"
  30. try await checkRequest(
  31. request: makeVerifyPasswordRequest(),
  32. expected: kExpectedAPIURL,
  33. key: kEmailKey,
  34. value: kTestEmail
  35. )
  36. let requestDictionary = try XCTUnwrap(rpcIssuer.decodedRequest as? [String: AnyHashable])
  37. XCTAssertEqual(requestDictionary[kPasswordKey], kTestPassword)
  38. XCTAssertNil(requestDictionary[kCaptchaChallengeKey])
  39. XCTAssertNil(requestDictionary[kCaptchaResponseKey])
  40. XCTAssertTrue(try XCTUnwrap(requestDictionary[kSecureTokenKey] as? Bool))
  41. }
  42. func testVerifyPasswordRequestOptionalFields() async throws {
  43. let kEmailKey = "email"
  44. let kPasswordKey = "password"
  45. let kCaptchaChallengeKey = "captchaChallenge"
  46. let kTestCaptchaChallenge = "testCaptchaChallenge"
  47. let kCaptchaResponseKey = "captchaResponse"
  48. let kTestCaptchaResponse = "testCaptchaResponse"
  49. let kSecureTokenKey = "returnSecureToken"
  50. let kTestPendingToken = "testPendingToken"
  51. let kClientTypeKey = "clientType"
  52. let kTestClientType = "testClientType"
  53. let kRecaptchaVersionKey = "recaptchaVersion"
  54. let kTestRecaptchaVersion = "testRecaptchaVersion"
  55. let kExpectedAPIURL =
  56. "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=APIKey"
  57. let request = makeVerifyPasswordRequest()
  58. request.pendingIDToken = kTestPendingToken
  59. request.captchaChallenge = kTestCaptchaChallenge
  60. request.captchaResponse = kTestCaptchaResponse
  61. request.clientType = kTestClientType
  62. request.recaptchaVersion = kTestRecaptchaVersion
  63. try await checkRequest(
  64. request: request,
  65. expected: kExpectedAPIURL,
  66. key: kEmailKey,
  67. value: kTestEmail
  68. )
  69. let requestDictionary = try XCTUnwrap(rpcIssuer.decodedRequest as? [String: AnyHashable])
  70. XCTAssertEqual(requestDictionary[kPasswordKey], kTestPassword)
  71. XCTAssertEqual(requestDictionary[kCaptchaChallengeKey], kTestCaptchaChallenge)
  72. XCTAssertEqual(requestDictionary[kCaptchaResponseKey], kTestCaptchaResponse)
  73. XCTAssertEqual(requestDictionary[kClientTypeKey], kTestClientType)
  74. XCTAssertEqual(requestDictionary[kRecaptchaVersionKey], kTestRecaptchaVersion)
  75. XCTAssertTrue(try XCTUnwrap(requestDictionary[kSecureTokenKey] as? Bool))
  76. }
  77. func testVerifyPasswordRequestErrors() async throws {
  78. let kUserDisabledErrorMessage = "USER_DISABLED"
  79. let kOperationNotAllowedErrorMessage = "OPERATION_NOT_ALLOWED"
  80. let kEmailNotFoundErrorMessage = "EMAIL_NOT_FOUND"
  81. let kWrongPasswordErrorMessage = "INVALID_PASSWORD"
  82. let kInvalidEmailErrorMessage = "INVALID_EMAIL"
  83. let kBadRequestErrorMessage = "Bad Request"
  84. let kInvalidKeyReasonValue = "keyInvalid"
  85. let kAppNotAuthorizedReasonValue = "ipRefererBlocked"
  86. let kTooManyAttemptsErrorMessage = "TOO_MANY_ATTEMPTS_TRY_LATER:"
  87. let kPasswordLoginDisabledErrorMessage = "PASSWORD_LOGIN_DISABLED"
  88. try await checkBackendError(
  89. request: makeVerifyPasswordRequest(),
  90. message: kUserDisabledErrorMessage,
  91. errorCode: AuthErrorCode.userDisabled
  92. )
  93. try await checkBackendError(
  94. request: makeVerifyPasswordRequest(),
  95. message: kEmailNotFoundErrorMessage,
  96. errorCode: AuthErrorCode.userNotFound
  97. )
  98. try await checkBackendError(
  99. request: makeVerifyPasswordRequest(),
  100. message: kWrongPasswordErrorMessage,
  101. errorCode: AuthErrorCode.wrongPassword
  102. )
  103. try await checkBackendError(
  104. request: makeVerifyPasswordRequest(),
  105. message: kInvalidEmailErrorMessage,
  106. errorCode: AuthErrorCode.invalidEmail
  107. )
  108. try await checkBackendError(
  109. request: makeVerifyPasswordRequest(),
  110. message: kTooManyAttemptsErrorMessage,
  111. errorCode: AuthErrorCode.tooManyRequests
  112. )
  113. try await checkBackendError(
  114. request: makeVerifyPasswordRequest(),
  115. message: kBadRequestErrorMessage,
  116. reason: kInvalidKeyReasonValue,
  117. errorCode: AuthErrorCode.invalidAPIKey
  118. )
  119. try await checkBackendError(
  120. request: makeVerifyPasswordRequest(),
  121. message: kOperationNotAllowedErrorMessage,
  122. errorCode: AuthErrorCode.operationNotAllowed
  123. )
  124. try await checkBackendError(
  125. request: makeVerifyPasswordRequest(),
  126. message: kPasswordLoginDisabledErrorMessage,
  127. errorCode: AuthErrorCode.operationNotAllowed
  128. )
  129. try await checkBackendError(
  130. request: makeVerifyPasswordRequest(),
  131. message: kBadRequestErrorMessage,
  132. reason: kAppNotAuthorizedReasonValue,
  133. errorCode: AuthErrorCode.appNotAuthorized
  134. )
  135. }
  136. /** @fn testSuccessfulVerifyPasswordResponse
  137. @brief Tests a successful attempt of the verify password flow.
  138. */
  139. func testSuccessfulVerifyPasswordResponse() async throws {
  140. let kLocalIDKey = "localId"
  141. let kTestLocalID = "testLocalId"
  142. let kEmailKey = "email"
  143. let kTestEmail = "testgmail.com"
  144. let kDisplayNameKey = "displayName"
  145. let kTestDisplayName = "testDisplayName"
  146. let kIDTokenKey = "idToken"
  147. let kTestIDToken = "ID_TOKEN"
  148. let kExpiresInKey = "expiresIn"
  149. let kTestExpiresIn = "12345"
  150. let kRefreshTokenKey = "refreshToken"
  151. let kTestRefreshToken = "REFRESH_TOKEN"
  152. let kPhotoUrlKey = "photoUrl"
  153. let kTestPhotoUrl = "www.example.com"
  154. rpcIssuer?.respondBlock = {
  155. try self.rpcIssuer?.respond(withJSON: [
  156. kLocalIDKey: kTestLocalID,
  157. kEmailKey: kTestEmail,
  158. kDisplayNameKey: kTestDisplayName,
  159. kIDTokenKey: kTestIDToken,
  160. kExpiresInKey: kTestExpiresIn,
  161. kRefreshTokenKey: kTestRefreshToken,
  162. kPhotoUrlKey: kTestPhotoUrl,
  163. ])
  164. }
  165. let rpcResponse = try await AuthBackend.call(with: makeVerifyPasswordRequest())
  166. XCTAssertEqual(rpcResponse.email, kTestEmail)
  167. XCTAssertEqual(rpcResponse.localID, kTestLocalID)
  168. XCTAssertEqual(rpcResponse.displayName, kTestDisplayName)
  169. XCTAssertEqual(rpcResponse.idToken, kTestIDToken)
  170. let expiresIn = try XCTUnwrap(rpcResponse.approximateExpirationDate?.timeIntervalSinceNow)
  171. XCTAssertEqual(expiresIn, 12345, accuracy: 0.1)
  172. XCTAssertEqual(rpcResponse.refreshToken, kTestRefreshToken)
  173. XCTAssertEqual(rpcResponse.photoURL?.absoluteString, kTestPhotoUrl)
  174. }
  175. private func makeVerifyPasswordRequest() -> VerifyPasswordRequest {
  176. return VerifyPasswordRequest(email: kTestEmail, password: kTestPassword,
  177. requestConfiguration: makeRequestConfiguration())
  178. }
  179. }