{"size": 3899, "ext": "js", "max_stars_repo_path": "app.js", "max_stars_repo_name": "GoldenMaximo/Express.js-EJS-ECommerce", "max_stars_repo_stars_event_min_datetime": "2020-08-11T20:54:30.000Z", "max_stars_repo_stars_event_max_datetime": "2020-08-24T12:31:06.000Z", "max_issues_repo_path": "app.js", "max_issues_repo_name": "GoldenMaximo/Express.js-EJS-ECommerce", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "app.js", "max_forks_repo_name": "GoldenMaximo/Express.js-EJS-ECommerce", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 2, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 29.3157894737, "max_line_length": 159, "alphanum_fraction": 0.6381123365}
require('dotenv').config();

const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const csurf = require('csurf');
const flash = require('connect-flash');
const multer = require('multer');
const { v4: uuidv4 } = require('uuid');
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');
const fs = require('fs');
var favicon = require('serve-favicon');
// const https = require('https');


const User = require('./models/User');

const MONGODB_URI = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}@cluster0.ygqkk.mongodb.net/${process.env.DB_NAME}?retryWrites=true&w=majority`

const app = express();

const store = new MongoDBStore({
    uri: MONGODB_URI,
    collection: 'sessions'
});

const csrfProtection = csurf(); //TODO: refactor later

// const privateKey = fs.readFileSync('server.key');
// const certificate = fs.readFileSync('server.cert');

const fileStorage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'images');
    },
    filename: (req, file, cb) => {
        cb(null, uuidv4() + '-' + file.originalname);
    },
});

const fileFilter = (req, file, cb) => {
    if (file.mimetype === 'image/jpg' || file.mimetype === 'image/png' || file.mimetype === 'image/jpeg') {
        cb(null, true);
    } else {
        cb(null, false)
    }
}

app.set('view engine', 'ejs');
app.set('views', 'views');

const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const authRoutes = require('./routes/auth');
const errorRoutes = require('./routes/errors');

const accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });

// Middlewares
app.use(favicon(__dirname + '/public/favicon/favicon.ico'));
app.use(morgan('combined', { stream: accessLogStream }));
app.use(helmet());
app.use(compression());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ storage: fileStorage, fileFilter: fileFilter }).single('image'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/images', express.static(path.join(__dirname, 'images')));
app.use(session({
    secret: 'whateverSecret',
    resave: false,
    saveUninitialized: false,
    store
}));

app.use(csrfProtection);
app.use(flash());

app.use((req, res, next) => {
    res.locals.isAuthenticated = req.session.isLoggedIn;
    res.locals.csrfToken = req.csrfToken();
    next();
})

app.use((req, res, next) => {
    // On synchronous code expess detects errors and fowards them to the error handling middleware
    // throw new Error('dummy error');
    if (!req.session.user) {
        return next();
    }
    User.findById(req.session.user._id).then(user => {
        // On asynchronous code you have to catch the error and call next for it to be forwarded to the error handling middleware
        // throw new Error('dummy error');
        if (!user) {
            return next();
        }
        req.user = user;
        next();
    }).catch(err => {
        next(new Error(err));
    });
});

// Routes
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);
app.use(errorRoutes);

app.use((error, req, res, next) => {
    console.log('ERROR: ', error);
    res.status(500).render('500', {
        pageTitle: 'Error occured',
        path: '/500',
        isAuthenticated: req.session.isLoggedIn
    });
})

mongoose.connect(MONGODB_URI).then(connection => {
    app.listen(process.env.PORT || 3000);
    // https.createServer(
    //     {
    //         key: privateKey,
    //         cert: certificate
    //     },
    //     app
    // ).listen(process.env.PORT || 3000);
}).catch(err => console.log(err));
