Skip to content

feat(auth)!: use native for isSignInWithEmailLink / BREAKING CHANGE: return type now Promise<boolean> not boolean #8450

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,20 @@ private void createUserWithEmailAndPassword(
});
}

/**
* isSignInWithEmailLink
*
* @param email
* @param promise
*/
@ReactMethod
public void isSignInWithEmailLink(String appName, String emailLink, final Promise promise) {
Log.d(TAG, "isSignInWithEmailLink");
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
promise.resolve(firebaseAuth.isSignInWithEmailLink(emailLink));
}

/**
* signInWithEmailAndPassword
*
Expand Down
17 changes: 12 additions & 5 deletions packages/auth/e2e/emailLink.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,18 @@ describe('auth() -> emailLink Provider', function () {
const emailLink3 = 'https://www.example.com/action?mode=signIn';
const emailLink4 =
'https://x59dg.app.goo.gl/?link=https://rnfirebase-b9ad4.firebaseapp.com/__/auth/action?apiKey%3Dfoo%26mode%3DsignIn%26oobCode%3Dbar';

should.equal(true, isSignInWithEmailLink(auth, emailLink1));
should.equal(false, isSignInWithEmailLink(auth, emailLink2));
should.equal(false, isSignInWithEmailLink(auth, emailLink3));
should.equal(true, isSignInWithEmailLink(auth, emailLink4));
const emailLink5 = 'https://www.example.com/action?mode=signIn&oobCode=oobCode&apiKey=foo';

// ios does not require apiKey, but android and web/other do
if (!Platform.ios) {
should.equal(false, await isSignInWithEmailLink(auth, emailLink1));
} else {
should.equal(true, await isSignInWithEmailLink(auth, emailLink1));
}
should.equal(false, await isSignInWithEmailLink(auth, emailLink2));
should.equal(false, await isSignInWithEmailLink(auth, emailLink3));
should.equal(true, await isSignInWithEmailLink(auth, emailLink4));
should.equal(true, await isSignInWithEmailLink(auth, emailLink5));
});
});

Expand Down
9 changes: 9 additions & 0 deletions packages/auth/ios/RNFBAuth/RNFBAuthModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ - (void)invalidate {
}];
}

RCT_EXPORT_METHOD(isSignInWithEmailLink
: (FIRApp *)firebaseApp
: (NSString *)emailLink
: (RCTPromiseResolveBlock)resolve
: (RCTPromiseRejectBlock)reject) {
resolve(
@([RCTConvert BOOL:@([[FIRAuth authWithApp:firebaseApp] isSignInWithEmailLink:emailLink])]));
}

RCT_EXPORT_METHOD(signInWithEmailLink
: (FIRApp *)firebaseApp
: (NSString *)email
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2013,12 +2013,12 @@ export namespace FirebaseAuthTypes {
* #### Example
*
* ```js
* const signedInWithLink = firebase.auth().isSignInWithEmailLink(link);
* const signedInWithLink = await firebase.auth().isSignInWithEmailLink(link);
* ```
*
* @param emailLink The email link to check whether the user signed in with it.
*/
isSignInWithEmailLink(emailLink: string): boolean;
isSignInWithEmailLink(emailLink: string): Promise<boolean>;

/**
* Signs the user in with an email link.
Expand Down
6 changes: 1 addition & 5 deletions packages/auth/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,7 @@
}

isSignInWithEmailLink(emailLink) {
return (
typeof emailLink === 'string' &&
(emailLink.includes('mode=signIn') || emailLink.includes('mode%3DsignIn')) &&
(emailLink.includes('oobCode=') || emailLink.includes('oobCode%3D'))
);
return this.native.isSignInWithEmailLink(emailLink);

Check warning on line 364 in packages/auth/lib/index.js

View check run for this annotation

Codecov / codecov/patch

packages/auth/lib/index.js#L364

Added line #L364 was not covered by tests
}

signInWithEmailLink(email, emailLink) {
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/lib/modular/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ export function initializeRecaptchaConfig(auth: Auth): Promise<void>;
*
* @param auth - The Auth instance.
* @param emailLink - The email link to check.
* @returns True if the link is a sign-in with email link.
* @returns A promise that resolves if the link is a sign-in with email link.
*/
export function isSignInWithEmailLink(auth: Auth, emailLink: string): boolean;
export function isSignInWithEmailLink(auth: Auth, emailLink: string): Promise<boolean>;

/**
* Adds an observer for changes to the user's sign-in state.
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/lib/modular/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export async function getRedirectResult(auth, resolver) {
* Checks if an incoming link is a sign-in with email link suitable for signInWithEmailLink().
* @param {Auth} auth - The Auth instance.
* @param {string} emailLink - The email link to check.
* @returns {boolean}
* @returns {Promise<boolean>}
*/
export function isSignInWithEmailLink(auth, emailLink) {
return auth.isSignInWithEmailLink(emailLink);
Expand Down
14 changes: 14 additions & 0 deletions packages/auth/lib/web/RNFBAuthModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
multiFactor,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
isSignInWithEmailLink,
signInWithEmailLink,
signInWithCustomToken,
sendPasswordResetEmail,
Expand Down Expand Up @@ -449,6 +450,19 @@ export default {
});
},

/**
* Check if a sign in with email link is valid
* @param {string} appName - The name of the app to get the auth instance for.
* @param {string} emailLink - The email link to sign in with.
* @returns {Promise<boolean>} - Whether the link is a valid sign in with email link.
*/
async isSignInWithEmailLink(appName, emailLink) {
return guard(async () => {
const auth = getCachedAuthInstance(appName);
return await isSignInWithEmailLink(auth, emailLink);
});
},

/**
* Sign in with email link.
* @param {string} appName - The name of the app to get the auth instance for.
Expand Down
Loading