You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

144 lines
6.0 KiB

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 }