diff --git a/src/app/auth/auth.service.ts b/src/app/auth/auth.service.ts new file mode 100644 index 0000000..c16d795 --- /dev/null +++ b/src/app/auth/auth.service.ts @@ -0,0 +1,37 @@ +import {Injectable} from "@angular/core"; +import {BehaviorSubject, from} from "rxjs"; +import {AngularFirestore} from "@angular/fire/firestore"; +import {AngularFireAuth} from "@angular/fire/auth"; +import {auth} from 'firebase'; +import {Router} from "@angular/router"; +import {flatMap, map, skip} from 'rxjs/operators'; +import {User} from './user'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + readonly collection = 'Users'; + + user = new BehaviorSubject(null); + + constructor(private afAuth: AngularFireAuth, private router: Router, private db: AngularFirestore) { + this.afAuth.user.pipe( + flatMap((user: any) => { + if(!user) return from([false]); + let ref = this.db.collection(this.collection).doc(user.uid); + return ref.valueChanges().pipe(map(dbUser => Object.assign({ref: ref}, user, dbUser))) + }) + ).subscribe(user => this.user.next(user)); + } + + async loginWithGoogle() { + this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider()); + return this.user.pipe(skip(1)); + } + + async logout() { + await this.afAuth.auth.signOut(); + return this.router.navigate(['/']); + } +} diff --git a/src/app/auth/guards/admin.guard.ts b/src/app/auth/guards/admin.guard.ts new file mode 100644 index 0000000..2de4ad4 --- /dev/null +++ b/src/app/auth/guards/admin.guard.ts @@ -0,0 +1,17 @@ +import {CanActivate, Router} from '@angular/router'; +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; +import {filter, map, tap} from 'rxjs/operators'; +import {AuthService} from '../auth.service'; + +@Injectable({ + providedIn: 'root' +}) +export class AdminGuard implements CanActivate { + + constructor(private auth: AuthService, private router: Router) {} + + canActivate(): Observable { + return this.auth.user.pipe(filter((user: any) => user != null), map(user => user && user.isAdmin)); + } +} diff --git a/src/app/auth/guards/guest.guard.ts b/src/app/auth/guards/guest.guard.ts new file mode 100644 index 0000000..70c1629 --- /dev/null +++ b/src/app/auth/guards/guest.guard.ts @@ -0,0 +1,17 @@ +import {CanActivate, Router} from '@angular/router'; +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; +import {filter, map, tap} from 'rxjs/operators'; +import {AuthService} from '../auth.service'; + +@Injectable({ + providedIn: 'root' +}) +export class GuestGuard implements CanActivate { + + constructor(private auth: AuthService, private router: Router) {} + + canActivate(): Observable { + return this.auth.user.pipe(filter((user: any) => user != null), map(user => user && user.isAnonymous), tap(auth => auth ? this.router.navigate(['/']) : null)); + } +} diff --git a/src/app/auth/guards/login.guard.ts b/src/app/auth/guards/login.guard.ts new file mode 100644 index 0000000..ddb6896 --- /dev/null +++ b/src/app/auth/guards/login.guard.ts @@ -0,0 +1,17 @@ +import {CanActivate, Router} from '@angular/router'; +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; +import {filter, map, tap} from 'rxjs/operators'; +import {AuthService} from '../auth.service'; + +@Injectable({ + providedIn: 'root' +}) +export class LoginGuard implements CanActivate { + + constructor(private auth: AuthService, private router: Router) {} + + canActivate(): Observable { + return this.auth.user.pipe(filter((user: any) => user != null), map(user => user && !user.isAnonymous), tap(auth => auth ? null : this.router.navigate(['/login']))); + } +} diff --git a/src/app/auth/user.ts b/src/app/auth/user.ts new file mode 100644 index 0000000..2dbd4b8 --- /dev/null +++ b/src/app/auth/user.ts @@ -0,0 +1,9 @@ +import {User as FirebaseUser} from "firebase" +import {AngularFirestoreDocument} from '@angular/fire/firestore'; + +export interface User extends FirebaseUser { + ref?: AngularFirestoreDocument; + + isAdmin: boolean; + battery: string; +}