#mongoose with NEST and validation

16 messages · Page 1 of 1 (latest)

reef crown
#

I have a problem with validation in mongoose with NEST. According to the code, validation should work, but when I don't check it manually, duplicate e-mails and userId are still saved to the database.
//schema

export type UsersDocument = HydratedDocument<Users>

@Schema()
export class Users extends Document {
    @Prop({ required: true, index: true, unique: true })
    email: string;

    @Prop({ required: true })
    password: string;

    @Prop({ required: true, index: true, unique: true })
    userId: string;

    @Prop()
    refreshToken?: string | null | undefined;
}

export const UsersSchema = SchemaFactory.createForClass(Users); ```



//usersService

 ```async createUser(user: UserInterface): Promise<UserInterface> {
        const userExists = await this.userModel.findOne({ email: user.email });

        const userIdExists = await this.userModel.findOne({ userId: user.userId });

        if (userExists || userIdExists) {
            //Here i cheking manuallu
        }

        const newUser = new this.userModel(user);
        return newUser.save();

    }```

//auth service

``` async register(dto: AuthDto) {
        const hashPassword = await this.hashData(dto.password);
        const customId = uuidv4();
        const newUser = {
            email: dto.email,
            password: hashPassword,
            userId: customId
        }
        await this.usersService.createUser(newUser);
    } ```

//controller
``` @Public()
    @Post('/register')
    @HttpCode(HttpStatus.CREATED)
    register(@Body() dto: AuthDto) {
        return this.authService.register(dto)
    }```
azure oasis
# reef crown I have a problem with validation in mongoose with NEST. According to the code, v...

when I don't check it manually, duplicate e-mails and userId are still saved to the database.
Isn't that expected behavior? When you don't check the user's input against the database before creating entities, duplicate documents can happen.

Instead of executing two findOne queries, you can take advantage of the MongoDB features and do those checkings in just a single, more optimized query:

const userExists = await this.userModel.exists({
  $or: [
    { email: user.email },
    { userId: user.userId }
  ]
});
if (userExists) {
  // ...
}

https://mongoosejs.com/docs/api/model.html#Model.exists()

Also, please stick to the MongoDB ObjectIds as the user identifier instead of UUIDs, as it takes less space, is sortable, and contains the creation timestamp.

reef crown
#

Okay, I added these uuids to the user, but why would I then search for, for example, orders for a specific user using this uuid? Can I use ObjectId from mongo for this and thus sign the jwt?

azure oasis
warm echo
#

I believe if you use unique: true you don't need the index.

#

The unique constraint causes an index to be built automatically.

reef crown
warm echo
#

@reef crown - Did you try removing index: true in your prop definitions to see what happens?

reef crown
#

@warm echo yes, but nothing happen and honesly i now only index is used to extract data faster, but I have data from a warehouse where one collection can have up to 5 million records and about 3TB of data. And i dont now how to check is indexing.O and I also know that every time I turn the application on and off, indexing in Mongo tries to re-index everything and then connect? I think well?

warm echo
#

Like I wrote earlier, the unique constraint will cause an index to be built. If you have prior data and the index is already built, then the index will not be rebuilt at app start-up. At least it shouldn't.

For your min reproduction repo, what steps does one need to take to reproduce the issue?

reef crown
#

Okej i can check that, but now i dont have any issue. I just wanted to find out whether the code itself is good, whether I'm doing the right thing by generating a uuid for each user during registration or should I just go for the _id? and remove uuid generation. About jwt and generally the entire authentication

warm echo
#

For the ids, I'd highly suggest to use MongoDBs ObjectIDs. They are "automatic" when using the MongoDB driver (which Mongoose uses). Otherwise, you are 100% responsible for the ID creation.

reef crown
#

Based on the _id from mongo, I also have to create relations, e.g. to the orders of a given user, and when generating a token for the user for the xx.sub field (I use sub in the token to know which user is calling the data). Am I thinking right?

warm echo
#

Yes, I think you are. 🙂

reef crown
#

Well, now another question and the last one (my first application in NestJS and the second backend application with Mongo). When creating relationships to Mongo, e.g. in orders, should I use ObjectID or maybe ObjectId.tostring() as the property of the relationship? probably using ObjectId will be better but I could be wrong

azure oasis