Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added verifyBeforeUpdateEmail method to Web, iOS, Android #741

Merged
merged 9 commits into from
Oct 23, 2024
25 changes: 25 additions & 0 deletions packages/authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ const useEmulator = async () => {
* [`signOut()`](#signout)
* [`unlink(...)`](#unlink)
* [`updateEmail(...)`](#updateemail)
* [`verifyBeforeUpdateEmail(...)`](#verifyBeforeUpdateEmail)
* [`updatePassword(...)`](#updatepassword)
* [`updateProfile(...)`](#updateprofile)
* [`useAppLanguage()`](#useapplanguage)
Expand Down Expand Up @@ -1450,6 +1451,22 @@ Updates the email address of the currently signed in user.

--------------------

### verifyBeforeUpdateEmail(...)

```typescript
verifyBeforeUpdateEmail(options: VerifyBeforeUpdateEmailOptions) => Promise<void>
```

Verifies the email before updating the email address of the currently signed in user.

| Param | Type |
| ------------- | ----------------------------------------------------------------- |
| **`options`** | <code><a href="#verifybeforeupdateemailoptions">VerifyBeforeUpdateEmailOptions</a></code> |

**Since:** 6.2.0

--------------------


### updatePassword(...)

Expand Down Expand Up @@ -1953,6 +1970,14 @@ An interface covering the possible persistence mechanism types.
| **`newEmail`** | <code>string</code> | The new email address. | 0.2.2 |


#### VerifyBeforeUpdateEmailOptions

| Prop | Type | Description | Since |
| -------------- | ------------------- | ---------------------- | ----- |
| **`newEmail`** | <code>string</code> | The new email address. | 0.2.2 |
| **`actionCodeSettings`** | <code><a href="#actioncodesettings">ActionCodeSettings</a></code> | Structure that contains the required continue/state URL with optional Android and iOS bundle identifiers. | 1.1.0 |


#### UpdatePasswordOptions

| Prop | Type | Description | Since |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,16 @@ public void updateEmail(FirebaseUser user, @NonNull String newEmail, @NonNull Ru
);
}

public void verifyBeforeUpdateEmail(FirebaseUser user, @NonNull String newEmail, @NonNull ActionCodeSettings actionCodeSettings, @NonNull Runnable callback) {
robingenz marked this conversation as resolved.
Show resolved Hide resolved
user
.verifyBeforeUpdateEmail(newEmail, actionCodeSettings)
.addOnCompleteListener(
task -> {
callback.run();
}
);
robingenz marked this conversation as resolved.
Show resolved Hide resolved
}

public void updatePassword(FirebaseUser user, @NonNull String newPassword, @NonNull Runnable callback) {
user
.updatePassword(newPassword)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,36 @@ public void updateEmail(PluginCall call) {
}
}

@PluginMethod
public void verifyBeforeUpdateEmail(PluginCall call) {
try {
String newEmail = call.getString("newEmail");
if (newEmail == null) {
call.reject(ERROR_NEW_EMAIL_MISSING);
return;
}

FirebaseUser user = implementation.getCurrentUser();
if (user == null) {
call.reject(ERROR_NO_USER_SIGNED_IN);
return;
}

JSObject settings = call.getObject("actionCodeSettings");
if (settings == null) {
call.reject(ERROR_ACTION_CODE_SETTINGS_MISSING);
return;
}
ActionCodeSettings actionCodeSettings = FirebaseAuthenticationHelper.createActionCodeSettings(settings);

implementation.verifyBeforeUpdateEmail(user, newEmail, actionCodeSettings, () -> call.resolve());
robingenz marked this conversation as resolved.
Show resolved Hide resolved
} catch (Exception exception) {
Logger.error(TAG, exception.getMessage(), exception);
String code = FirebaseAuthenticationHelper.createErrorCode(exception);
call.reject(exception.getMessage(), code);
}
}

@PluginMethod
public void updatePassword(PluginCall call) {
try {
Expand Down
13 changes: 13 additions & 0 deletions packages/authentication/ios/Plugin/FirebaseAuthentication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,19 @@ public typealias AuthStateChangedObserver = () -> Void
}
}

@objc func verifyBeforeUpdateEmail(_ newEmail: String, actionCodeSettings: ActionCodeSettings, completion: @escaping (Error?) -> Void) {
guard let user = self.getCurrentUser() else {
completion(RuntimeError(plugin.errorNoUserSignedIn))
return
}

let completion: (Error?) -> Void = { error in
completion(error)
}

user.sendEmailVerification(beforeUpdatingEmail: newEmail, actionCodeSettings: actionCodeSettings, completion: completion)
}

@objc func sendPasswordResetEmail(_ options: SendPasswordResetEmailOptions, completion: @escaping (Error?) -> Void) {
let email = options.getEmail()
let actionCodeSettings = options.getActionCodeSettings()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
CAP_PLUGIN_METHOD(reload, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(revokeAccessToken, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(sendEmailVerification, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(verifyBeforeUpdateEmail, CAPPluginReturnPromise);
robingenz marked this conversation as resolved.
Show resolved Hide resolved
CAP_PLUGIN_METHOD(sendPasswordResetEmail, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(sendSignInLinkToEmail, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setLanguageCode, CAPPluginReturnPromise);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,32 @@ public class FirebaseAuthenticationPlugin: CAPPlugin {
})
}

@objc func verifyBeforeUpdateEmail(_ call: CAPPluginCall) {
guard let newEmail = call.getString("newEmail") else {
call.reject(errorNewEmailMissing)
return
}

guard let actionCodeSettingsDict = call.getObject("actionCodeSettings") else {
call.reject(errorActionCodeSettingsMissing)
return
}
guard let actionCodeSettings = FirebaseAuthenticationHelper.createActionCodeSettings(actionCodeSettingsDict) else {
call.reject(errorActionCodeSettingsMissing)
return
}

implementation?.verifyBeforeUpdateEmail(newEmail, actionCodeSettings: actionCodeSettings, completion: { error in
if let error = error {
CAPLog.print("[", self.tag, "] ", error)
let code = FirebaseAuthenticationHelper.createErrorCode(error: error)
call.reject(error.localizedDescription, code)
return
}
call.resolve()
})
}

@objc func updatePassword(_ call: CAPPluginCall) {
guard let newPassword = call.getString("newPassword") else {
call.reject(errorNewPasswordMissing)
Expand Down
24 changes: 24 additions & 0 deletions packages/authentication/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,12 @@ export interface FirebaseAuthenticationPlugin {
* @since 0.2.0
*/
useEmulator(options: UseEmulatorOptions): Promise<void>;
/**
* Verifies the new email address before updating the email address of the currently signed in user.
*
* @since 6.2.0
robingenz marked this conversation as resolved.
Show resolved Hide resolved
*/
verifyBeforeUpdateEmail(options: VerifyBeforeUpdateEmailOptions): Promise<void>;
/**
* Listen for the user's sign-in state changes.
*
Expand Down Expand Up @@ -780,6 +786,24 @@ export interface UpdateEmailOptions {
newEmail: string;
}

/**
* @since 6.2.0
*/
export interface VerifyBeforeUpdateEmailOptions {
/**
* The new email address.
robingenz marked this conversation as resolved.
Show resolved Hide resolved
*
* @since 6.2.0
robingenz marked this conversation as resolved.
Show resolved Hide resolved
*/
newEmail: string;
/**
* The action code settings
*
* @since 6.2.0
robingenz marked this conversation as resolved.
Show resolved Hide resolved
*/
actionCodeSettings?: ActionCodeSettings;
robingenz marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @since 0.2.2
*/
Expand Down
11 changes: 11 additions & 0 deletions packages/authentication/src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
updateEmail,
updatePassword,
updateProfile,
verifyBeforeUpdateEmail,
} from 'firebase/auth';

import type {
Expand Down Expand Up @@ -102,6 +103,7 @@ import type {
User,
UserInfo,
UserMetadata,
VerifyBeforeUpdateEmailOptions,
} from './definitions';
import { Persistence, ProviderId } from './definitions';

Expand Down Expand Up @@ -761,6 +763,15 @@ export class FirebaseAuthenticationWeb
}
}

public async verifyBeforeUpdateEmail(options: VerifyBeforeUpdateEmailOptions): Promise<void> {
const auth = getAuth();
const currentUser = auth.currentUser;
if (!currentUser) {
throw new Error(FirebaseAuthenticationWeb.ERROR_NO_USER_SIGNED_IN);
}
return verifyBeforeUpdateEmail(currentUser, options?.newEmail, options?.actionCodeSettings);
}

private handleAuthStateChange(user: FirebaseUser | null): void {
const userResult = this.createUserResult(user);
const change: AuthStateChange = {
Expand Down