Initial commit
This commit is contained in:
7
.env
Normal file
7
.env
Normal 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
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
.env
|
||||||
|
package-lock.json
|
||||||
21
Dockerfile
Normal file
21
Dockerfile
Normal 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
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# ETA API
|
||||||
|
|
||||||
|
ETA Viaporte API
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
- NodeJS v18
|
||||||
35
config/apiConfig.json
Normal file
35
config/apiConfig.json
Normal 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": "QhM8gQ5O3hVDIf41YeO5/A6Wo58D1xQz8pzxBB2W",
|
||||||
|
"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
7
dotenv
Normal 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
62
index.js
Normal 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
87
lib/Middlewares.js
Normal 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
23
lib/jwtValidator.js
Normal 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
44
package.json
Normal 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
17
sections/sections.js
Normal 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
8
sections/test/routes.js
Normal 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
20
sections/test/services.js
Normal 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
9
sections/users/routes.js
Normal 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;
|
||||||
20
sections/users/services.js
Normal file
20
sections/users/services.js
Normal 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};
|
||||||
Reference in New Issue
Block a user