File

src/module/services/auth-process.service.ts

Index

Properties
Methods

Constructor

constructor(afa: AngularFireAuth, config: NgxAuthFirebaseUIConfig, _snackBar: MatSnackBar, _fireStoreService: FirestoreSyncService, _matSnackBarConfig: MatSnackBarConfig)
Parameters :
Name Type Optional
afa AngularFireAuth No
config NgxAuthFirebaseUIConfig No
_snackBar MatSnackBar No
_fireStoreService FirestoreSyncService No
_matSnackBarConfig MatSnackBarConfig No

Methods

Public deleteAccount
deleteAccount()
Returns : Promise<any>
getMessageOnAuthError
getMessageOnAuthError(error: any)
Parameters :
Name Type Optional
error any No
Returns : string
Public getPhotoPath
getPhotoPath(image: string)
Parameters :
Name Type Optional
image string No
Returns : string
Public getUserPhotoUrl
getUserPhotoUrl()
Returns : string
handleError
handleError(error: any)
Parameters :
Name Type Optional
error any No
Returns : void
Async handleSuccess
handleSuccess(userCredential: UserCredential)
Parameters :
Name Type Optional
userCredential UserCredential No
Returns : any
listenToUserEvents
listenToUserEvents()
Returns : void
notifyError
notifyError(error: any)
Parameters :
Name Type Optional
error any No
Returns : void
Public parseUserInfo
parseUserInfo(user: User)
Parameters :
Name Type Optional
user User No
Returns : UserInfo
reloadUserInfo
reloadUserInfo()
Returns : any
Public resetPassword
resetPassword(email: string)

Reset the password of the ngx-auth-firebaseui-user via email

Parameters :
Name Type Optional Description
email string No
  • the email to reset
Returns : any
Async sendNewVerificationEmail
sendNewVerificationEmail()
Returns : {}
showErrorToast
showErrorToast(error: any)
Parameters :
Name Type Optional
error any No
Returns : void
showToast
showToast(message: string)
Parameters :
Name Type Optional
message string No
Returns : void
Public Async signInWith
signInWith(provider: AuthProvider, credentials?: ICredentials)

General sign in mechanism to authenticate the users with a firebase project using a traditional way, via username and password or by using an authentication provider like google, facebook, twitter and github

Parameters :
Name Type Optional Description
provider AuthProvider No
  • the provider to authenticate with (google, facebook, twitter, github)
credentials ICredentials Yes
Returns : any
Public signInWithPhoneNumber
signInWithPhoneNumber()
Returns : void
Async signOut
signOut()
Returns : any
Public Async signUp
signUp(displayName: string, credentials: ICredentials)

Sign up new users via email and password. After that the ngx-auth-firebaseui-user should verify and confirm an email sent via the firebase

Parameters :
Name Type Optional Description
displayName string No
  • the displayName if the new ngx-auth-firebaseui-user
credentials ICredentials No
Returns : any
Public updateProfile
updateProfile(name: string, photoURL: string)

Update the profile (name + photo url) of the authenticated ngx-auth-firebaseui-user in the firebase authentication feature (not in firestore)

Parameters :
Name Type Optional Description
name string No
  • the new name of the authenticated ngx-auth-firebaseui-user
photoURL string No
  • the new photo url of the authenticated ngx-auth-firebaseui-user
Returns : Promise<any>

Properties

Public afa
Type : AngularFireAuth
Public config
Type : NgxAuthFirebaseUIConfig
Decorators :
@Inject(undefined)
emailConfirmationSent
Type : boolean
emailToConfirm
Type : string
messageOnAuthError
Type : messageOnAuthErrorType
messageOnAuthSuccess
Type : string
onErrorEmitter
Type : EventEmitter<any>
Default value : new EventEmitter<any>()
onSuccessEmitter
Type : EventEmitter<any>
Default value : new EventEmitter<any>()
user
Type : User
user$
Type : Observable<User>
import { EventEmitter, forwardRef, Inject, Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { MatSnackBar, MatSnackBarConfig, MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material';
import { firebase } from '@firebase/app';
import '@firebase/auth';
import { User, UserInfo } from 'firebase/app';
import { isFunction } from 'lodash';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Accounts } from '../enums';
import { NgxAuthFirebaseUIConfig } from '../interfaces/config.interface';
import { ICredentials, ISignInProcess, ISignUpProcess } from '../interfaces/main.interface';
import { NgxAuthFirebaseUIConfigToken } from '../ngx-auth-firebase-u-i.module';
import { FirestoreSyncService } from './firestore-sync.service';

// import User = firebase.User;

import UserCredential = firebase.auth.UserCredential;

export const facebookAuthProvider = new firebase.auth.FacebookAuthProvider();
export const googleAuthProvider = new firebase.auth.GoogleAuthProvider();
export const twitterAuthProvider = new firebase.auth.TwitterAuthProvider();
export const githubAuthProvider = new firebase.auth.GithubAuthProvider();
export const microsoftAuthProvider = new firebase.auth.OAuthProvider('microsoft.com');
export const yahooAuthProvider = new firebase.auth.OAuthProvider('yahoo.com');

export enum AuthProvider {
  ALL = 'all',
  ANONYMOUS = 'anonymous',
  EmailAndPassword = 'firebase',
  Google = 'google',
  Facebook = 'facebook',
  Twitter = 'twitter',
  Github = 'github',
  Microsoft = 'microsoft',
  Yahoo = 'yahoo',
  PhoneNumber = 'phoneNumber'
}

export type getErrorMessageType = (error: any) => string;
export type messageOnAuthErrorType = string | getErrorMessageType;

@Injectable({
  providedIn: 'root'
})
export class AuthProcessService implements ISignInProcess, ISignUpProcess {
  onSuccessEmitter: EventEmitter<any> = new EventEmitter<any>();
  onErrorEmitter: EventEmitter<any> = new EventEmitter<any>();

  // Useful to know aubout auth state even between reloads.
  // Replace emailConfirmationSent and emailToConfirm.
  user$: Observable<User>;
  user: User;

  messageOnAuthSuccess: string;
  messageOnAuthError: messageOnAuthErrorType;

  // Legacy field that is setted to true after sign up. Value is lost in case of reload. The idea here is to know if we just sent a verification email.
  emailConfirmationSent: boolean;
  // Lefacy filed that contain the mail to confirm. Same lifecyle than emailConfirmationSent.
  emailToConfirm: string;

  constructor(
    public afa: AngularFireAuth,
    @Inject(forwardRef(() => NgxAuthFirebaseUIConfigToken)) public config: NgxAuthFirebaseUIConfig,
    private _snackBar: MatSnackBar,
    private _fireStoreService: FirestoreSyncService,
    @Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) private _matSnackBarConfig: MatSnackBarConfig
  ) {}

  listenToUserEvents() {
    this.user$ = this.afa.user.pipe(
      tap(user => {
        this.user = user;
      })
    );
  }

  /**
   * Reset the password of the ngx-auth-firebaseui-user via email
   *
   * @param email - the email to reset
   * @returns
   */
  public resetPassword(email: string) {
    return this.afa.auth.sendPasswordResetEmail(email)
      .then(() => console.log('Password reset email sent'))
      .catch((error) => this.notifyError(error));
  }

  /**
   * General sign in mechanism to authenticate the users with a firebase project
   * using a traditional way, via username and password or by using an authentication provider
   * like google, facebook, twitter and github
   *
   * @param provider - the provider to authenticate with (google, facebook, twitter, github)
   * @param credentials
   * @returns
   */
  public async signInWith(provider: AuthProvider, credentials?: ICredentials) {
    try {
      let signInResult: UserCredential | any;

      switch (provider) {
        case AuthProvider.ANONYMOUS:
          signInResult = await this.afa.auth.signInAnonymously() as UserCredential;
          break;

        case AuthProvider.EmailAndPassword:
          signInResult = await this.afa.auth.signInWithEmailAndPassword(credentials.email, credentials.password) as UserCredential;
          break;

        case AuthProvider.Google:
          signInResult = await this.afa.auth.signInWithPopup(googleAuthProvider) as UserCredential;
          break;

        case AuthProvider.Facebook:
          signInResult = await this.afa.auth.signInWithPopup(facebookAuthProvider) as UserCredential;
          break;

        case AuthProvider.Twitter:
          signInResult = await this.afa.auth.signInWithPopup(twitterAuthProvider) as UserCredential;
          break;

        case AuthProvider.Github:
          signInResult = await this.afa.auth.signInWithPopup(githubAuthProvider) as UserCredential;
          break;

        case AuthProvider.Microsoft:
          signInResult = await this.afa.auth.signInWithPopup(microsoftAuthProvider) as UserCredential;
          break;

        case AuthProvider.Yahoo:
          signInResult = await this.afa.auth.signInWithPopup(yahooAuthProvider) as UserCredential;
          break;

        case AuthProvider.PhoneNumber:
          // coming soon - see feature/sms branch
          break;

        default:
          throw new Error(`${AuthProvider[provider]} is not available as auth provider`);
      }
      await this.handleSuccess(signInResult);
    } catch (err) {
      this.handleError(err);
    }
  }

  /**
   * Sign up new users via email and password.
   * After that the ngx-auth-firebaseui-user should verify and confirm an email sent via the firebase
   *
   * @param displayName - the displayName if the new ngx-auth-firebaseui-user
   * @param credentials
   * @returns
   */
  public async signUp(displayName: string, credentials: ICredentials) {
    try {
      const userCredential: UserCredential = await this.afa.auth.createUserWithEmailAndPassword(credentials.email, credentials.password);
      const user = userCredential.user;
      await this.updateProfile(displayName, user.photoURL);

      if (this.config.enableFirestoreSync) {
        await this._fireStoreService
          .getUserDocRefByUID(user.uid)
          .set({
            uid: user.uid,
            displayName: displayName,
            email: user.email,
            photoURL: user.photoURL
          } as User);
      }

      if (this.config.enableEmailVerification) {
        await user.sendEmailVerification();
      }

      // Legacy fields
      this.emailConfirmationSent = true;
      this.emailToConfirm = credentials.email;

      await this.handleSuccess(userCredential);
    } catch (err) {
      this.handleError(err);
    }
  }

  async sendNewVerificationEmail() {
    if (!this.user) {
      return Promise.reject(new Error('No signed in user'));
    }
    return this.user.sendEmailVerification();
  }

  async signOut() {
    try {
      await this.afa.auth.signOut();
    } catch (error) {
      this.notifyError(error);
    }
  }

  /**
   * Update the profile (name + photo url) of the authenticated ngx-auth-firebaseui-user in the
   * firebase authentication feature (not in firestore)
   *
   * @param name - the new name of the authenticated ngx-auth-firebaseui-user
   * @param photoURL - the new photo url of the authenticated ngx-auth-firebaseui-user
   * @returns
   */
  public updateProfile(name: string, photoURL: string): Promise<any> {
    if (!photoURL) {
      return this.afa.auth.currentUser.updateProfile({displayName: name});
    } else {
      return this.afa.auth.currentUser.updateProfile({displayName: name, photoURL: photoURL});
    }
  }

  public deleteAccount(): Promise<any> {
    return this.afa.auth.currentUser.delete();
  }

  public parseUserInfo(user: User): UserInfo {
    return {
      uid: user.uid,
      displayName: user.displayName,
      email: user.email,
      phoneNumber: user.phoneNumber,
      photoURL: user.photoURL,
      providerId: user.providerData.length > 0 ? user.providerData[0].providerId : null
    };
  }

  public getUserPhotoUrl(): string {

    const user: firebase.User | null = this.afa.auth.currentUser;

    if (!user) {
      return;
    } else if (user.photoURL) {
      return user.photoURL;
    } else if (user.emailVerified) {
      return this.getPhotoPath(Accounts.CHECK);
    } else if (user.isAnonymous) {
      return this.getPhotoPath(Accounts.OFF);
    } else {
      return this.getPhotoPath(Accounts.NONE);
    }
  }

  public getPhotoPath(image: string) {
    return `assets/user/${image}.svg`;
  }

  public signInWithPhoneNumber() {
    // todo: 3.1.18
  }

  async handleSuccess(userCredential: UserCredential) {
    this.onSuccessEmitter.next(userCredential.user);
    if (this.config.enableFirestoreSync) {
      try {
        await this._fireStoreService.updateUserData(this.parseUserInfo(userCredential.user));
      } catch (e) {
        console.error(`Error occurred while updating user data with firestore: ${e}`);
      }
    }
    if (this.config.toastMessageOnAuthSuccess) {
      const fallbackMessage = `Hello ${userCredential.user.displayName ? userCredential.user.displayName : ''}!`;
      this.showToast(this.messageOnAuthSuccess || fallbackMessage);
    }
  }

  handleError(error: any) {
    this.notifyError(error);
    console.error(error);
  }

  // Refresh user info. Can be useful for instance to get latest status regarding email verification.
  reloadUserInfo() {
    return this.user.reload();
  }

  // Search for an error message.
  // Consumers of this library are given the possibility to provide a function in case they want to instrument message based on error properties.
  getMessageOnAuthError(error: any) {
    let message: string;
    const fallbackMessage = 'Sorry, something went wrong. Please retry later.';
    if (isFunction(this.messageOnAuthError)) {
      message = this.messageOnAuthError(error);
    } else {
      message = this.messageOnAuthError || fallbackMessage;
    }
    return message;
  }

  // Show a toast using current snackbar config. If message is empty, no toast is displayed allowing to opt-out when needed.
  // Default MatSnackBarConfig has no duration, meaning it stays visible forever.
  // If that's the case, an action button is added to allow the end-user to dismiss the toast.
  showToast(message: string) {
    if (message) {
      this._snackBar.open(message, this._matSnackBarConfig.duration ? null : 'OK');
    }
  }

  showErrorToast(error: any) {
    if (this.config.toastMessageOnAuthError) {
      this.showToast(this.getMessageOnAuthError(error));
    }
  }

  notifyError(error: any) {
    this.onErrorEmitter.emit(error);
    this.showErrorToast(error);
  }

}

result-matching ""

    No results matching ""