const bodyParser = require('body-parser'); import * as api from '../client/src/api'; import Knex from 'knex'; import { CreateSongEndpointHandler } from './endpoints/CreateSong'; import { CreateArtistEndpointHandler } from './endpoints/CreateArtist'; import { QueryEndpointHandler } from './endpoints/Query'; import { ArtistDetailsEndpointHandler } from './endpoints/ArtistDetails' import { SongDetailsEndpointHandler } from './endpoints/SongDetails'; import { ModifyArtistEndpointHandler } from './endpoints/ModifyArtist'; import { ModifySongEndpointHandler } from './endpoints/ModifySong'; import { CreateTagEndpointHandler } from './endpoints/CreateTag'; import { ModifyTagEndpointHandler } from './endpoints/ModifyTag'; import { TagDetailsEndpointHandler } from './endpoints/TagDetails'; import { CreateAlbumEndpointHandler } from './endpoints/CreateAlbum'; import { ModifyAlbumEndpointHandler } from './endpoints/ModifyAlbum'; import { AlbumDetailsEndpointHandler } from './endpoints/AlbumDetails'; import { DeleteTagEndpointHandler } from './endpoints/DeleteTag'; import { MergeTagEndpointHandler } from './endpoints/MergeTag'; import { RegisterUserEndpointHandler } from './endpoints/RegisterUser'; import * as endpointTypes from './endpoints/types'; import { sha512 } from 'js-sha512'; // 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); } })(); }); app.use(require('express-session')({ secret: 'EA9q5cukt7UFhN', resave: false, saveUninitialized: false })); 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 REST API endpoints app.post(apiBaseUrl + api.CreateSongEndpoint, checkLogin(), _invoke(CreateSongEndpointHandler)); app.post(apiBaseUrl + api.QueryEndpoint, checkLogin(), _invoke(QueryEndpointHandler)); app.post(apiBaseUrl + api.CreateArtistEndpoint, checkLogin(), _invoke(CreateArtistEndpointHandler)); app.put(apiBaseUrl + api.ModifyArtistEndpoint, checkLogin(), _invoke(ModifyArtistEndpointHandler)); app.put(apiBaseUrl + api.ModifySongEndpoint, checkLogin(), _invoke(ModifySongEndpointHandler)); app.get(apiBaseUrl + api.SongDetailsEndpoint, checkLogin(), _invoke(SongDetailsEndpointHandler)); app.get(apiBaseUrl + api.ArtistDetailsEndpoint, checkLogin(), _invoke(ArtistDetailsEndpointHandler)); app.post(apiBaseUrl + api.CreateTagEndpoint, checkLogin(), _invoke(CreateTagEndpointHandler)); app.put(apiBaseUrl + api.ModifyTagEndpoint, checkLogin(), _invoke(ModifyTagEndpointHandler)); app.get(apiBaseUrl + api.TagDetailsEndpoint, checkLogin(), _invoke(TagDetailsEndpointHandler)); app.post(apiBaseUrl + api.CreateAlbumEndpoint, checkLogin(), _invoke(CreateAlbumEndpointHandler)); app.put(apiBaseUrl + api.ModifyAlbumEndpoint, checkLogin(), _invoke(ModifyAlbumEndpointHandler)); app.get(apiBaseUrl + api.AlbumDetailsEndpoint, checkLogin(), _invoke(AlbumDetailsEndpointHandler)); app.delete(apiBaseUrl + api.DeleteTagEndpoint, checkLogin(), _invoke(DeleteTagEndpointHandler)); app.post(apiBaseUrl + api.MergeTagEndpoint, checkLogin(), _invoke(MergeTagEndpointHandler)); app.post(apiBaseUrl + api.RegisterUserEndpoint, _invoke(RegisterUserEndpointHandler)); app.post('/login', passport.authenticate('local'), (req: any, res: any) => { res.status(200).send({ userId: req.user.id }); }); app.post('/logout', function (req: any, res: any) { req.logout(); res.status(200).send(); }); } export { SetupApp }