I've been trying to save a document with a username and a token in a mongodb database using mongoose. Whenever client makes a request to the server, the token is updated and saved in the database. To update the document I'm querying the collection with username(as it's unique), and then update the returned document's(say doc) token field and then calling the doc.save(). The problem is doc.save() gives me username validation error alternately(i.e. works on 1st and 3rd attempt, and so on...) but fails on 2nd attempt, 4th attempt and so on.

If I remove username validation constraint then the code works, however for apparent reasons, I can not remove the validation constraint.

usermodel.js

    let mongoose = require('mongoose');

let user = new mongoose.Schema({
    username: {
        type: String,
        match: /^[A-Za-z0-9_]+$/g,
        unique: true,
        required: true,
    },
    password: {
        type: String,
        match: /.{8,}/g,
        required: true,
    },
    token: String
});

module.exports = mongoose.model('user', user);

getData.js

   module.exports = async function putData(database, model, query, fields, queryType='one'){
    let mongoose = require('mongoose');
    const connectionURL = `mongodb://127.0.0.1:27017/${database}`;
    mongoose.connect(connectionURL, {
        useNewUrlParser: true,
        useCreateIndex: true
    });

    return model.init().then(async ()=>{
        let res;
        switch(queryType){
            case 'one':
                res = await model.findOne(query).select(fields).exec();
                break;
            case 'all':
                res = await model.find(query).select(fields).exec();
        }
        return res;
    })
}

putData.js

   module.exports = async function putData(database, model, data){
    let mongoose = require('mongoose');
    const connectionURL = `mongodb://127.0.0.1:27017/${database}`;
    mongoose.connect(connectionURL, {
        useNewUrlParser: true,
        useCreateIndex: true
    });

    return model.init().then(async ()=>{
        console.log('Username is, ', data.username);
        let prom = await data.save();
        return prom;
    });
}

updateToken.js


let user = require('../models/users-model');
let putData = require('../putData');
let bcrypt = require('bcrypt');
let getData = require('../getData');

function update_token(username, token, callbackfn){
    getData('users', user, {
        username: username,
        token: token
    }, 'username token').then((userData)=>{
        console.log(userData);
        if(userData){
            bcrypt.hash(JSON.stringify(userData), 5).then((hash)=>{
                userData.token = hash;
                return putData('users', user, userData, true);
            }).then((data)=>{
                callbackfn(null, data);
            }).catch((err)=>{
                //console.log(err);
                callbackfn(err, null);
            })
        }
        else{
            callbackfn(new Error('Invalid token'), null);
        }
    }).catch((err)=>{
        console.log(err);
        callbackfn(err, null);
    })
}

module.exports = {
    update_token: update_token
}

server.js

let express = require('express');
let app = express();
let usersRouter = require('./routers/users');
let tourMakerRouter = require('./routers/tour-maker');
let bodyparser = require('body-parser');
let utils = require('./utils/utils');
let getData = require('./getData');
let user = require('./models/users-model');
const host = '127.0.0.1';
const port = 8000;

let jsonencodedparser = bodyparser.json();

app.post('/', jsonencodedparser, (req, res)=>{
    console.log('Request received!');
    utils.update_token(req.body.username, req.body.token, (err, data)=>{
        if(err){
            console.log(err);
            if(err.message === 'Invalid token'){
                res.status(401).end();
            }
            res.status(500).end();
        }
        else{
            res.json({
                token: data.token,
                username: data.username
            });
        }
    })
})

app.listen(port, host, ()=>{
    console.log(`Listening at http://${host}:${port}`);
})

First Request:

Request received! { _id: 5cdadbdfeeb7c02610b14f1a, username: 'user1', token: '$2b$05$oHkFuyW532Yq6p2o04TumeAON8SBtIL/lZ.Kty1gX2lqHqnMEI/Pa' } Username is, user1

Second Request:

Request received! { _id: 5cdadbdfeeb7c02610b14f1a, username: 'user1', token: '$2b$05$gaS5U4kRiVqCShKbiZe/t.LTUBTh5H7AAE7p2MXIUW65xezbPslG2' } Username is, user1 { ValidationError: user validation failed: username: Pathusernameis invalid (user1). at ValidationError.inspect (/home/arpit/Study/Projects/tour-maker/node_modules/mongoose/lib/error/validation.js:59:24) at formatValue (util.js:430:38) at inspect (util.js:324:10) at format (util.js:191:12) at Console.log (console.js:130:21) at utils.update_token (/home/arpit/Study/Projects/tour-maker/server/server.js:18:21) at bcrypt.hash.then.then.catch (/home/arpit/Study/Projects/tour-maker/server/utils/utils.js:20:17) at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7) errors: { username: { ValidatorError: Pathusernameis invalid (user1). at new ValidatorError (/home/arpit/Study/Projects/tour-maker/node_modules/mongoose/lib/error/validator.js:29:11) at validate (/home/arpit/Study/Projects/tour-maker/node_modules/mongoose/lib/schematype.js:978:13) at /home/arpit/Study/Projects/tour-maker/node_modules/mongoose/lib/schematype.js:1031:11 at Array.forEach (<anonymous>) at SchemaString.SchemaType.doValidate (/home/arpit/Study/Projects/tour-maker/node_modules/mongoose/lib/schematype.js:987:14) at /home/arpit/Study/Projects/tour-maker/node_modules/mongoose/lib/document.js:2101:9 at _combinedTickCallback (internal/process/next_tick.js:131:7) at process._tickCallback (internal/process/next_tick.js:180:9) message: 'Pathusernameis invalid (user1).', name: 'ValidatorError', properties: [Object], kind: 'regexp', path: 'username', value: 'user1', reason: undefined, [Symbol(mongoose:validatorError)]: true } }, _message: 'user validation failed', name: 'ValidationError' }

Any help is appreciated. Thanks in advance!

1 Answers

-1
tryingToDevelop On

I don't have enough reputation to comment, but have you tried checking the request every time to see what you're actually sending as the username? There could be some validation issues for some reason.