0

I'm currently building an Angular project with Firestore. I have a users collection which contains a users uid plus their name, email and company name. Upon logging in, I can successfully take the users uid, look up the document in firestore and then redirect them to domain.com/theircompanyname - theircompanyname is what's stored in firestore under the user collection > document.

However, this currently doesn't prevent anyone entering a company name to the url and successfully navigating there. How would I go about implementing a route guard that only grants access to users who have a matching company to that which is visible in the url?

login.ts

login(email: string, password:string) {
  this.afAuth.auth.signInWithEmailAndPassword(email, password).then(value => {
      const user_id = value.user.uid;
      this.userService.checkUserForCorrectRedirect(user_id)
  });
}

user.service.ts This will redirect the user to the appropriate URL based on their company name in firestore (which i check by passing the user_id from login to this function)

checkUserForCorrectRedirect(user_id: string) {
   var docRef = this.db.collection("users").doc(`${user_id}`);

   docRef.get().then((doc) => {
    if (doc.exists) {
        const data = doc.data();
        this.company = data.company;
        this.router.navigate(['e', data.company]);
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
 }).catch((error) => {
    console.log("Error getting document:", error);
 });
}

All of the above works. The route guard is what I'd like assistance with if possible please.

router.guard This doesn't work obviously, and I don't really know how to make this work.

 import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';
import { UserService } from '../services/user.service';

@Injectable()

export class AuthGuardService implements CanActivate {

    authGuardStateURL: string;

    constructor(
        private router: Router,
        private userService: UserService,
    ) { }



    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
        if (this.userService.company == "testcompany") {
            return true;
        } else {
            return false;
        }
    }

    }
Que
  • 957
  • 2
  • 14
  • 35
  • can you show your router guard code? – davecar21 Apr 02 '19 at 09:01
  • Added. However, it's pretty useless as it's so bad... :) – Que Apr 02 '19 at 09:03
  • what is the return value of `this.userService.company` – davecar21 Apr 02 '19 at 09:20
  • Whatever their company name is. Upon logging in, I take the user id, look up their document in firestore an update a company variable in the user.service.ts - That's what I'm hoping to check against. Not sure if that's the right approach. – Que Apr 02 '19 at 09:22
  • Can you post the code of your method `this.userService.company`. – davecar21 Apr 02 '19 at 09:37
  • ` if (this.userService.company == "testcompany")` does this condition working propertly? – davecar21 Apr 02 '19 at 09:37
  • In user.service there's the following line `this.company = data.company;`. As for the if statement, no, that doesn't work. I've tried hard coding the values first to see if I could get it to work. I can't. – Que Apr 02 '19 at 09:45

1 Answers1

0

I think correct way to go is to create rules in your firestore database, so that it is secure. I did mine using rules, check if the user owns the company, and grant the read access

pawan nepal
  • 387
  • 2
  • 10