Bump version to 0.0.14-beta + major web server updates
This commit is contained in:
@@ -945,8 +945,10 @@ module.exports = () => {
|
||||
],
|
||||
|
||||
web: {
|
||||
path: '/f/',
|
||||
routePath: '/f/[a-zA-Z0-9]+$',
|
||||
// if you change the /_f/ prefix here, ensure something
|
||||
// non-colliding with other routes is utilized
|
||||
path: '/_f/',
|
||||
routePath: '^/_f/[a-zA-Z0-9]+$',
|
||||
expireMinutes: 1440, // 1 day
|
||||
},
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ const fs = require('graceful-fs');
|
||||
const paths = require('path');
|
||||
const mimeTypes = require('mime-types');
|
||||
const forEachSeries = require('async/forEachSeries');
|
||||
const findSeries = require('async/findSeries');
|
||||
|
||||
const ModuleInfo = (exports.moduleInfo = {
|
||||
name: 'Web',
|
||||
@@ -74,14 +75,6 @@ exports.getModule = class WebServerModule extends ServerModule {
|
||||
this.enableHttps = config.contentServers.web.https.enabled || false;
|
||||
|
||||
this.routes = {};
|
||||
|
||||
if (this.isEnabled() && config.contentServers.web.staticRoot) {
|
||||
this.addRoute({
|
||||
method: 'GET',
|
||||
path: '/static/.*$',
|
||||
handler: this.routeStaticFile.bind(this),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
buildUrl(pathAndQuery) {
|
||||
@@ -210,13 +203,21 @@ exports.getModule = class WebServerModule extends ServerModule {
|
||||
}
|
||||
|
||||
routeRequest(req, resp) {
|
||||
const route = _.find(this.routes, r => r.matchesRequest(req));
|
||||
let route = _.find(this.routes, r => r.matchesRequest(req));
|
||||
|
||||
if (!route && '/' === req.url) {
|
||||
return this.routeIndex(req, resp);
|
||||
if (route) {
|
||||
return route.handler(req, resp);
|
||||
} else {
|
||||
this.tryStaticRoute(req, resp, wasHandled => {
|
||||
if (!wasHandled) {
|
||||
this.tryRouteIndex(req, resp, wasHandled => {
|
||||
if (!wasHandled) {
|
||||
return this.fileNotFound(resp);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return route ? route.handler(req, resp) : this.accessDenied(resp);
|
||||
}
|
||||
|
||||
respondWithError(resp, code, bodyText, title) {
|
||||
@@ -256,27 +257,57 @@ exports.getModule = class WebServerModule extends ServerModule {
|
||||
return this.respondWithError(resp, 404, 'File not found.', 'File Not Found');
|
||||
}
|
||||
|
||||
routeIndex(req, resp) {
|
||||
const filePath = paths.join(Config().contentServers.web.staticRoot, 'index.html');
|
||||
return this.returnStaticPage(filePath, resp);
|
||||
tryRouteIndex(req, resp, cb) {
|
||||
const tryFiles = Config().contentServers.web.tryFiles || [
|
||||
'index.html',
|
||||
'index.htm',
|
||||
];
|
||||
|
||||
findSeries(
|
||||
tryFiles,
|
||||
(tryFile, nextTryFile) => {
|
||||
const fileName = paths.join(
|
||||
req.url.substr(req.url.lastIndexOf('/', 1)),
|
||||
tryFile
|
||||
);
|
||||
const filePath = this.resolveStaticPath(fileName);
|
||||
|
||||
fs.stat(filePath, (err, stats) => {
|
||||
if (err || !stats.isFile()) {
|
||||
return nextTryFile(null, false);
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'Content-Type':
|
||||
mimeTypes.contentType(paths.basename(filePath)) ||
|
||||
mimeTypes.contentType('.bin'),
|
||||
'Content-Length': stats.size,
|
||||
};
|
||||
|
||||
const readStream = fs.createReadStream(filePath);
|
||||
resp.writeHead(200, headers);
|
||||
readStream.pipe(resp);
|
||||
|
||||
return nextTryFile(null, true);
|
||||
});
|
||||
},
|
||||
(_, wasHandled) => {
|
||||
return cb(wasHandled);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
routeStaticFile(req, resp) {
|
||||
const fileName = req.url.substr(req.url.indexOf('/', 1));
|
||||
tryStaticRoute(req, resp, cb) {
|
||||
const fileName = req.url.substr(req.url.lastIndexOf('/', 1));
|
||||
const filePath = this.resolveStaticPath(fileName);
|
||||
return this.returnStaticPage(filePath, resp);
|
||||
}
|
||||
|
||||
returnStaticPage(filePath, resp) {
|
||||
const self = this;
|
||||
|
||||
if (!filePath) {
|
||||
return this.fileNotFound(resp);
|
||||
return cb(false);
|
||||
}
|
||||
|
||||
fs.stat(filePath, (err, stats) => {
|
||||
if (err || !stats.isFile()) {
|
||||
return self.fileNotFound(resp);
|
||||
return cb(false);
|
||||
}
|
||||
|
||||
const headers = {
|
||||
@@ -288,7 +319,9 @@ exports.getModule = class WebServerModule extends ServerModule {
|
||||
|
||||
const readStream = fs.createReadStream(filePath);
|
||||
resp.writeHead(200, headers);
|
||||
return readStream.pipe(resp);
|
||||
readStream.pipe(resp);
|
||||
|
||||
return cb(true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ module.exports = class User2FA_OTPWebRegister {
|
||||
(token, textTemplate, htmlTemplate, callback) => {
|
||||
const webServer = getWebServer();
|
||||
const registerUrl = webServer.instance.buildUrl(
|
||||
`/enable_2fa_otp?token=${token}&otpType=${otpType}`
|
||||
`/_internal/enable_2fa_otp?token=${token}&otpType=${otpType}`
|
||||
);
|
||||
|
||||
const replaceTokens = s => {
|
||||
@@ -170,7 +170,7 @@ module.exports = class User2FA_OTPWebRegister {
|
||||
return User2FA_OTPWebRegister.accessDenied(webServer, resp);
|
||||
}
|
||||
|
||||
const postUrl = webServer.instance.buildUrl('/enable_2fa_otp');
|
||||
const postUrl = webServer.instance.buildUrl('/_internal/enable_2fa_otp');
|
||||
const config = Config();
|
||||
return webServer.instance.routeTemplateFilePage(
|
||||
_.get(config, 'users.twoFactorAuth.otp.registerPageTemplate'),
|
||||
@@ -296,12 +296,12 @@ ${backupCodes}
|
||||
[
|
||||
{
|
||||
method: 'GET',
|
||||
path: '^\\/enable_2fa_otp\\?token\\=[a-f0-9]+&otpType\\=[a-zA-Z0-9_]+$',
|
||||
path: /^\/_internal\/enable_2fa_otp\?token=[a-f0-9]+&otpType=[a-zA-Z0-9_]+$/,
|
||||
handler: User2FA_OTPWebRegister.routeRegisterGet,
|
||||
},
|
||||
{
|
||||
method: 'POST',
|
||||
path: '^\\/enable_2fa_otp$',
|
||||
path: /^\/_internal\/enable_2fa_otp$/,
|
||||
handler: User2FA_OTPWebRegister.routeRegisterPost,
|
||||
},
|
||||
].forEach(r => {
|
||||
|
||||
@@ -22,7 +22,7 @@ const _ = require('lodash');
|
||||
|
||||
const PW_RESET_EMAIL_TEXT_TEMPLATE_DEFAULT = `%USERNAME%:
|
||||
A password reset has been requested for your account on %BOARDNAME%.
|
||||
|
||||
|
||||
* If this was not you, please ignore this email.
|
||||
* Otherwise, follow this link: %RESET_URL%
|
||||
`;
|
||||
@@ -121,7 +121,7 @@ class WebPasswordReset {
|
||||
const sendMail = require('./email.js').sendMail;
|
||||
|
||||
const resetUrl = webServer.instance.buildUrl(
|
||||
`/reset_password?token=${
|
||||
`/_internal/reset_password?token=${
|
||||
user.properties[UserProps.EmailPwResetToken]
|
||||
}`
|
||||
);
|
||||
@@ -194,13 +194,13 @@ class WebPasswordReset {
|
||||
{
|
||||
// this is the page displayed to user when they GET it
|
||||
method: 'GET',
|
||||
path: '^\\/reset_password\\?token\\=[a-f0-9]+$', // Config.contentServers.web.forgotPasswordPageTemplate
|
||||
path: /^\/_internal\/reset_password\?token=[a-f0-9]+$/,
|
||||
handler: WebPasswordReset.routeResetPasswordGet,
|
||||
},
|
||||
// POST handler for performing the actual reset
|
||||
{
|
||||
method: 'POST',
|
||||
path: '^\\/reset_password$',
|
||||
path: /^\/_internal\/reset_password$/,
|
||||
handler: WebPasswordReset.routeResetPasswordPost,
|
||||
},
|
||||
].forEach(r => {
|
||||
@@ -269,7 +269,7 @@ class WebPasswordReset {
|
||||
);
|
||||
}
|
||||
|
||||
const postResetUrl = webServer.instance.buildUrl('/reset_password');
|
||||
const postResetUrl = webServer.instance.buildUrl('/_internal/reset_password');
|
||||
|
||||
const config = Config();
|
||||
return webServer.instance.routeTemplateFilePage(
|
||||
|
||||
Reference in New Issue
Block a user