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.
 
 
 
 

137 lines
4.9 KiB

const bodyParser = require('body-parser');
import * as api from '../client/src/api/api';
import Knex from 'knex';
import { DataEndpoints } from './endpoints/Data';
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({ limit: "10mb" }));
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(apiBaseUrl + '/integrations', checkLogin(), createIntegrations(knex, apiBaseUrl));
// 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,
DataEndpoints,
].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 }