const bodyParser = require('body-parser'); import * as api from '../client/src/api'; import Knex from 'knex'; import { Query } from './endpoints/Query'; import { PostArtist, PutArtist, GetArtist } from './endpoints/Artist'; import { PostAlbum, PutAlbum, GetAlbum } from './endpoints/Album'; import { PostSong, PutSong, GetSong } from './endpoints/Song'; import { PostTag, PutTag, GetTag, DeleteTag, MergeTag } from './endpoints/Tag'; import { PostIntegration, PutIntegration, GetIntegration, DeleteIntegration, ListIntegrations } from './endpoints/Integration'; import { RegisterUser } from './endpoints/RegisterUser'; 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.catchUnhandledErrors) .catch((_e: endpointTypes.EndpointError) => { let e: endpointTypes.EndpointError = _e; console.log("Error handling request: ", e.internalMessage); 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 REST API endpoints app.post(apiBaseUrl + api.CreateSongEndpoint, checkLogin(), _invoke(PostSong)); app.put(apiBaseUrl + api.ModifySongEndpoint, checkLogin(), _invoke(PutSong)); app.get(apiBaseUrl + api.SongDetailsEndpoint, checkLogin(), _invoke(GetSong)); app.post(apiBaseUrl + api.QueryEndpoint, checkLogin(), _invoke(Query)); app.post(apiBaseUrl + api.CreateArtistEndpoint, checkLogin(), _invoke(PostArtist)); app.put(apiBaseUrl + api.ModifyArtistEndpoint, checkLogin(), _invoke(PutArtist)); app.get(apiBaseUrl + api.ArtistDetailsEndpoint, checkLogin(), _invoke(GetArtist)); app.post(apiBaseUrl + api.CreateAlbumEndpoint, checkLogin(), _invoke(PostAlbum)); app.put(apiBaseUrl + api.ModifyAlbumEndpoint, checkLogin(), _invoke(PutAlbum)); app.get(apiBaseUrl + api.AlbumDetailsEndpoint, checkLogin(), _invoke(GetAlbum)); app.post(apiBaseUrl + api.CreateTagEndpoint, checkLogin(), _invoke(PostTag)); app.put(apiBaseUrl + api.ModifyTagEndpoint, checkLogin(), _invoke(PutTag)); app.get(apiBaseUrl + api.TagDetailsEndpoint, checkLogin(), _invoke(GetTag)); app.delete(apiBaseUrl + api.DeleteTagEndpoint, checkLogin(), _invoke(DeleteTag)); app.post(apiBaseUrl + api.MergeTagEndpoint, checkLogin(), _invoke(MergeTag)); app.post(apiBaseUrl + api.CreateIntegrationEndpoint, checkLogin(), _invoke(PostIntegration)); app.put(apiBaseUrl + api.ModifyIntegrationEndpoint, checkLogin(), _invoke(PutIntegration)); app.get(apiBaseUrl + api.IntegrationDetailsEndpoint, checkLogin(), _invoke(GetIntegration)); app.delete(apiBaseUrl + api.DeleteIntegrationEndpoint, checkLogin(), _invoke(DeleteIntegration)); app.get(apiBaseUrl + api.ListIntegrationsEndpoint, checkLogin(), _invoke(ListIntegrations)); app.post(apiBaseUrl + api.RegisterUserEndpoint, _invoke(RegisterUser)); 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(); }); } export { SetupApp }