-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
179 lines (168 loc) · 5.94 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
/*
* Scaffnode
* TODO: Your project info here
*/
/** Depends **/
const express = require("express"),
nunjucks = require("nunjucks"),
fs = require("fs"),
dateFilter = require('nunjucks-date-filter'),
bunyan = require("bunyan"),
bodyParser = require("body-parser"),
expressSession = require("express-session"),
//multer = require('multer'), // uncomment if using file-upload or other multi-part
i18n = require('i18n'),
redis = require("ioredis"),
{RedisStore} = require("connect-redis"),
hpp = require('hpp'),
Routes = require("./routes"),
Utils = require("./utils"),
site = module.exports = express();
// Load configuration details based on your environment
let config;
const packagejson = require('./package');
let isTestMode = false;
if (process.env.NODE_ENV === "dev" || process.env.NODE_ENV === "live" || process.env.NODE_ENV === "test"){
// If we're in test mode, just set a flag on the config object and switch the NODE_ENV to "dev"
if (process.env.NODE_ENV === "test"){
isTestMode = true;
process.env.NODE_ENV = "dev";
}
config = require("./config").config;
config.isTestMode = isTestMode;
config.NODE_ENV = process.env.NODE_ENV;
config.appName = packagejson.name;
config.appVersion = packagejson.version;
site.locals.config = config;
}else{
console.log("Missing NODE_ENV environment variable. Must be set to 'dev' or 'live'.");
process.exit();
}
//Setup views and nunjucks templates
const env = nunjucks.configure("views", {
autoescape: true,
noCache: config.NODE_ENV === "dev",
express: site
});
env.addFilter('date', dateFilter);
env.addFilter('nl2br', function(str) {
return str.replace(/\n/gi, "<br />");
});
config.nunjucks = env;
site.set("view engine", "html");
site.set("views", __dirname + "/views");
site.enable("trust proxy"); // This app is meant to be run behind NGINX
site.disable("x-powered-by");
//The rest of our static-served files
site.use(express.static(__dirname + "/public"));
// Configure logging
const log = bunyan.createLogger({
name: packagejson.name + " " + packagejson.version,
streams:
[{
level: isTestMode ? "fatal" : config.LOG_LEVEL, // Priority of levels looks like this: Trace -> Debug -> Info -> Warn -> Error -> Fatal
stream: process.stdout
}
// Setup an addional logger with ease
/*,{
level: 'warn',
stream: new utils(), // looks for 'write' method. https://github.com/trentm/node-bunyan
}*/
]}
);
// Setup redis
let redisReady = false;
const redisClient = new redis({"detect_buffers": true, port: config.REDIS_PORT, host: config.REDIS_HOST, password: config.REDIS_PASSWORD || null});
site.set('redis', redisClient);
redisClient.on("error", (err) => {
log.error("Redis Client", err);
});
redisClient.on("end", (err) => {
log.error("Redis unavailable", err);
redisReady = true;
});
redisClient.on("ready", () => {
log.debug("✅ Connected to Redis");
redisReady = true;
});
// Initalize routes and a few utilities helpers (i18n and error handling utils)
const utils = new Utils(site, log, config, redisClient);
const routes = new Routes(log, config, redisClient, utils);
// Multipart upload handler
// Enable multi-part uploads only on routes you need them on like this:
// site.post("/upload-image", upload.single("imagefieldname"), routes.handleUploadRoute)
// More details: https://github.com/expressjs/multer
/*var upload = multer({
dest: "/tmp/",
rename: function (fieldname, filename) {
return filename.replace(/\W+/g, "-").toLowerCase();
}
});
*/
site.locals.webpackAssets = {files: [], css: [], js: []};
fs.readdirSync(__dirname + '/public/dist').forEach((file) => {
if ((/\.js$/i).test(file)){
site.locals.webpackAssets.js.push(file);
} else if ((/\.css$/i).test(file)) {
site.locals.webpackAssets.css.push(file);
} else {
site.locals.webpackAssets.files.push(file);
}
});
// Middlewares!
if (config.NODE_ENV === "dev"){
log.info("Webpack HMR enabled");
}
site.use(bodyParser.urlencoded({extended: true}));
site.use(bodyParser.json());
site.use(hpp()); // Protect against HTTP Parameter Pollution attacks
site.use(expressSession({
secret: config.SESSION_SECRET,
key: "scaffnode-session.sid",
resave: true,
saveUninitialized: false,
store: new RedisStore({
client: redisClient,
logErrors: log.error,
ttl: 2592000 // 30 days in s
}),
cookie: {
maxAge: 2592000 * 1000, // 30 days in ms
path: "/",
//secure: config.NODE_ENV !== "dev", // Enable when you've got SSL setup
//domain: ".scaffnode.com" // Enable when you've got your domain setup
},
rolling: true,
unset: "destroy"
}));
// Setup i18n for use with templates
i18n.configure({
locales: config.SUPPORTED_LOCALES,
cookie: packagejson.name + "_lang.sid",
directory: __dirname + '/locales'
});
// Express helper (makes '__' functions available in templates)
site.use(i18n.init);
// Middleware helper, makes user language preferences sticky and watches for "lang" query variable
site.use(utils.i18nHelper);
site.use((req, res, next) => {
if (!redisReady){
return res.json({error: true, message: "Waiting for Redis...", data: false});
}
next();
});
////Routes/Views
site.get("/", routes.base.index);
site.get("/about", routes.base.aboutUs);
//Catch all other attempted routes and throw them a 404!
site.all("*", function(req, resp, next){
next({name: "NotFound", "message": "Oops! The page you requested doesn't exist", "status": 404});
});
// Finally, if no other routes match, use our errorHandler
site.use(utils.errorHandler);
// Get proper from from ENV variable for live mode, otherwise use port 8888
const port = process.env.PORT || 8888;
site.listen(port, (server) => {
utils.setRunningServer(server);
log.info("Server listening on http://" + site.locals.config.API_DOMAIN + ":" + port + " in " + site.locals.config.NODE_ENV + " mode");
});