traxxx/src/web/server.js

173 lines
4.7 KiB
JavaScript

'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 pg = 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(pg);
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;