-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
187 lines (171 loc) · 5.59 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// @ts-check
const path = require('path');
const rootDir = require('./utils/paths');
const http = require('http');
const express = require('express');
const session = require('express-session');
const multer = require('multer');
const csurf = require('csurf');
const flash = require('connect-flash');
const MongoDBStrore = require('connect-mongodb-session')(session);
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');
const demyConfig = require('./utils/config');
const dbConnections = require('./utils/database');
const filesUtil = require('./utils/files');
const sequelize = !demyConfig.useMongoDB ? dbConnections.sequelize : undefined;
const mongoConnection = demyConfig.useMongoDB ? dbConnections.mongoConnection : undefined;
const port = demyConfig.serverPort;
const app = express();
if (process.env.NODE_ENV === 'production') {
// extra plugins for production
app.use(helmet());
app.use(compression());
}
// morgan reques logging
app.use(morgan('combined', { stream: filesUtil.reqLoggerFileStream }));
const adminEmail = 'admin1@test.com';
const sessionStore = new MongoDBStrore(
{ uri: demyConfig.mongoDBPath, collection: 'Sessions' },
function(error) {
if (error) {
console.log('MongoDB(sessions) connection error');
}
}
);
let Product, User, Cart, CartItem, Order, OrderItem;
if (demyConfig.useMongoDB) {
// MongoDB database models
User = require('./models/mongo/user');
} else {
// Sequelize database models
Product = require('./models/product');
User = require('./models/user');
Cart = require('./models/cart');
CartItem = require('./models/cart-item');
Order = require('./models/order');
OrderItem = require('./models/order-item');
}
// defining templating engine
app.set('view engine', 'ejs'); // templating engine to use
app.set('views', 'views'); // path of views
// importing routes
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const authRoutes = require('./routes/auth');
const checkAuth = require('./middleware/check-auth');
const errorCtrl = require('./controllers/error');
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(session({
secret: demyConfig.sessionSecret,
resave: false,
saveUninitialized: false,
store: sessionStore
}));
// multer file storage
const multerFileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, demyConfig.productImgsRoot);
},
filename: (req, file, cb) => {
cb(null, new Date().getTime() + '-' + file.originalname);
}
});
const multerFileFilter = (req, file, cb) => {
// multer file type filter
if (file.mimetype === 'image/png' || file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg') {
cb(null, true); // save file
} else {
cb(null, false); // don't save file
}
};
app.use(multer({ storage: multerFileStorage, fileFilter: multerFileFilter }).single('image'));
app.use(csurf({ }));
app.use(flash());
// public folders
app.use(express.static(path.join(rootDir, 'public')));
filesUtil.createImgsFolderIfNotPresent();
app.use(`/${demyConfig.productImgsRoot}`, express.static(path.join(rootDir, demyConfig.productImgsRoot)));
// add user details/object under request
app.use((req, res, next) => {
if (!req.session.user) {
return next();
}
const userPromise = demyConfig.useMongoDB ?
User.findById(req.session.user._id) :
User.findOne({ where: { email: adminEmail }});
userPromise.then(user => {
if (!user) {
return next();
}
req.user = user && demyConfig.useMongoDB ? user : user;
next();
}).catch(error => {
throw new Error(error);
});
});
// common values for template views
app.use((req, res, next) => {
res.locals.isAuthenticated = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
next();
});
// using routes
app.use('/admin', checkAuth.isLoggedIn, adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);
// error handlers
app.use(errorCtrl.notFound); // 404 route
app.use(errorCtrl.serverError); // server error handler
const appServer = http.createServer(app);
if (demyConfig.useMongoDB) {
// connect to MongoDB
mongoConnection().then(connection => {
console.log('MongoDB connected');
return User.findOne({ email: adminEmail });
}).then(() => {
appServer.listen(port, () => {
console.log(`Listening at http://localhost:${port}/`);
});
}).catch(error => {
console.log(error.message || 'Failed to start server');
});
} else {
// connect to SQL DB
// database tables association
Product.belongsTo(User, { constraints: true, onDelete: 'CASCADE' });
User.hasMany(Product);
User.hasOne(Cart);
Cart.belongsTo(User);
Cart.belongsToMany(Product, { through: CartItem });
Product.belongsToMany(Cart, { through: CartItem });
Order.belongsTo(User);
User.hasMany(Order);
Order.belongsToMany(Product, { through: OrderItem });
// sync database and tables
sequelize.sync({ logging: false, force: false }).then(result => {
console.log('Database sync complete');
return User.findOne({ where: { email: adminEmail }}).then(user => {
if (!user) {
return User.create({name: 'Admin1', email: adminEmail});
}
return user;
});
}).then(user => {
// get cart
return user.getCart().then(cart => {
if (!cart) {
return user.createCart(); // create cart for user
}
return cart;
});
}).then(() => {
appServer.listen(port, () => {
console.log(`Listening at http://localhost:${port}/`);
});
}).catch(error => {
console.log('Failed to sync Database', error);
});
}