All files / src/app/services auth.service.ts

100% Statements 26/26
100% Branches 1/1
100% Functions 8/8
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 1061x 1x 1x       1x 1x 1x 1x             1x                     7x 7x 7x   7x     7x 7x                             1x                     2x                   1x   1x             1x   1x               1x   1x               1x   1x      
import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import {
    AngularFirestore,
    AngularFirestoreDocument
} from '@angular/fire/firestore';
import { Router } from '@angular/router';
import { auth } from 'firebase/app';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { UserCredentialsModel, UserModel } from '../models';
 
/**
 * Authentication Service
 */
@Injectable({providedIn: 'root'})
export class AuthService {
    /** current user */
    user$: Observable<UserModel>;
 
    /**
     * constructor of AuthService
     * @param afAuth: AngularFireAuth
     * @param afs: AngularFirestore
     * @param router: Router
     */
    constructor(
        private readonly afAuth: AngularFireAuth,
        private readonly afs: AngularFirestore,
        private readonly router: Router
    ) {
        this.user$ = this.afAuth.authState.pipe(
            switchMap(user => {
                // istanbul ignore else
                if (user) {
                    return this.afs.doc<any>(`users/${user.uid}`)
                        .valueChanges();
                }
 
                // istanbul ignore next
                return of(undefined);
            })
        );
    }
 
    /**
     * register user
     * @param credentials: user credentials
     */
    async register(credentials: UserCredentialsModel): Promise<any> {
        return this.afAuth.auth.createUserWithEmailAndPassword(
                credentials.email,
                credentials.password
            );
    }
 
    /**
     * log in with credentials
     * @param credentials: user credentials
     */
    async logIn(credentials: UserCredentialsModel): Promise<any> {
        return this.afAuth.auth.signInWithEmailAndPassword(
                credentials.email,
                credentials.password
            );
    }
 
    /**
     * sign in with google
     */
    async googleSignIn(): Promise<void> {
        const provider = new auth.GoogleAuthProvider();
 
        return this.oAuthLogin(provider);
    }
 
    /**
     * sign out
     */
    async signOut(): Promise<boolean> {
        await this.afAuth.auth.signOut();
 
        return this.router.navigate(['/']);
    }
 
    /**
     * attempt to login
     * @param provider: Firebase Auth Provider
     */
    private async oAuthLogin(provider): Promise<void> {
        const credential = await this.afAuth.auth.signInWithPopup(provider);
 
        return this.updateUserData(credential.user);
    }
 
    /**
     * update current user data
     * @param userData: uid, email, display name, photo URL, etc
     */
    private async updateUserData(userData: UserModel): Promise<void> {
        const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${userData.uid}`);
 
        return userRef.set(userData, {merge: true});
    }
}