mongoose-field-encryption
mongoose-field-encryption copied to clipboard
Model is not a constructor, TypeError
Hello,
I am trying to use your package to encrypt a specific field of my schema on a collection named Customers.
However, upon first run, it got an error: TypeError: Customers is not a constructor
I am using express.js for my endpoints.
Error message:
createCustomer e: TypeError: Customers is not a constructor
at exports.createCustomer (C:\Users\User\Desktop\project\backend\controllers\customers.js:12:26)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:275:10)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:284:7
My model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
const mongooseFieldEncryption = require("mongoose-field-encryption").fieldEncryption;
const customersSchema = new mongoose.Schema(
{
firstName: {
type: String,
default: ''
},
lastName: {
type: String,
default: ''
},
fullName: {
type: String,
default: ''
},
streetAddress: {
type: String,
default: ''
},
extendedAddress: {
type: String,
default: ''
},
city: {
type: String,
default: ''
},
state: {
type: String,
default: ''
},
zip: {
type: String,
default: ''
},
customerType: {
type: String,
default: null
},
user: {
type: ObjectId,
ref: "User"
},
nextActivity: {
type: String,
default: null
},
total: { type: Number },
status: {
type: String,
default: "Sales Order",
enum: [
"Sales Order",
"Quotation",
] // enum means string objects
},
},
{ timestamps: true }
);
var encKey = process.env.SOME_32BYTE_BASE64_STRING;
customersSchema.plugin(mongooseFieldEncryption, {
fields: ["streetAddress", "fullName"],
secret: encKey, // "some secret key",
saltGenerator: function (secret) {
return "1234567890123456";
},
});
mongoose.model("Customers", customersSchema, 'customers');
My controller method:
const Customers = require('../models/customers')
const log = console.log
exports.createCustomer = async ( req, res ) =>
{
log( `Beginning createCustomer! Here's req.body: `, req.body )
let a = {}
try {
a.new_customer = new Customers( req.body )
a.new_customer_doc = await a.new_customer.save().catch( err => log( `a.new_customer.save err: `, err ) )
res.json( a.new_customer_doc )
} catch ( e ) {
log( `createCustomer e: `, e )
res.status( 400 ).json( { error: e } )
}
}
My routes file:
const express = require("express");
const router = express.Router();
const {
createCustomer,
} = require( "../controllers/customers" )
// generate customer
router.post( "/customers/createnewcustomer", createCustomer )
module.exports = router;
My test JSON data going into Postman:
{
"firstName": "Bob",
"lastName": "Saget",
"fullName": "Bob Saget",
"streetAddress": "389 N. Palm Dr.",
"extendedAddress": "Unit 3",
"city": "Palm Beach",
"state": "FL",
"zip": "40888",
"customerType": "ebay",
"user": "6020daa83294c92c281ef313",
"nextActivity": "Check if encryption worked",
"total": 1,
"status": "Sales Order"
}
Here is the complete response shown in the console:
Beginning createCustomer! Here's req.body: {
firstName: 'Bob',
lastName: 'Saget',
fullName: 'Bob Saget',
streetAddress: '389 N. Palm Dr.',
extendedAddress: 'Unit 3',
city: 'Palm Beach',
state: 'FL',
zip: '40888',
customerType: 'ebay',
user: '6020daa83294c92c281ef313',
nextActivity: 'Check if encryption worked',
total: 1,
status: 'Sales Order'
}
createCustomer e: TypeError: Customers is not a constructor
at exports.createCustomer (C:\Users\User\Desktop\project\backend\controllers\customers.js:12:26)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:275:10)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\User\Desktop\project\backend\node_modules\express\lib\router\index.js:284:7
POST /api/customers/createnewcustomer 400 22.531 ms - 12
Even further, I tried to add this code which did nothing to change the error:
// function to generate salt
var genRandomString = function(length){
return crypto.randomBytes(Math.ceil(length/2))
.toString('hex') /** convert to hexadecimal format */
.slice(0,length); /** return required number of characters */
};
var sha512 = function(password, salt){
var hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */
hash.update(password);
var value = hash.digest('hex');
return {
salt:salt,
passwordHash:value
};
};
function saltHashPassword(userpassword) {
var salt = genRandomString(16); /** Gives us salt of length 16 */
var passwordData = sha512(userpassword, salt);
console.log('UserPassword = '+userpassword);
console.log('Passwordhash = '+passwordData.passwordHash);
console.log('\nSalt = '+passwordData.salt);
}
customersSchema.plugin(mongooseFieldEncryption, {
fields: ["streetAddress", "fullName"],
secret: encKey, // "some secret key",
saltGenerator: function ( secret ) {
var salt = genRandomString(16); /** Gives us salt of length 16 */
console.log( `salt: `, salt )
var data = sha512(secret, salt);
console.log( `data: `, data )
return data
},
});
What am I doing wrong?
Hi @doverradio
Sorry for the delay in responding to this. From the error TypeError: Customers is not a constructor, it seems that your Customers class has not been defined properly. If you can post the code for this, I could perhaps advise further.