Skip to content

Commit

Permalink
Reimplement #10068 in auth-swift after rebase (#11005)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulb777 committed Apr 5, 2023
1 parent 658a401 commit d555aca
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 1,942 deletions.
18 changes: 12 additions & 6 deletions FirebaseAuth/Sources/Swift/AuthProvider/OAuthCredential.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import Foundation
@objc public let OAuthResponseURLString: String?
@objc public let sessionID: String?
@objc public let pendingToken: String?
let fullName: PersonNameComponents?
// private
@objc public let rawNonce: String?

Expand All @@ -46,12 +47,14 @@ import Foundation
rawNonce: String? = nil,
accessToken: String? = nil,
secret: String? = nil,
fullName: PersonNameComponents? = nil,
pendingToken: String? = nil) {
self.idToken = idToken
self.rawNonce = rawNonce
self.accessToken = accessToken
self.pendingToken = pendingToken
self.secret = secret
self.fullName = fullName
OAuthResponseURLString = nil
sessionID = nil
super.init(provider: providerID)
Expand All @@ -67,6 +70,7 @@ import Foundation
secret = nil
idToken = nil
rawNonce = nil
fullName = nil
super.init(provider: providerID)
}

Expand Down Expand Up @@ -99,19 +103,21 @@ import Foundation
public static var supportsSecureCoding: Bool = true

public func encode(with coder: NSCoder) {
coder.encode(idToken)
coder.encode(rawNonce)
coder.encode(accessToken)
coder.encode(pendingToken)
coder.encode(secret)
coder.encode(idToken, forKey: "IDToken")
coder.encode(rawNonce, forKey: "rawNonce")
coder.encode(accessToken, forKey: "accessToken")
coder.encode(pendingToken, forKey: "pendingToken")
coder.encode(secret, forKey: "secret")
coder.encode(fullName, forKey: "fullName")
}

public required init?(coder: NSCoder) {
idToken = coder.decodeObject(forKey: "idToken") as? String
idToken = coder.decodeObject(forKey: "IDToken") as? String
rawNonce = coder.decodeObject(forKey: "rawNonce") as? String
accessToken = coder.decodeObject(forKey: "accessToken") as? String
pendingToken = coder.decodeObject(forKey: "pendingToken") as? String
secret = coder.decodeObject(forKey: "secret") as? String
fullName = coder.decodeObject(forKey: "fullName") as? PersonNameComponents
OAuthResponseURLString = nil
sessionID = nil
super.init(provider: OAuthProvider.id)
Expand Down
22 changes: 22 additions & 0 deletions FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ import CommonCrypto
}
}

/** @fn appleCredentialWithIDToken:rawNonce:fullName:
* @brief Creates an `AuthCredential` for the Sign in with Apple OAuth 2 provider identified by ID
* token, raw nonce, and full name. This method is specific to the Sign in with Apple OAuth 2
* provider as this provider requires the full name to be passed explicitly.
*
* @param idToken The IDToken associated with the Sign in with Apple Auth credential being created.
* @param rawNonce The raw nonce associated with the Sign in with Apple Auth credential being
* created.
* @param fullName The full name associated with the Sign in with Apple Auth credential being
* created.
* @return An `AuthCredential`.
*/
@objc(appleCredentialWithIDToken:rawNonce:fullName:)
public static func appleCredential(withIDToken idToken: String,
rawNonce: String?,
fullName: PersonNameComponents?) -> OAuthCredential {
return OAuthCredential(withProviderID: AuthProviderString.apple.rawValue,
idToken: idToken,
rawNonce: rawNonce,
fullName: fullName)
}

@available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *)
public func credential(with UIDelegate: AuthUIDelegate?) async throws -> AuthCredential {
return try await withCheckedThrowingContinuation { continuation in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ private let kSessionIDKey = "sessionId"
*/
private let kTenantIDKey = "tenantId"

/** @var kUserKey
@brief The key for the "user" value in the request. The value is a JSON object that contains the
name of the user.
*/
private let kUserKey = "user"

/** @var kNameKey
@brief The key for the "name" value in the request. The value is a JSON object that contains the
first and/or last name of the user.
*/
private let kNameKey = "name"

/** @var kFirstNameKey
@brief The key for the "firstName" value in the request.
*/
private let kFirstNameKey = "firstName"

/** @var kLastNameKey
@brief The key for the "lastName" value in the request.
*/
private let kLastNameKey = "lastName"

/** @class FIRVerifyAssertionRequest
@brief Represents the parameters for the verifyAssertion endpoint.
@see https://developers.google.com/identity/toolkit/web/reference/relyingparty/verifyAssertion
Expand Down Expand Up @@ -170,6 +192,11 @@ private let kTenantIDKey = "tenantId"
*/
@objc public var autoCreate: Bool = false

/** @property fullName
@brief A full name from the IdP.
*/
@objc public var fullName: PersonNameComponents?

/** @var response
@brief The corresponding response for this request
*/
Expand Down Expand Up @@ -210,6 +237,24 @@ private let kTenantIDKey = "tenantId"
queryItems.append(URLQueryItem(name: kIdentifierKey, value: inputEmail))
}

if fullName?.givenName != nil || fullName?.familyName != nil {
var nameDict = [String: String]()
if let given = fullName?.givenName {
nameDict[kFirstNameKey] = given
}
if let lastName = fullName?.familyName {
nameDict[kLastNameKey] = lastName
}
let userDict = [kNameKey: nameDict]
do {
let userJson = try JSONSerialization.data(withJSONObject: userDict)
let jsonString = String(data: userJson, encoding: .utf8)
queryItems.append(URLQueryItem(name: kUserKey, value: jsonString))
} catch {
fatalError("Auth Internal error: failed to serialize dictionary to json: \(error)")
}
}

components.queryItems = queryItems

var body: [String: AnyHashable] = [
Expand Down
Loading

0 comments on commit d555aca

Please sign in to comment.