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

Refactor Auth social features and user credential creation #25

Merged
merged 8 commits into from
Sep 27, 2020

Conversation

gustavohenke
Copy link
Owner

  • It's wasn't possible to have a user be linked with multiple providers, so this is now possible by using User#providerData;
  • Operations like linkWithPopup happen from the User object, so social mocks should be accessible by both it and Auth;
  • UserCredential creation didn't seem very stable with 0ae4267, and to make matters worse there would be some duplication when implementing User#linkWithPopup. This is now its own class which takes few and simple arguments.

@@ -54,7 +55,7 @@ describe("#onAuthStateChange()", () => {
expect(listener).toHaveBeenCalledWith(credential.user);
});

it("doesn't invokes the listener after it's disposed", async () => {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

auth/auth.ts Outdated Show resolved Hide resolved
@@ -26,11 +45,10 @@ export class User implements firebase.User, UserSchema {
password?: string;
phoneNumber: string | null;
photoURL: string | null;
providerData: (firebase.UserInfo | null)[];
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was probably inherited from Firebase v4 or something.

@gustavohenke gustavohenke mentioned this pull request Jun 30, 2020
@coveralls
Copy link

coveralls commented Jun 30, 2020

Coverage Status

Coverage increased (+0.1%) to 90.097% when pulling e62435b on social-refactor into 0ae4267 on master.

Copy link
Collaborator

@wSedlacek wSedlacek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This are looking pretty good.
I do believe there is some room for cleanup but that may be down to personal taste.

That may be more of a job for the next PR rather then this one though.

auth/auth.ts Outdated Show resolved Hide resolved
return Promise.resolve(new UserCredential(user, "signIn", isNewUser));
}

private async signInWithSocial(provider: firebase.auth.AuthProvider) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we use @firebase/auth-types to avoid having to use firebase.auth for every one of these types.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package is not intended for direct usage, and should only be used via the officially supported firebase package.

😕 from https://www.npmjs.com/package/@firebase/auth-types/v/0.10.1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that is simply because it is intended to be a private API for firebase, we are already very much working with internal APIs when mocking.

auth/auth.ts Outdated
Comment on lines 120 to 127
const data = await this.store.consumeSocialMock(provider);
let user = this.store.findByProviderAndEmail(data.email, provider.providerId);
if (user) {
return this.signIn(user, { isNewUser: false });
}

user = this.store.add({ ...data, providerId: provider.providerId });
return this.signIn(user, { isNewUser: true });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Little confused why it appears that we are removing the data from the store just to add it again

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate? I'm not following.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well if I am not mistaken consumeSocialMock() removes the provider from the store, but this.store.add() would add it back to the store.

Maybe consumeSocialMock() (and other functions) could use a JSDoc comment to elaborate on what it does to make this more clear?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments around, let me know if it's clearer now!

auth/auth.ts Outdated Show resolved Hide resolved
private idStore = new Map<string, UserSchema>();
private emailStore = new Map<string, UserSchema>();
private store = new Map<string, UserSchema>();
private readonly socialMocks: SocialSignInMock[] = [];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would make sense for this to be a Map or Set to simplify consumeSocialMock() with methods like .get(), .remove() or .has()?

Comment on lines 42 to 47
findByEmail(email: string): User | undefined {
const schema = this.emailStore.get(email);
return schema ? new User(schema, this) : undefined;
for (const user of this.store.values()) {
if (user.email === email) {
return new User(user, this);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it would be a good place for .find()

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm quite sure this made more sense when I wrote it 😅

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why I wrote that that way is because .values() returns an iterator. To turn it into an array, one needs to spread it, which is an extra iteration if doing .find() on top of it.

Even though that's in theory slower, I went it to make that method shorter 👍

auth/user.ts Outdated Show resolved Hide resolved
@gustavohenke gustavohenke merged commit ecb462a into master Sep 27, 2020
@gustavohenke gustavohenke deleted the social-refactor branch September 27, 2020 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants