From 6ab0f7ba930888b630edec3c1ea6ec3f59bc6036 Mon Sep 17 00:00:00 2001
From: Eduardo Mathias <ems19@inf.ufpr.br>
Date: Thu, 13 Apr 2023 10:40:44 -0300
Subject: [PATCH] Make VerifyToken and adapta FindById to FindOne

---
 config.json.example                  | 157 ---------------------------
 script_req.sh                        |  10 ++
 src/libs/app.js                      |   4 -
 src/libs/db/postgres.js              |  23 +---
 src/libs/middlewares/oauth2.js       |   3 +-
 src/libs/middlewares/passport.js     |   2 +-
 src/libs/models/user.js              |  59 ++++++++--
 src/libs/models/verificationToken.js |  39 +++----
 src/libs/routes_v1/resetToken.js     |   4 +-
 src/libs/routes_v1/user.js           |   6 +-
 src/libs/routes_v1/verifyToken.js    |   2 +-
 11 files changed, 91 insertions(+), 218 deletions(-)
 delete mode 100644 config.json.example
 create mode 100755 script_req.sh

diff --git a/config.json.example b/config.json.example
deleted file mode 100644
index 1fa157c1..00000000
--- a/config.json.example
+++ /dev/null
@@ -1,157 +0,0 @@
-{
-    "development":
-    {
-        "port": 3000,
-        "ip": "127.0.0.1",
-        "debug" : true,
-        "monetdb": {
-            "host": "simcaqdb3.c3sl.ufpr.br",
-            "port": 50000,
-            "dbname": "simcaq",
-            "user": "monetdb",
-            "password":"monetdb",
-            "nrConnections": "4"
-        },
-        "cdn" : {
-            "url": "http://simcaqdb3.c3sl.ufpr.br:3000",
-            "download": "https://simcaqdev.c3sl.ufpr.br/download/"
-        },
-        "mongodb" : {
-            "uri": "mongodb://localhost/dev_users"
-        },
-        "monq": {
-            "uri": "mongodb://localhost/dev_monq"
-        },
-        "default": {
-            "api": {
-                "version" : "v1"
-            },
-            "lde": {
-                "url": "http://ldedev.c3sl.ufpr.br/#"
-            },
-            "simcaq": {
-                "url": "http://simcaqdev.c3sl.ufpr.br/#"
-            }
-        },
-        "email": {
-            "host": "SMTP.office365.com",
-            "port": 587,
-            "secureConnection": false,
-            "auth": {
-                "user": "dadoseducacionais@ufpr.br",
-                "pass": "COLOCAR_A_SENHA_AQUI"
-            },
-            "tls": {
-                "ciphers": "SSLv3"
-            },
-            "from": "\"Laboratório de Dados Educacionais\" <dadoseducacionais@ufpr.br>"
-        },
-        "security": {
-            "tokenLife": 3600
-        }
-    },
-    "test":
-    {
-        "port": 3000,
-        "ip": "127.0.0.1",
-        "debug" : true,
-        "monetdb": {
-            "host": "simcaqdb3.c3sl.ufpr.br",
-            "port": 50000,
-            "dbname": "simcaq",
-            "user": "monetdb",
-            "password":"monetdb",
-            "nrConnections": "4"
-        },
-        "cdn" : {
-            "url": "http://simcaqdb3.c3sl.ufpr.br:3000",
-            "download": "https://simcaqdev.c3sl.ufpr.br/download/"
-        },
-        "mongodb" : {
-            "uri": "mongodb://localhost/test_users",
-            "secret": "SimCAQC3SL"
-        },
-        "monq": {
-            "uri": "mongodb://localhost/test_monq"
-        },
-        "default": {
-            "api": {
-                "version" : "v1"
-            },
-            "lde": {
-                "url": "http://ldedev.c3sl.ufpr.br/#"
-            },
-            "simcaq": {
-                "url": "http://simcaqdev.c3sl.ufpr.br/#"
-            }
-        },
-        "email": {
-            "host": "SMTP.office365.com",
-            "port": 587,
-            "secureConnection": false,
-            "auth": {
-                "user": "dadoseducacionais@ufpr.br",
-                "pass": "COLOCAR_A_SENHA_AQUI"
-            },
-            "tls": {
-                "ciphers": "SSLv3"
-            },
-            "from": "\"Laboratório de Dados Educacionais\" <dadoseducacionais@ufpr.br>"
-        },
-        "security": {
-            "tokenLife": 3600
-        }
-    },
-    "production":
-    {
-        "port": 3000,
-        "ip": "127.0.0.1",
-        "debug" : false,
-        "monetdb": {
-            "host": "simcaqdb3.c3sl.ufpr.br",
-            "port": 50000,
-            "dbname": "simcaq",
-            "user": "monetdb",
-            "password":"monetdb",
-            "nrConnections": "4"
-        },
-        "cdn" : {
-            "url": "http://simcaqdb3.c3sl.ufpr.br:7000",
-            "download": "https://simcaq.c3sl.ufpr.br/download/"
-        },
-        "mongodb" : {
-            "uri": "mongodb://localhost/users",
-            "secret": "SimCAQC3SL"
-        },
-        "monq": {
-            "uri": "mongodb://localhost/monq"
-        },
-        "default": {
-            "api": {
-                "version" : "v1"
-            },
-            "lde": {
-                "url": "http://lde.c3sl.ufpr.br/#"
-            },
-            "simcaq": {
-                "url": "http://simcaq.c3sl.ufpr.br/#"
-            }
-        },
-        "email": {
-            "host": "SMTP.office365.com",
-            "port": 587,
-            "secureConnection": false,
-            "auth": {
-                "user": "dadoseducacionais@ufpr.br",
-                "pass": "COLOCAR_A_SENHA_AQUI"
-            },
-            "tls": {
-                "ciphers": "SSLv3"
-            },
-            "from": "\"Laboratório de Dados Educacionais\" <dadoseducacionais@ufpr.br>"
-        },
-        "security": {
-            "tokenLife": 3600
-        }
-    }
-}
diff --git a/script_req.sh b/script_req.sh
new file mode 100755
index 00000000..125204b8
--- /dev/null
+++ b/script_req.sh
@@ -0,0 +1,10 @@
+curl -X 'POST' \
+  'http://10.254.221.20:3000/api/v1//auth/token' \
+  -H 'accept: application/json' \
+  -H 'Content-Type: application/json' \
+  -d '{
+  "email": "eduardomsouza@ufpr.br",
+  "password": "teste123",
+  "client_secret": "LDE",
+  "grant_type": "password"
+}'
\ No newline at end of file
diff --git a/src/libs/app.js b/src/libs/app.js
index 9731038a..bab5e52d 100644
--- a/src/libs/app.js
+++ b/src/libs/app.js
@@ -19,10 +19,6 @@ const api_v2 = require('./routes_v2/api');
 
 const passport = require('passport');
 
-const postgres = require(`${libs}/db/postgres`);
-
-const db = mongoose();
-
 require(`${libs}/middlewares/passport`);
 
 app.use(bodyParser.json({limit: '50mb'}));
diff --git a/src/libs/db/postgres.js b/src/libs/db/postgres.js
index 58c6d59e..c60d28c6 100644
--- a/src/libs/db/postgres.js
+++ b/src/libs/db/postgres.js
@@ -1,21 +1,8 @@
-const libs = `${process.cwd()}/libs`;
+const Sequelize = require('sequelize');
 
-const config = require(`${libs}/config`);
+// if you are using postgres, your DB URL will look like this
+const DATABASE_URL = 'postgres://postgres:postgres@localhost:5432/postgres'
 
-const log = require(`${libs}/log`)(module);
+const db = new Sequelize(DATABASE_URL)
 
-const { Pool} = require('pg');
-
-module.exports = () => {
-    
-    const pool = new Pool({
-        user: "postgres",
-        database: "postgres",
-        password: "postgres",
-        port: 5432,
-        host: "localhost",
-
-    });
-    
-    return pool;
-};
+module.exports = db
\ No newline at end of file
diff --git a/src/libs/middlewares/oauth2.js b/src/libs/middlewares/oauth2.js
index cc9a45ed..4cb6adcd 100644
--- a/src/libs/middlewares/oauth2.js
+++ b/src/libs/middlewares/oauth2.js
@@ -7,7 +7,6 @@ const libs = `${process.cwd()}/libs`;
 const config = require(`${libs}/config`);
 const log = require(`${libs}/log`)(module);
 
-const db = require(`${libs}/db/mongoose`);
 const User = require(`${libs}/models/user`);
 const AccessToken = require(`${libs}/models/accessToken`);
 const RefreshToken = require(`${libs}/models/refreshToken`);
@@ -88,7 +87,7 @@ aserver.exchange(oauth2orize.exchange.refreshToken((client, refreshToken, scope,
             return done(null, false);
         }
 
-        User.findById(token.userId, (err, user)  => {
+        User.findOne({token: token.userId} , (err, user)  => {
             if (err) { 
                 log.error(err);
                 return done(err);
diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js
index ab895a96..246a95ea 100644
--- a/src/libs/middlewares/passport.js
+++ b/src/libs/middlewares/passport.js
@@ -50,7 +50,7 @@ passport.use(new BearerStrategy( (accessToken, done) => {
                 return done(null, false, { msg: 'Token expired' });
             }
 
-            User.findById(token.userId, function(err, usuario) {
+            User.findOne({token: token.userId}, function(err, usuario) {
                 if (err) {
                     return done(err);
                 }
diff --git a/src/libs/models/user.js b/src/libs/models/user.js
index 4d40c4e2..04fcb892 100644
--- a/src/libs/models/user.js
+++ b/src/libs/models/user.js
@@ -1,10 +1,16 @@
 const Sequelize = require("sequelize");
 const crypto = require('crypto')
+const db = require('../db/postgres.js')
 const libs = `${process.cwd()}/libs`;
 const log = require(`${libs}/log`)(module);
 
 // set up a sequelize model 
-var User = sequelize.define("User",{
+var User = db.define("User",{
+    id:{
+        type: Sequelize.STRING,
+        allowNull:false,
+        unique: true
+    },
     email: {
         type: Sequelize.STRING,
         allowNull: false,
@@ -13,16 +19,28 @@ var User = sequelize.define("User",{
             notNull: { msg: "O campo Email é obrigatório." },
         }
     },
+    password:{
+        type: Sequelize.STRING,
+        get(){
+            return () => this.getDataValue('password')
+        }
+    },
     hashed_password:{
         type: Sequelize.STRING,
         allowNull: false,
         validate: {
             notNull: { msg: "O campo Senha é obrigatório." },
+        },
+        get() {
+            return() => this.getDataValue('salt')
         }
     },
     salt: {
         type: Sequelize.STRING,
-        allowNull: false
+        allowNull: false,
+        get() {
+            return() => this.getDataValue('salt')
+        }
     },
     name:{
         type: Sequelize.STRING,
@@ -143,20 +161,39 @@ var User = sequelize.define("User",{
     {}
 );
 
+User.generateSalt = function() {
+    return crypto.randomBytes(128).toString('hex');
+}
+
 User.encryptPassword = function(password) {
     return crypto.pbkdf2Sync(password+'', this.salt, 10000, 512, 'sha512');
+}
+
+User.generateObjectId = function(){
+    var timestamp = (new Date().getTime() / 1000 | 0).toString(16);
+    return timestamp + 'xxxxxxxxxxxxxxxx'.replace(/[x]/g, function() {
+        return (Math.random() * 16 | 0).toString(16);
+    }).toLowerCase();
+}
+
+const setSaltAndPassword = user => {
+    if (user.changed('password')) {
+        user.salt = User.generateSalt()
+        user.password = User.encryptPassword(user.password())
+        this.hashed_password = this.encryptPassword(password).toString('hex');
+    }
+}
+
+const setObjectId = user => {
+   user.id = User.generateObjectId()
 };
 
-User.virtual('password').set(function(password) {
-    this._plainPassword = password+'';
-    this.salt = crypto.randomBytes(128).toString('hex');
-    this.hashed_password = this.encryptPassword(password).toString('hex');
-}).get(function() {
-    return this._plainPassword;
-});
+User.beforeCreate(setSaltAndPassword)
+User.beforeCreate(setObjectId)
+User.beforeUpdate(setSaltAndPassword)
 
-User.checkPassword = function(password) {
-    return this.encryptPassword(password).toString('hex') === this.hashed_password;
+User.prototype.checkPassword = function(enteredPassword) {
+    return User.encryptPassword(enteredPassword, this.salt()) === this.hashed_password()
 }
 
 module.exports = User; 
diff --git a/src/libs/models/verificationToken.js b/src/libs/models/verificationToken.js
index ef7e109e..793ed56c 100644
--- a/src/libs/models/verificationToken.js
+++ b/src/libs/models/verificationToken.js
@@ -1,33 +1,32 @@
-const mongoose = require('mongoose');
-const Schema = mongoose.Schema;
-const libs = `${process.cwd()}/libs`;
+const Sequelize = require("sequelize");
+const crypto = require('crypto')
+const db = require('../db/postgres.js')
 const log = require(`${libs}/log`)(module);
 const User = require(`${libs}/models/user`);
 const uuid = require('node-uuid');
 
-let VerificationToken = new Schema({
+var VerificationToken = db.define("VerificationToken",{
     userId: {
-        type: Schema.Types.ObjectId,
-        required: true,
-        ref: 'User'
+        type: Sequelize.STRING, 
+        allowNull: false
     },
-    token: {
-        type: String,
-        required: true
+    token:{
+        type: Sequelize.STRING,
+        allowNull: false
     },
-    verified: {
-        type: Boolean,
-        required: true,
+    verified:{
+        type: Sequelize.BOOLEAN,
+        allowNull: false,
         default: false
     },
-    createdAt: {
-        type: Date,
-        required: true,
+    createdAt:{
+        type: Sequelize.DATE,
+        allowNull: false,
         default: Date.now
     }
-});
+})
 
-VerificationToken.methods.createVerificationToken = function(done) {
+VerificationToken.createVerificationToken = function(done) {
     let verificationToken = this;
     let token = uuid.v4();
     verificationToken.set('token', token);
@@ -38,4 +37,6 @@ VerificationToken.methods.createVerificationToken = function(done) {
     })
 }
 
-module.exports = mongoose.model('VerificationToken', VerificationToken);
+VerificationToken.belongsTo(User);
+
+module.exports = VerificationToken;
diff --git a/src/libs/routes_v1/resetToken.js b/src/libs/routes_v1/resetToken.js
index 34ece845..faa4caa6 100644
--- a/src/libs/routes_v1/resetToken.js
+++ b/src/libs/routes_v1/resetToken.js
@@ -32,7 +32,7 @@ resetTokenApp.get('/:token', (req, res, next) => {
             })
             return next({msg: 'Token expired', status: 410});
         }
-        User.findById(rToken.userId, (err, user) => {
+        User.findOne({token: rToken.userId}, (err, user) => {
             if(err) {
                 log.error(err);
                 next(err);
@@ -55,7 +55,7 @@ resetTokenApp.post('/:token', (req, res, next) => {
             res.statusCode = 404;
             return next({msg: 'Token not found', status:404});
         }
-        User.findById(rToken.userId, (err, user) => {
+        User.findOne({token: rToken.userId}, (err, user) => {
             if(err) {
                 log.error(err);
                 next(err);
diff --git a/src/libs/routes_v1/user.js b/src/libs/routes_v1/user.js
index 7ff088ee..951717d7 100644
--- a/src/libs/routes_v1/user.js
+++ b/src/libs/routes_v1/user.js
@@ -100,7 +100,7 @@ userApp.get('/me', passport.authenticate('bearer', { session: false }), (req, re
 }, response('user'));
 
 userApp.get('/:id', (req, res, next) => {
-  User.findById(req.params.id, (err, user) => {
+  User.findOne({id: req.params.id}, (err, user) => {
     if(err) {
       log.error(err);
       return next(err);
@@ -161,7 +161,7 @@ userApp.post('/', (req, res, next) => {
 
       // Create verification token
       let verificationToken = new VerificationToken({
-        userId: user._id
+        userId: user.id
       });
 
       verificationToken.createVerificationToken((err, token) => {
@@ -195,7 +195,7 @@ userApp.post('/', (req, res, next) => {
 });
 
 userApp.put('/:id', passport.authenticate('bearer', { session: false }), (req, res, next) => {
-  User.findById(req.params.id, (err, user) => {
+  User.findOne({id:req.params.id}, (err, user) => {
     if (err) {
       log.error(err);
       return next({err});
diff --git a/src/libs/routes_v1/verifyToken.js b/src/libs/routes_v1/verifyToken.js
index d54f64aa..ecb834b3 100644
--- a/src/libs/routes_v1/verifyToken.js
+++ b/src/libs/routes_v1/verifyToken.js
@@ -22,7 +22,7 @@ verifyTokenApp.get('/:token', (req, res, next) => {
             res.statusCode = 404;
             return next({msg: 'Token not found', status:404});
         }
-        User.findById(vToken.userId, (err, user) => {
+        User.findOne({token:vToken.userId}, (err, user) => {
             if(err) {
                 log.error(err);
                 next(err);
-- 
GitLab