const bodyParser = require('body-parser'); import * as api from '../client/src/api/api'; import Knex from 'knex'; import { importExportEndpoints } from './endpoints/ImportExport'; import { queryEndpoints } from './endpoints/Query'; import { artistEndpoints } from './endpoints/Artist'; import { albumEndpoints } from './endpoints/Album'; import { trackEndpoints } from './endpoints/Track'; import { tagEndpoints } from './endpoints/Tag'; import { integrationEndpoints } from './endpoints/Integration'; import { userEndpoints } from './endpoints/User'; import * as endpointTypes from './endpoints/types'; import { sha512 } from 'js-sha512'; import { createIntegrations } from './integrations/integrations'; // For authentication var passport = require('passport'); var Strategy = require('passport-local').Strategy; const invokeHandler = (handler: endpointTypes.EndpointHandler, knex: Knex) => { return async (req: any, res: any) => { console.log("Incoming", req.method, " @ ", req.url); await handler(req, res, knex) .catch(endpointTypes.handleErrorsInEndpoint) .catch((_e: endpointTypes.EndpointError) => { let e: endpointTypes.EndpointError = _e; console.log("Error handling request: ", e.message); res.sendStatus(e.httpStatus); }) console.log("Finished handling", req.method, "@", req.url); }; } const SetupApp = (app: any, knex: Knex, apiBaseUrl: string) => { app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // Set up auth. See: https://github.com/passport/express-4.x-local-example.git passport.use(new Strategy( function (email: string, password: string, cb: any) { (async () => { try { const user = await knex.select(['email', 'passwordHash', 'id']) .from('users') .where({ 'email': email }) .then((users: any) => users[0]); if (!user) { cb(null, false); } if (sha512(password) != user.passwordHash) { return cb(null, false); } return cb(null, user); } catch (error) { cb(error); } })(); })); passport.serializeUser(function (user: any, cb: any) { cb(null, user.id); }); passport.deserializeUser(function (id: number, cb: any) { (async () => { try { const user = await knex.select(['email', 'passwordHash', 'id']) .from('users') .where({ 'id': id }) .then((users: any) => users[0]); if (!user) { cb(null, false); } return cb(null, user); } catch (error) { cb(error); } })(); }); var session = require('express-session') var MemoryStore = require('memorystore')(session) app.use(session({ secret: 'EA9q5cukt7UFhN', resave: false, saveUninitialized: false, cookie: { maxAge: 86400000 }, //24h store: new MemoryStore({ checkPeriod: 86400000, //24h }), })); app.use(passport.initialize()); app.use(passport.session()); const _invoke = (handler: endpointTypes.EndpointHandler) => { return invokeHandler(handler, knex); } const checkLogin = () => { return function (req: any, res: any, next: any) { if (!req.isAuthenticated || !req.isAuthenticated()) { return res .status(401) .json({ reason: "NotLoggedIn" }) .send(); } next(); } } // Set up integration proxies app.use('/integrations', checkLogin(), createIntegrations(knex)); // Set up auth endpoints app.post(apiBaseUrl + api.LoginEndpoint, passport.authenticate('local'), (req: any, res: any) => { res.status(200).send({ userId: req.user.id }); }); app.post(apiBaseUrl + api.LogoutEndpoint, function (req: any, res: any) { req.logout(); res.status(200).send(); }); // Set up other endpoints [ albumEndpoints, artistEndpoints, tagEndpoints, trackEndpoints, integrationEndpoints, userEndpoints, queryEndpoints, importExportEndpoints, ].forEach((endpoints: [string, string, boolean, endpointTypes.EndpointHandler][]) => { endpoints.forEach((endpoint: [string, string, boolean, endpointTypes.EndpointHandler]) => { let [url, method, authenticated, handler] = endpoint; if (authenticated) { app[method](apiBaseUrl + url, checkLogin(), _invoke(handler)); } else { app[method](apiBaseUrl + url, _invoke(handler)); } }) }); } export { SetupApp }