Nestjs not receiving data service to Controller - nestjs

I am looking for a response from userService .. but it is returning a null value..
I have consoled the data in userSerice it's showing here.
may be my controller is giving a response before receiving value from userService.
how can I solve this?
usercontroller
import {
Controller,
Post,
Body,
Get,
Param,
Patch,
Delete,
} from '#nestjs/common';
import { UserService } from './user.service';
#Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
#Post('/login')
async login(
#Body('email') userEmail,
#Body('password') userPassword
) {
const token = await this.userService.Login(userEmail, userPassword)
console.log(token, 'token')
return token;
}
}
Userservice :
import { Injectable, NotFoundException, UnauthorizedException } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import * as jwt from 'jsonwebtoken';
import { Model } from 'mongoose';
import { User } from './user.model';
import * as bcrypt from 'bcrypt'
import { resolve } from 'dns';
#Injectable()
export class UserService {
constructor(
#InjectModel('User') private readonly userModel: Model<User>,
) { }
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
bcrypt.compare(password, user.password, function (err, result) {
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = jwt.sign({ name: user.name, email: user.email, role: user.role }, "testSecreate");
const response = { name: user.name, email: user.email, role: user.role, token: authJwtToken }
console.log(response)
return response;
});
}
}

Tushar has n all right answer, but it's still mixing promises and callbacks, which I think should be avoided if possible. You can use this instead to not have any callbacks and just use async/await and promises throughout the method
import {
Injectable,
NotFoundException,
UnauthorizedException,
} from "#nestjs/common";
import { InjectModel } from "#nestjs/mongoose";
import * as jwt from "jsonwebtoken";
import { Model } from "mongoose";
import { User } from "./user.model";
import * as bcrypt from "bcrypt";
#Injectable()
export class UserService {
constructor(#InjectModel("User") private readonly userModel: Model<User>) {}
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
const result = await bcrypt.compare(password, user.password);
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = await jwt.sign(
{ name: user.name, email: user.email, role: user.role },
"testSecreate"
);
const response = {
name: user.name,
email: user.email,
role: user.role,
token: authJwtToken,
};
console.log(response);
return response;
}
}
Now, the console.log(response) will fire before console.log('token', token) in your controller method, and the flow will look synchronous while actually being asynchronous in nature.

import { Injectable, NotFoundException, UnauthorizedException } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import * as jwt from 'jsonwebtoken';
import { Model } from 'mongoose';
import { User } from './user.model';
import * as bcrypt from 'bcrypt'
import { resolve } from 'dns';
#Injectable()
export class UserService {
constructor(
#InjectModel('User') private readonly userModel: Model<User>,
) { }
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
await bcrypt.compare(password, user.password, function (err, result) {
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = await jwt.sign({ name: user.name, email: user.email, role: user.role }, "testSecreate");
const response = { name: user.name, email: user.email, role: user.role, token: authJwtToken }
console.log(response)
return response;
});
}
}
NOTE
The asynchronous method will be executed in parallel with your main program, so your console.log will be done before the callback function inside bcrypt.compare. You will see always 'oops, it was false'.

Related

I can't update information from inside the entity with typeorm

I'm building a "forgot password" controller, so my goal in "forgotPasswordController" is to generate a token and send it to my user entity, but the problem is that even following the typeorm documentation, I can't.but it still doesn't work, even though I use the const user instead of the User directly from the entity
error : (property) tokenResetPass: string Expected 3 arguments, but got 2.ts(2554) EntityManager.d.ts(208, 145): An argument for 'partialEntity' was not provided.
the problem is in
const sendToken = await AppDataSource.manager.update(User, {
tokenResetPass: token
});
forgotPassController
import { Request, Response } from "express";
import { User } from "../entities/User";
import { AppDataSource } from "../database/Config";
import jwt from 'jsonwebtoken';
import sendEmail from "../utils/mailer";
class forgotPasswordController {
async authenticate(req: Request, res: Response) {
const { email } = req.body;
const secret = process.env.JWT_SEC as string;
try {
const user = await AppDataSource.manager.findOneBy(User, {
email: email
});
if (!user) {
return res.status(401).json('Email not registered!');
};
if (user.isResetPass === true) {
return res.status(401).json('You have already made a request, check your email inbox.');
}
const token = jwt.sign({ id: user.id }, secret, {
expiresIn: process.env.EXPIRES_LOGIN,
});
if (!token) {
return res.status(401).json('Expired token, please try again.')
}
const sendToken = await AppDataSource.manager.update(User, {
tokenResetPass: token
});
sendEmail({
from: 'noreply#email.com',
to: user.email,
subject: 'Reset Password E-mail',
text: 'Token sending email to reset password',
html: `<h2>Copy the generated token below to reset your password</h2>
<h4>${token}</h4>
`,
});
return res.status(200).json('Email sent! Check your email box. ');
} catch (err) {
return res.status(500).json(err);
}
}
}
export default new forgotPasswordController();
user entity
import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import bcrypt from 'bcryptjs';
#Entity('users')
export class User {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column()
username: string;
#Column()
email: string;
#Column()
password: string;
#Column({
default: false
})
isResetPass: boolean;
#Column({
default: null
})
tokenResetPass: string;
#BeforeInsert()
#BeforeUpdate()
hashPassword() {
this.password = bcrypt.hashSync(this.password, 8);
}
}

NestJS and Prisma ORM : cleanest way to exclude password from response while allow it in requests?

I'm using NestJS with Prisma ORM and kinda of struggling with the use of #Exclude() decorator because when I add it on my UserDto, it also excludes the password from the incoming requests, so Prisma does not access to the password.
For now, I've done this, but I'm sure it is not the cleanest way to do it.
User DTO
export class CreateUserDto {
// [...]
// Not #Exclude() here because otherwise I don't get Passwords from Incoming requests
#IsString()
#IsNotEmpty()
password: string;
}
export class UserDto extends CreateUserDto {
#Exclude()
password: string;
}
User Service
// [...]
async create(userData: CreateUserDto): Promise<User> {
userData.password = await argon.hash(userData.password);
try {
const createdUser = await this.prismaService.user.create({
data: userData,
});
// *** DIRTY PART ***
return plainToClass(UserDto, createdUser) as User;
// *** DIRTY PART ***
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === 'P2002')
throw new ConflictException('A user with this email already exists');
}
throw e;
}
}
// [...]
User Controller
// [...]
#Post('register')
async register(#Body() userData: CreateUserDto) {
console.log(userData);
return this.userService.create(userData);
}
// [...]
Thanks for your answers!
This is currently an issue being worked on by Prisma.
You can follow the issue at: https://github.com/prisma/prisma/issues/5042
There are two solutions to this problem:
Manually stripping the password from any response of type User:
async findOne(userId: string) {
const admin = await this.prismaService.user.findUnique({
where: {
id: userId,
},
});
const { id, email, phoneNumber, createdAt, updatedAt } = admin;
return { id, email, phoneNumber, createdAt, updatedAt };
}
Create a global interceptor to remove all 'password' values:
import { Injectable,
NestInterceptor,
ExecutionContext,
CallHandler } from '#nestjs/common';
import { map, Observable } from 'rxjs';
#Injectable()
export class RemovePasswordInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
map((value) => {
value.password = undefined;
return value;
}),
);
}
}

Nest.js with AWS Cognito, How to get access to the user attributes

I have created the Nest.js app. And I use AWS Cognito to manage user authentication and authorization. I use amazon-cognito-identity-js for handling user signin/signout and #nestjs/passport / #UseGuards(AuthGuard('jwt')) for validating tokens and user access for the routes.
Now I need to get access to the current user attributes(email, phone_number...) in other routes of the app. What is the best way to do this?
auth.service.ts
import { AuthConfig } from './auth.config';
import { Injectable } from '#nestjs/common';
import {
AuthenticationDetails,
CognitoUser,
CognitoUserPool,
CognitoUserAttribute,
} from 'amazon-cognito-identity-js';
#Injectable()
export class AuthService {
private userPool: CognitoUserPool;
private sessionUserAttributes: {};
constructor(private readonly authConfig: AuthConfig) {
this.userPool = new CognitoUserPool({
UserPoolId: this.authConfig.userPoolId,
ClientId: this.authConfig.clientId,
});
}
registerUser(registerRequest: {
name: string;
email: string;
password: string;
}) {
const { name, email, password } = registerRequest;
return new Promise((resolve, reject) => {
return this.userPool.signUp(
name,
password,
[new CognitoUserAttribute({ Name: 'email', Value: email })],
null,
(err, result) => {
if (!result) {
reject(err);
} else {
resolve(result.user);
}
},
);
});
}
authenticateUser(user: { name: string; password: string }) {
const { name, password } = user;
const authenticationDetails = new AuthenticationDetails({
Username: name,
Password: password,
});
const userData = {
Username: name,
Pool: this.userPool,
};
const newUser = new CognitoUser(userData);
return new Promise((resolve, reject) => {
return newUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
resolve(result);
},
onFailure: (err) => {
reject(err);
},
});
});
}
}
jwt.strategi.ts
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '#nestjs/passport';
import { Injectable } from '#nestjs/common';
import { AuthService } from './auth.service';
import { passportJwtSecret } from 'jwks-rsa';
import { AuthConfig } from './auth.config';
#Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly authService: AuthService,
private authConfig: AuthConfig,
) {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `${authConfig.authority}/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: authConfig.clientId,
issuer: authConfig.authority,
algorithms: ['RS256'],
});
}
public async validate(payload: any) {
return !!payload.sub;
}
}
app.controller.ts
import { Controller, Get, UseGuards, Header } from '#nestjs/common';
import { AppService } from './app.service';
import { AuthGuard } from '#nestjs/passport';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
#UseGuards(AuthGuard('jwt'))
#Header('Content-Type', 'text/html')
getHello(): string {
return this.appService.getHello();
}
}
user is set as a property on the request when passport successfully authenticates the user.
The request can be injected in your controller and user property then accessed.
import { Controller, Get, UseGuards, Header, Request } from '#nestjs/common';
import { AppService } from './app.service';
import { AuthGuard } from '#nestjs/passport';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
#UseGuards(AuthGuard('jwt'))
#Header('Content-Type', 'text/html')
getHello(#Request() req): string {
console.log(req.user);
return this.appService.getHello();
}
}

Nestjs sending data before complete execution from service to Controller

I have a controller and service. From service, I am sending login success data to the controller. but its sending data before complete execution in service. but i am trying to send data after complete execution in loginservice.
I need to return user data after complete Login function..
userService
import { Injectable, NotFoundException, UnauthorizedException } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import * as jwt from 'jsonwebtoken';
import { Model } from 'mongoose';
import { User } from './user.model';
import * as bcrypt from 'bcrypt'
#Injectable()
export class UserService {
constructor(
#InjectModel('User') private readonly userModel: Model<User>,
) { }
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
await bcrypt.compare(password, user.password, function (err, result) {
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = jwt.sign({ name: user.name, email: user.email, role: user.role }, "testSecreate");
const response = { name: user.name, email: user.email, role: user.role, token: authJwtToken }
console.log(response)
return response;
});
}
}
userController
import {
Controller,
Post,
Body,
Get,
Param,
Patch,
Delete,
} from '#nestjs/common';
import { UserService } from './user.service';
#Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
#Post('/login')
async login(
#Body('email') userEmail,
#Body('password') userPassword
) {
const token = await this.userService.Login(userEmail, userPassword)
console.log(token, 'token')
return token;
}
}
since you're providing the callback func (last arg) to bcrypt.compare it will not return a promise. Please read the docs: https://www.npmjs.com/package/bcrypt#with-promises

How can i implement role redirection after a successful login in my MEAN stack Application

I have developed a MEAN stack application the backend works fine and the frontend but i want to go much further by implementing role based redirection after login i have 5 roles thats is admin, teacher, nurse, sportsman, and janitor i want each of them to access his/her own page after successful login and should use the same login page
I have tried some several solution online but so far nothing has come to help me this is the fifth time am asking this question without a real solution, please help me solve this its my final year project
here is my routes.ts
```import { Routes } from '#angular/router';
import { UserComponent } from './user/user.component';
import { SignUpComponent } from './user/sign-up/sign-up.component';
import { SignInComponent } from './user/sign-in/sign-in.component';
import { AuthGuard } from './auth/auth.guard';
import { AdminComponent } from './user/admin/admin.component';
import { AdminSportComponent} from './user/admin-sport/admin-sport.component'
import { AdminSuaHubComponent } from './user/admin-sua-hub/admin-sua-hub.component';
import { AdminCictComponent } from './user/admin-cict/admin-cict.component';
import { ViewadminsectionsComponent } from './user/viewadminsections/viewadminsections.component'
import { from } from 'rxjs';
export const appRoutes: Routes = [
{
path: 'user',component:SignInComponent
},
{
path:'signup', component:SignUpComponent, canActivate:[AuthGuard]
},
{
path:'admin', component:AdminComponent,
canActivate:[AuthGuard],
data:{
roles:['admin']
}
},
{
path:'viewsectionadmins',
component:ViewadminsectionsComponent,
canActivate:[AuthGuard],
data:{
roles:['admin']
}
},
{
path:'admincict',
component:AdminCictComponent,
canActivate:[AuthGuard],
data:{
roles:['admincict']
}
},
{
path:'adminsport',
component:AdminSportComponent,
canActivate:[AuthGuard],
data:{
roles:['adminsport']
}
},
{
path:'adminsuahub',
component: AdminSuaHubComponent,
canActivate:[AuthGuard],
data:{
roles:['adminsuahub']
}
},
{
path: '',component:SignInComponent
},
{
path:'',redirectTo:'/user', pathMatch:'full'
}
];```
Here is my app.module.ts
```import { BrowserModule } from '#angular/platform-browser';
import { NgModule, forwardRef } from '#angular/core';
import{ FormsModule } from '#angular/forms';
import{ RouterModule } from '#angular/router'
import { HttpClientModule, HTTP_INTERCEPTORS } from '#angular/common/http'
//components
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
import { SignUpComponent } from './user/sign-up/sign-up.component';
import { from } from 'rxjs';
//routes
import { appRoutes } from './routes';
import { SignInComponent } from './user/sign-in/sign-in.component';
import { UserService } from './shared/user.service';
import { AuthGuard } from './auth/auth.guard';
import { AuthInterceptor } from './auth/auth.interceptor';
import { AdminComponent } from './user/admin/admin.component';
import { AdminSportComponent } from './user/admin-sport/admin-sport.component';
import { AdminSuaHubComponent } from './user/admin-sua-hub/admin-sua-hub.component';
import { AdminCictComponent } from './user/admin-cict/admin-cict.component';
import { ViewadminsectionsComponent } from './user/viewadminsections/viewadminsections.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#NgModule({
declarations: [
AppComponent,
UserComponent,
SignUpComponent,
SignInComponent,
AdminComponent,
AdminSportComponent,
AdminSuaHubComponent,
AdminCictComponent,
ViewadminsectionsComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
RouterModule.forRoot(appRoutes),
HttpClientModule,
BrowserAnimationsModule
],
providers: [{
provide:forwardRef(() => {HTTP_INTERCEPTORS}),
useClass:forwardRef(() =>{ AuthInterceptor}),
multi:true
},AuthGuard,UserService],
bootstrap: [AppComponent]
})
export class AppModule { }```
Here is my User.js
``` const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const userSchema = new mongoose.Schema({
fullname:{
type:String,
required:'Full name cant be empty',
min:6,
max:255
},
email:{
type:String,
required:'Email cant be Empty',
max:255,
unique:true
},
University:{
type:String,
default:"Sokoine University of Agriculture"
},
College:{
type:String,
required:'College cant be Empty'
},
Department:{
type:String,
required:'department cant be empty'
},
password:{
type:String,
required:'pasword cant be empty',
max :1024,
minlength: [6,'password must be atlest 6 character long']
},
admintype:{
type:String,
enum :['HOD','CICT','Sports','SUASAB','Admin']
},
date:{
type:Date,
default:Date.now
},
saltSecret:String
});
//custom validation
userSchema.path('email').validate((val) => {
emailRegex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return emailRegex.test(val);
},'Invalid E-mail. ');
//events
userSchema.pre('save', function(next) {
bcrypt.genSalt(10, (err, salt)=> {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
//methods
userSchema.methods.verifyPassword = function(password){
return bcrypt.compareSync(password, this.password);
};
userSchema.methods.generateJwt = function() {
return jwt.sign({ _id:this._id},
process.env.JWT_SECRET,
{expiresIn:process.env.JWT_EXP});
}
module.exports = mongoose.model('User',userSchema)```
Here is my user.controller.js
```const mongoose = require('mongoose');
const User = mongoose.model('User');
const passport = require('passport');
const _ = require('lodash');
module.exports.register = (req,res, next) => {
const user = new User();
user.fullname = req.body.fullname;
user.email = req.body.email;
user.College = req.body.College;
user.Department = req.body.Department;
user.password = req.body.password;
user.admintype = req.body.admintype;
user.save((err, doc) => {
if(!err) { res.send(doc)}
else
{
if(err.code == 11000)
res.status(422).send(['Duplicate email Address Found.'])
else
return next(err);
}
})
}
module.exports.authenticate = (req, res, next ) => {
//calll for passport authentication
passport.authenticate('local', (err, user, info) => {
//error form paasport middleware
if(err) return res.status(400).json(err);
//registered user
else if (user) return res.status(200).json({ "token":user.generateJwt() });
//unknown user or wrong password
else return res.status(404).json(info);
})(req, res);
}
module.exports.userProfile = (req, res, next) =>{
User.findOne({ _id:req._id},
(err,user) =>{
if(!user)
return res.status(404).json({ status: false, message : 'User Record not Found. '});
else
return res.status(200).json({ status:true , user : _.pick(user, ['fullname','email','university','College','Department','admintype'])});
} );
//get admins
}```
here is my auth.guard.ts
```import { Injectable } from '#angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '#angular/router';
import { Observable } from 'rxjs';
import { UserService } from '../shared/user.service';
import { Router } from '#angular/router';
#Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private userService:UserService,private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
if(!this.userService.isloggedIn()){
this.router.navigateByUrl('/user');
this.userService.deleteToken();
return false;
}
return true;
}
}```
here is my user.model.ts
```export class User {
fullname:string;
email:string;
university:string;
College:string;
Department:string;
password:string;
admintype:string;
}```
here is my user.service.ts
```import { Injectable } from '#angular/core';
import { User } from './user.model';
import{ HttpClient, HttpHeaders } from '#angular/common/http';
import{ environment } from '../../environments/environment';
import { from } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class UserService {
selectedUser: User = {
fullname:'',
email:'',
university:'',
College:'',
Department:'',
password:'',
admintype:''
}
noAuthHeader = { headers: new HttpHeaders({ 'NoAuth': 'True'})};
constructor(private http: HttpClient) { }
//http methods
postUser(user:User)
{
return this.http.post(environment.apiBaseUrl+ '/register' ,user)
}
login(authCredentials)
{
return this.http.post(environment.apiBaseUrl+ '/authenticate',authCredentials,this.noAuthHeader);
}
getUserProfile()
{
return this.http.get(environment.apiBaseUrl + '/userProfile');
}
//helper methods
setToken(token:string)
{
localStorage.setItem('token',token);
}
getToken()
{
localStorage.getItem('token');
}
deleteToken()
{
localStorage.removeItem('token');
}
getUserPayload(){
var token = localStorage.getItem('token');
if(token)
{
var userPayload = atob(token.split('.')[1]);
return JSON.parse(userPayload);
}
else
return null;
}
isloggedIn()
{
var userPayload = this.getUserPayload();
if (userPayload)
{
return userPayload.exp > Date.now() / 1000;
}
}
getUserRole()
{
}
}```
here is my sign-in.component.ts
```import { Component, OnInit } from '#angular/core';
import { NgForm } from '#angular/forms';
import { UserService } from 'src/app/shared/user.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-sign-in',
templateUrl: './sign-in.component.html',
styleUrls: ['./sign-in.component.css']
})
export class SignInComponent implements OnInit {
constructor( private userService:UserService, private router:Router) { }
model = {
email:'',
password:''
};
emailRegex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
serverErrorMessages : string;
ngOnInit() {
if(this.userService.isloggedIn())
{
this.router.navigateByUrl('/admin');
}
}
onSubmit(form :NgForm)
{
this.userService.login(form.value).subscribe(
res =>{
this.userService.setToken(res['token']);
this.router.navigateByUrl('/admin');
},
err =>{
this.serverErrorMessages = err.message;
});
}
}```
so far i have no errors but am in need of implementing role based redirection
i would suggest you to create a field in mongodb schema as admin with boolean value as true or false depending upon the user, add different fields if any other roles exists,
on login check the user admin status and accordingly inform other parts of your application by subscribing the observables in your service file
call the method in your service file on OnInit method of the component and check whether the user is admin or not if not admin hide the things you don't want to show
and to stop a user from going to routes that are meant for admin add a guard which will navigate the user to homepage if he is not an admin by checking the same observable that you created in the service file.
i hope it helps

Resources