Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJS - Avoid returning user's password

I have a little problem with my project using GraphQL and Mongoose (code-first approach). I have a findCurrentUser query in my user's resolver that returns the information about the currently authenticated user, but I don't want to return the user's password, how I can avoid this?

User's Resolver:

@Query(() => User)
@UseGuards(GqlAuthGuard)
async findCurrentUser(@CurrentUser() user: JwtPayload): Promise<User> {
  return await this.usersService.findCurrent(user.id);
}

User's Service:

async findCurrent(id: string): Promise<User> {
    try {
      // find the user
      const user = await this.userModel.findOne({ _id: id });

      // if the user does not exists throw an error
      if (!user) {
        throw new BadRequestException('User not found');
      }

      // we should not return the user's password
      // TODO: this is a temporary solution, needs to be improved
      user.password = '';

      return user;
    } catch (error) {
      throw new InternalServerErrorException(error.message);
    }
  }

User's Entity:

import { ObjectType, Field, ID } from '@nestjs/graphql';
import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
import { Document, Schema as MongooseSchema } from 'mongoose';
import { nanoid } from 'nanoid';

@Schema()
@ObjectType()
export class User {
  @Field(() => ID)
  _id: MongooseSchema.Types.ObjectId;

  @Field(() => String, { nullable: false })
  @Prop({ type: String, required: true, trim: true })
  firstName: string;

  @Field(() => String, { nullable: true })
  @Prop({ type: String, required: false, trim: true })
  lastName?: string;

  @Field(() => String, { nullable: true })
  @Prop({ type: String, required: false, default: nanoid(10) })
  username: string;

  @Field(() => String, { nullable: false })
  @Prop({
    type: String,
    unique: true,
    required: true,
    lowercase: true,
    trim: true
  })
  email: string;

  @Field(() => String, { nullable: false })
  @Prop({ type: String, required: true, trim: true, minlength: 6 })
  password: string;

  @Field(() => Boolean, { defaultValue: true })
  @Prop({ type: Boolean, default: true })
  isActive: boolean;

  @Field(() => Date, { defaultValue: Date.now() })
  @Prop({ type: Date, default: Date.now() })
  createdAt: Date;
}

export type UserDocument = User & Document;

export const UserSchema = SchemaFactory.createForClass(User);

In the documentation, the NestJS team mentions "Serialization, " but I already tried and didn't work. I get the following error on my GraphQL Playground:

"message": "Cannot return null for non-nullable field User._id."

like image 268
Angel Martinez Avatar asked Jan 29 '26 06:01

Angel Martinez


2 Answers

You should simply remove @Field decorator from password property.

// @Field(() => String, { nullable: false })
@Prop({ type: String, required: true, trim: true, minlength: 6 })
password: string;
like image 158
Eranga Heshan Avatar answered Jan 31 '26 22:01

Eranga Heshan


You can avoid returning the password, by setting select Prop option to false.

@Prop({ ..., select: false })
password: string;

If you don't want to return the password on operations other than a simple select (API create/update/login etc.), you can change the document's toJSON transform method as following :

//
UserSchema.set('toJSON', {
    transform: (doc, ret, opt) => {
        delete ret.password;
        return ret;
    }
});
like image 34
Ismail Hachimi Avatar answered Jan 31 '26 23:01

Ismail Hachimi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!