2019-09-05 17:20:24 -06:00
'use strict'
require ( 'make-promises-safe' ) ; // installs an 'unhandledRejection' handler
const path = require ( 'path' ) ;
2019-09-06 18:23:55 -06:00
let siteConfig ;
try {
2019-09-08 21:54:43 -06:00
siteConfig = require ( './config.json' ) ;
2019-09-06 18:23:55 -06: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-05 17:20:24 -06:00
const fastify = require ( 'fastify' ) ( {
2019-09-06 18:12:56 -06:00
logger : process . env . NODE _ENV !== 'production' ,
2019-09-05 17:20:24 -06:00
} ) ;
2019-09-06 22:17:45 -06:00
fastify . decorate ( 'siteConfig' , siteConfig ) ; // Insert siteConfig into global fastify instance
2020-08-24 11:25:45 -06:00
fastify . register ( require ( 'fastify-helmet' ) , { // Add security stuff
contentSecurityPolicy : { // Modify Content Security Policy headers to allow content from specific domains
directives : {
'default-src' : [ "'self'" ] , // Default value
'base-uri' : [ "'self'" ] , // Default value
'block-all-mixed-content' : [ ] , // Default value
'frame-ancestors' : [ "'self'" ] , // Default value
'style-src' : [ "'self'" , "https: 'unsafe-inline'" ] , // Default value
'upgrade-insecure-requests' : [ ] , // Default value
'object-src' : [ "'none'" ] , // Default value
'script-src' : [ "'self'" , 'polyfill.io' , "https: 'unsafe-inline'" ] , // Allow loading scripts inline (required for Choo) and from polyfill.io
'img-src' : [ "'self'" , siteConfig . inventaireDomain , 'openlibrary.org' , 'covers.openlibrary.org' , "data:" ] , // Allow images from Inventaire, Open Library, and raw `data:` hashes
}
}
} ) ;
2019-09-06 22:17:45 -06:00
fastify . register ( require ( 'fastify-compress' ) ) ; // Compress output data for smaller packet delivery
fastify . register ( require ( 'fastify-static' ) , { // Enable delivering static content efficiently
2019-09-08 21:54:43 -06:00
root : path . resolve ( _ _dirname , '../public' ) , // all static content will be delivered from the public/ folder
2019-09-05 17:20:24 -06:00
} ) ;
2019-09-06 22:17:45 -06: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-18 17:15:06 -06: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 13:04:17 -06:00
? path . resolve ( _ _dirname , fastify . siteConfig . sqlite _location )
2019-09-18 17:15:06 -06: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-06-14 13:20:27 -06:00
fastify . register ( require ( './fastify-plugins/fastify-sequelize' ) , {
config : sequelizeConfig ,
registerModels : require ( './sequelize/models' ) ,
} ) ;
2019-09-06 22:17:45 -06:00
2019-09-27 18:40:39 -06: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###' ) ;
2020-06-14 13:20:27 -06:00
fastify . decorate ( 'canEmail' , false ) ;
2019-09-27 18:40:39 -06:00
} else {
2020-01-04 19:11:57 -07:00
fastify . register ( require ( './fastify-plugins/fastify-nodemailer' ) , {
2019-09-27 18:40:39 -06: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-06 22:17:45 -06:00
// Every request, check to see if a valid token exists
2019-09-27 17:10:43 -06: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 ;
}
}
2020-02-24 11:29:07 -07:00
if ( typeof request . cookies . lang !== 'undefined' ) {
request . language = request . cookies . lang ;
}
2019-09-06 22:17:45 -06:00
} ) ;
2019-09-05 17:20:24 -06:00
2019-10-27 12:48:28 -06:00
// Store i18n files in fastify object and register locales routes
fastify . register ( require ( './i18n' ) ) ;
2019-09-06 18:23:55 -06:00
2019-09-05 17:20:24 -06:00
// Routes
2019-09-08 21:56:16 -06:00
fastify . register ( require ( './routes/public' ) ) ;
2019-09-12 17:04:50 -06:00
fastify . register ( require ( './routes/books' ) ) ;
2019-09-17 15:10:46 -06:00
fastify . register ( require ( './routes/account' ) ) ;
2019-12-01 15:31:34 -07:00
fastify . register ( require ( './routes/shelf' ) ) ;
2019-09-09 14:19:22 -06:00
fastify . register ( require ( './routes/search' ) ) ;
2019-09-05 17:20:24 -06:00
// Start the server
2019-09-06 18:23:55 -06:00
fastify . listen ( fastify . siteConfig . port , function ( err , address ) {
2019-09-05 17:20:24 -06:00
if ( err ) {
fastify . log . error ( err ) ;
process . exit ( 1 ) ;
}
} ) ;