Initial commit

This commit is contained in:
2023-10-05 11:29:24 -06:00
commit 55f1c6e091
15 changed files with 370 additions and 0 deletions

7
.env Normal file
View File

@@ -0,0 +1,7 @@
SERVER_PORT=8080
API_CONFIG=/config/apiConfig.json
ROOT_PATH=/home/josepablocb/Documents/Work/EnRuta/SysS/ETAAPI
############################
# PATHS relative to ROOT
############################
LIB_PATH=lib

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules/
.env
package-lock.json

21
Dockerfile Normal file
View File

@@ -0,0 +1,21 @@
# Use an official Python runtime as a parent image
FROM node:14-alpine
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY sections /app/sections
COPY lib /app/lib
COPY config /app/config
COPY index.js /app
COPY package.json /app
COPY dotenv /app/.env
RUN npm install 2>/dev/null
EXPOSE 8080
ENV ROOT_PATH="/app"
ENTRYPOINT npm start

7
README.md Normal file
View File

@@ -0,0 +1,7 @@
# ETA API
ETA Viaporte API
# Dependencies
- NodeJS v18

35
config/apiConfig.json Normal file
View File

@@ -0,0 +1,35 @@
{
"authentication": {
"jwtSecret":"9o3BBz0EsrwXliwEJ/SFuywZoN8=",
"jwtTimeout":720,
"tokenSecret":"9Z'jMt|(h_f(&/S+zv.K",
"jwtOptions": {
"header": {
"typ": "access"
},
"audience": "https://www.etaviaporte.com",
"issuer": "etaviaporte",
"algorithm": "HS256",
"expiresIn": "1d"
}
},
"version" : {
"version" : "0.0.0",
"name": "ETA Beta",
"date":"10/2023"
},
"S3" : {
"accessKeyId": "AKIAXTQEUF6MLCHTUIKW",
"secretAccessKey": "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",
"bucket": "enruta",
"region": "us-west-1"
},
"sendgrid" : {
"HOST": "smtp.sendgrid.net",
"PORT": "465",
"username": "apikey",
"API_KEY": "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",
"FROM": "noreply@etaviaporte.com"
},
"mongodb": "mongodb+srv://enruta_admin:NeptFx4RUZG8OsfA@enruta.vwofshy.mongodb.net/enrutaviaporte?retryWrites=true&w=majority"
}

7
dotenv Normal file
View File

@@ -0,0 +1,7 @@
SERVER_PORT=8080
API_CONFIG=/config/apiConfig.json
ROOT_PATH=/home/josepablocb/Documents/Work/EnRuta/SysS/ETAAPI
############################
# PATHS relative to ROOT
############################
LIB_PATH=/lib

62
index.js Normal file
View File

@@ -0,0 +1,62 @@
'use strict';
const express = require('express');
require('dotenv').config();
const { ROOT_PATH , LIB_PATH } = process.env;
const cors = require('cors');
const compression = require('compression');
const morgan = require('morgan');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const fileUpload = require('express-fileupload');
const sections = require('./sections/sections.js');
const middleWares = require( `${ROOT_PATH}/${LIB_PATH}/Middlewares.js` );
const app = express();
const serverPort = process.env.SERVER_PORT || 3000;
app.use( middleWares.Auth );
app.use(
fileUpload({
limits: { fileSize: 4 * 1024 * 1024 },
abortOnLimit: true,
limitHandler: (req,res,next) => {
req.limitSize = true;
},
})
);
app.use((req, res, next) => {
if (req.limitSize) {
res.status(413).send({message:"File size limit has been reached",status:"PAYLOAD_TOO_LARGE"});
}else{
next()
}
});
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(morgan('dev'));
app.use(helmet());
app.use(compression());
app.use(cors({
origin: '*',
methods: [
'GET',
'POST',
'PATCH',
'PUT',
'DELETE'
],
allowedHeaders: ['Content-Type', 'Authorization']
}));
app.use( middleWares.errorJSON );
app.use( sections );
app.use( middleWares.error404 );
app.listen( serverPort , function(err){
if( !err ){
console.log('API listen on port', serverPort );
}else{
console.log( err );
}
});

87
lib/Middlewares.js Normal file
View File

@@ -0,0 +1,87 @@
'use strict';
/**
* HASH
*****************************************************
* DEPENDENCIES
*****************************************************
* Based on Express Framework
* System
*****************************************************
* PUBLIC METHODS
*****************************************************
* Auth( req, res, next)
* Extract JWT or BasicAuth data
* errorJSON( error , request , response , next )
* Generate error response on bad JSON format
* error404( request , response , next )
* Generate error 404 response
* apiKey( request , response , next )
* Generate error on invalid apikey
**/
/// Extract JWT or BasicAuth
function Auth( req, res , next ){
///
/// Try to extract the authorization data from headers
///
let auth;
if( req.headers.hasOwnProperty( "authorization" ) ){
auth = req.headers.authorization;
auth = auth.split(" ")[1];
if( !auth ){ console.log( "NO HEADER AUTH available" ); return next(); }
//console.log( auth );
/// Try BasicAuth {
try{
let ba = Buffer.from( auth , 'base64' ).toString()
//const [user,pass] = ba.split(':');
ba = ba.split(':');
if( ba.length == 2 ){
req.basicAuth = { user : ba[0] , password : ba[1] };
}
}catch(error){
console.log("MIDDLEWARE_AUTH_ERR_BA",error);
}
/// Try BasicAuth }
}else if( req.query.access_token ){
auth = req.query.access_token;
if( !auth ){ console.log( "NO QUERY AUTH available" ); return next(); }
}
if( auth ){
/// Try JWT {
try{
let jwt = auth.split(".");
if( jwt.length == 3 ){
req.JWT = {};
req.JWT.raw = auth;
}
}catch( error ){
console.log("MIDDLEWARE_AUTH_ERR_JWT",error);
}
/// Try JWT }
}
next();
}
function errorJSON( error , request , response , next ){
console.log(error);
if( error !== null ){
/// For body-parser errors
if( error instanceof SyntaxError && error.status === 400 && 'body' in error ){
return response.status(400).json({ error : 'Invalid json' , code : 400 });
}
/// For any error
return response.status(500).send( { error: "Internal server error" , code : 500 } );
}else{
return next();
}
}
function error404( request , response , next ){
return response.status(404).send( { error : "Page not found", code : 404 } );
}
module.exports = {
Auth,
errorJSON,
error404,
};

23
lib/jwtValidator.js Normal file
View File

@@ -0,0 +1,23 @@
'user strict';
const { ROOT_PATH, API_CONFIG } = process.env;
const jwt = require('jsonwebtoken');
const apiConfig = require(ROOT_PATH + API_CONFIG);
const secret = apiConfig.authentication.jwtSecret;
function middleware( req, res, next ){
if( req.JWT ){
req.JWT.payload = jwt.verify( req.JWT.raw, apiConfig.authentication.jwtSecret , (err, user) => {
if( err ){
return res.status(401).send({error:"Unauthorized",code:401});
}
});
next();
}else{
return res.status(401).send({error:"Unauthorized",code:401});
}
}
module.exports = {
middleware
};

44
package.json Normal file
View File

@@ -0,0 +1,44 @@
{
"name": "etaapi",
"version": "1.0.0",
"description": "ETA API",
"main": "index.js",
"scripts": {
"start": "nodemon index.js",
"dev": "nodemon index.js"
},
"repository": {
"type": "git",
"url": "git+https://gitlab.com/jcruzbaasworkspace/enruta/etaapi.git"
},
"author": "Josepablo C.",
"license": "ISC",
"bugs": {
"url": "https://gitlab.com/jcruzbaasworkspace/enruta/etaapi/issues"
},
"homepage": "https://gitlab.com/jcruzbaasworkspace/enruta/etaapi#readme",
"dependencies": {
"audit": "^0.0.6",
"aws-sdk": "^2.1470.0",
"axios": "^1.5.1",
"body-parser": "^1.20.2",
"compression": "^1.7.4",
"cors": "^2.8.5",
"crypto-js": "^4.1.1",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-fileupload": "^1.4.1",
"express-jwt": "^8.4.1",
"form-data": "^4.0.0",
"helmet": "^7.0.0",
"jsonwebtoken": "^9.0.2",
"knex": "^2.5.1",
"mongodb-core": "^3.2.7",
"mongoose": "^7.5.4",
"morgan": "^1.10.0",
"nodemailer": "^6.9.5",
"nodemon": "^3.0.1",
"objection": "^3.1.2",
"uuid": "^9.0.1"
}
}

17
sections/sections.js Normal file
View File

@@ -0,0 +1,17 @@
'use strict';
const { ROOT_PATH , LIB_PATH } = process.env;
/// Router instance
const router = require('express').Router();
const jwtValidator = require( `${ROOT_PATH}/${LIB_PATH}/jwtValidator.js` );
const test = require('./test/routes.js');
const users = require('./users/routes.js');
router.use("/test", test);
router.use( jwtValidator.middleware );
router.use("/users", users);
module.exports = router;

8
sections/test/routes.js Normal file
View File

@@ -0,0 +1,8 @@
'use strict';
const router = require('express').Router();
const services= require('./services.js');
router.get('/apitest', services.postTest);
router.get('/version', services.getVersion);
module.exports = router;

20
sections/test/services.js Normal file
View File

@@ -0,0 +1,20 @@
"use strict";
const apiConfig = require( process.env.ROOT_PATH + process.env.API_CONFIG );
const postTest = async(req, res) => {
res.send({
msg:"Hello world!",
data:{
apiQuery:req.query,
apiParams:req.params.params,
body:req.body,
}
});
};
const getVersion = async(req, res) => {
res.send( apiConfig.version );
};
module.exports = { postTest , getVersion };

9
sections/users/routes.js Normal file
View File

@@ -0,0 +1,9 @@
'use strict';
const router = require('express').Router();
const services= require('./services.js');
router.get('/', services.getUsers);
router.get('/profile', services.getProfileData);
router.get('/:userId', services.getUserData);
module.exports = router;

View File

@@ -0,0 +1,20 @@
"use strict";
const apiConfig = require( process.env.ROOT_PATH + process.env.API_CONFIG );
const getUsers = async(req, res) => {
console.log( req.params );
res.send({ user : "hello world!" });
};
const getUserData = async(req, res) => {
console.log( req.params );
res.send({ user : "hello world!" });
};
const getProfileData = async(req, res) => {
console.log( req.params );
res.send({ user : "hello world!" });
};
module.exports = { getUsers , getUserData , getProfileData};