'use strict'; const path = require('path'); const config = require('config'); const express = require('express'); const Router = require('express-promise-router'); const bodyParser = require('body-parser'); const session = require('express-session'); const KnexSessionStore = require('connect-session-knex')(session); const { nanoid } = require('nanoid'); const logger = require('../logger')(__filename); const knex = require('../knex'); const errorHandler = require('./error'); const initPg = require('./postgraphile'); const { login, logout, signup, fetchMe, } = require('./auth'); const { fetchScene, fetchScenes, fetchScenePoster, } = require('./releases'); const { fetchActor, fetchActors, } = require('./actors'); const { fetchEntity, fetchEntities, } = require('./entities'); const { fetchTag, fetchTags, } = require('./tags'); const { createStash, removeStash, stashActor, stashScene, stashMovie, unstashActor, unstashScene, unstashMovie, updateStash, } = require('./stashes'); const { addAlert, removeAlert, updateNotifications, updateNotification, } = require('./alerts'); function getIp(req) { return req.headers['x-forwarded-for'] ? req.headers['x-forwarded-for'].split(',')[0] : req.connection.remoteAddress; // See src/ws } async function initServer() { const app = express(); const router = Router(); const store = new KnexSessionStore({ knex }); app.set('view engine', 'ejs'); router.use('/media', express.static(config.media.path)); router.use(express.static('public')); router.use('/img', (req, res) => { res.status(404).send(); }); router.use(bodyParser.json({ strict: false })); router.use(session({ ...config.web.session, store })); router.use(initPg(config.database.query)); router.use((req, res, next) => { req.session.safeId = req.session.safeId || nanoid(); next(); }); router.use((req, res, next) => { const ip = getIp(req); logger.silly(`${ip} (${req.headers['CF-IPCountry'] || 'country N/A'}) requested ${req.originalUrl} as ${req.session.user ? `${req.session.user.username} (${req.session.user.id})` : 'guest'}`); next(); }); router.get('/api/session', fetchMe); router.post('/api/session', login); router.delete('/api/session', logout); router.post('/api/users', signup); router.patch('/api/users/:userId/notifications', updateNotifications); router.patch('/api/users/:userId/notifications/:notificationId', updateNotification); router.post('/api/stashes', createStash); router.patch('/api/stashes/:stashId', updateStash); router.delete('/api/stashes/:stashId', removeStash); router.post('/api/stashes/:stashId/actors', stashActor); router.post('/api/stashes/:stashId/scenes', stashScene); router.post('/api/stashes/:stashId/movies', stashMovie); router.delete('/api/stashes/:stashId/actors/:actorId', unstashActor); router.delete('/api/stashes/:stashId/scenes/:sceneId', unstashScene); router.delete('/api/stashes/:stashId/movies/:movieId', unstashMovie); router.post('/api/alerts', addAlert); router.delete('/api/alerts/:alertId', removeAlert); router.get('/api/scenes', fetchScenes); router.get('/api/scenes/:releaseId', fetchScene); router.get('/api/scenes/:releaseId/poster', fetchScenePoster); // router.get('/api/movies', fetchMovies); // router.get('/api/movies/:releaseId', fetchMovie); router.get('/api/actors', fetchActors); router.get('/api/actors/:actorId', fetchActor); router.get('/api/entities', async (req, res) => fetchEntities(req, res, null)); router.get('/api/entities/:entityId', async (req, res) => fetchEntity(req, res, null)); router.get('/api/channels', async (req, res) => fetchEntities(req, res, 'channel')); router.get('/api/channels/:entityId', async (req, res) => fetchEntity(req, res, 'channel')); router.get('/api/networks', async (req, res) => fetchEntities(req, res, 'network')); router.get('/api/networks/:entityId', async (req, res) => fetchEntity(req, res, 'network')); router.get('/api/studios', async (req, res) => fetchEntities(req, res, 'studio')); router.get('/api/studios/:entityId', async (req, res) => fetchEntity(req, res, 'studio')); router.get('/api/tags', fetchTags); router.get('/api/tags/:tagId', fetchTag); router.get('*', (req, res) => { res.render(path.join(__dirname, '../../assets/index.ejs'), { env: JSON.stringify({ sfw: !!req.headers.sfw || Object.prototype.hasOwnProperty.call(req.query, 'sfw'), login: config.auth.login, signup: config.auth.signup, sessionId: req.session.safeId, }), }); }); router.use(errorHandler); app.use(router); const server = app.listen(config.web.port, config.web.host, () => { const { address, port } = server.address(); logger.info(`Web server listening on ${address}:${port}`); }); } module.exports = initServer;