diff --git a/app.js b/app.js index a5c5423..3b79090 100644 --- a/app.js +++ b/app.js @@ -4,32 +4,27 @@ if (appEnv == undefined) { } require('dotenv').config({ path: `.env.${appEnv}` }); const { promisify } = require('util'), - bodyParser = require('body-parser'), - chalk = require('chalk'), - utils = require('./routes/utils'), - exceptionHandler = require('./middlewares/exceptions.handler.js'), - connectDB = require('./src/services/connectDB'); + chalk = require('chalk'); + //bodyParser = require('body-parser') var express = require('express'), session = require('express-session'), cors = require('cors'), errorhandler = require('errorhandler'), - mongoose = require('mongoose'), morgan = require('morgan'); -var isProduction = appEnv === 'production'; +const utils = require('./src/utils'), + exceptionHandler = require('./src/middlewares/exceptions.handler'), + connectDb = require('./src/database/connectDatabase'); // Create global app object var app = express(); - app.use(cors()); -// Normal express config defaults -//app.use(morgan('combined')); +// Morgan status code color config morgan.token('statusColor', (req, res) => { let status = (typeof res.headersSent !== 'boolean' ? Boolean(res.header) : res.headersSent) ? res.statusCode : undefined - return status >= 500 ? chalk.red(status) : status >= 429 ? chalk.magenta(status) : status >= 400 ? chalk.yellow(status) @@ -37,38 +32,34 @@ morgan.token('statusColor', (req, res) => { : status >= 200 ? chalk.green(status) : chalk.underline(status); }); +// Morgan log line config app.use(morgan('[:date[iso]] ":method :url HTTP/:http-version" :statusColor :res[content-length] ":referrer" ":user-agent" :remote-addr')); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(bodyParser.json()); + +//use express.json() to parse incoming requests with JSON payloads +app.use(express.json()); +//parse incoming requests with urlencoded payloads +app.use(express.urlencoded({ extended: true })); + +//app.use(bodyParser.urlencoded({ extended: false })); +//app.use(bodyParser.json()); app.use(require('method-override')()); app.use(express.static(__dirname + '/public')); -app.use(session({ secret: 'acapisecret', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false })); +app.use(session({ secret: process.env.SECRET, cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false })); -if (!isProduction) { +if (appEnv !== 'production') { app.use(errorhandler()); } -if(isProduction){ - mongoose.connect(process.env.MONGODB_URI); -} else { - mongoose.set('strictQuery', true); - mongoose.connect(process.env.MONGODB_URI).then(() => { - console.log(`${utils.getDateTimeISOString()}`, chalk.green('MongoDB connection has been established successfully')); - }).catch(() => { - console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MongoDB database')); - }); - mongoose.set('debug', process.env.DEBUG); - console.log(`${utils.getDateTimeISOString()}`, chalk.red('debug :'), chalk.yellow(process.env.DEBUG)); -} +require('./src/database/models/mongo'); +require('./src/config/passport'); -require('./models/mongo'); -require('./config/passport'); +//var userid = new mongoose.Types.ObjectId(); +//console.log('userid: ', userid._id.toString()); + +connectDb.connectAllDb(); -var userid = new mongoose.Types.ObjectId(); -console.log('userid: ', userid._id.toString()); -connectDB(); app.use(require('./src/routes')); app.use(exceptionHandler.notFoundErrorHandler); diff --git a/config/db.js b/config/db.js deleted file mode 100644 index 72587fe..0000000 --- a/config/db.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - "development": { - "username": 'c4adastracomu1', - "password": 'kbrnrt5jPK12', - "database": 'c4adastracomdb1', - "host": '176.31.255.24', - "port": 3306, - "dialect": 'mysql' - }, - "test": { - "username": 'c4adastracomu1', - "password": 'kbrnrt5jPK12', - "database": 'c4adastracomdb1', - "host": '176.31.255.24', - "port": 3306, - "dialect": 'mysql' - }, - "production": { - "username": 'c4adastracomu1', - "password": 'kbrnrt5jPK12', - "database": 'c4adastracomdb1', - "host": '176.31.255.24', - "port": 3306, - "dialect": 'mysql' - } -} \ No newline at end of file diff --git a/models/index.js b/models/index.js index 7bbdb28..681fbaf 100644 --- a/models/index.js +++ b/models/index.js @@ -1,15 +1,15 @@ -exports.User = require('./mongo/User'); -exports.Application = require('./mongo/Application'); -exports.Aeronef = require('./mongo/Aeronef'); -exports.Canopy = require('./mongo/Canopy'); -exports.Dropzone = require('./mongo/Dropzone'); -exports.JumpFile = require('./mongo/JumpFile'); -exports.Jump = require('./mongo/Jump'); -exports.Qcm = require('./mongo/Qcm'); -exports.QcmCategory = require('./mongo/QcmCategory'); -exports.QcmQuestion = require('./mongo/QcmQuestion'); -exports.QcmChoice = require('./mongo/QcmChoice'); -exports.X2DataLog = require('./mongo/X2DataLog'); -exports.Article = require('./mongo/Article'); -exports.Comment = require('./mongo/Comment'); -exports.Tag = require('./mongo/Tag'); \ No newline at end of file +exports.User = require('../src/database/models/mongo/User'); +exports.Application = require('../src/database/models/mongo/Application'); +exports.Aeronef = require('../src/database/models/mongo/Aeronef'); +exports.Canopy = require('../src/database/models/mongo/Canopy'); +exports.Dropzone = require('../src/database/models/mongo/Dropzone'); +exports.JumpFile = require('../src/database/models/mongo/JumpFile'); +exports.Jump = require('../src/database/models/mongo/Jump'); +exports.Qcm = require('../src/database/models/mongo/Qcm'); +exports.QcmCategory = require('../src/database/models/mongo/QcmCategory'); +exports.QcmQuestion = require('../src/database/models/mongo/QcmQuestion'); +exports.QcmChoice = require('../src/database/models/mongo/QcmChoice'); +exports.X2DataLog = require('../src/database/models/mongo/X2DataLog'); +exports.Article = require('../src/database/models/mongo/Article'); +exports.Comment = require('../src/database/models/mongo/Comment'); +exports.Tag = require('../src/database/models/mongo/Tag'); \ No newline at end of file diff --git a/routes/auth.js b/routes/auth.js index 28107dc..fa912c3 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -1,7 +1,7 @@ //var jwt = require('express-jwt'); var { expressjwt: jwt } = require("express-jwt"), - secret = require('../config').secret, + secret = require('../src/config').secret, bcrypt = require('bcrypt'); const { v4 } = require('uuid'), passport = require('passport'), diff --git a/routes/utils.js b/routes/utils.js deleted file mode 100644 index caa5f0c..0000000 --- a/routes/utils.js +++ /dev/null @@ -1,84 +0,0 @@ -const chalk = require('chalk'); -const utils = { - getDateString: () => { - let today = new Date(); - let dateNow = today.toLocaleDateString(); - return `${dateNow}`; - }, - getTimeString: () => { - let today = new Date(); - let timeNow = today.toLocaleTimeString(); - return `${timeNow}`; - }, - getDateTimeString: (delimiter = true) => { - let today = new Date(); - let dateString = `${today.toLocaleDateString()} ${today.toLocaleTimeString()}`; - if (delimiter) { - dateString = `[${dateString}]`; - } - return dateString; - }, - getDateTimeISOString: (delimiter = true) => { - let today = new Date(); - let dateString = today.toISOString(); - if (delimiter) { - dateString = `[${dateString}]`; - } - return dateString; - }, - async fetchSkydiverIdApi(path, query) { - let limit = 50; - let offset = 0; - let args = ''; - if (typeof query.limit !== 'undefined') { - limit = query.limit; - } - if (typeof query.offset !== 'undefined') { - offset = ((query.offset/limit)+1); - } - if (offset > 1) { - args += `&page=${offset}`; - } - if (typeof query.dateRangeStart !== 'undefined' && typeof query.dateRangeEnd !== 'undefined') { - args += `&filter[and][0][date][gte]=${query.dateRangeStart}`; - args += `&filter[and][0][date][lte]=${query.dateRangeEnd}`; - } - try { - let url = `${process.env.SKYDIVERID_API_URL}/${path}`; - if (typeof query.limit !== 'undefined') { - url += `?per-page=${limit}${args}`; - } - /* url pour provoquer une erreur en dev : url = `https://www.goldapi.ioppppp/api/${price.metal}/${price.currency}`; */ - let options = { - method: 'GET', - headers: { - 'Authorization': `Bearer ${process.env.SKYDIVERID_API_TOKEN}`, - 'Content-Type': 'application/json' - }, - redirect: 'follow' - }; - /* Pour tester le retour d'erreur : return { errors: { name: 'error name', message: 'error message', type: 'TYPE', code: 'CODE' } }; */ - //const response = await fetch(url, options); - return fetch(url, options).then(function (response) { - if (response.status >= 200 && response.status < 400) { - console.log(`${utils.getDateTimeISOString()}`, chalk.green(`Réception des sauts via SkydiverId API`), `${response.status} ${response.statusText}`); - const data = response.json(); - console.log(data); - return data; - } else { - console.log(`${utils.getDateTimeISOString()}`, chalk.red(`Erreur ${response.status} ${response.statusText}`)); - return { errors: { name: response.statusText, message: `Une erreur ${response.status} '${response.statusText}' est survenue lors de la récupération des sauts via SkydiverId API`, type: 'API Error', code: response.status } }; - } - }) - .catch(error => { - console.log(`${utils.getDateTimeISOString()}`, chalk.red(`A fetchSkydiverIdApi error occured ${error.code} ${error.type}`)); - return { errors: { name: error.name, message: `A fetchSkydiverIdApi error occured : ${error.message}`, type: error.type, code: error.code } }; - }); - } catch (error) { - console.log(`${utils.getDateTimeISOString()}`, chalk.red(`fetchSkydiverIdApi error`)); - return { errors: { name: error.name, message: error.message, type: error.type, code: error.code } }; - } - } -}; - -module.exports = utils; diff --git a/config/index.js b/src/config/index.js similarity index 100% rename from config/index.js rename to src/config/index.js diff --git a/config/passport.js b/src/config/passport.js similarity index 94% rename from config/passport.js rename to src/config/passport.js index 04b982a..a40f7a1 100644 --- a/config/passport.js +++ b/src/config/passport.js @@ -1,4 +1,4 @@ -var secret = require('../config').secret, +var secret = require('.').secret, bcrypt = require('bcrypt'); const passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; @@ -6,7 +6,7 @@ var HeaderAPIKeyStrategy = require('passport-headerapikey').HeaderAPIKeyStrategy var mongoose = require('mongoose'); var Application = mongoose.model('Application'); //var User = mongoose.model('User'); -const { UserService } = require('../src/services'); +const { UserService } = require('../services'); passport.use('headerapikey', new HeaderAPIKeyStrategy( diff --git a/src/database/connectDatabase.js b/src/database/connectDatabase.js new file mode 100644 index 0000000..dd8982e --- /dev/null +++ b/src/database/connectDatabase.js @@ -0,0 +1,68 @@ + +const chalk = require('chalk'); +const mongoose = require('mongoose'); + + +const DB = require('.'); +const sequelize = require('./config/sequelize'); +const associate = require('./relationships'); +const utils = require('../utils'); + +// Connect to the MongoDB database and log a message to the console +const connectMongoDb = async () => { + try { + if (process.env.APP_ENV === 'production') { + mongoose.connect(process.env.MONGODB_URI); + } else { + mongoose.set('strictQuery', true); + mongoose.connect(process.env.MONGODB_URI).then(() => { + console.log(`${utils.getDateTimeISOString()}`, chalk.green('MongoDB connection has been established successfully 🟢')); + }).catch(() => { + console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MongoDB database 🔴')); + }); + mongoose.set('debug', process.env.DEBUG); + console.log(`${utils.getDateTimeISOString()}`, chalk.red('debug :'), chalk.yellow(process.env.DEBUG)); + } + } catch (error) { + console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MongoDB database 🔴')); + console.error('MongoDB connection error:', error); + // Exit the process if the connection is not successful + process.exit(1); + } +}; + +// Connect to the MySQL database and log a message to the console +const connectMysqlDb = async () => { + try { + await sequelize.authenticate(); + console.log('Connection has been established successfully 🔹'); + console.log(`${utils.getDateTimeISOString()}`, chalk.green('MySQL connection has been established successfully 🟢')); + + // Synchronize the database with the models without need of dropping the tables + await DB.sequelize.sync({ + force: false, + }); + + // Call the associate function to create the relationships between the models + associate(); + + } catch (error) { + console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MySQL database 🔴')); + console.error('MySQL connection error:', error); + // Exit the process if the connection is not successful + process.exit(1); + } + +}; + +// Connect to all database and log a message to the console +const connectAllDb = async () => { + connectMongoDb(); + connectMysqlDb(); +}; + + +module.exports.connectAllDb = connectAllDb; +module.exports.connectMongoDb = connectMongoDb; +module.exports.connectMysqlDb = connectMysqlDb; +module.exports.default = connectAllDb; diff --git a/models/mongo/Aeronef.js b/src/database/models/mongo/Aeronef.js similarity index 100% rename from models/mongo/Aeronef.js rename to src/database/models/mongo/Aeronef.js diff --git a/models/mongo/Application.js b/src/database/models/mongo/Application.js similarity index 100% rename from models/mongo/Application.js rename to src/database/models/mongo/Application.js diff --git a/models/mongo/Article.js b/src/database/models/mongo/Article.js similarity index 100% rename from models/mongo/Article.js rename to src/database/models/mongo/Article.js diff --git a/models/mongo/Canopy.js b/src/database/models/mongo/Canopy.js similarity index 100% rename from models/mongo/Canopy.js rename to src/database/models/mongo/Canopy.js diff --git a/models/mongo/Comment.js b/src/database/models/mongo/Comment.js similarity index 100% rename from models/mongo/Comment.js rename to src/database/models/mongo/Comment.js diff --git a/models/mongo/Dropzone.js b/src/database/models/mongo/Dropzone.js similarity index 100% rename from models/mongo/Dropzone.js rename to src/database/models/mongo/Dropzone.js diff --git a/models/mongo/Jump.js b/src/database/models/mongo/Jump.js similarity index 100% rename from models/mongo/Jump.js rename to src/database/models/mongo/Jump.js diff --git a/models/mongo/JumpFile.js b/src/database/models/mongo/JumpFile.js similarity index 100% rename from models/mongo/JumpFile.js rename to src/database/models/mongo/JumpFile.js diff --git a/models/mongo/Qcm.js b/src/database/models/mongo/Qcm.js similarity index 100% rename from models/mongo/Qcm.js rename to src/database/models/mongo/Qcm.js diff --git a/models/mongo/QcmCategory.js b/src/database/models/mongo/QcmCategory.js similarity index 100% rename from models/mongo/QcmCategory.js rename to src/database/models/mongo/QcmCategory.js diff --git a/models/mongo/QcmChoice.js b/src/database/models/mongo/QcmChoice.js similarity index 100% rename from models/mongo/QcmChoice.js rename to src/database/models/mongo/QcmChoice.js diff --git a/models/mongo/QcmQuestion.js b/src/database/models/mongo/QcmQuestion.js similarity index 100% rename from models/mongo/QcmQuestion.js rename to src/database/models/mongo/QcmQuestion.js diff --git a/models/mongo/Tag.js b/src/database/models/mongo/Tag.js similarity index 100% rename from models/mongo/Tag.js rename to src/database/models/mongo/Tag.js diff --git a/models/mongo/User.js b/src/database/models/mongo/User.js similarity index 97% rename from models/mongo/User.js rename to src/database/models/mongo/User.js index eb30511..8709c61 100644 --- a/models/mongo/User.js +++ b/src/database/models/mongo/User.js @@ -2,8 +2,8 @@ var mongoose = require('mongoose'); var uniqueValidator = require('mongoose-unique-validator'); var crypto = require('crypto'); var jwt = require('jsonwebtoken'), - secret = require('../../config').secret, - session_lifetime = require('../../config').session_lifetime; + secret = require('../../../config').secret, + session_lifetime = require('../../../config').session_lifetime; var UserSchema = new mongoose.Schema({ email: { type: String, lowercase: true, unique: true, required: [true, "email can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true }, diff --git a/models/mongo/X2DataLog.js b/src/database/models/mongo/X2DataLog.js similarity index 100% rename from models/mongo/X2DataLog.js rename to src/database/models/mongo/X2DataLog.js diff --git a/models/mongo/index.js b/src/database/models/mongo/index.js similarity index 100% rename from models/mongo/index.js rename to src/database/models/mongo/index.js diff --git a/src/database/models/mysql/User.js b/src/database/models/mysql/User.js index 2d1ec78..14d80f8 100644 --- a/src/database/models/mysql/User.js +++ b/src/database/models/mysql/User.js @@ -1,8 +1,8 @@ const { DataTypes, Model } = require("sequelize"); var crypto = require('crypto'); var jwt = require('jsonwebtoken'), - secret = require('../../../../config').secret, - session_lifetime = require('../../../../config').session_lifetime; + secret = require('../../../config').secret, + session_lifetime = require('../../../config').session_lifetime; const sequelize = require("../../config/sequelize"); diff --git a/middlewares/exceptions.handler.js b/src/middlewares/exceptions.handler.js similarity index 97% rename from middlewares/exceptions.handler.js rename to src/middlewares/exceptions.handler.js index bbac03b..9cce4cd 100644 --- a/middlewares/exceptions.handler.js +++ b/src/middlewares/exceptions.handler.js @@ -4,7 +4,7 @@ if (appEnv == undefined) { } const isProduction = appEnv === 'production', chalk = require('chalk'), - utils = require('../routes/utils'); + utils = require('../utils'); const exceptionHandler = { notFoundErrorHandler: (req, res, next) => { diff --git a/src/routes/auth.js b/src/routes/auth.js index 1413db4..28107dc 100644 --- a/src/routes/auth.js +++ b/src/routes/auth.js @@ -1,7 +1,7 @@ //var jwt = require('express-jwt'); var { expressjwt: jwt } = require("express-jwt"), - secret = require('../../config').secret, + secret = require('../config').secret, bcrypt = require('bcrypt'); const { v4 } = require('uuid'), passport = require('passport'), diff --git a/src/services/connectDB.js b/src/services/connectDB.js deleted file mode 100644 index 98d2f30..0000000 --- a/src/services/connectDB.js +++ /dev/null @@ -1,23 +0,0 @@ -const DB = require('../database'); -const sequelize = require('../database/config/sequelize'); -const associate = require('../database/relationships'); - -// Connect to the database and log a message to the console -const connectDB = async () => { - try { - await sequelize.authenticate(); - console.log('Connection has been established successfully🔥'); - - // Synchronize the database with the models without need of dropping the tables - await DB.sequelize.sync({ - force: false, - }); - - associate(); // Call the associate function to create the relationships between the models - } catch (error) { - console.error('Unable to connect to the database:', error); - process.exit(1); // Exit the process if the connection is not successful - } -}; - -module.exports = connectDB; diff --git a/src/utils/index.js b/src/utils/index.js index 9d9587d..caa5f0c 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1 +1,84 @@ -console.log('this is placeholder for routes'); +const chalk = require('chalk'); +const utils = { + getDateString: () => { + let today = new Date(); + let dateNow = today.toLocaleDateString(); + return `${dateNow}`; + }, + getTimeString: () => { + let today = new Date(); + let timeNow = today.toLocaleTimeString(); + return `${timeNow}`; + }, + getDateTimeString: (delimiter = true) => { + let today = new Date(); + let dateString = `${today.toLocaleDateString()} ${today.toLocaleTimeString()}`; + if (delimiter) { + dateString = `[${dateString}]`; + } + return dateString; + }, + getDateTimeISOString: (delimiter = true) => { + let today = new Date(); + let dateString = today.toISOString(); + if (delimiter) { + dateString = `[${dateString}]`; + } + return dateString; + }, + async fetchSkydiverIdApi(path, query) { + let limit = 50; + let offset = 0; + let args = ''; + if (typeof query.limit !== 'undefined') { + limit = query.limit; + } + if (typeof query.offset !== 'undefined') { + offset = ((query.offset/limit)+1); + } + if (offset > 1) { + args += `&page=${offset}`; + } + if (typeof query.dateRangeStart !== 'undefined' && typeof query.dateRangeEnd !== 'undefined') { + args += `&filter[and][0][date][gte]=${query.dateRangeStart}`; + args += `&filter[and][0][date][lte]=${query.dateRangeEnd}`; + } + try { + let url = `${process.env.SKYDIVERID_API_URL}/${path}`; + if (typeof query.limit !== 'undefined') { + url += `?per-page=${limit}${args}`; + } + /* url pour provoquer une erreur en dev : url = `https://www.goldapi.ioppppp/api/${price.metal}/${price.currency}`; */ + let options = { + method: 'GET', + headers: { + 'Authorization': `Bearer ${process.env.SKYDIVERID_API_TOKEN}`, + 'Content-Type': 'application/json' + }, + redirect: 'follow' + }; + /* Pour tester le retour d'erreur : return { errors: { name: 'error name', message: 'error message', type: 'TYPE', code: 'CODE' } }; */ + //const response = await fetch(url, options); + return fetch(url, options).then(function (response) { + if (response.status >= 200 && response.status < 400) { + console.log(`${utils.getDateTimeISOString()}`, chalk.green(`Réception des sauts via SkydiverId API`), `${response.status} ${response.statusText}`); + const data = response.json(); + console.log(data); + return data; + } else { + console.log(`${utils.getDateTimeISOString()}`, chalk.red(`Erreur ${response.status} ${response.statusText}`)); + return { errors: { name: response.statusText, message: `Une erreur ${response.status} '${response.statusText}' est survenue lors de la récupération des sauts via SkydiverId API`, type: 'API Error', code: response.status } }; + } + }) + .catch(error => { + console.log(`${utils.getDateTimeISOString()}`, chalk.red(`A fetchSkydiverIdApi error occured ${error.code} ${error.type}`)); + return { errors: { name: error.name, message: `A fetchSkydiverIdApi error occured : ${error.message}`, type: error.type, code: error.code } }; + }); + } catch (error) { + console.log(`${utils.getDateTimeISOString()}`, chalk.red(`fetchSkydiverIdApi error`)); + return { errors: { name: error.name, message: error.message, type: error.type, code: error.code } }; + } + } +}; + +module.exports = utils;