Hiding elements in FireBase and Angular based on user identification

Currently venturing into the world of Firebase in conjunction with AngularJS after previously working with php and server-side rendered pages.

I am grappling with how to securely hide specific parts of an application from certain users. I have three distinct levels of users - guests, members, and admins. Using ng-show based on user type can hide elements client-side, but the data is still being sent to the user.

An applicable scenario:

The menu options vary depending on the user's level. My initial thought was to use ngshow and check for the uuid, but revealing the admin's uuid seems like a major security risk.

Another idea was to store the menu items in a database and retrieve them as needed. However, this approach could lead to numerous deliberate 'unauthorized access attempts' by certain users.

What is the proper way to address this issue? It feels like there must be a crucial aspect regarding client-only applications that utilize Firebase services that I am overlooking.

Answer №1

Inspect the userStatus method within the service layer and its implementation in other layers.

Service Layer :

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { AngularFireAuthModule, AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';

@Injectable()
export class AuthService {

  user: Observable<firebase.User>;
  
  constructor(private fireAuth: AngularFireAuth) {
  }

  loginGoogle() {

    this.fireAuth.auth.signInWithPopup(new firebase.auth.EmailAuthProvider())
      .catch(function (error) {
        alert('Please try again');
      });
  }

  logout() {
    this.fireAuth.auth.signOut();
  }

  userStatus() {
    return this.fireAuth.authState;
  }
}

Navbar Component :

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Observable } from 'rxjs/Observable';
import * as firebase from 'firebase/app';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {

  user: Observable<firebase.User>;

  constructor(private authservice: AuthService) {
    this.user = this.authservice.userStatus();
  }

  ngOnInit() {
  }

  login() {
    this.authservice.loginGoogle();
  }

  logout() {
    this.authservice.logout();
  }
}

Here is the Navbar view, where you can display or hide elements based on whether the user is authenticated :

<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
  <a class="navbar-brand" routerLink="/">Firebase</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item ">
        <a class="nav-link" routerLink="/">Home</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" *ngIf="(user | async)?.uid" routerLink="/listings">Listings</a>
      </li>
      <li class="nav-item">
          <a class="nav-link" *ngIf="(user | async)?.uid" routerLink="/add-listing">Add Listing</a>
        </li>
    </ul>
    <ul class="navbar-nav navbar-right">
      <li class="nav-item">
        <a class="nav-link" *ngIf="!(user | async)?.uid" (click)="login()">Login</a>
        <a class="nav-link" *ngIf="(user | async)?.uid" (click)="logout()">Logout</a>
      </li>
    </ul>
    <div *ngIf="(user | async)?.uid">
        <img src="{{(user | async)?.photoURL}}" style="width:30px;height:30px;">
        <br> Email: {{(user | async)?.email}}
        <br> Name: {{(user | async)?.displayName}}
      </div>
  </div>
</nav>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

No matter what I attempt, my presentation refuses to align in the center

My slideshow, which is powered by jQuery/JS and involves absolute positioning for each image, is causing me trouble when trying to horizontally center it on the page. No matter what I do, I can't seem to get it right. The challenge is not only getting ...

Utilize Google Sheets to extract information from a web address containing quotation marks

I am currently utilizing a script called "ImportJSON" developed by paulgambill https://gist.github.com/paulgambill/cacd19da95a1421d3164 The URL I am working with contains quotes characters For instance: http://SomeAPIULR?{"Type": "SomeType"}&APIKE ...

"Efficiently handle JSON and binary data passing with the enhanced functionality of Express Body Parser

Within my express app router, I have routes set up to handle both POST requests with JSON data and binary data. The issue arises when I use body parser to parse the JSON data, as it incorrectly interprets the binary data as JSON and causes errors during th ...

Limitations exist when trying to open multiple tabs using the same link in Express puppeteer

Update: I found that changing "networkidle0" to "networkidle2" fixed the issue. Special thanks to vsemozhebuty for their helpful comment on this topic. I'm currently working on a web scraping project using Express and puppeteer. The following code sn ...

Tips for sending multiple values in a data object using jQuery AJAX

I am currently working on a form that contains two input fields, with the possibility of more being added later. The first input is a text field and the second is a checkbox. I want to be able to send these inputs using $.ajax. To accomplish this, I have ...

Record the success or failure of a Protractor test case to generate customized reports

Recently, I implemented Protractor testing for our Angular apps at the company and I've been searching for a straightforward method to record the pass/fail status of each scenario in the spec classes. Is there a simple solution for this? Despite my at ...

Navigating variable columns and rows in a static column table

Here is a preview of how my table will appear: <table> <thead> <tr> <th>Name</th> <th>Week 1</th> <th>Week 2</th> <th>Week 3</th> </tr> < ...

Unable to locate the element within a component using Cypress

I need help locating the dropdown arrow. I tried using the Cypress command cy.get('.dropdown-arrow').click() but it's throwing an error saying element not found. Below is the code snippet: <widgets-bms-scoreboard> <div class=&q ...

Multiple buttons in a single field

I am attempting to replace a Dropdown list with a series of buttons that will streamline the choices previously displayed by the dropdown list. Specifically, we are using graphic png files for the types of buttons. We experimented with checkboxing and ra ...

Preventing default behavior in a JQuery post request

Encountering an issue with jQuery functionality on a mobile device. function send() { $.post("scripts/post.php", { username: $("input[name=username]").val(), password: $("input[name=password]").val() }, function(data) { if ($(".data div" ...

Learning how to utilize getDerivedStateFromProps over componentWillReceiveProps in React

To address a deprecated error, I am looking to update my code from using componentWillReceiveProps to getDerivedStateFromProps. The component is being passed a date prop, and whenever this date changes, the getList function needs to be run with the new dat ...

Toggle the functionality of the login button in foundation

I am currently utilizing the front-end framework Foundation. My question is, how can I modify this menu so that the Log in button is only enabled when both the Login and Password input fields are filled with text? <form data-abide="ajax"> <div ...

Showing Stationary Pictures at Full Size in OpenLayers

I am trying to showcase static images as maps using a StaticImage layer in ol3, with the image size set at 100% in pixels. However, I am facing difficulty in ensuring that the displayed images are always the correct size based on the extent and zoom variab ...

Why is it not performing as expected when removing all non-numeric elements from the array?

let arr = [1, "5", 3, 27, undefined, { name: 'Steven' }, 11]; for (let i = 0; i < arr.length; i++) { if (typeof arr[i] !== 'number') { arr.splice(i, 1); } } console.log(arr); // result: [1, 3, 27, {…}, 11 ...

How can I securely store passwords for web scraping with Puppeteer to ensure maximum safety?

Looking for advice on scraping a website that requires login. The current code saves username and password in a config JSON file, which poses a security risk if the file is accessed by unauthorized individuals. Is there a more secure method, such as encr ...

Creating a unique chrome extension that swaps out HTML and JavaScript components

Is there a possibility to create a Chrome extension that eliminates the JavaScript and CSS from a website while it loads, replacing them with new scripts from a separate source? For example, changing 'Old script' to 'new script', or &a ...

Receiving JSON objects from Javascript in Django Views

When I attempt to pass a Json Object value from making an API call to my views.py in Django template, I encounter difficulty retrieving the value after an ajax call. let application = JSON.parse(sessionStorage.getItem("appId")); let kycStatus = a ...

Oops! The system encountered a problem while trying to identify the value `Han` for the property `Script

I'm attempting to extract Chinese characters from a string. According to this particular answer, the following code snippet should work: const nonChinese = /[^\p{Script=Han}]/gimu; const text = "asdP asfasf这些年asfagg 我开源的 几 ...

Eliminate the navigation bar option from a website template

Is there a way to permanently eliminate the menu button in this theme? Any guidance would be appreciated. Here's the link to the theme: https://github.com/vvalchev/creative-theme-jekyll-new ...

Activate audio when the link is clicked

Recently, I created a compact web application and it's almost complete. However, there is one cool functionality that I am missing. My goal is to have a sound play when the user clicks a link, but after playing, I want the navigation to continue as us ...