diff --git a/.changeset/thin-queens-learn.md b/.changeset/thin-queens-learn.md new file mode 100644 index 00000000..81eaf4ba --- /dev/null +++ b/.changeset/thin-queens-learn.md @@ -0,0 +1,5 @@ +--- +"@capacitor-firebase/authentication": minor +--- + +feat(ios): return `authorizationCode` on Apple Sign-In diff --git a/packages/authentication/README.md b/packages/authentication/README.md index 8af47492..99d9b9e2 100644 --- a/packages/authentication/README.md +++ b/packages/authentication/README.md @@ -1267,13 +1267,14 @@ Remove all listeners for this plugin. #### AuthCredential -| Prop | Type | Description | Since | -| ----------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----- | -| **`providerId`** | string | The authentication provider ID for the credential. | 0.1.0 | -| **`accessToken`** | string | The OAuth access token associated with the credential if it belongs to an OAuth provider. | 0.1.0 | -| **`idToken`** | string | The OAuth ID token associated with the credential if it belongs to an OIDC provider. | 0.1.0 | -| **`secret`** | string | The OAuth access token secret associated with the credential if it belongs to an OAuth 1.0 provider. | 0.1.0 | -| **`nonce`** | string | The random string used to make sure that the ID token you get was granted specifically in response to your app's authentication request. | 0.1.0 | +| Prop | Type | Description | Since | +| ----------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----- | +| **`accessToken`** | string | The OAuth access token associated with the credential if it belongs to an OAuth provider. | 0.1.0 | +| **`authorizationCode`** | string | A token that the app uses to interact with the server. Only available for Apple Sign-in on iOS. | 1.2.0 | +| **`idToken`** | string | The OAuth ID token associated with the credential if it belongs to an OIDC provider. | 0.1.0 | +| **`nonce`** | string | The random string used to make sure that the ID token you get was granted specifically in response to your app's authentication request. | 0.1.0 | +| **`providerId`** | string | The authentication provider ID for the credential. | 0.1.0 | +| **`secret`** | string | The OAuth access token secret associated with the credential if it belongs to an OAuth 1.0 provider. | 0.1.0 | #### AdditionalUserInfo diff --git a/packages/authentication/ios/Plugin/FirebaseAuthentication.swift b/packages/authentication/ios/Plugin/FirebaseAuthentication.swift index 289d712b..eae21f79 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthentication.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthentication.swift @@ -401,17 +401,17 @@ public typealias AuthStateChangedObserver = () -> Void } func handleSuccessfulSignIn(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?) { - self.handleSuccessfulSignIn(credential: credential, idToken: idToken, nonce: nonce, accessToken: accessToken, displayName: nil) + self.handleSuccessfulSignIn(credential: credential, idToken: idToken, nonce: nonce, accessToken: accessToken, displayName: nil, authorizationCode: nil) } - func handleSuccessfulSignIn(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?, displayName: String?) { + func handleSuccessfulSignIn(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?, displayName: String?, authorizationCode: String?) { guard let savedCall = self.savedCall else { return } let skipNativeAuth = savedCall.getBool("skipNativeAuth", config.skipNativeAuth) if skipNativeAuth == true { let result = FirebaseAuthenticationHelper.createSignInResult(credential: credential, user: nil, idToken: idToken, nonce: nonce, - accessToken: accessToken, additionalUserInfo: nil, displayName: displayName) + accessToken: accessToken, additionalUserInfo: nil, displayName: displayName, authorizationCode: authorizationCode) savedCall.resolve(result) return } @@ -424,7 +424,7 @@ public typealias AuthStateChangedObserver = () -> Void return } let result = FirebaseAuthenticationHelper.createSignInResult(credential: authResult?.credential, user: authResult?.user, idToken: idToken, nonce: nonce, accessToken: accessToken, - additionalUserInfo: authResult?.additionalUserInfo, displayName: displayName) + additionalUserInfo: authResult?.additionalUserInfo, displayName: displayName, authorizationCode: authorizationCode) savedCall.resolve(result) } } @@ -438,10 +438,10 @@ public typealias AuthStateChangedObserver = () -> Void } func handleSuccessfulLink(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?) { - self.handleSuccessfulLink(credential: credential, idToken: idToken, nonce: nonce, accessToken: accessToken, displayName: nil) + self.handleSuccessfulLink(credential: credential, idToken: idToken, nonce: nonce, accessToken: accessToken, displayName: nil, authorizationCode: nil) } - func handleSuccessfulLink(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?, displayName: String?) { + func handleSuccessfulLink(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?, displayName: String?, authorizationCode: String?) { guard let user = getCurrentUser() else { self.handleFailedLink(message: plugin.errorNoUserSignedIn, error: nil) return @@ -455,7 +455,7 @@ public typealias AuthStateChangedObserver = () -> Void return } let result = FirebaseAuthenticationHelper.createSignInResult(credential: authResult?.credential, user: authResult?.user, idToken: idToken, nonce: nonce, accessToken: accessToken, - additionalUserInfo: authResult?.additionalUserInfo, displayName: displayName) + additionalUserInfo: authResult?.additionalUserInfo, displayName: displayName, authorizationCode: authorizationCode) savedCall.resolve(result) } } diff --git a/packages/authentication/ios/Plugin/FirebaseAuthenticationHelper.swift b/packages/authentication/ios/Plugin/FirebaseAuthenticationHelper.swift index cc5e5a4f..7f12c1b4 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthenticationHelper.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthenticationHelper.swift @@ -22,8 +22,13 @@ public class FirebaseAuthenticationHelper { } public static func createSignInResult(credential: AuthCredential?, user: User?, idToken: String?, nonce: String?, accessToken: String?, additionalUserInfo: AdditionalUserInfo?, displayName: String?) -> JSObject { + return createSignInResult(credential: credential, user: user, idToken: idToken, nonce: nonce, accessToken: accessToken, additionalUserInfo: additionalUserInfo, displayName: nil, + authorizationCode: nil) + } + + public static func createSignInResult(credential: AuthCredential?, user: User?, idToken: String?, nonce: String?, accessToken: String?, additionalUserInfo: AdditionalUserInfo?, displayName: String?, authorizationCode: String?) -> JSObject { let userResult = self.createUserResult(user, displayName: displayName) - let credentialResult = self.createCredentialResult(credential, idToken: idToken, nonce: nonce, accessToken: accessToken) + let credentialResult = self.createCredentialResult(credential, idToken: idToken, nonce: nonce, accessToken: accessToken, authorizationCode: authorizationCode) let additionalUserInfoResult = self.createAdditionalUserInfoResult(additionalUserInfo) var result = JSObject() result["user"] = userResult @@ -59,8 +64,8 @@ public class FirebaseAuthenticationHelper { return result } - public static func createCredentialResult(_ credential: AuthCredential?, idToken: String?, nonce: String?, accessToken: String?) -> JSObject? { - if credential == nil && idToken == nil && nonce == nil && accessToken == nil { + public static func createCredentialResult(_ credential: AuthCredential?, idToken: String?, nonce: String?, accessToken: String?, authorizationCode: String?) -> JSObject? { + if credential == nil && idToken == nil && nonce == nil && accessToken == nil && authorizationCode == nil { return nil } var result = JSObject() @@ -90,6 +95,9 @@ public class FirebaseAuthenticationHelper { if let accessToken = accessToken { result["accessToken"] = accessToken } + if let authorizationCode = authorizationCode { + result["authorizationCode"] = authorizationCode + } return result } diff --git a/packages/authentication/ios/Plugin/Handlers/AppleAuthProviderHandler.swift b/packages/authentication/ios/Plugin/Handlers/AppleAuthProviderHandler.swift index 58beb8c6..cf711b37 100644 --- a/packages/authentication/ios/Plugin/Handlers/AppleAuthProviderHandler.swift +++ b/packages/authentication/ios/Plugin/Handlers/AppleAuthProviderHandler.swift @@ -110,6 +110,10 @@ extension AppleAuthProviderHandler: ASAuthorizationControllerDelegate, ASAuthori print("Unable to fetch identity token") return } + var authorizationCode: String? + if let authorizationCodeData = appleIDCredential.authorizationCode { + authorizationCode = String(data: authorizationCodeData, encoding: .utf8) + } guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else { print("Unable to serialize token string from data: \(appleIDToken.debugDescription)") return @@ -125,9 +129,11 @@ extension AppleAuthProviderHandler: ASAuthorizationControllerDelegate, ASAuthori return } if isLink == true { - self.pluginImplementation.handleSuccessfulLink(credential: credential, idToken: idTokenString, nonce: nonce, accessToken: nil, displayName: displayName) + self.pluginImplementation.handleSuccessfulLink(credential: credential, idToken: idTokenString, nonce: nonce, + accessToken: nil, displayName: displayName, authorizationCode: authorizationCode) } else { - self.pluginImplementation.handleSuccessfulSignIn(credential: credential, idToken: idTokenString, nonce: nonce, accessToken: nil, displayName: displayName) + self.pluginImplementation.handleSuccessfulSignIn(credential: credential, idToken: idTokenString, nonce: nonce, + accessToken: nil, displayName: displayName, authorizationCode: authorizationCode) } } diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index 33cf9a69..9ec5ccc6 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -922,18 +922,19 @@ export interface User { */ export interface AuthCredential { /** - * The authentication provider ID for the credential. + * The OAuth access token associated with the credential if it belongs to an OAuth provider. * - * @example "google.com" * @since 0.1.0 */ - providerId: string; + accessToken?: string; /** - * The OAuth access token associated with the credential if it belongs to an OAuth provider. + * A token that the app uses to interact with the server. * - * @since 0.1.0 + * Only available for Apple Sign-in on iOS. + * + * @since 1.2.0 */ - accessToken?: string; + authorizationCode?: string; /** * The OAuth ID token associated with the credential if it belongs to an OIDC provider. * @@ -941,17 +942,24 @@ export interface AuthCredential { */ idToken?: string; /** - * The OAuth access token secret associated with the credential if it belongs to an OAuth 1.0 provider. + * The random string used to make sure that the ID token you get was granted specifically in response to your app's authentication request. * * @since 0.1.0 */ - secret?: string; + nonce?: string; /** - * The random string used to make sure that the ID token you get was granted specifically in response to your app's authentication request. + * The authentication provider ID for the credential. * + * @example "google.com" * @since 0.1.0 */ - nonce?: string; + providerId: string; + /** + * The OAuth access token secret associated with the credential if it belongs to an OAuth 1.0 provider. + * + * @since 0.1.0 + */ + secret?: string; } /**