generator-restgoose
Version:
Modern, Lightweight, and Powerfull Rest API Code generator. Out-Of-Box NodeJS REST API Server generator built on top of Mongoose, Express, Cors, Passport, JWT and many more.
440 lines (400 loc) • 10.2 kB
JavaScript
;
// Module dependencies.
const mongoose = require('mongoose');
// const debug = require('debug')('App:ApiObject:item')
// const Util = require('../library').Util
const Model = mongoose.models.User;
const Constants = require('../library').Constants;
const Util = require('../library').Util;
const ModelOptions = {
projection: ['_id', 'email', 'profile', 'role', 'status', 'contact'],
mutable: ['auth', 'profile', 'contact', 'onboarding', 'resetPasswordToken', 'resetPasswordExpires'],
search: ['auth', 'email', 'profile', 'contact', 'role', 'status', 'onboarding', 'resetPasswordToken', 'resetPasswordExpires']
};
/*
========= [ CORE METHODS ] =========
*/
// ALL
exports.ReadList = (listOptions, role, status) => {
const res = {
data: {},
count: 0
};
const predicate = {};
if (role !== 'all' && role !== null) {
predicate.role = role;
}
if (status !== 'all' && status !== null) {
predicate.status = status;
}
const projection = ModelOptions.projection.join(' ');
// return Promise.reject(new Error('Fake Error')) // Quick Err Check
return Model.find(predicate, projection)
.limit(listOptions.limit)
.skip(listOptions.skip)
.sort({ createdAt: listOptions.sort })
.exec()
.then((list) => {
res.data = list;
return Model.countDocuments();
})
.then(count => {
res.count = count;
return res;
});
};
// GET
exports.Read = (id) => {
return Model.findOne({
_id: id
})
.then(data => {
if (!data) {
return Promise.reject(new Error(404));
}
return data;
});
};
// POST
exports.Create = (data) => {
data = new Model(data);
return data.save()
.then(() => data.toObject());
};
// PUT
exports.Update = (id, updateData) => {
const finalData = {};
ModelOptions.mutable.forEach(prop => {
if (typeof updateData[prop] !== 'undefined') {
finalData[prop] = updateData[prop];
}
});
return Model.findOneAndUpdate({
_id: id
}, {
$set: finalData
}, {
new: true
})
.then(data => {
return data.toObject() || null;
}); // eo Model.findOneAndUpdate
};
// DELETE
// @TODO: Implement Cloud Storage Delete
exports.Delete = (id) => {
return Model.deleteOne({
_id: id
}).then(() => {
return 'The data got Deleted';
});
};
// UPLOAD AVATAR
// @TODO: Implement Google Storage
exports.UploadAvatar = (id, file) => {
const filename = id + '.jpg';
const fileUri = file.destination + filename;
// fs.rename(req.file.path, fileUri, function (err) {
// if (err) {
// console.log('ERROR: ' + err)
// return res.status(500).json({ error: err })
// }
// return res.status(200).json({
// url: req.headers.host + '/' + Util.DIR_AVATAR + filename,
// path: fileUri
// })
// })
return Promise.resolve();
};
/*
========= [ SEARCH METHODS ] =========
*/
// SEARCH
exports.Search = (listOptions, keywordObj, strict) => {
let k = {};
if (strict) {
k = keywordObj;
} else {
Object.keys(keywordObj).forEach(key => {
if (isNaN(keywordObj[key])) {
k[key] = new RegExp(keywordObj[key], 'i');
} else {
k[key] = keywordObj[key];
}
});
}
return Model.find(k)
.limit(listOptions.limit)
.skip(listOptions.skip)
.sort({ createdAt: listOptions.sort })
.exec();
};
// SEARCH ADVANCED
// TODO: Create Generic LIbrary for Search (Util.Search)
exports.SearchAdvanced = (listOptions, data) => {
const searchObj = [];
ModelOptions.search.forEach(prop => {
if (typeof data[prop] !== 'undefined') {
// let negate = data[prop].negate || false;
switch (data[prop].search) {
case 'single':
searchObj.push({
[prop]: new RegExp(data[prop].value, 'i')
});
break;
case 'range':
searchObj.push({
[prop]: {
$gte: data[prop].value[0] || Number.MAX_SAFE_INTEGER
}
});
searchObj.push({
[prop]: {
$lte: data[prop].value[1] || Number.MIN_SAFE_INTEGER
}
});
break;
case 'array':
searchObj.push({
[prop]: {
$in: [].concat(data[prop].value)
}
});
break;
}
}
});
// debug('Modelfields.search: %o', ModelOptions.search);
// debug('data: %o', data);
// debug('searchObj: %o', searchObj);
if (!searchObj || searchObj.length === 0) {
return Promise.resolve([]);
}
return Model.find({
$and: searchObj
})
.skip(listOptions.skip)
.limit(listOptions.limit)
.sort({ createdAt: listOptions.sort })
.exec();
};
exports.Exists = (email) => {
return Model.findOne({
email: email
})
.then(data => {
return Promise.resolve(data);
});
};
exports.UpdateOAuth = async (provider, tokenData) => {
return Model.findOne({ email: tokenData.email })
.then(user => {
if (!user) {
return Promise.reject(new Error('User not found!'));
}
const existingProviderProfile = user.auth.find((x) => x.provider === provider);
if (existingProviderProfile) {
user.auth.find((x) => x.provider === provider).oAuthUserId = tokenData.id;
} else {
user.auth.push({
provider: provider,
oAuthUserId: tokenData.id
});
}
user.profile.firstName = tokenData.firstName;
user.profile.lastName = tokenData.lastName;
user.oAuthAvatar = tokenData.picture;
return user.save().then(() => user.toObject());
});
};
exports.ModifyUser = {
FindEmail: async (emailId) => {
return Model.findOne({ email: emailId }, '_id email profile status role')
.then(data => {
return data || null;
});
},
Password: async (emailId, newPassword) => {
const password = await Util.GenerateHash(newPassword);
return Model.findOneAndUpdate({
email: emailId
}, {
$set: { password: password }
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('User not found!');
}
return data._id || null;
});
},
Role: (userId, newRole) => {
return Model.findOneAndUpdate({
_id: userId
}, {
$set: { role: newRole }
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('User not found!');
}
return data.role || null;
});
},
Status: (userId, newStatus) => {
return Model.findOneAndUpdate({
_id: userId
}, {
$set: { status: newStatus }
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('User not found!');
}
return data.status || null;
});
},
Suspend: (userId) => {
return Model.findOneAndUpdate({
_id: userId
}, {
$set: { status: Constants.Status.Suspended }
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('User not found!');
}
return data.status || null;
});
},
Activate: (userId) => {
return Model.findOneAndUpdate({
_id: userId
}, {
$set: { status: Constants.Status.Active }
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('User not found!');
}
return data.status || null;
});
}
};
exports.Validate = {
Password: async (userId, password) => {
return Model.findOne({
_id: userId,
status: Constants.Status.Active
})
.then(user => {
if (!user) {
throw new Error('Cannot Validate unknown/Terminated/Suspended User!');
}
return new Promise((resolve, reject) => {
return user.comparePassword(password, (err, isMatch) => {
if (err) {
return reject(new Error(err));
}
return resolve(isMatch);
});
});
});
},
VerifyEmail: async (token) => {
return Model.findOneAndUpdate({
verifyEmailToken: token,
verifyEmailExpires: {
$gt: Date.now()
},
status: Constants.Status.Pending
}, {
$set: {
status: Constants.Status.Active,
verifyEmailToken: null,
verifyEmailExpires: Date.now()
}
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('Cannot Activate unknown/Terminated/Expired User!');
}
return data.toObject() || null;
});
},
ChangeForgotPasswordWithToken: async (token, newPass) => {
const pass = await Util.GenerateHash(newPass);
const srchObj = {
resetPasswordToken: token,
resetPasswordExpires: {
$gt: Date.now()
},
status: Constants.Status.Active
};
return Model.findOneAndUpdate(srchObj, {
$set: {
password: pass,
resetPasswordToken: null,
resetPasswordExpires: Date.now()
}
}, {
new: true
})
.then(data => {
if (!data) {
throw new Error('Cannot Change Password of unknown/Terminated/Expired User!');
}
return data.toObject() || null;
});
}
};
exports.SaveToken = {
ForgotPassword: async (emailId, token, expires) => {
return Model.findOneAndUpdate({
email: emailId,
status: Constants.Status.Active
}, {
$set: {
resetPasswordToken: token,
resetPasswordExpires: expires
}
}, {
new: true
}).then(data => {
if (!data) {
throw new Error('User not found!');
}
return data.toObject() || null;
});
},
VerifyEmail: async (emailId, token, expires) => {
return Model.findOneAndUpdate({
email: emailId,
status: Constants.Status.Pending
}, {
$set: {
verifyEmailToken: token,
verifyEmailExpires: expires
}
}, {
new: true
}).then(data => {
if (!data) {
throw new Error('User not found!');
}
return data.toObject() || null;
});
}
};