From 383aef8b6c0d171ee01942ffc49218e3d779dad5 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:42:42 +0100 Subject: [PATCH 01/16] feat: extend authentication to support id token change event (#710) * adds type definitions --- packages/authentication/src/definitions.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index fcd993b3..2bdf026e 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -483,6 +483,17 @@ export interface FirebaseAuthenticationPlugin { eventName: 'authStateChange', listenerFunc: AuthStateChangeListener, ): Promise; + /** + * Listen for changes to the signed-in user's ID token changes. + * + * **Attention:** This listener will not be triggered automatically upon ID token expiration. + * + * @since TODO: Add since for idTokenChange + */ + addListener( + eventName: 'idTokenChange', + listenerFunc: AuthStateChangeListener, + ): Promise; /** * Listen for a completed phone verification. * From 7c731aaa18a7f5fc442b6b72dd5bbb3112484ee2 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:43:32 +0100 Subject: [PATCH 02/16] feat: extend authentication to support id token change event (#710) * implements idTokenChange on the web --- packages/authentication/src/web.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/authentication/src/web.ts b/packages/authentication/src/web.ts index da0f1198..4f387a5e 100644 --- a/packages/authentication/src/web.ts +++ b/packages/authentication/src/web.ts @@ -112,6 +112,7 @@ export class FirebaseAuthenticationWeb implements FirebaseAuthenticationPlugin { public static readonly AUTH_STATE_CHANGE_EVENT = 'authStateChange'; + public static readonly ID_TOKEN_CHANGE_EVENT = 'idTokenChange'; public static readonly PHONE_CODE_SENT_EVENT = 'phoneCodeSent'; public static readonly PHONE_VERIFICATION_FAILED_EVENT = 'phoneVerificationFailed'; @@ -128,7 +129,8 @@ export class FirebaseAuthenticationWeb constructor() { super(); const auth = getAuth(); - auth.onAuthStateChanged(user => this.handleAuthStateChange(user)); + auth.onAuthStateChanged(user => this.handleAuthStateChange(FirebaseAuthenticationWeb.AUTH_STATE_CHANGE_EVENT, user)); + auth.onIdTokenChanged(user => this.handleAuthStateChange(FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, user)) } public async applyActionCode(options: ApplyActionCodeOptions): Promise { @@ -778,13 +780,13 @@ export class FirebaseAuthenticationWeb ); } - private handleAuthStateChange(user: FirebaseUser | null): void { + private handleAuthStateChange(eventName: string, user: FirebaseUser | null): void { const userResult = this.createUserResult(user); const change: AuthStateChange = { user: userResult, }; this.notifyListeners( - FirebaseAuthenticationWeb.AUTH_STATE_CHANGE_EVENT, + eventName, change, true, ); From edb122b8398470265418605f951add33198b01b2 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:50:58 +0100 Subject: [PATCH 03/16] feat: extend authentication to support id token change event (#710) * refactors handling id token change in separate method on the web --- packages/authentication/src/web.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/authentication/src/web.ts b/packages/authentication/src/web.ts index 4f387a5e..9d4fafe7 100644 --- a/packages/authentication/src/web.ts +++ b/packages/authentication/src/web.ts @@ -129,8 +129,8 @@ export class FirebaseAuthenticationWeb constructor() { super(); const auth = getAuth(); - auth.onAuthStateChanged(user => this.handleAuthStateChange(FirebaseAuthenticationWeb.AUTH_STATE_CHANGE_EVENT, user)); - auth.onIdTokenChanged(user => this.handleAuthStateChange(FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, user)) + auth.onAuthStateChanged(user => this.handleAuthStateChange(user)); + auth.onIdTokenChanged(user => this.handleIdTokenChange(user)); } public async applyActionCode(options: ApplyActionCodeOptions): Promise { @@ -780,13 +780,25 @@ export class FirebaseAuthenticationWeb ); } - private handleAuthStateChange(eventName: string, user: FirebaseUser | null): void { + private handleAuthStateChange(user: FirebaseUser | null): void { const userResult = this.createUserResult(user); const change: AuthStateChange = { user: userResult, }; this.notifyListeners( - eventName, + FirebaseAuthenticationWeb.AUTH_STATE_CHANGE_EVENT, + change, + true, + ); + } + + private handleIdTokenChange(user: FirebaseUser | null): void { + const userResult = this.createUserResult(user); + const change: AuthStateChange = { + user: userResult, + }; + this.notifyListeners( + FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, change, true, ); From cd182a72e2b2d5ba778cfe1a99b1c89bfb1d9b2d Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:02:34 +0100 Subject: [PATCH 04/16] feat: extend authentication to support id token change event (#710) * implements idTokenChange on ios --- .../ios/Plugin/FirebaseAuthentication.swift | 3 +++ .../ios/Plugin/FirebaseAuthenticationPlugin.swift | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/packages/authentication/ios/Plugin/FirebaseAuthentication.swift b/packages/authentication/ios/Plugin/FirebaseAuthentication.swift index fd4b08b8..e361f523 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthentication.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthentication.swift @@ -28,6 +28,9 @@ public typealias AuthStateChangedObserver = () -> Void Auth.auth().addStateDidChangeListener {_, _ in self.plugin.handleAuthStateChange() } + _ = Auth.auth().addIDTokenDidChangeListener {_, _ in + self.plugin.handleIdTokenChange() + } } @objc func applyActionCode(oobCode: String, completion: @escaping (Error?) -> Void) { diff --git a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift index 7ebd3578..1b9714f4 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift @@ -36,6 +36,7 @@ public class FirebaseAuthenticationPlugin: CAPPlugin { "signInAnonymously cannot be used in combination with skipNativeAuth." public let errorDeviceUnsupported = "Device is not supported. At least iOS 13 is required." public let authStateChangeEvent = "authStateChange" + public let idTokenChangeEvent = "idTokenChange" public let phoneVerificationFailedEvent = "phoneVerificationFailed" public let phoneCodeSentEvent = "phoneCodeSent" private var implementation: FirebaseAuthentication? @@ -593,6 +594,14 @@ public class FirebaseAuthenticationPlugin: CAPPlugin { result["user"] = userResult ?? NSNull() notifyListeners(authStateChangeEvent, data: result, retainUntilConsumed: true) } + + @objc func handleIdTokenChange() { + let user = implementation?.getCurrentUser() + let userResult = FirebaseAuthenticationHelper.createUserResult(user) + var result = JSObject() + result["user"] = userResult ?? NSNull() + notifyListeners(idTokenChangeEvent, data: result, retainUntilConsumed: true) + } @objc func handlePhoneVerificationFailed(_ error: Error) { CAPLog.print("[", self.tag, "] ", error) From 491d76ae180178ef97e19769f10c8f4aac84e4b0 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:10:52 +0100 Subject: [PATCH 05/16] feat: extend authentication to support id token change event (#710) * implements idTokenChange on android --- .../firebase/authentication/FirebaseAuthentication.java | 6 ++++++ .../authentication/FirebaseAuthenticationPlugin.java | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index adea0c7d..a6437ae6 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -54,6 +54,7 @@ public class FirebaseAuthentication { private FirebaseAuthenticationPlugin plugin; private FirebaseAuthenticationConfig config; private FirebaseAuth.AuthStateListener firebaseAuthStateListener; + private FirebaseAuth.IdTokenListener firebaseIdTokenChangeListener; private AppleAuthProviderHandler appleAuthProviderHandler; private FacebookAuthProviderHandler facebookAuthProviderHandler; private GoogleAuthProviderHandler googleAuthProviderHandler; @@ -70,6 +71,11 @@ public FirebaseAuthentication(FirebaseAuthenticationPlugin plugin, FirebaseAuthe this.plugin.handleAuthStateChange(); }; getFirebaseAuthInstance().addAuthStateListener(this.firebaseAuthStateListener); + this.firebaseIdTokenChangeListener = + firebaseAuth -> { + this.plugin.handleIdTokenChange(); + }; + getFirebaseAuthInstance().addIdTokenListener(this.firebaseIdTokenChangeListener); } public void applyActionCode(@NonNull String oobCode, @NonNull Runnable callback) { diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index 6287df73..d0516c5c 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -62,6 +62,7 @@ public class FirebaseAuthenticationPlugin extends Plugin { public static final String ERROR_SIGN_IN_ANONYMOUSLY_SKIP_NATIVE_AUTH = "signInAnonymously cannot be used in combination with skipNativeAuth."; public static final String AUTH_STATE_CHANGE_EVENT = "authStateChange"; + public static final String ID_TOKEN_CHANGE_EVENT = "idTokenChange"; private FirebaseAuthenticationConfig config; private FirebaseAuthentication implementation; @@ -984,6 +985,14 @@ public void handleAuthStateChange() { notifyListeners(AUTH_STATE_CHANGE_EVENT, result, true); } + public void handleIdTokenChange() { + FirebaseUser user = implementation.getCurrentUser(); + JSObject userResult = FirebaseAuthenticationHelper.createUserResult(user); + JSObject result = new JSObject(); + result.put("user", (userResult == null ? JSONObject.NULL : userResult)); + notifyListeners(ID_TOKEN_CHANGE_EVENT, result, true); + } + @Override protected void handleOnActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.handleOnActivityResult(requestCode, resultCode, data); From 64440d4687b3eb542fd50bafe2b8f74fa7d04b73 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:12:51 +0100 Subject: [PATCH 06/16] feat: extend authentication to support id token change event (#710) * ios pod install --- .../authentication/ios/Plugin.xcodeproj/project.pbxproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/authentication/ios/Plugin.xcodeproj/project.pbxproj b/packages/authentication/ios/Plugin.xcodeproj/project.pbxproj index af148aa7..88edbe5e 100644 --- a/packages/authentication/ios/Plugin.xcodeproj/project.pbxproj +++ b/packages/authentication/ios/Plugin.xcodeproj/project.pbxproj @@ -379,13 +379,14 @@ "${BUILT_PRODUCTS_DIR}/AppAuth/AppAuth.framework", "${BUILT_PRODUCTS_DIR}/FirebaseAppCheckInterop/FirebaseAppCheckInterop.framework", "${BUILT_PRODUCTS_DIR}/FirebaseAuth/FirebaseAuth.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseAuthInterop/FirebaseAuthInterop.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCoreExtension/FirebaseCoreExtension.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework", "${BUILT_PRODUCTS_DIR}/GTMAppAuth/GTMAppAuth.framework", "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", "${BUILT_PRODUCTS_DIR}/GoogleSignIn/GoogleSignIn.framework", "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", - "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", "${BUILT_PRODUCTS_DIR}/RecaptchaInterop/RecaptchaInterop.framework", "${PODS_XCFRAMEWORKS_BUILD_DIR}/FBAEMKit/FBAEMKit.framework/FBAEMKit", "${PODS_XCFRAMEWORKS_BUILD_DIR}/FBSDKCoreKit/FBSDKCoreKit.framework/FBSDKCoreKit", @@ -399,13 +400,14 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppAuth.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAppCheckInterop.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAuth.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAuthInterop.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreExtension.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMAppAuth.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleSignIn.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RecaptchaInterop.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBAEMKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSDKCoreKit.framework", From c3915d593769c2d65a6376f2dd923153fee5a913 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:54:07 +0100 Subject: [PATCH 07/16] feat: extend authentication to support id token change event (#710) * replaces user with an object with token property --- packages/authentication/src/definitions.ts | 18 +++++++++++- packages/authentication/src/web.ts | 34 +++++++++++++++++----- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index 2bdf026e..964a3e54 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -492,7 +492,7 @@ export interface FirebaseAuthenticationPlugin { */ addListener( eventName: 'idTokenChange', - listenerFunc: AuthStateChangeListener, + listenerFunc: IdTokenChangeListener, ): Promise; /** * Listen for a completed phone verification. @@ -1420,6 +1420,13 @@ export interface AdditionalUserInfo { */ export type AuthStateChangeListener = (change: AuthStateChange) => void; +/** + * Callback to receive the id token change notifications. + * + * @since TODO: Add since for IdTokenChangeListener + */ +export type IdTokenChangeListener = (change: IdTokenChange) => void; + /** * @since 0.1.0 */ @@ -1432,6 +1439,15 @@ export interface AuthStateChange { user: User | null; } +export interface IdTokenChange { + /** + * A JSON Web Token (JWT) used to identify the user to a Firebase service. + * + * @since TODO: Add since for IdTokenChange + */ + token: string | null; +} + /** * Callback to receive the verification code sent to the user's phone number. * diff --git a/packages/authentication/src/web.ts b/packages/authentication/src/web.ts index 9d4fafe7..89fe4f4d 100644 --- a/packages/authentication/src/web.ts +++ b/packages/authentication/src/web.ts @@ -71,6 +71,7 @@ import type { GetIdTokenOptions, GetIdTokenResult, GetTenantIdResult, + IdTokenChange, IsSignInWithEmailLinkOptions, IsSignInWithEmailLinkResult, LinkResult, @@ -793,15 +794,32 @@ export class FirebaseAuthenticationWeb } private handleIdTokenChange(user: FirebaseUser | null): void { - const userResult = this.createUserResult(user); - const change: AuthStateChange = { - user: userResult, + const change: IdTokenChange = { + token: null, }; - this.notifyListeners( - FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, - change, - true, - ); + if (user) { + void user + ?.getIdToken() + .then(token => { + change.token = token; + this.notifyListeners( + FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, + change, + true, + ); + }) + .catch(() => { + this.notifyListeners( + FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, + change, + ); + }); + } else { + this.notifyListeners( + FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, + change, + ); + } } private applySignInOptions( From c22b878ede2b9452466b7eb69c1d75ace23f93b2 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:33:59 +0100 Subject: [PATCH 08/16] feat: extend authentication to support id token change event (#710) * removes IdTokenChange interface --- packages/authentication/src/definitions.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index 964a3e54..a15ad86d 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -1425,7 +1425,7 @@ export type AuthStateChangeListener = (change: AuthStateChange) => void; * * @since TODO: Add since for IdTokenChangeListener */ -export type IdTokenChangeListener = (change: IdTokenChange) => void; +export type IdTokenChangeListener = (change: GetIdTokenResult) => void; /** * @since 0.1.0 @@ -1439,15 +1439,6 @@ export interface AuthStateChange { user: User | null; } -export interface IdTokenChange { - /** - * A JSON Web Token (JWT) used to identify the user to a Firebase service. - * - * @since TODO: Add since for IdTokenChange - */ - token: string | null; -} - /** * Callback to receive the verification code sent to the user's phone number. * From 43c1fe458c63822a7466f79c0844805284964d54 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:35:20 +0100 Subject: [PATCH 09/16] feat: extend authentication to support id token change event (#710) * refactors handleIdTokenChange on the web --- packages/authentication/src/web.ts | 41 ++++++++++-------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/packages/authentication/src/web.ts b/packages/authentication/src/web.ts index 89fe4f4d..3be7420d 100644 --- a/packages/authentication/src/web.ts +++ b/packages/authentication/src/web.ts @@ -71,7 +71,6 @@ import type { GetIdTokenOptions, GetIdTokenResult, GetTenantIdResult, - IdTokenChange, IsSignInWithEmailLinkOptions, IsSignInWithEmailLinkResult, LinkResult, @@ -131,7 +130,7 @@ export class FirebaseAuthenticationWeb super(); const auth = getAuth(); auth.onAuthStateChanged(user => this.handleAuthStateChange(user)); - auth.onIdTokenChanged(user => this.handleIdTokenChange(user)); + auth.onIdTokenChanged(() => void this.handleIdTokenChange()); } public async applyActionCode(options: ApplyActionCodeOptions): Promise { @@ -793,33 +792,21 @@ export class FirebaseAuthenticationWeb ); } - private handleIdTokenChange(user: FirebaseUser | null): void { - const change: IdTokenChange = { - token: null, + private async handleIdTokenChange(): Promise { + const change: GetIdTokenResult = { + token: '', }; - if (user) { - void user - ?.getIdToken() - .then(token => { - change.token = token; - this.notifyListeners( - FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, - change, - true, - ); - }) - .catch(() => { - this.notifyListeners( - FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, - change, - ); - }); - } else { - this.notifyListeners( - FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, - change, - ); + try { + const { token } = await this.getIdToken({ forceRefresh: false }); + change.token = token; + } catch { + change.token = ''; } + this.notifyListeners( + FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, + change, + true, + ); } private applySignInOptions( From e66ca4daabb6d06fb9d6f9ae0cf0f136bb2d86dc Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:37:17 +0100 Subject: [PATCH 10/16] feat: extend authentication to support id token change event (#710) * refactors handleIdTokenChange on ios and android --- packages/authentication/README.md | 81 +++++++++++++------ .../FirebaseAuthenticationPlugin.java | 19 +++-- .../Plugin/FirebaseAuthenticationPlugin.swift | 20 +++-- 3 files changed, 83 insertions(+), 37 deletions(-) diff --git a/packages/authentication/README.md b/packages/authentication/README.md index a8ab284b..0f02deb1 100644 --- a/packages/authentication/README.md +++ b/packages/authentication/README.md @@ -479,12 +479,13 @@ const verifyBeforeUpdateEmail = async () => { * [`signOut()`](#signout) * [`unlink(...)`](#unlink) * [`updateEmail(...)`](#updateemail) -* [`verifyBeforeUpdateEmail(...)`](#verifyBeforeUpdateEmail) * [`updatePassword(...)`](#updatepassword) * [`updateProfile(...)`](#updateprofile) * [`useAppLanguage()`](#useapplanguage) * [`useEmulator(...)`](#useemulator) +* [`verifyBeforeUpdateEmail(...)`](#verifybeforeupdateemail) * [`addListener('authStateChange', ...)`](#addlistenerauthstatechange) +* [`addListener('idTokenChange', ...)`](#addlisteneridtokenchange) * [`addListener('phoneVerificationCompleted', ...)`](#addlistenerphoneverificationcompleted) * [`addListener('phoneVerificationFailed', ...)`](#addlistenerphoneverificationfailed) * [`addListener('phoneCodeSent', ...)`](#addlistenerphonecodesent) @@ -1473,22 +1474,6 @@ Updates the email address of the currently signed in user. -------------------- -### verifyBeforeUpdateEmail(...) - -```typescript -verifyBeforeUpdateEmail(options: VerifyBeforeUpdateEmailOptions) => Promise -``` - -Verifies the email before updating the email address of the currently signed in user. - -| Param | Type | -| ------------- | ----------------------------------------------------------------- | -| **`options`** | VerifyBeforeUpdateEmailOptions | - -**Since:** 6.2.0 - --------------------- - ### updatePassword(...) @@ -1554,6 +1539,23 @@ Instrument your app to talk to the Authentication emulator. -------------------- +### verifyBeforeUpdateEmail(...) + +```typescript +verifyBeforeUpdateEmail(options: VerifyBeforeUpdateEmailOptions) => Promise +``` + +Verifies the new email address before updating the email address of the currently signed in user. + +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------- | +| **`options`** | VerifyBeforeUpdateEmailOptions | + +**Since:** 6.3.0 + +-------------------- + + ### addListener('authStateChange', ...) ```typescript @@ -1576,6 +1578,28 @@ Listen for the user's sign-in state changes. -------------------- +### addListener('idTokenChange', ...) + +```typescript +addListener(eventName: 'idTokenChange', listenerFunc: IdTokenChangeListener) => Promise +``` + +Listen for changes to the signed-in user's ID token changes. + +**Attention:** This listener will not be triggered automatically upon ID token expiration. + +| Param | Type | +| ------------------ | ----------------------------------------------------------------------- | +| **`eventName`** | 'idTokenChange' | +| **`listenerFunc`** | IdTokenChangeListener | + +**Returns:** Promise<PluginListenerHandle> + +**Since:** TODO: Add since for idTokenChange + +-------------------- + + ### addListener('phoneVerificationCompleted', ...) ```typescript @@ -1992,14 +2016,6 @@ An interface covering the possible persistence mechanism types. | **`newEmail`** | string | The new email address. | 0.2.2 | -#### VerifyBeforeUpdateEmailOptions - -| Prop | Type | Description | Since | -| -------------- | ------------------- | ---------------------- | ----- | -| **`newEmail`** | string | The new email address to be verified before update. | 0.2.2 | -| **`actionCodeSettings`** | ActionCodeSettings | Structure that contains the required continue/state URL with optional Android and iOS bundle identifiers. | 1.1.0 | - - #### UpdatePasswordOptions | Prop | Type | Description | Since | @@ -2024,6 +2040,14 @@ An interface covering the possible persistence mechanism types. | **`scheme`** | string | The emulator scheme. Only available for Web. | "http" | 5.2.0 | +#### VerifyBeforeUpdateEmailOptions + +| Prop | Type | Description | Since | +| ------------------------ | ----------------------------------------------------------------- | --------------------------------------------------- | ----- | +| **`newEmail`** | string | The new email address to be verified before update. | 6.3.0 | +| **`actionCodeSettings`** | ActionCodeSettings | The action code settings | 6.3.0 | + + #### PluginListenerHandle | Prop | Type | @@ -2089,6 +2113,13 @@ Callback to receive the user's sign-in state change notifications. (change: AuthStateChange): void +#### IdTokenChangeListener + +Callback to receive the id token change notifications. + +(change: GetIdTokenResult): void + + #### PhoneVerificationCompletedListener Callback to receive the verification code sent to the user's phone number. diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index d0516c5c..1b73a990 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -986,11 +986,20 @@ public void handleAuthStateChange() { } public void handleIdTokenChange() { - FirebaseUser user = implementation.getCurrentUser(); - JSObject userResult = FirebaseAuthenticationHelper.createUserResult(user); - JSObject result = new JSObject(); - result.put("user", (userResult == null ? JSONObject.NULL : userResult)); - notifyListeners(ID_TOKEN_CHANGE_EVENT, result, true); + NonEmptyResultCallback callback = new NonEmptyResultCallback() { + @Override + public void success(Result result) { + notifyListeners(ID_TOKEN_CHANGE_EVENT, result.toJSObject(), true); + } + + @Override + public void error(Exception exception) { + JSObject changeResult = new JSObject(); + changeResult.put("token", ""); + notifyListeners(ID_TOKEN_CHANGE_EVENT, changeResult, true); + } + }; + implementation.getIdToken(false, callback); } @Override diff --git a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift index 1b9714f4..ca2619be 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift @@ -509,7 +509,7 @@ public class FirebaseAuthenticationPlugin: CAPPlugin { call.reject(errorNewEmailMissing) return } - + guard let actionCodeSettingsDict = call.getObject("actionCodeSettings") else { call.reject(errorActionCodeSettingsMissing) return @@ -594,13 +594,19 @@ public class FirebaseAuthenticationPlugin: CAPPlugin { result["user"] = userResult ?? NSNull() notifyListeners(authStateChangeEvent, data: result, retainUntilConsumed: true) } - + @objc func handleIdTokenChange() { - let user = implementation?.getCurrentUser() - let userResult = FirebaseAuthenticationHelper.createUserResult(user) - var result = JSObject() - result["user"] = userResult ?? NSNull() - notifyListeners(idTokenChangeEvent, data: result, retainUntilConsumed: true) + implementation?.getIdToken(false, completion: { result, error in + var changeResult = JSObject() + if let error = error { + CAPLog.print("[", self.tag, "] ", error) + changeResult["token"] = "" + } + if let result = result { + changeResult = result.toJSObject() + } + self.notifyListeners(self.idTokenChangeEvent, data: changeResult, retainUntilConsumed: true) + }) } @objc func handlePhoneVerificationFailed(_ error: Error) { From 13d3cb8544ab83e1ddb7563f4c38ef991ede78a0 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:41:18 +0100 Subject: [PATCH 11/16] feat: extend authentication to support id token change event (#710) * removes todos --- packages/authentication/README.md | 2 +- packages/authentication/src/definitions.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/authentication/README.md b/packages/authentication/README.md index 0f02deb1..2b3a09f5 100644 --- a/packages/authentication/README.md +++ b/packages/authentication/README.md @@ -1595,7 +1595,7 @@ Listen for changes to the signed-in user's ID token changes. **Returns:** Promise<PluginListenerHandle> -**Since:** TODO: Add since for idTokenChange +**Since:** 6.2.0 -------------------- diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index a15ad86d..3c5972af 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -488,7 +488,7 @@ export interface FirebaseAuthenticationPlugin { * * **Attention:** This listener will not be triggered automatically upon ID token expiration. * - * @since TODO: Add since for idTokenChange + * @since 6.2.0 */ addListener( eventName: 'idTokenChange', @@ -1423,7 +1423,7 @@ export type AuthStateChangeListener = (change: AuthStateChange) => void; /** * Callback to receive the id token change notifications. * - * @since TODO: Add since for IdTokenChangeListener + * @since 6.2.0 */ export type IdTokenChangeListener = (change: GetIdTokenResult) => void; From 48d49acfd271161b1e3ec20ada9b2233cf523357 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:46:52 +0100 Subject: [PATCH 12/16] feat: extend authentication to support id token change event (#710) * adds changeset --- .changeset/chilled-pumpkins-kick.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chilled-pumpkins-kick.md diff --git a/.changeset/chilled-pumpkins-kick.md b/.changeset/chilled-pumpkins-kick.md new file mode 100644 index 00000000..fac95ae6 --- /dev/null +++ b/.changeset/chilled-pumpkins-kick.md @@ -0,0 +1,5 @@ +--- +'@capacitor-firebase/authentication': patch +--- + +feat: adds idTokenChange event listener From 635905de39e5864e33f5e31026034cb4adafeede Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Thu, 7 Nov 2024 10:21:28 +0100 Subject: [PATCH 13/16] Update .changeset/chilled-pumpkins-kick.md --- .changeset/chilled-pumpkins-kick.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/chilled-pumpkins-kick.md b/.changeset/chilled-pumpkins-kick.md index fac95ae6..4f0c2f6c 100644 --- a/.changeset/chilled-pumpkins-kick.md +++ b/.changeset/chilled-pumpkins-kick.md @@ -2,4 +2,4 @@ '@capacitor-firebase/authentication': patch --- -feat: adds idTokenChange event listener +feat: add `idTokenChange` event listener From 996dcf6c2d6c4f0beb019bdb67573761b71efb44 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Thu, 7 Nov 2024 10:21:55 +0100 Subject: [PATCH 14/16] Update packages/authentication/src/definitions.ts --- packages/authentication/src/definitions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index 3c5972af..340b7cdc 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -484,7 +484,7 @@ export interface FirebaseAuthenticationPlugin { listenerFunc: AuthStateChangeListener, ): Promise; /** - * Listen for changes to the signed-in user's ID token changes. + * Listen to ID token changes for the currently signed-in user. * * **Attention:** This listener will not be triggered automatically upon ID token expiration. * From fda61fddf85aaeae9fbeda6c47eb36d0276bcfd2 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Thu, 7 Nov 2024 10:22:06 +0100 Subject: [PATCH 15/16] Update packages/authentication/src/definitions.ts --- packages/authentication/src/definitions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index 340b7cdc..b7d278c4 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -1421,7 +1421,7 @@ export interface AdditionalUserInfo { export type AuthStateChangeListener = (change: AuthStateChange) => void; /** - * Callback to receive the id token change notifications. + * Callback to receive the ID token change notifications. * * @since 6.2.0 */ From c7f90cf36b06bf180db69a5bc922b3ede4c26fe6 Mon Sep 17 00:00:00 2001 From: Ehsan Barooni <66495214+ebarooni@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:08:10 +0100 Subject: [PATCH 16/16] feat: extend authentication to support id token change event (#710) * implements suggested changes --- .changeset/chilled-pumpkins-kick.md | 2 +- packages/authentication/README.md | 8 ++++---- .../FirebaseAuthenticationPlugin.java | 4 +--- .../Plugin/FirebaseAuthenticationPlugin.swift | 6 ++---- packages/authentication/src/definitions.ts | 6 +++--- packages/authentication/src/web.ts | 20 +++++++++---------- 6 files changed, 20 insertions(+), 26 deletions(-) diff --git a/.changeset/chilled-pumpkins-kick.md b/.changeset/chilled-pumpkins-kick.md index 4f0c2f6c..453b262b 100644 --- a/.changeset/chilled-pumpkins-kick.md +++ b/.changeset/chilled-pumpkins-kick.md @@ -1,5 +1,5 @@ --- -'@capacitor-firebase/authentication': patch +'@capacitor-firebase/authentication': minor --- feat: add `idTokenChange` event listener diff --git a/packages/authentication/README.md b/packages/authentication/README.md index 2b3a09f5..407621d1 100644 --- a/packages/authentication/README.md +++ b/packages/authentication/README.md @@ -1584,9 +1584,9 @@ Listen for the user's sign-in state changes. addListener(eventName: 'idTokenChange', listenerFunc: IdTokenChangeListener) => Promise ``` -Listen for changes to the signed-in user's ID token changes. +Listen to ID token changes for the currently signed-in user. -**Attention:** This listener will not be triggered automatically upon ID token expiration. +**Attention:** This listener is not triggered when the `skipNativeAuth` is used. Use the Firebase JavaScript SDK instead. | Param | Type | | ------------------ | ----------------------------------------------------------------------- | @@ -1595,7 +1595,7 @@ Listen for changes to the signed-in user's ID token changes. **Returns:** Promise<PluginListenerHandle> -**Since:** 6.2.0 +**Since:** 6.3.0 -------------------- @@ -2115,7 +2115,7 @@ Callback to receive the user's sign-in state change notifications. #### IdTokenChangeListener -Callback to receive the id token change notifications. +Callback to receive the ID token change notifications. (change: GetIdTokenResult): void diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index 1b73a990..d13ab6ed 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -994,9 +994,7 @@ public void success(Result result) { @Override public void error(Exception exception) { - JSObject changeResult = new JSObject(); - changeResult.put("token", ""); - notifyListeners(ID_TOKEN_CHANGE_EVENT, changeResult, true); + Logger.error(TAG, exception.getMessage(), exception); } }; implementation.getIdToken(false, callback); diff --git a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift index ca2619be..382ea80f 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift @@ -597,15 +597,13 @@ public class FirebaseAuthenticationPlugin: CAPPlugin { @objc func handleIdTokenChange() { implementation?.getIdToken(false, completion: { result, error in - var changeResult = JSObject() if let error = error { CAPLog.print("[", self.tag, "] ", error) - changeResult["token"] = "" + return } if let result = result { - changeResult = result.toJSObject() + self.notifyListeners(self.idTokenChangeEvent, data: result.toJSObject(), retainUntilConsumed: true) } - self.notifyListeners(self.idTokenChangeEvent, data: changeResult, retainUntilConsumed: true) }) } diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index b7d278c4..078bd701 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -486,9 +486,9 @@ export interface FirebaseAuthenticationPlugin { /** * Listen to ID token changes for the currently signed-in user. * - * **Attention:** This listener will not be triggered automatically upon ID token expiration. + * **Attention:** This listener is not triggered when the `skipNativeAuth` is used. Use the Firebase JavaScript SDK instead. * - * @since 6.2.0 + * @since 6.3.0 */ addListener( eventName: 'idTokenChange', @@ -1423,7 +1423,7 @@ export type AuthStateChangeListener = (change: AuthStateChange) => void; /** * Callback to receive the ID token change notifications. * - * @since 6.2.0 + * @since 6.3.0 */ export type IdTokenChangeListener = (change: GetIdTokenResult) => void; diff --git a/packages/authentication/src/web.ts b/packages/authentication/src/web.ts index 3be7420d..00da8f4e 100644 --- a/packages/authentication/src/web.ts +++ b/packages/authentication/src/web.ts @@ -130,7 +130,7 @@ export class FirebaseAuthenticationWeb super(); const auth = getAuth(); auth.onAuthStateChanged(user => this.handleAuthStateChange(user)); - auth.onIdTokenChanged(() => void this.handleIdTokenChange()); + auth.onIdTokenChanged(user => void this.handleIdTokenChange(user)); } public async applyActionCode(options: ApplyActionCodeOptions): Promise { @@ -792,19 +792,17 @@ export class FirebaseAuthenticationWeb ); } - private async handleIdTokenChange(): Promise { - const change: GetIdTokenResult = { - token: '', - }; - try { - const { token } = await this.getIdToken({ forceRefresh: false }); - change.token = token; - } catch { - change.token = ''; + private async handleIdTokenChange(user: FirebaseUser | null): Promise { + if (!user) { + return; } + const idToken = await user.getIdToken(false); + const result: GetIdTokenResult = { + token: idToken, + }; this.notifyListeners( FirebaseAuthenticationWeb.ID_TOKEN_CHANGE_EVENT, - change, + result, true, ); }