6

I have a UserSchema like this and I cannot seem to generate unique random activation_token's.

I am using rand-token for the generation. Found here.

 var UserSchema = new Schema({
        activation_token: {
            type: String,
            default: randToken.generate(64),
        },
        email: {
            type: String,
            unique: true,
            sparse: true
        },
        first_name: {
            type: String
        },
        last_name: {
            type: String
        }
});

Seemed to work fine, but when running unit tests with Mocha, all of the activation_token fields were the same. I initially thought this had to do with time, since that is probably what is used to generate the tokens. It was possible that for each new document, the timestamp was the same, so I ran some tests with a function that generated about 30 tokens one right after the other, and they were not similar.

Any ideas on what is going on here?

Here are some examples of the problem:

{
    "_id": {
        "$oid": "555dfd137c914edc1b41bbda"
    },
    "email": "oka@haek.io",
    "first_name": "Lenora",
    "last_name": "Aguilar",
    "date_added": {
        "$date": "2015-05-21T15:43:01.576Z"
    },
    "activation_token": "EyBNwu4vxOIXMzj7W5kVOeICfWwxfjXmHkz7ZPHLjkf0MU86QM2aIKNDyvI2YmTR",
    "__v": 0
},
{
    "_id": {
        "$oid": "555dfd107c914edc1b41bbd6"
    },
    "email": "ediuki@mu.edu",
    "first_name": "Eugene",
    "last_name": "Green",
    "date_added": {
        "$date": "2015-05-21T15:43:01.576Z"
    },
    "activation_token": "EyBNwu4vxOIXMzj7W5kVOeICfWwxfjXmHkz7ZPHLjkf0MU86QM2aIKNDyvI2YmTR",
    "__v": 0
}
Trevor Hutto
  • 2,112
  • 4
  • 21
  • 29

3 Answers3

18

It makes sense that they would all be the same. You're calling generate once at schema definition time and you're feeding the result of that call to the mongoose schema definition, not the function itself. You could try something like this:

var UserSchema = new Schema({
    activation_token: {
        type: String,
        default: function() {
            return randToken.generate(64);
        }
    },
    email: {
        type: String,
        unique: true,
        sparse: true
    },
    first_name: {
        type: String
    },
    last_name: {
        type: String
    }
});
Andrew Lavers
  • 8,023
  • 1
  • 33
  • 50
0

Andrews answer worked fine for me. Instead of just generating the random token once (when the schema is created). The function is called and creates a new token every time a new user is created.

The only thing I changed to make it shorter and better readable was to use a lambda instead:

var UserSchema = new Schema({
    activation_token: {
        type: String,
        default: () => randToken.generate(64)
    },
    email: {
        type: String,
        unique: true,
        sparse: true
    },
    first_name: {
        type: String
    },
    last_name: {
        type: String
    }
});
-2
npm install rand-token --save

install the node package,

const randtoken = require('rand-token');

import in to js file and generate token

const a = randtoken.generate(256);

arul mb
  • 27
  • 1