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

Deleting Firestore ancestor documents and sub-collections that do not exist

My goal is to tidy up my collection data. The collection I'm working with is named "teams". Within this collection, there is a sub-collection called "players". I used a basic delete query in Firestore to remove the document under ...

Error in JSON Format Detected in Google Chrome Extension

Struggling with formatting the manifest for a simple Chrome extension I'm developing. I've been bouncing back and forth between these two resources to try and nail down the correct syntax: https://www.sitepoint.com/create-chrome-extension-10-mi ...

Unable to set the active tab using $rootScope

Is there anyone who can assist me with the issue I am currently facing? I have a NavCtrl to manage my active tags, and although I was able to change the active tab when clicking on the menu item, it does not update when clicking on links in the body views. ...

Navigating production mode in nuxtjs and uncovering errors

There seem to be numerous inquiries regarding this matter. Unfortunately, there doesn't appear to be a definitive solution. Is there any way to view detailed error logs in production mode? https://i.stack.imgur.com/prXUt.jpg ...

Converting long date format to short date format: yyyy-mm-dd

Is there a way to convert the long date format from "Sat Dec 13 2014 06:00:00 GMT+0600" to "2014-12-13" in yyyy-mm-dd format? <script> function myDate(val) { var now = new Date("<?php echo $Cnextdue;?>"); now.setDate(now.getDate() + 30*val); ...

Tips for showcasing the Phaser game screen exclusively within a React route

I am trying to make sure that my game screen only appears on the '/game' route. However, when I initialize it using the method "new Phaser.Game(config)", it ends up displaying on every route including '/home', the default route '/& ...

Resolving a CSS Layout Dilemma: How to Overlay Sidebar on Wrappers

I've run into a challenge while attempting to position a sidebar over page wrappers. The issue with absolute positioning arises when the sidebar needs to align with the corner of the blue header. I have contemplated using JavaScript to maintain its cu ...

Create a form in a React component that allows the user to input information

My challenge is to create a functionality where each time the add button is clicked, it should dynamically add an input field that I can save. It's similar to this example, but with inputs instead. The complexity arises from the fact that the inputs a ...

The Vue.js component is only refreshing after I manually refresh the browser page

As a newcomer to Vue.js and other reactive frameworks, I am still learning the ropes. I have a component that needs to update whenever there is a change. The goal is to display a balance from a specific login. <li :key="balance">Balance {{ balance ...

How can I resolve the issue of encountering the "Modal dialog present: If you navigate away from this page, any unsaved changes will be lost" message while using Internet Explorer with

Here's the code snippet I'm working with. While it successfully removes the alert box, it throws an error in the console: Exception in thread "main" org.openqa.selenium.UnhandledAlertException: Modal dialog present: If you leave this page, any c ...

Step-by-step guide for serving static JavaScript files using NextJS

I am currently exploring the process of hosting static js and css files using NextJS. My journey began with creating a react app through create-react-app, where I developed an App component before executing the npm run build command. This resulted in the ...

Using AJAX for uploading files upon a change event rather than upon submission

Below is the code I have been using to implement an iframe for ajax file upload without refreshing the page upon form submission. The current code works as expected. window.onload=init; function init() { document.getElementById('form').onsubmi ...

Replace existing styled-component CSS properties with custom ones

One of my components includes a CheckBox and Label element. I want to adjust the spacing around the label when it's used inside the CheckBox. Can this be achieved with styled()? Debugging Info The issue seems to be that the className prop is not b ...

Tips for organizing multiple TextField components within a Grid container using Material-UI

I utilize Material-UI for my front-end design needs. I have a query related to the Grid layout feature. My goal is to include 7 TextField elements, but they are appearing overlapped. When I modify all 7 TextField elements from xs={1} to xs={2}, they become ...

Having trouble getting my JavaScript code to function properly on Firefox browser

I have created a script where the cursor automatically moves to the next form field once it reaches its maximum length, in this case 1. Here is the JavaScript code: window.onload=function(){ var container = document.getElementsByClassName("container")[0] ...

Tips for arranging bar series in the NVD3 multibar angularJS directive

I am trying to generate a multi-bar chart using the nvd3 AngularJS directive by cmaurer, but I am facing an issue with stacking some series. Here is the data I am working with: $scope.exampleData = [ { "key": "Initial ...

What is the best way to retrieve EXIF data following the AJAX loading of images?

Currently, I am developing a swipe-able wine image viewer for NapaWapa.com and it's functioning quite smoothly: The challenge I'm facing is related to using a jquery plugin to extract the exif data from the images in the gallery. Unfortunately, ...

When attempting to submit form data, req.file returns as undefined

I'm currently facing an issue with my file upload functionality. I have a form that sends data to the controller in my routes file, but when the data is posted, the req.file appears as undefined. My goal is to upload the image to the public/images dir ...

Storing data in a text or HTML file using server-side JavaScript

Currently, I am working on a JavaScript form that involves saving user-entered variables to either a .txt file or a new webpage with the variables pre-filled in the inputs. I know that JavaScript cannot directly manipulate the user's machine, but I am ...

Modify the paragraph's class upon clicking the radio button

I have been struggling with changing the color of <p> based on the radio button selected using two classes, red and blue. However, for some reason, it's not working as expected. If anyone has any insights or suggestions on how to fix this issue ...