· 6 years ago · Jan 31, 2020, 10:00 PM
1// require mongoose and setup the Schema
2const mongoose = require("mongoose");
3const bcrypt = require('bcryptjs');
4const jwt = require('jsonwebtoken');
5require('dotenv').config();
6
7const Schema = mongoose.Schema;
8
9// define the user schema that is related to this service
10const userSchema = new Schema({
11 "userName": {
12 type: String,
13 required: true,
14 unique: true
15 },
16 "password": {
17 type: String,
18 required: true,
19 },
20 "lastActiveAt": {
21 type: Date,
22 default: Date.now
23 },
24 "email": {
25 type: String,
26 required: true,
27 unique: true
28 }
29}, { timestamps: true });
30
31let UserCollection = mongoose.model(process.env.DB, userSchema); //env in our current case, itemStore
32
33
34
35/**
36* Opens the default mongoose connection.
37* connect to the localhost mongo running on default port 27017
38* @returns status code.
39* @0 - connected successfully
40* @-1 - connection error
41*/
42module.exports.connectToUserDB = async function () {
43 try {
44 const DB_URL = process.env.DB_ROOT + process.env.DB;
45 console.log(`Connecting to ${DB_URL}`);
46
47 mongoose.set('useUnifiedTopology', true);
48 mongoose.set('useNewUrlParser', true);
49 var db = await mongoose.connect(DB_URL); //returns psudo-promise;
50
51 return 0;
52 }
53 catch (err) {
54 console.log("Failed to connect to MongoDB instance");
55 console.log(err);
56 return -1;
57 }
58}
59
60
61/**
62* Get the list of all the users in the DB, dont know why but you can do it.
63* @returns ArrayList<User>
64*/
65module.exports.getAllUsers = async function () {
66 return await UserCollection.find({}).exec(); // Exec returns promises
67}
68
69
70/**
71 * Adds new user to the MongoDB user collection
72 * @param userData { username: required, password: required, }
73 */
74module.exports.createNewUser = async function(userData) {
75
76 let salt = await bcrypt.genSalt(12);
77
78 let hash = await bcrypt.hash(userData.password,salt);
79
80 userData.password = hash;
81
82 let result = await UserCollection.create(userData);
83 return result;
84}
85
86/**
87 * Validates user credentials against MongoDB
88 * @param userCred { username: required, password: required }
89 * @returns a JWT token that user can use to access restricted routes for a limited time
90 */
91module.exports.loginUser = async function(userCred) {
92
93 let dbUser = await UserCollection.findOne({ userName: userCred.userName }).exec();
94
95 let matchingPassword = await bcrypt.compare(userCred.password,dbUser.password);
96
97 console.log(`password matching? ${matchingPassword}`);
98 if(matchingPassword){
99
100 let token = jwt.sign(userCred,process.env.PRIVATE_KEY,{
101 expiresIn: "30min"
102 });
103 return token;
104 }
105 return -1;
106}
107
108/**
109 * Verifies a token against private key
110 * @param token a JWT token
111 */
112module.exports.verifyToken = async function(token){
113
114 // Wrapping it in promise to be consistant with the API
115 return new Promise((resolve,reject)=>{
116 jwt.verify(token,process.env.PRIVATE_KEY,(validationError, authData)=>{
117 if(validationError)
118 {
119 console.log(validationError);
120 reject("failed to verify");
121 }
122 resolve("verified");
123 })
124 })
125}