-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
145 lines (121 loc) Β· 4.41 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
/**
* app.js
*
* @description :: The main entry point of the API
* @version :: 1.0
*/
// Import packages
const express = require('express');
const mongoose = require('mongoose');
const morgan = require('morgan');
const path = require('path');
const cors = require('cors');
const history = require('connect-history-api-fallback');
const methodOverride = require('method-override');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const { generateSecretKey } = require('./utils/utils');
// Import routes of the versioned API
const v1Routes = require('./routes/v1');
const API_VERSION = 1; // Which API version to use (global constant)
require('dotenv').config(); // set-up environment variables (.env)
// Attempt to access .env variables, otherwise replace by the default values
const port = process.env.PORT || 3000;
const mongoURI = process.env.MONGODB_URI || 'mongodb:https://127.0.0.1:27017/SEManagerDB';
const SESSION_SECRET = process.env.SESSION_SECRET || generateSecretKey();
// Attempt to establish a connection with MongoDB
mongoose.connect(mongoURI).catch((err) => {
if (err) {
console.error(`Failed to connect to MongoDB with URI: ${mongoURI}`);
console.error(err.stack);
process.exit(1);
}
console.log(`Connected to MongoDB with URI: ${mongoURI}`);
});
// Create Express app
const app = express();
// Parse requests of content-type 'application/json'
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Cookies and sessions
app.use(cookieParser());
app.use(
session({
secret: SESSION_SECRET,
resave: false,
saveUninitialized: true
})
);
// HTTP request logger
app.use(morgan('dev'));
// Enable cross-origin resource sharing for frontend must be registered before api
// Enable cookies modification
app.use(cors({ withCredentials: true, credentials: true, origin: true }));
// Enable HTTP overriding (for multiple formats)
// This means that all middleware can be reached by using the GET/POST
// method given the method override parameter in the request body.
app.use(methodOverride('X-HTTP-Method')); // Microsoft
app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
app.use(methodOverride('X-Method-Override')); // IBM
/* ---Middleware----------------------------------------------------------------------------- */
app.get('/api', (req, res) => {
const VERSION_LINKS = {
'v1': {
'status': 'stable',
'href': '/api/v1',
'type': 'application/json'
},
/* Add new API versions here.
'v1.x': {
'status': 'experimental',
'href': '/api/v1.x',
'type': 'application/json'
} */
};
res.json({
'message': 'Welcome to the SEManager API',
'version_links': VERSION_LINKS
});
});
/* ---VERSION 1.0 API--- */
app.use('/api/v1', v1Routes);
/* ---VERSION 1.x API--- */
// Increment the API version and add the new routes here
// Handle all undefined routes
app.use('/api/*', (req, res) => {
res.status(404).json({ 'message': 'Not Found' });
});
/* ---Middleware----------------------------------------------------------------------------- */
// Configuration for serving frontend in production mode
// Support Vue.js HTML 5 history mode
app.use(history());
// Serve static assets
const root = path.normalize(__dirname + '/..');
const client = path.join(root, 'client', 'dist');
app.use(express.static(client));
// Error handler (i.e., when exception is thrown) must be registered last
const env = process.env.NODE_ENV || 'development';
// Note: if the product is in development mode, the returned JSON object
// contains the full stack off the error.
app.use((err, req, res) => {
console.error(err.stack);
let err_res = {
'message': err.message,
'error': {}
};
if (env === 'development') {
// Return sensitive stack trace only in dev mode
err_res['error'] = err.stack;
}
res.status(err.status || 500);
res.json(err_res);
});
// listen on the defined port
app.listen(port, (err) => {
if (err) throw err;
console.log(`Express server listening on port ${port}, in ${env} mode`);
console.log(`Backend: http:https://localhost:${port}/api/v${API_VERSION}`);
console.log(`Frontend (production): http:https://localhost:${port}/`);
console.log(`Connected to MongoDB with URI: ${mongoURI}`);
});
module.exports = app;