Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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