Ways to protect my client's password in API response

I am relatively new to the world of JavaScript and MERN stack development. Currently, I am working on building a small-scale social media application. However, while coding the sign-up API, I encountered an issue where I could not properly segregate and hide the password from the user's information.

Below is the snippet of code in question:

userRouter.post("/signUp", async (req, res) => {
    
    const {name, userName, email, password} = req.body

    const existingUser = await userSchema.findOne({email: email})
    const SameUserName = await userSchema.findOne({userName: userName})
    if (existingUser) {
        return res.status(406).send({
            message: `Apologies, but an account with the email: ${email} already exists.`
        })
    } else if (SameUserName) {
        return res.status(406).send({
            message: `Sorry, that username is already taken. Please choose another one.`
        })
    }

    const newUser = new userSchema({
        name,
        userName,
        email,
        password
    })
    console.log(newUser)

    try {
        await newUser.save()
        res.status(201).send({
            message: `Account successfully created!`,
            user: newUser
        })
    } catch (err) {
        res.send({
            message:`Something went wrong`,
        })
    }
})

Now, I'm seeking guidance on how to exclude the password when sending the user information. Any suggestions?

Answer №1

After reading through your comment, I have some suggestions for you.

It is essential that you refactor your code.

try {
 const userSaved = await newUser.save();
 delete userSaved.password // if this is the property name
 return res.status(201).send({ message: 'Account created successfully', user: userSaved })
}

Alternatively, you can:

try {
 const userSaved = await newUser.save();
 delete userSaved.password // if this is the property name
 return userSaved;
}

With this approach, you manage the message and other aspects on the front-end.

Answer №2

Ensure you integrate the toJSON and transform methods into your schema. These functions will enable you to manipulate schema objects during creation and when they are being sent to the client.

Here's a demonstration:

Schema:

import { Schema, model } from 'mongoose';

const schema = new Schema(
    {
        name: {
            required: true,
            type: String
        },
        userName: {
            required: true,
            type: String
        },
        email: {
            required: true,
            type: String
        },
        password: {
            required: true,
            type: String
        }
    },
    {
        // Here we define the `toJSON` method to serialize the user object without the password and other unnecessary fields;
        // We also convert the mongo-specific `_id` property to a format compatible with any database
        toJSON: {
            transform(_, ret) {
                ret.id = ret._id;

                delete ret.password;
                delete ret._id;
                delete ret.__v;
            }
        }
    }
);

// This is our user schema, used for initializing new user objects before saving them in the database
const User = model('User', schema);

userRouter.post('/signUp', async (req, res) => {
    // Retrieve the inputs - validity of these inputs must be checked separately
    const { name, userName, email, password } = req.body;

    // Validate the email format and perform necessary checks
    if (!email) {
        // Handle error response
    }

    // Check if the email is already in use
    const existingUser = await User.findOne({ email });
    if (existingUser) {
        return res.status(400).send({
            message: `Sorry, an account with email: ${email} already exists.`
        });
    }

    // Validate the userName format here
    if (!userName) {
        // Handle error response
    }

    // Only query for duplicate userName after passing the email check to minimize computation
    const sameUserName = await User.findOne({ userName });
    if (sameUserName) {
        return res.status(400).send({
            message: `Sorry, this user name is already taken. Please choose another one.`
        });
    }

    // Perform additional validations for name and password
    if (!name || ...) {
        // Handle error response
    }

    // If all validations pass, create a new user using the schema as a template
    const newUser = new User({ name, userName, email, password });

    // Save the new user
    await newUser.save().catch((ex) => {
        // Handle error response
    });

    res.status(201).send({
        message: `Account created successfully!`,
        user: newUser
    });
});

You may also consider using express-validator, a middleware that simplifies request body validation tasks.

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

Preventing redundant connections in a clustered express.js app with Mongoose

Recently, I implemented clustering in my express.js application with 2 workers. However, I encountered an issue where my mongoose connection to the database (mongoose.connect) was being called twice when I run the app. I attempted to place it in the master ...

Angular 5 - Creating a dynamic function that generates a different dynamic function

One of my latest projects involved creating a versatile function that generates switch-case statements dynamically. export function generateReducer(initialState, reducerName: ReducerName, adapter: EntityAdapter<any>): (state, initialState) => ISt ...

CodeIgniter functionality for generating auto-incrementing IDs that are accessible in both the view and within JavaScript's Window.Print() method

While working on creating an invoice, I encountered a few issues. First, I want the Invoice No: to be displayed in my view (receipt.php) as 0001 and use it as the primary key in my tbl_payment table. However, I'm unsure how to have an auto-incremented ...

Guide to interacting with the Li element using JavaScript in Selenium

Is there a way to click on the item inside the li element using a Selenium script with JavaScript? I've tried different methods like By.cssSelector or by css, but I keep getting an ElementClickInterceptedError: element click intercepted:Other element ...

Discover how to obtain an access token using Yelp API V3 with JavaScript

Currently in the process of learning how to utilize this system, however there appears to be an issue with my code. $.ajax({ dataType: "POST", url: "https://api.yelp.com/oauth2/token", grant_type: "client_credentials", client_i ...

Following an AJAX request, jQuery.each() does not have access to the newly loaded CSS selectors

Note: While I value the opinions of others, I don't believe this issue is a duplicate based on the provided link. I have searched for a solution but have not found one that addresses my specific problem. Objective: Load HTML content to an element u ...

Error encountered: Unable to reference Vue as it has not been defined while importing an external JavaScript file

Currently, I am implementing a package called https://github.com/hartwork/vue-tristate-checkbox within my Vue.js component by adding it through the command: yarn add hartwork/vue-tristate-checkbox. In my Vue.js component, the package is imported in the fo ...

The "initialized" event in angular2-tree-component fires prior to the data being loaded

Utilizing the angular2-tree-component, my goal is to display an already expanded tree. According to Angular docs, the initialized event should be used for expanding the tree after the data has been received: This event triggers after the tree model has ...

Unable to integrate Express.js into my React JS project

Having trouble integrating express.js into my react js Project. After adding the following lines to my app.js code: const express = require('express') const app = express(); I encounter the error messages below: - Module not found: Error: Can&ap ...

execute function following ng-repeat

I'm diving into Angular for the first time and I want to start with a simple example. After using ng-repeat to display some data, I'd like to manipulate that data with JavaScript functions. However, I'm not sure when to trigger the JavaScri ...

Create dynamic HTML files using Express, EJS, and FS, and deliver them using Nginx as the server instead of relying

Imagine a scenario where we have a JSON object: [ { "id": 1, "title": "Title 1", "description": "Description 1" }, { "id": 2, "title": "Title 2", ...

The tool tip feature is not recognizing line breaks

I've encountered an issue with the tooltip in my project. Despite trying various solutions found on stackoverflow, I am still unable to resolve it. In my ReactJS application, I am dynamically creating elements using createElement and applying the too ...

What could be causing the relative route to fail in my routes.js file?

I am aiming to enhance the reusability of my code by making it easier to create variations for experimentation purposes. Could someone clarify why this scenario works: router.post('/baseline/auth/create-email-sms', function (req, res) { res. ...

Convert the value to JSON format by utilizing the PHP GET method

After retrieving a value using the GET method in my PHP file, I am attempting to access it. Below is how my PHP file appears: <?php include 'Con.php'; header('content-Type: application/json'); $catid = $_GET["CatId"]; //array ...

Ways to integrate npm dependencies into your Cordova plugin

Currently working on implementing a Cordova plugin called core-cordova found in this repository. This particular plugin has a dependency on another NPM package. The issue arises after installing the plugin in my app using: $ cordova plugin add @aerogears ...

Polymer custom components and Polymer motion recognition techniques

Looking to implement a listener event on a Polymer custom element using Polymer-gestures. Here is a snippet of my code: - my-custom-element.html <link rel="import" href="../polymer/polymer.html"> <polymer-element name="my-custom-element" attri ...

Inject Dynamic HTML Content onto the Page or in a Pop-up Box

I am currently working on a C# asp.net Web Forms project that involves a credit card payment system. The system returns HTML code for a 3D payment page, but it does not auto-redirect. Here is a snippet of my request: thirdBasketItem.Price = "0.2"; basketI ...

I'm struggling with developing react applications due to problems with canvas elements

I am currently using an M1 MacBook Pro, with Node version 15.4.1 and npm version 7.0.15. When I ran the command npx create-react-app my-app, it gave me this output: https://i.sstatic.net/OKKnA.jpg I have attempted various solutions but keep encountering ...

When React JS and PHP(Mysql) combine, the error message "records.map is not a function" may appear

What problem am I facing with my code? The issue lies in my JavaScript code while trying to display the JSON array fetched correctly by the PHP file. The JavaScript implementation of JSON in the state is accurate, but an error occurs when attempting to us ...

Exploring the differences between using Node.js JSON.parse during object creation versus when utilizing a getter property

This topic primarily focuses on seeking feedback on whether the current approach is optimal or if there are better ways to handle it. If you have any advice or comments on the content below, even if not directly asked for, please feel free to share. In my ...