2019-09-06 01:20:24 +02:00
|
|
|
'use strict'
|
|
|
|
|
|
|
|
require('make-promises-safe'); // installs an 'unhandledRejection' handler
|
|
|
|
|
|
|
|
const path = require('path');
|
2019-09-07 02:23:55 +02:00
|
|
|
let siteConfig;
|
|
|
|
try {
|
2019-09-09 05:54:43 +02:00
|
|
|
siteConfig = require('./config.json');
|
2019-09-07 02:23:55 +02:00
|
|
|
} catch (ex) {
|
|
|
|
console.error('Please copy `config.example.json` to `config.json` and fill it with your server\'s data.');
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
2019-09-06 01:20:24 +02:00
|
|
|
const fastify = require('fastify')({
|
2019-09-07 02:12:56 +02:00
|
|
|
logger: process.env.NODE_ENV !== 'production',
|
2019-09-06 01:20:24 +02:00
|
|
|
});
|
2019-09-07 06:17:45 +02:00
|
|
|
fastify.decorate('siteConfig', siteConfig); // Insert siteConfig into global fastify instance
|
|
|
|
fastify.register(require('fastify-helmet')); // Add security stuff
|
|
|
|
fastify.register(require('fastify-compress')); // Compress output data for smaller packet delivery
|
|
|
|
fastify.register(require('fastify-static'), { // Enable delivering static content efficiently
|
2019-09-09 05:54:43 +02:00
|
|
|
root: path.resolve(__dirname, '../public'), // all static content will be delivered from the public/ folder
|
2019-09-06 01:20:24 +02:00
|
|
|
});
|
2019-09-07 06:17:45 +02:00
|
|
|
fastify.register(require('fastify-cookie')); // Enable reading and setting http-level cookies for the sole purpose of storing login tokens
|
|
|
|
fastify.register(require('fastify-jwt'), { // Enable creating, parsing, and verifying JSON Web Tokens from the global fastify object
|
|
|
|
secret: fastify.siteConfig.jwtSecretKey, // The secret key used to generate JWTs. Make it big and random!
|
|
|
|
});
|
2019-09-19 01:15:06 +02:00
|
|
|
|
|
|
|
const sequelizeConfig = {
|
|
|
|
instance: 'sequelize',
|
|
|
|
autoConnect: true,
|
|
|
|
dialect: fastify.siteConfig.db_engine,
|
|
|
|
};
|
|
|
|
switch (fastify.siteConfig.db_engine) {
|
|
|
|
case 'sqlite': {
|
|
|
|
sequelizeConfig.storage = typeof fastify.siteConfig.sqlite_location !== 'undefined'
|
2019-10-03 21:04:17 +02:00
|
|
|
? path.resolve(__dirname, fastify.siteConfig.sqlite_location)
|
2019-09-19 01:15:06 +02:00
|
|
|
: path.resolve(__dirname, './database.sqlite');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
sequelizeConfig.host = fastify.siteConfig.db_host;
|
|
|
|
sequelizeConfig.port = fastify.siteConfig.db_port;
|
|
|
|
sequelizeConfig.database = fastify.siteConfig.db_database;
|
|
|
|
sequelizeConfig.username = fastify.siteConfig.db_username;
|
|
|
|
sequelizeConfig.password = fastify.siteConfig.db_password;
|
|
|
|
}
|
|
|
|
}
|
2020-01-05 03:11:57 +01:00
|
|
|
fastify.register(require('./fastify-plugins/fastify-sequelize'), sequelizeConfig);
|
2019-09-07 06:17:45 +02:00
|
|
|
|
2019-09-28 02:40:39 +02:00
|
|
|
if (!fastify.siteConfig.email_host || !fastify.siteConfig.email_username) {
|
|
|
|
console.warn('###\nNo email server set up. You will not be able to send emails without entering your email configuration.\n###');
|
|
|
|
} else {
|
2020-01-05 03:11:57 +01:00
|
|
|
fastify.register(require('./fastify-plugins/fastify-nodemailer'), {
|
2019-09-28 02:40:39 +02:00
|
|
|
pool: true,
|
|
|
|
host: fastify.siteConfig.email_host,
|
|
|
|
port: fastify.siteConfig.email_port,
|
|
|
|
secure: true, // use TLS
|
|
|
|
auth: {
|
|
|
|
user: fastify.siteConfig.email_username,
|
|
|
|
pass: fastify.siteConfig.email_password,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-09-07 06:17:45 +02:00
|
|
|
// Every request, check to see if a valid token exists
|
2019-09-28 01:10:43 +02:00
|
|
|
fastify.addHook('onRequest', async (request, reply) => {
|
|
|
|
request.isLoggedInUser = false;
|
|
|
|
if (typeof request.cookies.token !== 'undefined' && fastify.jwt.verify(request.cookies.token)) {
|
|
|
|
const { id } = fastify.jwt.verify(request.cookies.token);
|
|
|
|
const user = await fastify.models.User.findByPk(id).catch(ex => fastify.log(ex));
|
|
|
|
if (!user) {
|
|
|
|
console.log('Invalid user id from token');
|
|
|
|
request.clearCookie('token', token, {
|
|
|
|
path: '/',
|
|
|
|
expires: new Date(Date.now() - 9999),
|
|
|
|
maxAge: new Date(Date.now() - 9999), // Both are set as a "just in case"
|
|
|
|
httpOnly: true, // Prevents JavaScript on the front end from grabbing it
|
|
|
|
sameSite: true, // Prevents the cookie from being used outside of this site
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
request.isLoggedInUser = true;
|
|
|
|
request.user = user;
|
|
|
|
}
|
|
|
|
}
|
2019-09-07 06:17:45 +02:00
|
|
|
});
|
2019-09-06 01:20:24 +02:00
|
|
|
|
2019-10-27 19:48:28 +01:00
|
|
|
// Store i18n files in fastify object and register locales routes
|
|
|
|
fastify.register(require('./i18n'));
|
2019-09-07 02:23:55 +02:00
|
|
|
|
2019-09-06 01:20:24 +02:00
|
|
|
// Routes
|
2019-09-09 05:56:16 +02:00
|
|
|
fastify.register(require('./routes/public'));
|
2019-09-13 01:04:50 +02:00
|
|
|
fastify.register(require('./routes/books'));
|
2019-09-17 23:10:46 +02:00
|
|
|
fastify.register(require('./routes/account'));
|
2019-12-01 23:31:34 +01:00
|
|
|
fastify.register(require('./routes/shelf'));
|
2019-09-09 22:19:22 +02:00
|
|
|
fastify.register(require('./routes/search'));
|
2019-09-06 01:20:24 +02:00
|
|
|
|
|
|
|
// Start the server
|
2019-09-07 02:23:55 +02:00
|
|
|
fastify.listen(fastify.siteConfig.port, function (err, address) {
|
2019-09-06 01:20:24 +02:00
|
|
|
if (err) {
|
|
|
|
fastify.log.error(err);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
2019-09-28 01:10:43 +02:00
|
|
|
|
2019-09-28 02:40:39 +02:00
|
|
|
fastify.decorate('canEmail', typeof fastify.nodemailer !== 'undefined');
|
2020-01-14 23:26:39 +01:00
|
|
|
fastify.decorate('models', require('./sequelize/models')(fastify.sequelize));
|
2019-09-06 01:20:24 +02:00
|
|
|
});
|