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
2020-08-24 19:25:45 +02: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-07 06:17:45 +02: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-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-06-14 21:20:27 +02:00
fastify . register ( require ( './fastify-plugins/fastify-sequelize' ) , {
config : sequelizeConfig ,
registerModels : require ( './sequelize/models' ) ,
} ) ;
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###' ) ;
2020-06-14 21:20:27 +02:00
fastify . decorate ( 'canEmail' , false ) ;
2019-09-28 02:40:39 +02:00
} 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
2021-04-22 05:41:18 +02:00
fastify . addHook ( 'onRequest' , async ( request , reply ) => {
2019-09-28 01:10:43 +02:00
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-09-21 01:21:05 +02:00
request . language = typeof request . cookies . lang !== 'undefined' ? request . cookies . lang : 'en' ;
2021-04-15 23:27:57 +02:00
// Opt out of Google Chrome tracking everything you do.
// For more info, see: https://plausible.io/blog/google-floc
reply . header ( 'Permissions-Policy' , 'interest-cohort=()' ) ;
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 ) ;
}
2021-04-15 23:27:57 +02:00
} ) ;