mirror of https://github.com/calzoneman/sync.git
Web refactoring
This commit is contained in:
parent
566e932e7e
commit
50ca141f1d
1
index.js
1
index.js
|
@ -3,6 +3,7 @@ try {
|
|||
} catch (err) {
|
||||
console.error('FATAL: Failed to require() lib/server.js');
|
||||
console.error('Have you run `npm run build-server` yet to generate it?');
|
||||
console.error(err.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
var Config = require("./lib/config");
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import createError from 'create-error';
|
||||
import * as HTTPStatus from './web/httpstatus';
|
||||
|
||||
export const ChannelStateSizeError = createError('ChannelStateSizeError');
|
||||
export const ChannelNotFoundError = createError('ChannelNotFoundError');
|
||||
export const CSRFError = createError('CSRFError');
|
||||
export const HTTPError = createError('HTTPError', {
|
||||
status: HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
});
|
||||
|
|
|
@ -42,6 +42,9 @@ var $util = require("./utilities");
|
|||
var db = require("./database");
|
||||
var Flags = require("./flags");
|
||||
var sio = require("socket.io");
|
||||
import LocalChannelIndex from './web/localchannelindex';
|
||||
import IOConfiguration from './configuration/ioconfig';
|
||||
import NullClusterClient from './io/cluster/nullclusterclient';
|
||||
|
||||
var Server = function () {
|
||||
var self = this;
|
||||
|
@ -60,8 +63,14 @@ var Server = function () {
|
|||
ChannelStore.init();
|
||||
|
||||
// webserver init -----------------------------------------------------
|
||||
const ioConfig = IOConfiguration.fromOldConfig(Config);
|
||||
const clusterClient = new NullClusterClient(ioConfig);
|
||||
const channelIndex = new LocalChannelIndex();
|
||||
self.express = express();
|
||||
require("./web/webserver").init(self.express);
|
||||
require("./web/webserver").init(self.express,
|
||||
ioConfig,
|
||||
clusterClient,
|
||||
channelIndex);
|
||||
|
||||
// http/https/sio server init -----------------------------------------
|
||||
var key = "", cert = "", ca = undefined;
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
* Adapted from https://github.com/expressjs/csurf
|
||||
*/
|
||||
|
||||
import { CSRFError } from '../errors';
|
||||
|
||||
var csrf = require("csrf");
|
||||
var createError = require("http-errors");
|
||||
|
||||
var tokens = csrf();
|
||||
|
||||
|
@ -39,8 +40,6 @@ exports.verify = function csrfVerify(req) {
|
|||
var token = req.body._csrf || req.query._csrf;
|
||||
|
||||
if (!tokens.verify(secret, token)) {
|
||||
throw createError(403, 'invalid csrf token', {
|
||||
code: 'EBADCSRFTOKEN'
|
||||
});
|
||||
throw new CSRFError('Invalid CSRF token');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export const BAD_REQUEST = 400;
|
||||
export const FORBIDDEN = 403;
|
||||
export const INTERNAL_SERVER_ERROR = 500;
|
|
@ -0,0 +1,14 @@
|
|||
import Promise from 'bluebird';
|
||||
import Server from '../server';
|
||||
|
||||
var SERVER = null;
|
||||
|
||||
export default class LocalChannelIndex {
|
||||
listPublicChannels() {
|
||||
if (SERVER === null) {
|
||||
SERVER = require('../server').getServer();
|
||||
}
|
||||
|
||||
return Promise.resolve(SERVER.packChannelList(true));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import CyTubeUtil from '../../utilities';
|
||||
import { sanitizeText } from '../../xss';
|
||||
import { sendJade } from '../jade';
|
||||
import * as HTTPStatus from '../httpstatus';
|
||||
import { HTTPError } from '../../errors';
|
||||
|
||||
export default function initialize(app, ioConfig) {
|
||||
app.get('/r/:channel', (req, res) => {
|
||||
if (!req.params.channel || !CyTubeUtil.isValidChannelName(req.params.channel)) {
|
||||
throw new HTTPError(`"${sanitizeText(req.params.channel)} is not a valid ` +
|
||||
'channel name.', { status: HTTPStatus.BAD_REQUEST });
|
||||
}
|
||||
|
||||
const endpoints = ioConfig.getSocketEndpoints();
|
||||
if (endpoints.length === 0) {
|
||||
throw new HTTPError('No socket.io endpoints configured');
|
||||
}
|
||||
const socketBaseURL = endpoints[0].url;
|
||||
|
||||
sendJade(res, 'channel', {
|
||||
channelName: req.params.channel,
|
||||
sioSource: `${socketBaseURL}/socket.io/socket.io.js`
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { sendJade } from '../jade';
|
||||
|
||||
export default function initialize(app, channelIndex) {
|
||||
app.get('/', (req, res) => {
|
||||
channelIndex.listPublicChannels().then((channels) => {
|
||||
channels.sort((a, b) => {
|
||||
if (a.usercount === b.usercount) {
|
||||
return a.uniqueName > b.uniqueName ? -1 : 1;
|
||||
}
|
||||
|
||||
return b.usercount - a.usercount;
|
||||
});
|
||||
|
||||
sendJade(res, 'index', {
|
||||
channels: channels
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,16 +1,12 @@
|
|||
import IOConfiguration from '../../configuration/ioconfig';
|
||||
import NullClusterClient from '../../io/cluster/nullclusterclient';
|
||||
import Config from '../../config';
|
||||
import CyTubeUtil from '../../utilities';
|
||||
import Logger from '../../logger';
|
||||
import * as HTTPStatus from '../httpstatus';
|
||||
|
||||
export default function initialize(app) {
|
||||
const ioConfig = IOConfiguration.fromOldConfig(Config);
|
||||
const clusterClient = new NullClusterClient(ioConfig);
|
||||
|
||||
export default function initialize(app, clusterClient) {
|
||||
app.get('/socketconfig/:channel.json', (req, res) => {
|
||||
if (!req.params.channel || !CyTubeUtil.isValidChannelName(req.params.channel)) {
|
||||
return res.status(404).json({
|
||||
return res.status(HTTPStatus.NOT_FOUND).json({
|
||||
error: `Channel "${req.params.channel}" does not exist.`
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ var morgan = require("morgan");
|
|||
var session = require("../session");
|
||||
var csrf = require("./csrf");
|
||||
var XSS = require("../xss");
|
||||
import * as HTTPStatus from './httpstatus';
|
||||
import { CSRFError } from '../errors';
|
||||
|
||||
const LOG_FORMAT = ':real-address - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
|
||||
morgan.token('real-address', function (req) { return req._ip; });
|
||||
|
@ -71,51 +73,6 @@ function redirectHttp(req, res) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a GET request for /r/:channel - serves channel.html
|
||||
*/
|
||||
function handleChannel(req, res) {
|
||||
if (!$util.isValidChannelName(req.params.channel)) {
|
||||
res.status(404);
|
||||
res.send("Invalid channel name '" + XSS.sanitizeText(req.params.channel) + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
var sio;
|
||||
if (net.isIPv6(ipForRequest(req))) {
|
||||
sio = Config.get("io.ipv6-default");
|
||||
}
|
||||
|
||||
if (!sio) {
|
||||
sio = Config.get("io.ipv4-default");
|
||||
}
|
||||
|
||||
sio += "/socket.io/socket.io.js";
|
||||
|
||||
sendJade(res, "channel", {
|
||||
channelName: req.params.channel,
|
||||
sioSource: sio
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request for the index page
|
||||
*/
|
||||
function handleIndex(req, res) {
|
||||
var channels = Server.getServer().packChannelList(true);
|
||||
channels.sort(function (a, b) {
|
||||
if (a.usercount === b.usercount) {
|
||||
return a.uniqueName > b.uniqueName ? -1 : 1;
|
||||
}
|
||||
|
||||
return b.usercount - a.usercount;
|
||||
});
|
||||
|
||||
sendJade(res, "index", {
|
||||
channels: channels
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy socket.io configuration endpoint. This is being migrated to
|
||||
* /socketconfig/<channel name>.json (see ./routes/socketconfig.js)
|
||||
|
@ -185,7 +142,7 @@ module.exports = {
|
|||
/**
|
||||
* Initializes webserver callbacks
|
||||
*/
|
||||
init: function (app) {
|
||||
init: function (app, ioConfig, clusterClient, channelIndex) {
|
||||
app.use(function (req, res, next) {
|
||||
req._ip = ipForRequest(req);
|
||||
next();
|
||||
|
@ -241,10 +198,10 @@ module.exports = {
|
|||
Logger.syslog.log("Enabled express-minify for CSS and JS");
|
||||
}
|
||||
|
||||
app.get("/r/:channel", handleChannel);
|
||||
app.get("/", handleIndex);
|
||||
require("./routes/channel")(app, ioConfig);
|
||||
require("./routes/index")(app, channelIndex);
|
||||
app.get("/sioconfig(.json)?", handleSocketConfig);
|
||||
require("./routes/socketconfig")(app);
|
||||
require("./routes/socketconfig")(app, clusterClient);
|
||||
app.get("/useragreement", handleUserAgreement);
|
||||
app.get("/contact", handleContactPage);
|
||||
require("./auth").init(app);
|
||||
|
@ -256,21 +213,24 @@ module.exports = {
|
|||
}));
|
||||
app.use(function (err, req, res, next) {
|
||||
if (err) {
|
||||
if (err.message && err.message.match(/failed to decode param/i)) {
|
||||
return res.status(400).send("Malformed path: " + req.path);
|
||||
} else if (err.message && err.message.match(/range not satisfiable/i)) {
|
||||
return res.status(416).end();
|
||||
} else if (err.message && err.message.match(/request entity too large/i)) {
|
||||
return res.status(413).end();
|
||||
} else if (err.message && err.message.match(/bad request/i)) {
|
||||
return res.status(400).end("Bad Request");
|
||||
} else if (err.message && err.message.match(/invalid csrf token/i)) {
|
||||
res.status(403);
|
||||
sendJade(res, 'csrferror', { path: req.path });
|
||||
return;
|
||||
if (err instanceof CSRFError) {
|
||||
res.status(HTTPStatus.FORBIDDEN);
|
||||
return sendJade(res, 'csrferror', { path: req.path });
|
||||
}
|
||||
Logger.errlog.log(err.stack);
|
||||
res.status(500).end();
|
||||
|
||||
let { message, status } = err;
|
||||
if (!status) {
|
||||
status = HTTPStatus.INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (!message) {
|
||||
message = 'An unknown error occurred.';
|
||||
}
|
||||
|
||||
if (Math.floor(status / 100) === 5) {
|
||||
Logger.errlog.log(err.stack);
|
||||
}
|
||||
|
||||
return res.status(status).send(message);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue