Guidelines for securing login access where the "IsApproved" field must be true before authorization

During the account registration process, I initially set the default value to false for the field IsApproved. I need to create security rules that allow login only for users with IsApproved:true, and redirect those with IsApproved:false to the accessdenied page. Here is the code used for user registration:

async register(){
    if(this.firstname && this.lastname && this.email && this.password){
      const loading =await this.loadingCtrl.create({
        message:'Processing...',
        spinner:'crescent',
        showBackdrop:true
      });
      loading.present();
      
      this.afauth.createUserWithEmailAndPassword(this.email,this.password)
      .then((data)=>{
        this.afs.collection('user').doc(data.user.uid).set({
          'userId':data.user.uid,
          'IsApproved':false,
          'userEmail':this.email,
          'userFirstname':this.firstname,
          'userLastname':this.lastname
        })
        .then(()=>{
          loading.dismiss();
          this.toast('Registration Success','success');
          this.router.navigate(['/login']);
        })
        .catch(error=>{
          loading.dismiss();
          this.toast(error.message,'danger')
        })
      })
    }
  }

How can I check whether the IsApproved field is true or false when a user attempts to sign in? Here is the code used for signing in:

async SignIn(email,password)
    {
     const loading =await this.LoadingCtrl.create({
       message:'Authenticating..',
       spinner:"crescent",
       showBackdrop:true
     });
     loading.present();
     this.afauth.setPersistence(firebase.default.auth.Auth.Persistence.LOCAL)
     .then(()=>{
       this.afauth.signInWithEmailAndPassword(email,password)
       .then((data)=>{
         if(!data.user){
           loading.dismiss();
           this.toast('Please check your credentials','warning');
           this.afauth.signOut();
         }else{
           loading.dismiss();
           this.router.navigate(['/menu']);
         }
       })
       .catch(error=>{
         loading.dismiss();
         this.toast(error.message,'danger');
       })
     })
     .catch(error=>{
       loading.dismiss();
       this.toast(error.message,'danger');
     });
    }

In my attempt to check using If-Else statement If(!data.user.IsApproved):

  if(!data.user){
       loading.dismiss();
       this.toast('Please check your credentials','warning');
       this.afauth.signOut();
     }else{
       loading.dismiss();
        if(data.user.IsApproved===true){
          this.router.navigate(['/menu']);
         }else{
            this.router.navigate(['/accessdenied']);
      }
       
    }
   })

However, I encountered the error message:

Property 'IsApproved' does not exist on type 'User'.
My user model looks like this:

export interface User {
    userId:string;
    IsApproved:boolean;
    userEmail:string;
    userPhoto:string;
    userFirstname:string;
    userLastname:string;
}

I attempted to modify the security rules as follows:

allow read,write:if request.auth.uid.IsApproved!=false;
But it resulted in an unknown error occurred. I am aiming to restrict access to only users with IsApproved:true, while routing others to the access denied page.

Answer №1

Storing the IsApproved value in a user-specific profile document in Firestore allows you to easily access and utilize this information in your security rules. By using the get() method on that document, you can retrieve its data and make decisions based on the stored value.

service cloud.firestore {
  match /databases/{database}/documents {
    allow read: if get(/databases/$(database)/documents/user/$(request.auth.uid)).data.IsApproved == true;
  }
}

To explore further examples of this approach, I encourage you to review Firebase's documentation on attribute and role based access control. This resource provides valuable insights and serves as a guide for implementing similar strategies in your own projects.

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

Limiting drag and drop in Three.js with specified distance thresholds

Is there a way to restrict the distance an object can be dragged and dropped in Three.js using DragControl? I am looking to set a maximum distance from the object's original position to prevent users from dragging it too far. ...

Set the Checkbox selections by utilizing the array values in the MUI DataGrid

In my MUI Datagrid, I have 2 columns for ID and City Name. There are only 3 cities represented in the table. Within a citizen object like this: const userMockup = { id: 1, name: "Citizen 1", cities: [1, 2], isAlive: true }; The cities ar ...

I am looking to efficiently store various pieces of data in a database by utilizing a singular variable through JS, PHP, and AJAX for streamlined processing and management

I am not very familiar with the technical jargon in programming, so please bear with me if my question is a bit unclear. To provide more clarity, I have shared the code that I have already written. I will elaborate on the issue after presenting the code: ...

Determine the estimated download duration using the $http protocol

I am experiencing an issue with a function that calculates the time it takes to download a text file (3MB in size) from my server. While it works well for single requests, when I attempt to run multiple requests simultaneously, the time spent waiting for a ...

Having trouble loading services within my Angular controller

After developing my Angular application, I added some basic code to my controller which is displayed below. Now, I am attempting to include two services that I created in my services.js file. This file is being loaded in my index.html and required within m ...

Exploring methods for testing React components with TypeScript's props

I am currently tackling a react-typescript project and I am looking to conduct testing on props passed to a react component using react-testing library. Here, we have the SharedDashboardUiLatestValueWidget.tsx component: export interface SharedDashboardU ...

The image file that was uploaded to our S3 storage has been detected

I'm attempting to upload an image created by cropperjs to a DigitalOcean space. To achieve this, I am utilizing a pre-signed URL and performing a put request using Axios. The problem arises when I try to open the uploaded image, as it appears to be ...

What is the TypeScript term for assigning multiple parameters an alias?

Imagine having a piece of code structured like this: export async function execute(conf: Record<string, string>, path: string, params: Array<string>) { const cmd = params[1]; const commandOption = params.slice(2) switch(cmd){ ...

The @emit event in vue.js is not being received by the parent component

Within my application, there is a form located in the ManageCards component. This form includes a child component called ImageUpload, which emits an image file and its local URL to the parent component: <form class="mb-3"> <div class ...

"An in-depth guide on parsing JSON and showcasing it in an HTML format

As part of my order processing, I am saving the order details into a JSON file named order_details.json. Here is an example of how the data is structured: [{ "uniqueID": "CHECKOUT_IE01", "orderID": "4001820182", "date": "06-02-2019 16:55:32.32 ...

What is the best way to set up playwright-jest so that I can skip a specific Test Suite (spec) file during execution?

In my repository, I have a setup using `playwright-jest` with multiple spec files for test suites. I need to skip one of the spec files without moving it from its current directory in the repo. The default script in `package.json` is `"test": "jest -c jes ...

The test window displays the Angular test component

During my test runs, I have noticed a strange occurrence. Components are appearing in the DOM near where the tests are being conducted. What's even more peculiar is that only one component is visible at a time. This phenomenon seems to occur with ever ...

Error encountered during navigation: navigator has not been defined

I encountered an issue where the page gets redirected upon form submission without triggering the catch block. However, in the backend, I am facing an error stating that the API body is not being executed. Below is the code snippet of the page: "use cl ...

Incorporate v-if to target a particular item within a v-for loop

On my Vue page, I have the following HTML code snippet: <div v-for="profile in lab.profiles" v-if="edit || profile.active" class="lab-tests-row-div" @mouseover=""> <div class="clickBox" :class="['clickBox-' + lab.id + ' ...

Update button Image upon click

Is there a way to swap the image on a button when it's clicked? I want my button to start with one icon, but then change to another icon once it has been clicked. How can I achieve this effect? Any suggestions on how to make this happen? Check out ...

What is the best way to incorporate an expression into a package.json file?

Query: Is there a way to automatically increase the version in a script message? I need my release message to always be one version higher than the previous. Aim: For example, if I have version **0.1.2**, I would like to update my commit message to 0.1.3 ...

I'm having trouble seeing my remarks in the comment section

I've been working on setting up a comment section for my website, and I'm facing an issue with displaying the comments that users post in the database on the front end. When I try to retrieve and display the comment using a function, it doesn&apo ...

The Google Drive API in Node.js is notifying the deletion of files

I encountered an issue with the Google Drive API in my application. Even after deleting files from Google Drive, the listfiles function still returns those deleted files. Is there a solution to prevent this from happening? Below is the function of my API: ...

Elevate the scope analysis for a function within the Jasmine framework

I have written a few functions within the app component. I am experiencing an issue with increasing coverage in the summary for these component methods. The test cases are functioning correctly, but some lines are not being accounted for in the coverage s ...

Is it possible to configure Cypress to always open in the current tab instead of opening in a new tab?

One challenge with Cypress is testing on multiple tabs. Our website default to opening in a new tab. Is there a way to make Cypress continue the tests on the same tab? cy.get(element).invoke('attr', 'target', '_self').click() ...