2020-12-01 20:16:51 +01:00
|
|
|
const config = require('./config')
|
|
|
|
|
|
|
|
global.client_id_b64 = Buffer.from(`${config.reddit_app_id}:`).toString('base64')
|
2020-12-01 20:20:01 +01:00
|
|
|
global.reddit_access_token = null
|
|
|
|
global.reddit_refresh_token = null
|
2020-11-17 21:44:32 +01:00
|
|
|
|
|
|
|
const pug = require('pug')
|
|
|
|
const path = require('path')
|
|
|
|
const compression = require('compression')
|
|
|
|
const express = require('express')
|
2020-11-21 13:50:12 +01:00
|
|
|
const cookieParser = require('cookie-parser')
|
2020-11-17 21:44:32 +01:00
|
|
|
const r = require('redis')
|
2020-12-05 21:48:15 +01:00
|
|
|
|
2020-12-06 03:54:38 +01:00
|
|
|
const redis = (() => {
|
|
|
|
if (!config.redis_enabled) {
|
|
|
|
// Stub Redis if disabled
|
|
|
|
return {
|
|
|
|
get: (_, callback) => callback(null, null),
|
|
|
|
setex: (_, _1, _2, callback) => callback(null),
|
|
|
|
on: () => {}
|
|
|
|
}
|
|
|
|
}
|
2020-12-05 21:48:15 +01:00
|
|
|
|
2020-12-06 03:54:38 +01:00
|
|
|
const redisOptions = {
|
|
|
|
host: '127.0.0.1',
|
|
|
|
port: 6379
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.redis_host) {
|
|
|
|
redisOptions.host = config.redis_host
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.redis_port && config.redis_port > 0) {
|
|
|
|
redisOptions.port = config.redis_port
|
|
|
|
}
|
2020-12-05 21:48:15 +01:00
|
|
|
|
2020-12-06 03:54:38 +01:00
|
|
|
return r.createClient(redisOptions)
|
|
|
|
})()
|
2020-11-17 21:44:32 +01:00
|
|
|
const helmet = require('helmet')
|
|
|
|
const bodyParser = require('body-parser')
|
|
|
|
const fetch = require('node-fetch')
|
|
|
|
const fs = require('fs')
|
|
|
|
const app = express()
|
|
|
|
const request = require('postman-request')
|
|
|
|
const commons = require('./inc/commons.js')(request, fs)
|
|
|
|
const dlAndSave = require('./inc/downloadAndSave.js')(commons)
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(!config.https_enabled && config.redirect_http_to_https) {
|
2020-11-17 21:44:32 +01:00
|
|
|
console.error(`Cannot redirect HTTP=>HTTPS while "https_enabled" is false.`)
|
|
|
|
}
|
|
|
|
|
|
|
|
let https = null
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.https_enabled) {
|
|
|
|
const privateKey = fs.readFileSync(`${config.cert_dir}/privkey.pem`, 'utf8')
|
|
|
|
const certificate = fs.readFileSync(`${config.cert_dir}/cert.pem`, 'utf8')
|
|
|
|
const ca = fs.readFileSync(`${config.cert_dir}/chain.pem`, 'utf8')
|
2020-11-17 21:44:32 +01:00
|
|
|
const credentials = {
|
|
|
|
key: privateKey,
|
|
|
|
cert: certificate,
|
|
|
|
ca: ca
|
|
|
|
}
|
|
|
|
https = require('https').Server(credentials, app)
|
|
|
|
global.protocol = 'https://'
|
|
|
|
} else {
|
|
|
|
global.protocol = 'http://'
|
|
|
|
}
|
|
|
|
|
|
|
|
const http = require('http').Server(app)
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.redirect_www) {
|
2020-11-25 19:17:35 +01:00
|
|
|
app.use((req, res, next) => {
|
|
|
|
if(req.headers.host) {
|
|
|
|
if(req.headers.host.slice(0, 4) === 'www.') {
|
|
|
|
let newhost = req.headers.host.slice(4)
|
2020-11-28 17:37:18 +01:00
|
|
|
return res.redirect(301, `${req.protocol}://${newhost}${req.originalUrl}`)
|
2020-11-25 19:17:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
next()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.use_helmet && config.https_enabled) {
|
2020-11-17 21:44:32 +01:00
|
|
|
app.use(helmet())
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.use_helmet_hsts) {
|
2020-11-17 21:44:32 +01:00
|
|
|
app.use(helmet.hsts({ maxAge: 31536000, preload: true }))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.use_compression) {
|
2020-11-17 21:44:32 +01:00
|
|
|
app.use(compression())
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:50:12 +01:00
|
|
|
app.use(cookieParser())
|
|
|
|
|
2020-12-24 22:13:08 +01:00
|
|
|
const preferencesMiddleware = (req, res, next) => {
|
2020-12-13 02:26:01 +01:00
|
|
|
let themeOverride = req.query.theme
|
2020-12-24 22:13:08 +01:00
|
|
|
if(themeOverride) {
|
2020-12-13 02:26:01 +01:00
|
|
|
// Convert Dark to dark since the stylesheet has it lower case
|
2020-12-24 22:13:08 +01:00
|
|
|
themeOverride = themeOverride.toLowerCase()
|
2020-12-13 02:26:01 +01:00
|
|
|
// This override here will set it for the current request
|
|
|
|
req.cookies.theme = themeOverride
|
|
|
|
// this will set it for future requests
|
2020-12-24 22:13:08 +01:00
|
|
|
res.cookie('theme', themeOverride, { maxAge: 31536000, httpOnly: true })
|
2021-01-01 17:15:11 +01:00
|
|
|
} else if(!req.cookies.theme && req.cookies.theme !== '') {
|
|
|
|
req.cookies.theme = config.theme
|
2020-12-13 02:26:01 +01:00
|
|
|
}
|
2020-12-24 22:13:08 +01:00
|
|
|
|
|
|
|
let flairsOverride = req.query.flairs
|
|
|
|
if(flairsOverride) {
|
|
|
|
req.cookies.flairs = flairsOverride
|
|
|
|
res.cookie('flairs', flairsOverride, { maxAge: 31536000, httpOnly: true })
|
|
|
|
}
|
|
|
|
|
2020-12-27 23:25:39 +01:00
|
|
|
let nsfwEnabledOverride = req.query.nsfw_enabled
|
|
|
|
if(nsfwEnabledOverride) {
|
|
|
|
req.cookies.nsfw_enabled = nsfwEnabledOverride
|
|
|
|
res.cookie('nsfw_enabled', nsfwEnabledOverride, { maxAge: 31536000, httpOnly: true })
|
|
|
|
}
|
2021-01-04 22:50:47 +01:00
|
|
|
|
|
|
|
let highlightControversialOverride = req.query.highlight_controversial
|
|
|
|
if(highlightControversialOverride) {
|
|
|
|
req.cookies.highlight_controversial = highlightControversialOverride
|
|
|
|
res.cookie('highlight_controversial', highlightControversialOverride, { maxAge: 31536000, httpOnly: true })
|
|
|
|
}
|
2020-12-27 23:25:39 +01:00
|
|
|
|
2021-03-01 19:01:02 +01:00
|
|
|
let postMediaMaxHeight = req.query.post_media_max_height
|
|
|
|
if(postMediaMaxHeight) {
|
|
|
|
if(config.post_media_max_heights.hasOwnProperty(postMediaMaxHeight) || !isNaN(postMediaMaxHeight)) {
|
|
|
|
req.cookies.post_media_max_height = postMediaMaxHeight
|
|
|
|
res.cookie('post_media_max_height', postMediaMaxHeight, { maxAge: 31536000, httpOnly: true })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 18:07:27 +01:00
|
|
|
let collapseChildComments = req.query.collapse_child_comments
|
|
|
|
if(collapseChildComments) {
|
|
|
|
req.cookies.collapse_child_comments = collapseChildComments
|
|
|
|
res.cookie('collapse_child_comments', collapseChildComments, { maxAge: 31536000, httpOnly: true })
|
|
|
|
}
|
|
|
|
|
2020-12-24 22:13:08 +01:00
|
|
|
next()
|
2020-12-13 02:26:01 +01:00
|
|
|
}
|
|
|
|
|
2020-12-24 22:13:08 +01:00
|
|
|
app.use(preferencesMiddleware)
|
2020-12-13 02:26:01 +01:00
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.use_view_cache) {
|
2020-11-17 21:44:32 +01:00
|
|
|
app.set('view cache', true)
|
|
|
|
}
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.trust_proxy) {
|
2020-12-05 11:41:49 +01:00
|
|
|
app.set('trust proxy', config.trust_proxy_address)
|
2020-11-17 21:44:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
app.use(bodyParser.urlencoded({ extended: true }))
|
|
|
|
app.use(bodyParser.json())
|
2020-12-25 22:14:24 +01:00
|
|
|
app.use(express.static(`${__dirname}/static`))
|
2020-11-17 21:44:32 +01:00
|
|
|
|
|
|
|
app.set('views', './views')
|
|
|
|
app.set('view engine', 'pug')
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.redirect_http_to_https) {
|
2020-11-17 21:44:32 +01:00
|
|
|
app.use((req, res, next) => {
|
|
|
|
if(req.secure)
|
|
|
|
next()
|
|
|
|
else
|
|
|
|
res.redirect(`https://${req.headers.host}${req.url}`)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
const redditAPI = require('./inc/initRedditApi.js')(fetch)
|
|
|
|
require('./routes')(app, redis, fetch, redditAPI)
|
|
|
|
|
|
|
|
redis.on('error', (error) => {
|
|
|
|
if(error) {
|
|
|
|
console.error(`Redis error: ${error}`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-12-01 20:16:51 +01:00
|
|
|
if(config.https_enabled) {
|
2020-12-05 23:39:23 +01:00
|
|
|
https.listen(config.ssl_port, '::', () => console.log(`Teddit running on https://${config.domain}:${config.ssl_port}`))
|
2020-11-17 21:44:32 +01:00
|
|
|
}
|
2020-12-05 23:39:23 +01:00
|
|
|
http.listen(config.nonssl_port, '::', () => console.log(`Teddit running on http://${config.domain}:${config.nonssl_port}`))
|