|
|
@ -10,9 +10,12 @@ import sharedsession = require("express-socket.io-session");
|
|
|
|
import * as fsx from "fs-extra";
|
|
|
|
import * as fsx from "fs-extra";
|
|
|
|
import {buildSchema} from "graphql";
|
|
|
|
import {buildSchema} from "graphql";
|
|
|
|
import {importSchema} from "graphql-import";
|
|
|
|
import {importSchema} from "graphql-import";
|
|
|
|
|
|
|
|
import {IncomingMessage, ServerResponse} from "http";
|
|
|
|
import * as http from "http";
|
|
|
|
import * as http from "http";
|
|
|
|
import * as httpStatus from "http-status";
|
|
|
|
import * as httpStatus from "http-status";
|
|
|
|
import * as path from "path";
|
|
|
|
import * as path from "path";
|
|
|
|
|
|
|
|
import {RedisClient} from "redis";
|
|
|
|
|
|
|
|
import * as redis from "redis";
|
|
|
|
import {Sequelize} from "sequelize-typescript";
|
|
|
|
import {Sequelize} from "sequelize-typescript";
|
|
|
|
import * as socketIo from "socket.io";
|
|
|
|
import * as socketIo from "socket.io";
|
|
|
|
import * as socketIoRedis from "socket.io-redis";
|
|
|
|
import * as socketIoRedis from "socket.io-redis";
|
|
|
@ -23,6 +26,7 @@ import HomeRoute from "./routes/HomeRoute";
|
|
|
|
import {UploadRoute} from "./routes/UploadRoute";
|
|
|
|
import {UploadRoute} from "./routes/UploadRoute";
|
|
|
|
|
|
|
|
|
|
|
|
const SequelizeStore = require("connect-session-sequelize")(session.Store);
|
|
|
|
const SequelizeStore = require("connect-session-sequelize")(session.Store);
|
|
|
|
|
|
|
|
const createLimiter: (...args: any) => any = require("express-limiter");
|
|
|
|
const logger = globals.logger;
|
|
|
|
const logger = globals.logger;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -40,6 +44,16 @@ class App {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public io: socketIo.Server;
|
|
|
|
public io: socketIo.Server;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The instance of the redis client
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public redisClient: RedisClient;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The limiter for api requests
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public limiter: any;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* An instance of the http server where the site is served
|
|
|
|
* An instance of the http server where the site is served
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -63,6 +77,8 @@ class App {
|
|
|
|
constructor(id?: number) {
|
|
|
|
constructor(id?: number) {
|
|
|
|
this.id = id;
|
|
|
|
this.id = id;
|
|
|
|
this.app = express();
|
|
|
|
this.app = express();
|
|
|
|
|
|
|
|
this.redisClient = redis.createClient(null, null, {url: config.get("redis.connectionUri")});
|
|
|
|
|
|
|
|
this.limiter = createLimiter(this.app, this.redisClient);
|
|
|
|
this.server = new http.Server(this.app);
|
|
|
|
this.server = new http.Server(this.app);
|
|
|
|
this.io = socketIo(this.server);
|
|
|
|
this.io = socketIo(this.server);
|
|
|
|
this.sequelize = new Sequelize(config.get("database.connectionUri"));
|
|
|
|
this.sequelize = new Sequelize(config.get("database.connectionUri"));
|
|
|
@ -102,6 +118,7 @@ class App {
|
|
|
|
this.io.use(sharedsession(appSession, {autoSave: true}));
|
|
|
|
this.io.use(sharedsession(appSession, {autoSave: true}));
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("Configuring express app.");
|
|
|
|
logger.info("Configuring express app.");
|
|
|
|
|
|
|
|
this.server.setTimeout(config.get("server.timeout"));
|
|
|
|
this.app.set("views", path.join(__dirname, "views"));
|
|
|
|
this.app.set("views", path.join(__dirname, "views"));
|
|
|
|
this.app.set("view engine", "pug");
|
|
|
|
this.app.set("view engine", "pug");
|
|
|
|
this.app.set("trust proxy", 1);
|
|
|
|
this.app.set("trust proxy", 1);
|
|
|
@ -146,15 +163,37 @@ class App {
|
|
|
|
await homeRoute.init(this.io);
|
|
|
|
await homeRoute.init(this.io);
|
|
|
|
|
|
|
|
|
|
|
|
this.app.use("/home", homeRoute.router);
|
|
|
|
this.app.use("/home", homeRoute.router);
|
|
|
|
|
|
|
|
this.limiter({
|
|
|
|
|
|
|
|
expire: config.get("api.rateLimit.upload.expire"),
|
|
|
|
|
|
|
|
lookup: ["connection.remoteAddress"],
|
|
|
|
|
|
|
|
method: "all",
|
|
|
|
|
|
|
|
onRateLimited: (req: IncomingMessage, res: any) => {
|
|
|
|
|
|
|
|
res.status(httpStatus.TOO_MANY_REQUESTS);
|
|
|
|
|
|
|
|
res.json({error: "Rate Limit Exceeded"});
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
path: "/upload",
|
|
|
|
|
|
|
|
total: config.get("api.rateLimit.upload.total"),
|
|
|
|
|
|
|
|
});
|
|
|
|
this.app.use("/upload", uploadRoute.router);
|
|
|
|
this.app.use("/upload", uploadRoute.router);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// listen for graphql requests
|
|
|
|
// listen for graphql requests
|
|
|
|
|
|
|
|
this.limiter({
|
|
|
|
|
|
|
|
expire: config.get("api.rateLimit.graphql.expire"),
|
|
|
|
|
|
|
|
lookup: ["connection.remoteAddress"],
|
|
|
|
|
|
|
|
method: "all",
|
|
|
|
|
|
|
|
onRateLimited: (req: IncomingMessage, res: any) => {
|
|
|
|
|
|
|
|
res.status(httpStatus.TOO_MANY_REQUESTS);
|
|
|
|
|
|
|
|
res.json({errors: [{message: "Rate Limit Exceeded"}]});
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
path: "/graphql",
|
|
|
|
|
|
|
|
total: config.get("api.rateLimit.graphql.total"),
|
|
|
|
|
|
|
|
});
|
|
|
|
this.app.use("/graphql", graphqlHTTP((request, response) => {
|
|
|
|
this.app.use("/graphql", graphqlHTTP((request, response) => {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
// @ts-ignore all
|
|
|
|
// @ts-ignore all
|
|
|
|
context: {session: request.session},
|
|
|
|
context: {session: request.session},
|
|
|
|
graphiql: true,
|
|
|
|
graphiql: config.get("api.graphiql"),
|
|
|
|
rootValue: resolver(request, response),
|
|
|
|
rootValue: resolver(request, response),
|
|
|
|
schema: buildSchema(importSchema(path.join(__dirname, "./graphql/schema.graphql"))),
|
|
|
|
schema: buildSchema(importSchema(path.join(__dirname, "./graphql/schema.graphql"))),
|
|
|
|
};
|
|
|
|
};
|
|
|
|