mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-21 07:56:16 -04:00
lint: Run eslint --fix
on src/
This commit is contained in:
parent
b8d07a42eb
commit
8e5fd19db2
109 changed files with 9061 additions and 10572 deletions
|
@ -18,7 +18,7 @@ let serverName;
|
|||
exports.server = null;
|
||||
|
||||
exports.createServer = async () => {
|
||||
console.log("Report bugs at https://github.com/ether/etherpad-lite/issues")
|
||||
console.log('Report bugs at https://github.com/ether/etherpad-lite/issues');
|
||||
|
||||
serverName = `Etherpad ${settings.getGitCommit()} (https://etherpad.org)`;
|
||||
|
||||
|
@ -26,7 +26,7 @@ exports.createServer = async () => {
|
|||
|
||||
await exports.restartServer();
|
||||
|
||||
if (settings.ip === "") {
|
||||
if (settings.ip === '') {
|
||||
// using Unix socket for connectivity
|
||||
console.log(`You can access your Etherpad instance using the Unix socket at ${settings.port}`);
|
||||
} else {
|
||||
|
@ -42,26 +42,26 @@ exports.createServer = async () => {
|
|||
const env = process.env.NODE_ENV || 'development';
|
||||
|
||||
if (env !== 'production') {
|
||||
console.warn("Etherpad is running in Development mode. This mode is slower for users and less secure than production mode. You should set the NODE_ENV environment variable to production by using: export NODE_ENV=production");
|
||||
console.warn('Etherpad is running in Development mode. This mode is slower for users and less secure than production mode. You should set the NODE_ENV environment variable to production by using: export NODE_ENV=production');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.restartServer = async () => {
|
||||
if (exports.server) {
|
||||
console.log("Restarting express server");
|
||||
console.log('Restarting express server');
|
||||
await util.promisify(exports.server.close).bind(exports.server)();
|
||||
}
|
||||
|
||||
const app = express(); // New syntax for express v3
|
||||
|
||||
if (settings.ssl) {
|
||||
console.log("SSL -- enabled");
|
||||
console.log('SSL -- enabled');
|
||||
console.log(`SSL -- server key file: ${settings.ssl.key}`);
|
||||
console.log(`SSL -- Certificate Authority's certificate file: ${settings.ssl.cert}`);
|
||||
|
||||
const options = {
|
||||
key: fs.readFileSync( settings.ssl.key ),
|
||||
cert: fs.readFileSync( settings.ssl.cert )
|
||||
key: fs.readFileSync(settings.ssl.key),
|
||||
cert: fs.readFileSync(settings.ssl.cert),
|
||||
};
|
||||
|
||||
if (settings.ssl.ca) {
|
||||
|
@ -79,16 +79,16 @@ exports.restartServer = async () => {
|
|||
exports.server = http.createServer(app);
|
||||
}
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
app.use((req, res, next) => {
|
||||
// res.header("X-Frame-Options", "deny"); // breaks embedded pads
|
||||
if (settings.ssl) {
|
||||
// we use SSL
|
||||
res.header("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
|
||||
res.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
||||
}
|
||||
|
||||
// Stop IE going into compatability mode
|
||||
// https://github.com/ether/etherpad-lite/issues/2547
|
||||
res.header("X-UA-Compatible", "IE=Edge,chrome=1");
|
||||
res.header('X-UA-Compatible', 'IE=Edge,chrome=1');
|
||||
|
||||
// Enable a strong referrer policy. Same-origin won't drop Referers when
|
||||
// loading local resources, but it will drop them when loading foreign resources.
|
||||
|
@ -97,11 +97,11 @@ exports.restartServer = async () => {
|
|||
// marked with <meta name="referrer" content="no-referrer">
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
||||
// https://github.com/ether/etherpad-lite/pull/3636
|
||||
res.header("Referrer-Policy", "same-origin");
|
||||
res.header('Referrer-Policy', 'same-origin');
|
||||
|
||||
// send git version in the Server response header if exposeVersion is true.
|
||||
if (settings.exposeVersion) {
|
||||
res.header("Server", serverName);
|
||||
res.header('Server', serverName);
|
||||
}
|
||||
|
||||
next();
|
||||
|
@ -165,13 +165,13 @@ exports.restartServer = async () => {
|
|||
//
|
||||
// reference: https://github.com/expressjs/session/blob/v1.17.0/README.md#cookiesecure
|
||||
secure: 'auto',
|
||||
}
|
||||
},
|
||||
});
|
||||
app.use(exports.sessionMiddleware);
|
||||
|
||||
app.use(cookieParser(settings.sessionKey, {}));
|
||||
|
||||
hooks.callAll("expressConfigure", {"app": app});
|
||||
hooks.callAll('expressConfigure', {app});
|
||||
hooks.callAll('expressCreateServer', {app, server: exports.server});
|
||||
|
||||
await util.promisify(exports.server.listen).bind(exports.server)(settings.port, settings.ip);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
var eejs = require('ep_etherpad-lite/node/eejs');
|
||||
const eejs = require('ep_etherpad-lite/node/eejs');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
args.app.get('/admin', function(req, res) {
|
||||
if('/' != req.path[req.path.length-1]) return res.redirect('./admin/');
|
||||
args.app.get('/admin', (req, res) => {
|
||||
if ('/' != req.path[req.path.length - 1]) return res.redirect('./admin/');
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/admin/index.html', {req}));
|
||||
});
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
var eejs = require('ep_etherpad-lite/node/eejs');
|
||||
var settings = require('ep_etherpad-lite/node/utils/Settings');
|
||||
var installer = require('ep_etherpad-lite/static/js/pluginfw/installer');
|
||||
var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs');
|
||||
var _ = require('underscore');
|
||||
var semver = require('semver');
|
||||
const eejs = require('ep_etherpad-lite/node/eejs');
|
||||
const settings = require('ep_etherpad-lite/node/utils/Settings');
|
||||
const installer = require('ep_etherpad-lite/static/js/pluginfw/installer');
|
||||
const plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs');
|
||||
const _ = require('underscore');
|
||||
const semver = require('semver');
|
||||
const UpdateCheck = require('ep_etherpad-lite/node/utils/UpdateCheck');
|
||||
|
||||
exports.expressCreateServer = function(hook_name, args, cb) {
|
||||
args.app.get('/admin/plugins', function(req, res) {
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
args.app.get('/admin/plugins', (req, res) => {
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/admin/plugins.html', {
|
||||
plugins: plugins.plugins,
|
||||
req,
|
||||
|
@ -16,114 +16,108 @@ exports.expressCreateServer = function(hook_name, args, cb) {
|
|||
}));
|
||||
});
|
||||
|
||||
args.app.get('/admin/plugins/info', function(req, res) {
|
||||
var gitCommit = settings.getGitCommit();
|
||||
var epVersion = settings.getEpVersion();
|
||||
args.app.get('/admin/plugins/info', (req, res) => {
|
||||
const gitCommit = settings.getGitCommit();
|
||||
const epVersion = settings.getEpVersion();
|
||||
|
||||
res.send(eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", {
|
||||
gitCommit: gitCommit,
|
||||
epVersion: epVersion,
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/admin/plugins-info.html', {
|
||||
gitCommit,
|
||||
epVersion,
|
||||
latestVersion: UpdateCheck.getLatestVersion(),
|
||||
req,
|
||||
}));
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
||||
exports.socketio = function(hook_name, args, cb) {
|
||||
var io = args.io.of("/pluginfw/installer");
|
||||
io.on('connection', function(socket) {
|
||||
exports.socketio = function (hook_name, args, cb) {
|
||||
const io = args.io.of('/pluginfw/installer');
|
||||
io.on('connection', (socket) => {
|
||||
if (!socket.conn.request.session || !socket.conn.request.session.user || !socket.conn.request.session.user.is_admin) return;
|
||||
|
||||
socket.on("getInstalled", function(query) {
|
||||
socket.on('getInstalled', (query) => {
|
||||
// send currently installed plugins
|
||||
var installed = Object.keys(plugins.plugins).map(function(plugin) {
|
||||
return plugins.plugins[plugin].package
|
||||
});
|
||||
const installed = Object.keys(plugins.plugins).map((plugin) => plugins.plugins[plugin].package);
|
||||
|
||||
socket.emit("results:installed", {installed: installed});
|
||||
socket.emit('results:installed', {installed});
|
||||
});
|
||||
|
||||
socket.on("checkUpdates", async function() {
|
||||
socket.on('checkUpdates', async () => {
|
||||
// Check plugins for updates
|
||||
try {
|
||||
let results = await installer.getAvailablePlugins(/*maxCacheAge:*/ 60 * 10);
|
||||
const results = await installer.getAvailablePlugins(/* maxCacheAge:*/ 60 * 10);
|
||||
|
||||
var updatable = _(plugins.plugins).keys().filter(function(plugin) {
|
||||
const updatable = _(plugins.plugins).keys().filter((plugin) => {
|
||||
if (!results[plugin]) return false;
|
||||
|
||||
var latestVersion = results[plugin].version;
|
||||
var currentVersion = plugins.plugins[plugin].package.version;
|
||||
const latestVersion = results[plugin].version;
|
||||
const currentVersion = plugins.plugins[plugin].package.version;
|
||||
|
||||
return semver.gt(latestVersion, currentVersion);
|
||||
});
|
||||
|
||||
socket.emit("results:updatable", {updatable: updatable});
|
||||
socket.emit('results:updatable', {updatable});
|
||||
} catch (er) {
|
||||
console.warn(er);
|
||||
|
||||
socket.emit("results:updatable", {updatable: {}});
|
||||
socket.emit('results:updatable', {updatable: {}});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("getAvailable", async function(query) {
|
||||
socket.on('getAvailable', async (query) => {
|
||||
try {
|
||||
let results = await installer.getAvailablePlugins(/*maxCacheAge:*/ false);
|
||||
socket.emit("results:available", results);
|
||||
const results = await installer.getAvailablePlugins(/* maxCacheAge:*/ false);
|
||||
socket.emit('results:available', results);
|
||||
} catch (er) {
|
||||
console.error(er);
|
||||
socket.emit("results:available", {});
|
||||
socket.emit('results:available', {});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("search", async function(query) {
|
||||
socket.on('search', async (query) => {
|
||||
try {
|
||||
let results = await installer.search(query.searchTerm, /*maxCacheAge:*/ 60 * 10);
|
||||
var res = Object.keys(results)
|
||||
.map(function(pluginName) {
|
||||
return results[pluginName];
|
||||
})
|
||||
.filter(function(plugin) {
|
||||
return !plugins.plugins[plugin.name];
|
||||
});
|
||||
const results = await installer.search(query.searchTerm, /* maxCacheAge:*/ 60 * 10);
|
||||
let res = Object.keys(results)
|
||||
.map((pluginName) => results[pluginName])
|
||||
.filter((plugin) => !plugins.plugins[plugin.name]);
|
||||
res = sortPluginList(res, query.sortBy, query.sortDir)
|
||||
.slice(query.offset, query.offset+query.limit);
|
||||
socket.emit("results:search", {results: res, query: query});
|
||||
.slice(query.offset, query.offset + query.limit);
|
||||
socket.emit('results:search', {results: res, query});
|
||||
} catch (er) {
|
||||
console.error(er);
|
||||
|
||||
socket.emit("results:search", {results: {}, query: query});
|
||||
socket.emit('results:search', {results: {}, query});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("install", function(plugin_name) {
|
||||
installer.install(plugin_name, function(er) {
|
||||
socket.on('install', (plugin_name) => {
|
||||
installer.install(plugin_name, (er) => {
|
||||
if (er) console.warn(er);
|
||||
|
||||
socket.emit("finished:install", {plugin: plugin_name, code: er? er.code : null, error: er? er.message : null});
|
||||
socket.emit('finished:install', {plugin: plugin_name, code: er ? er.code : null, error: er ? er.message : null});
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("uninstall", function(plugin_name) {
|
||||
installer.uninstall(plugin_name, function(er) {
|
||||
socket.on('uninstall', (plugin_name) => {
|
||||
installer.uninstall(plugin_name, (er) => {
|
||||
if (er) console.warn(er);
|
||||
|
||||
socket.emit("finished:uninstall", {plugin: plugin_name, error: er? er.message : null});
|
||||
socket.emit('finished:uninstall', {plugin: plugin_name, error: er ? er.message : null});
|
||||
});
|
||||
});
|
||||
});
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
||||
function sortPluginList(plugins, property, /*ASC?*/dir) {
|
||||
return plugins.sort(function(a, b) {
|
||||
function sortPluginList(plugins, property, /* ASC?*/dir) {
|
||||
return plugins.sort((a, b) => {
|
||||
if (a[property] < b[property]) {
|
||||
return dir? -1 : 1;
|
||||
return dir ? -1 : 1;
|
||||
}
|
||||
|
||||
if (a[property] > b[property]) {
|
||||
return dir? 1 : -1;
|
||||
return dir ? 1 : -1;
|
||||
}
|
||||
|
||||
// a must be equal to b
|
||||
|
|
|
@ -1,55 +1,52 @@
|
|||
var eejs = require('ep_etherpad-lite/node/eejs');
|
||||
var settings = require('ep_etherpad-lite/node/utils/Settings');
|
||||
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
|
||||
var fs = require('fs');
|
||||
const eejs = require('ep_etherpad-lite/node/eejs');
|
||||
const settings = require('ep_etherpad-lite/node/utils/Settings');
|
||||
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
const fs = require('fs');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
args.app.get('/admin/settings', function(req, res) {
|
||||
args.app.get('/admin/settings', (req, res) => {
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/admin/settings.html', {
|
||||
req,
|
||||
settings: "",
|
||||
settings: '',
|
||||
search_results: {},
|
||||
errors: []
|
||||
errors: [],
|
||||
}));
|
||||
});
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
||||
exports.socketio = function (hook_name, args, cb) {
|
||||
var io = args.io.of("/settings");
|
||||
io.on('connection', function (socket) {
|
||||
|
||||
const io = args.io.of('/settings');
|
||||
io.on('connection', (socket) => {
|
||||
if (!socket.conn.request.session || !socket.conn.request.session.user || !socket.conn.request.session.user.is_admin) return;
|
||||
|
||||
socket.on("load", function (query) {
|
||||
fs.readFile('settings.json', 'utf8', function (err,data) {
|
||||
socket.on('load', (query) => {
|
||||
fs.readFile('settings.json', 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
|
||||
// if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result
|
||||
if(settings.showSettingsInAdminPage === false) {
|
||||
socket.emit("settings", {results: 'NOT_ALLOWED'});
|
||||
}
|
||||
else {
|
||||
socket.emit("settings", {results: data});
|
||||
if (settings.showSettingsInAdminPage === false) {
|
||||
socket.emit('settings', {results: 'NOT_ALLOWED'});
|
||||
} else {
|
||||
socket.emit('settings', {results: data});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("saveSettings", function (settings) {
|
||||
fs.writeFile('settings.json', settings, function (err) {
|
||||
socket.on('saveSettings', (settings) => {
|
||||
fs.writeFile('settings.json', settings, (err) => {
|
||||
if (err) throw err;
|
||||
socket.emit("saveprogress", "saved");
|
||||
socket.emit('saveprogress', 'saved');
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('restartServer', async () => {
|
||||
console.log("Admin request to restart server through a socket on /admin/settings");
|
||||
console.log('Admin request to restart server through a socket on /admin/settings');
|
||||
settings.reloadSettings();
|
||||
await hooks.aCallAll('restartServer');
|
||||
});
|
||||
|
||||
});
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
var log4js = require('log4js');
|
||||
var clientLogger = log4js.getLogger("client");
|
||||
var formidable = require('formidable');
|
||||
var apiHandler = require('../../handler/APIHandler');
|
||||
const log4js = require('log4js');
|
||||
const clientLogger = log4js.getLogger('client');
|
||||
const formidable = require('formidable');
|
||||
const apiHandler = require('../../handler/APIHandler');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
//The Etherpad client side sends information about how a disconnect happened
|
||||
args.app.post('/ep/pad/connection-diagnostic-info', function(req, res) {
|
||||
new formidable.IncomingForm().parse(req, function(err, fields, files) {
|
||||
clientLogger.info("DIAGNOSTIC-INFO: " + fields.diagnosticInfo);
|
||||
res.end("OK");
|
||||
// The Etherpad client side sends information about how a disconnect happened
|
||||
args.app.post('/ep/pad/connection-diagnostic-info', (req, res) => {
|
||||
new formidable.IncomingForm().parse(req, (err, fields, files) => {
|
||||
clientLogger.info(`DIAGNOSTIC-INFO: ${fields.diagnosticInfo}`);
|
||||
res.end('OK');
|
||||
});
|
||||
});
|
||||
|
||||
//The Etherpad client side sends information about client side javscript errors
|
||||
args.app.post('/jserror', function(req, res) {
|
||||
new formidable.IncomingForm().parse(req, function(err, fields, files) {
|
||||
// The Etherpad client side sends information about client side javscript errors
|
||||
args.app.post('/jserror', (req, res) => {
|
||||
new formidable.IncomingForm().parse(req, (err, fields, files) => {
|
||||
try {
|
||||
var data = JSON.parse(fields.errorInfo)
|
||||
}catch(e){
|
||||
return res.end()
|
||||
var data = JSON.parse(fields.errorInfo);
|
||||
} catch (e) {
|
||||
return res.end();
|
||||
}
|
||||
clientLogger.warn(data.msg+' --', data);
|
||||
res.end("OK");
|
||||
clientLogger.warn(`${data.msg} --`, data);
|
||||
res.end('OK');
|
||||
});
|
||||
});
|
||||
|
||||
//Provide a possibility to query the latest available API version
|
||||
args.app.get('/api', function (req, res) {
|
||||
res.json({"currentVersion" : apiHandler.latestApiVersion});
|
||||
// Provide a possibility to query the latest available API version
|
||||
args.app.get('/api', (req, res) => {
|
||||
res.json({currentVersion: apiHandler.latestApiVersion});
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
var stats = require('ep_etherpad-lite/node/stats')
|
||||
const stats = require('ep_etherpad-lite/node/stats');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
exports.app = args.app;
|
||||
|
||||
// Handle errors
|
||||
args.app.use(function(err, req, res, next) {
|
||||
args.app.use((err, req, res, next) => {
|
||||
// if an error occurs Connect will pass it down
|
||||
// through these "error-handling" middleware
|
||||
// allowing you to respond however you like
|
||||
res.status(500).send({ error: 'Sorry, something bad happened!' });
|
||||
console.error(err.stack? err.stack : err.toString());
|
||||
stats.meter('http500').mark()
|
||||
res.status(500).send({error: 'Sorry, something bad happened!'});
|
||||
console.error(err.stack ? err.stack : err.toString());
|
||||
stats.meter('http500').mark();
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,44 +1,43 @@
|
|||
const assert = require('assert').strict;
|
||||
var hasPadAccess = require("../../padaccess");
|
||||
var settings = require('../../utils/Settings');
|
||||
var exportHandler = require('../../handler/ExportHandler');
|
||||
var importHandler = require('../../handler/ImportHandler');
|
||||
var padManager = require("../../db/PadManager");
|
||||
var readOnlyManager = require("../../db/ReadOnlyManager");
|
||||
var authorManager = require("../../db/AuthorManager");
|
||||
const rateLimit = require("express-rate-limit");
|
||||
const securityManager = require("../../db/SecurityManager");
|
||||
const webaccess = require("./webaccess");
|
||||
const hasPadAccess = require('../../padaccess');
|
||||
const settings = require('../../utils/Settings');
|
||||
const exportHandler = require('../../handler/ExportHandler');
|
||||
const importHandler = require('../../handler/ImportHandler');
|
||||
const padManager = require('../../db/PadManager');
|
||||
const readOnlyManager = require('../../db/ReadOnlyManager');
|
||||
const authorManager = require('../../db/AuthorManager');
|
||||
const rateLimit = require('express-rate-limit');
|
||||
const securityManager = require('../../db/SecurityManager');
|
||||
const webaccess = require('./webaccess');
|
||||
|
||||
settings.importExportRateLimiting.onLimitReached = function(req, res, options) {
|
||||
settings.importExportRateLimiting.onLimitReached = function (req, res, options) {
|
||||
// when the rate limiter triggers, write a warning in the logs
|
||||
console.warn(`Import/Export rate limiter triggered on "${req.originalUrl}" for IP address ${req.ip}`);
|
||||
}
|
||||
};
|
||||
|
||||
var limiter = rateLimit(settings.importExportRateLimiting);
|
||||
const limiter = rateLimit(settings.importExportRateLimiting);
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
|
||||
// handle export requests
|
||||
args.app.use('/p/:pad/:rev?/export/:type', limiter);
|
||||
args.app.get('/p/:pad/:rev?/export/:type', async function(req, res, next) {
|
||||
var types = ["pdf", "doc", "txt", "html", "odt", "etherpad"];
|
||||
//send a 404 if we don't support this filetype
|
||||
args.app.get('/p/:pad/:rev?/export/:type', async (req, res, next) => {
|
||||
const types = ['pdf', 'doc', 'txt', 'html', 'odt', 'etherpad'];
|
||||
// send a 404 if we don't support this filetype
|
||||
if (types.indexOf(req.params.type) == -1) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// if abiword is disabled, and this is a format we only support with abiword, output a message
|
||||
if (settings.exportAvailable() == "no" &&
|
||||
["odt", "pdf", "doc"].indexOf(req.params.type) !== -1) {
|
||||
if (settings.exportAvailable() == 'no' &&
|
||||
['odt', 'pdf', 'doc'].indexOf(req.params.type) !== -1) {
|
||||
console.error(`Impossible to export pad "${req.params.pad}" in ${req.params.type} format. There is no converter configured`);
|
||||
|
||||
// ACHTUNG: do not include req.params.type in res.send() because there is no HTML escaping and it would lead to an XSS
|
||||
res.send("This export is not enabled at this Etherpad instance. Set the path to Abiword or soffice (LibreOffice) in settings.json to enable this feature");
|
||||
res.send('This export is not enabled at this Etherpad instance. Set the path to Abiword or soffice (LibreOffice) in settings.json to enable this feature');
|
||||
return;
|
||||
}
|
||||
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
|
||||
if (await hasPadAccess(req, res)) {
|
||||
let padId = req.params.pad;
|
||||
|
@ -49,7 +48,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
padId = await readOnlyManager.getPadId(readOnlyId);
|
||||
}
|
||||
|
||||
let exists = await padManager.doesPadExists(padId);
|
||||
const exists = await padManager.doesPadExists(padId);
|
||||
if (!exists) {
|
||||
console.warn(`Someone tried to export a pad that doesn't exist (${padId})`);
|
||||
return next();
|
||||
|
@ -62,7 +61,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
|
||||
// handle import requests
|
||||
args.app.use('/p/:pad/import', limiter);
|
||||
args.app.post('/p/:pad/import', async function(req, res, next) {
|
||||
args.app.post('/p/:pad/import', async (req, res, next) => {
|
||||
const {session: {user} = {}} = req;
|
||||
const {accessStatus} = await securityManager.checkAccess(
|
||||
req.params.pad, req.cookies.sessionID, req.cookies.token, user);
|
||||
|
@ -73,4 +72,4 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -62,14 +62,14 @@ const RESERVED_WORDS = [
|
|||
'volatile',
|
||||
'while',
|
||||
'with',
|
||||
'yield'
|
||||
'yield',
|
||||
];
|
||||
|
||||
const regex = /^[a-zA-Z_$][0-9a-zA-Z_$]*(?:\[(?:".+"|\'.+\'|\d+)\])*?$/;
|
||||
|
||||
module.exports.check = function(inputStr) {
|
||||
var isValid = true;
|
||||
inputStr.split(".").forEach(function(part) {
|
||||
module.exports.check = function (inputStr) {
|
||||
let isValid = true;
|
||||
inputStr.split('.').forEach((part) => {
|
||||
if (!regex.test(part)) {
|
||||
isValid = false;
|
||||
}
|
||||
|
@ -80,4 +80,4 @@ module.exports.check = function(inputStr) {
|
|||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
const OpenAPIBackend = require('openapi-backend').default;
|
||||
const formidable = require('formidable');
|
||||
const { promisify } = require('util');
|
||||
const {promisify} = require('util');
|
||||
const cloneDeep = require('lodash.clonedeep');
|
||||
const createHTTPError = require('http-errors');
|
||||
|
||||
|
@ -57,12 +57,12 @@ const resources = {
|
|||
create: {
|
||||
operationId: 'createGroup',
|
||||
summary: 'creates a new group',
|
||||
responseSchema: { groupID: { type: 'string' } },
|
||||
responseSchema: {groupID: {type: 'string'}},
|
||||
},
|
||||
createIfNotExistsFor: {
|
||||
operationId: 'createGroupIfNotExistsFor',
|
||||
summary: 'this functions helps you to map your application group ids to Etherpad group ids',
|
||||
responseSchema: { groupID: { type: 'string' } },
|
||||
responseSchema: {groupID: {type: 'string'}},
|
||||
},
|
||||
delete: {
|
||||
operationId: 'deleteGroup',
|
||||
|
@ -71,7 +71,7 @@ const resources = {
|
|||
listPads: {
|
||||
operationId: 'listPads',
|
||||
summary: 'returns all pads of this group',
|
||||
responseSchema: { padIDs: { type: 'array', items: { type: 'string' } } },
|
||||
responseSchema: {padIDs: {type: 'array', items: {type: 'string'}}},
|
||||
},
|
||||
createPad: {
|
||||
operationId: 'createGroupPad',
|
||||
|
@ -80,12 +80,12 @@ const resources = {
|
|||
listSessions: {
|
||||
operationId: 'listSessionsOfGroup',
|
||||
summary: '',
|
||||
responseSchema: { sessions: { type: 'array', items: { $ref: '#/components/schemas/SessionInfo' } } },
|
||||
responseSchema: {sessions: {type: 'array', items: {$ref: '#/components/schemas/SessionInfo'}}},
|
||||
},
|
||||
list: {
|
||||
operationId: 'listAllGroups',
|
||||
summary: '',
|
||||
responseSchema: { groupIDs: { type: 'array', items: { type: 'string' } } },
|
||||
responseSchema: {groupIDs: {type: 'array', items: {type: 'string'}}},
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -94,28 +94,28 @@ const resources = {
|
|||
create: {
|
||||
operationId: 'createAuthor',
|
||||
summary: 'creates a new author',
|
||||
responseSchema: { authorID: { type: 'string' } },
|
||||
responseSchema: {authorID: {type: 'string'}},
|
||||
},
|
||||
createIfNotExistsFor: {
|
||||
operationId: 'createAuthorIfNotExistsFor',
|
||||
summary: 'this functions helps you to map your application author ids to Etherpad author ids',
|
||||
responseSchema: { authorID: { type: 'string' } },
|
||||
responseSchema: {authorID: {type: 'string'}},
|
||||
},
|
||||
listPads: {
|
||||
operationId: 'listPadsOfAuthor',
|
||||
summary: 'returns an array of all pads this author contributed to',
|
||||
responseSchema: { padIDs: { type: 'array', items: { type: 'string' } } },
|
||||
responseSchema: {padIDs: {type: 'array', items: {type: 'string'}}},
|
||||
},
|
||||
listSessions: {
|
||||
operationId: 'listSessionsOfAuthor',
|
||||
summary: 'returns all sessions of an author',
|
||||
responseSchema: { sessions: { type: 'array', items: { $ref: '#/components/schemas/SessionInfo' } } },
|
||||
responseSchema: {sessions: {type: 'array', items: {$ref: '#/components/schemas/SessionInfo'}}},
|
||||
},
|
||||
// We need an operation that return a UserInfo so it can be picked up by the codegen :(
|
||||
getName: {
|
||||
operationId: 'getAuthorName',
|
||||
summary: 'Returns the Author Name of the author',
|
||||
responseSchema: { info: { $ref: '#/components/schemas/UserInfo' } },
|
||||
responseSchema: {info: {$ref: '#/components/schemas/UserInfo'}},
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -124,7 +124,7 @@ const resources = {
|
|||
create: {
|
||||
operationId: 'createSession',
|
||||
summary: 'creates a new session. validUntil is an unix timestamp in seconds',
|
||||
responseSchema: { sessionID: { type: 'string' } },
|
||||
responseSchema: {sessionID: {type: 'string'}},
|
||||
},
|
||||
delete: {
|
||||
operationId: 'deleteSession',
|
||||
|
@ -134,7 +134,7 @@ const resources = {
|
|||
info: {
|
||||
operationId: 'getSessionInfo',
|
||||
summary: 'returns informations about a session',
|
||||
responseSchema: { info: { $ref: '#/components/schemas/SessionInfo' } },
|
||||
responseSchema: {info: {$ref: '#/components/schemas/SessionInfo'}},
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -143,7 +143,7 @@ const resources = {
|
|||
listAll: {
|
||||
operationId: 'listAllPads',
|
||||
summary: 'list all the pads',
|
||||
responseSchema: { padIDs: { type: 'array', items: { type: 'string' } } },
|
||||
responseSchema: {padIDs: {type: 'array', items: {type: 'string'}}},
|
||||
},
|
||||
createDiffHTML: {
|
||||
operationId: 'createDiffHTML',
|
||||
|
@ -158,7 +158,7 @@ const resources = {
|
|||
getText: {
|
||||
operationId: 'getText',
|
||||
summary: 'returns the text of a pad',
|
||||
responseSchema: { text: { type: 'string' } },
|
||||
responseSchema: {text: {type: 'string'}},
|
||||
},
|
||||
setText: {
|
||||
operationId: 'setText',
|
||||
|
@ -167,7 +167,7 @@ const resources = {
|
|||
getHTML: {
|
||||
operationId: 'getHTML',
|
||||
summary: 'returns the text of a pad formatted as HTML',
|
||||
responseSchema: { html: { type: 'string' } },
|
||||
responseSchema: {html: {type: 'string'}},
|
||||
},
|
||||
setHTML: {
|
||||
operationId: 'setHTML',
|
||||
|
@ -176,12 +176,12 @@ const resources = {
|
|||
getRevisionsCount: {
|
||||
operationId: 'getRevisionsCount',
|
||||
summary: 'returns the number of revisions of this pad',
|
||||
responseSchema: { revisions: { type: 'integer' } },
|
||||
responseSchema: {revisions: {type: 'integer'}},
|
||||
},
|
||||
getLastEdited: {
|
||||
operationId: 'getLastEdited',
|
||||
summary: 'returns the timestamp of the last revision of the pad',
|
||||
responseSchema: { lastEdited: { type: 'integer' } },
|
||||
responseSchema: {lastEdited: {type: 'integer'}},
|
||||
},
|
||||
delete: {
|
||||
operationId: 'deletePad',
|
||||
|
@ -190,7 +190,7 @@ const resources = {
|
|||
getReadOnlyID: {
|
||||
operationId: 'getReadOnlyID',
|
||||
summary: 'returns the read only link of a pad',
|
||||
responseSchema: { readOnlyID: { type: 'string' } },
|
||||
responseSchema: {readOnlyID: {type: 'string'}},
|
||||
},
|
||||
setPublicStatus: {
|
||||
operationId: 'setPublicStatus',
|
||||
|
@ -199,22 +199,22 @@ const resources = {
|
|||
getPublicStatus: {
|
||||
operationId: 'getPublicStatus',
|
||||
summary: 'return true of false',
|
||||
responseSchema: { publicStatus: { type: 'boolean' } },
|
||||
responseSchema: {publicStatus: {type: 'boolean'}},
|
||||
},
|
||||
authors: {
|
||||
operationId: 'listAuthorsOfPad',
|
||||
summary: 'returns an array of authors who contributed to this pad',
|
||||
responseSchema: { authorIDs: { type: 'array', items: { type: 'string' } } },
|
||||
responseSchema: {authorIDs: {type: 'array', items: {type: 'string'}}},
|
||||
},
|
||||
usersCount: {
|
||||
operationId: 'padUsersCount',
|
||||
summary: 'returns the number of user that are currently editing this pad',
|
||||
responseSchema: { padUsersCount: { type: 'integer' } },
|
||||
responseSchema: {padUsersCount: {type: 'integer'}},
|
||||
},
|
||||
users: {
|
||||
operationId: 'padUsers',
|
||||
summary: 'returns the list of users that are currently editing this pad',
|
||||
responseSchema: { padUsers: { type: 'array', items: { $ref: '#/components/schemas/UserInfo' } } },
|
||||
responseSchema: {padUsers: {type: 'array', items: {$ref: '#/components/schemas/UserInfo'}}},
|
||||
},
|
||||
sendClientsMessage: {
|
||||
operationId: 'sendClientsMessage',
|
||||
|
@ -227,13 +227,13 @@ const resources = {
|
|||
getChatHistory: {
|
||||
operationId: 'getChatHistory',
|
||||
summary: 'returns the chat history',
|
||||
responseSchema: { messages: { type: 'array', items: { $ref: '#/components/schemas/Message' } } },
|
||||
responseSchema: {messages: {type: 'array', items: {$ref: '#/components/schemas/Message'}}},
|
||||
},
|
||||
// We need an operation that returns a Message so it can be picked up by the codegen :(
|
||||
getChatHead: {
|
||||
operationId: 'getChatHead',
|
||||
summary: 'returns the chatHead (chat-message) of the pad',
|
||||
responseSchema: { chatHead: { $ref: '#/components/schemas/Message' } },
|
||||
responseSchema: {chatHead: {$ref: '#/components/schemas/Message'}},
|
||||
},
|
||||
appendChatMessage: {
|
||||
operationId: 'appendChatMessage',
|
||||
|
@ -384,10 +384,10 @@ const defaultResponseRefs = {
|
|||
const operations = {};
|
||||
for (const resource in resources) {
|
||||
for (const action in resources[resource]) {
|
||||
const { operationId, responseSchema, ...operation } = resources[resource][action];
|
||||
const {operationId, responseSchema, ...operation} = resources[resource][action];
|
||||
|
||||
// add response objects
|
||||
const responses = { ...defaultResponseRefs };
|
||||
const responses = {...defaultResponseRefs};
|
||||
if (responseSchema) {
|
||||
responses[200] = cloneDeep(defaultResponses.Success);
|
||||
responses[200].content['application/json'].schema.properties.data = {
|
||||
|
@ -478,14 +478,14 @@ const generateDefinitionForVersion = (version, style = APIPathStyle.FLAT) => {
|
|||
},
|
||||
},
|
||||
},
|
||||
security: [{ ApiKey: [] }],
|
||||
security: [{ApiKey: []}],
|
||||
};
|
||||
|
||||
// build operations
|
||||
for (const funcName in apiHandler.version[version]) {
|
||||
let operation = {};
|
||||
if (operations[funcName]) {
|
||||
operation = { ...operations[funcName] };
|
||||
operation = {...operations[funcName]};
|
||||
} else {
|
||||
// console.warn(`No operation found for function: ${funcName}`);
|
||||
operation = {
|
||||
|
@ -497,7 +497,7 @@ const generateDefinitionForVersion = (version, style = APIPathStyle.FLAT) => {
|
|||
// set parameters
|
||||
operation.parameters = operation.parameters || [];
|
||||
for (const paramName of apiHandler.version[version][funcName]) {
|
||||
operation.parameters.push({ $ref: `#/components/parameters/${paramName}` });
|
||||
operation.parameters.push({$ref: `#/components/parameters/${paramName}`});
|
||||
if (!definition.components.parameters[paramName]) {
|
||||
definition.components.parameters[paramName] = {
|
||||
name: paramName,
|
||||
|
@ -533,7 +533,7 @@ const generateDefinitionForVersion = (version, style = APIPathStyle.FLAT) => {
|
|||
};
|
||||
|
||||
exports.expressCreateServer = (hookName, args, cb) => {
|
||||
const { app } = args;
|
||||
const {app} = args;
|
||||
|
||||
// create openapi-backend handlers for each api version under /api/{version}/*
|
||||
for (const version in apiHandler.version) {
|
||||
|
@ -550,7 +550,7 @@ exports.expressCreateServer = (hookName, args, cb) => {
|
|||
app.get(`${apiRoot}/openapi.json`, (req, res) => {
|
||||
// For openapi definitions, wide CORS is probably fine
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.json({ ...definition, servers: [generateServerForApiVersion(apiRoot, req)] });
|
||||
res.json({...definition, servers: [generateServerForApiVersion(apiRoot, req)]});
|
||||
});
|
||||
|
||||
// serve latest openapi definition file under /api/openapi.json
|
||||
|
@ -558,7 +558,7 @@ exports.expressCreateServer = (hookName, args, cb) => {
|
|||
if (isLatestAPIVersion) {
|
||||
app.get(`/${style}/openapi.json`, (req, res) => {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.json({ ...definition, servers: [generateServerForApiVersion(apiRoot, req)] });
|
||||
res.json({...definition, servers: [generateServerForApiVersion(apiRoot, req)]});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -586,7 +586,7 @@ exports.expressCreateServer = (hookName, args, cb) => {
|
|||
for (const funcName in apiHandler.version[version]) {
|
||||
const handler = async (c, req, res) => {
|
||||
// parse fields from request
|
||||
const { header, params, query } = c.request;
|
||||
const {header, params, query} = c.request;
|
||||
|
||||
// read form data if method was POST
|
||||
let formData = {};
|
||||
|
@ -602,7 +602,7 @@ exports.expressCreateServer = (hookName, args, cb) => {
|
|||
apiLogger.info(`REQUEST, v${version}:${funcName}, ${JSON.stringify(fields)}`);
|
||||
|
||||
// pass to api handler
|
||||
let data = await apiHandler.handle(version, funcName, fields, req, res).catch((err) => {
|
||||
const data = await apiHandler.handle(version, funcName, fields, req, res).catch((err) => {
|
||||
// convert all errors to http errors
|
||||
if (createHTTPError.isHttpError(err)) {
|
||||
// pass http errors thrown by handler forward
|
||||
|
@ -620,7 +620,7 @@ exports.expressCreateServer = (hookName, args, cb) => {
|
|||
});
|
||||
|
||||
// return in common format
|
||||
let response = { code: 0, message: 'ok', data: data || null };
|
||||
const response = {code: 0, message: 'ok', data: data || null};
|
||||
|
||||
// log response
|
||||
apiLogger.info(`RESPONSE, ${funcName}, ${JSON.stringify(response)}`);
|
||||
|
@ -654,24 +654,24 @@ exports.expressCreateServer = (hookName, args, cb) => {
|
|||
// https://github.com/ether/etherpad-lite/tree/master/doc/api/http_api.md#response-format
|
||||
switch (res.statusCode) {
|
||||
case 403: // forbidden
|
||||
response = { code: 4, message: err.message, data: null };
|
||||
response = {code: 4, message: err.message, data: null};
|
||||
break;
|
||||
case 401: // unauthorized (no or wrong api key)
|
||||
response = { code: 4, message: err.message, data: null };
|
||||
response = {code: 4, message: err.message, data: null};
|
||||
break;
|
||||
case 404: // not found (no such function)
|
||||
response = { code: 3, message: err.message, data: null };
|
||||
response = {code: 3, message: err.message, data: null};
|
||||
break;
|
||||
case 500: // server error (internal error)
|
||||
response = { code: 2, message: err.message, data: null };
|
||||
response = {code: 2, message: err.message, data: null};
|
||||
break;
|
||||
case 400: // bad request (wrong parameters)
|
||||
// respond with 200 OK to keep old behavior and pass tests
|
||||
res.statusCode = 200; // @TODO: this is bad api design
|
||||
response = { code: 1, message: err.message, data: null };
|
||||
response = {code: 1, message: err.message, data: null};
|
||||
break;
|
||||
default:
|
||||
response = { code: 1, message: err.message, data: null };
|
||||
response = {code: 1, message: err.message, data: null};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
var readOnlyManager = require("../../db/ReadOnlyManager");
|
||||
var hasPadAccess = require("../../padaccess");
|
||||
var exporthtml = require("../../utils/ExportHtml");
|
||||
const readOnlyManager = require('../../db/ReadOnlyManager');
|
||||
const hasPadAccess = require('../../padaccess');
|
||||
const exporthtml = require('../../utils/ExportHtml');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
// serve read only pad
|
||||
args.app.get('/ro/:id', async function(req, res) {
|
||||
|
||||
args.app.get('/ro/:id', async (req, res) => {
|
||||
// translate the read only pad to a padId
|
||||
let padId = await readOnlyManager.getPadId(req.params.id);
|
||||
const padId = await readOnlyManager.getPadId(req.params.id);
|
||||
if (padId == null) {
|
||||
res.status(404).send('404 - Not Found');
|
||||
return;
|
||||
|
@ -18,9 +17,9 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
|
||||
if (await hasPadAccess(req, res)) {
|
||||
// render the html document
|
||||
let html = await exporthtml.getPadHTMLDocument(padId, null);
|
||||
const html = await exporthtml.getPadHTMLDocument(padId, null);
|
||||
res.send(html);
|
||||
}
|
||||
});
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
var padManager = require('../../db/PadManager');
|
||||
var url = require('url');
|
||||
const padManager = require('../../db/PadManager');
|
||||
const url = require('url');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
|
||||
// redirects browser to the pad's sanitized url if needed. otherwise, renders the html
|
||||
args.app.param('pad', async function (req, res, next, padId) {
|
||||
args.app.param('pad', async (req, res, next, padId) => {
|
||||
// ensure the padname is valid and the url doesn't end with a /
|
||||
if (!padManager.isValidPadId(padId) || /\/$/.test(req.url)) {
|
||||
res.status(404).send('Such a padname is forbidden');
|
||||
return;
|
||||
}
|
||||
|
||||
let sanitizedPadId = await padManager.sanitizePadId(padId);
|
||||
const sanitizedPadId = await padManager.sanitizePadId(padId);
|
||||
|
||||
if (sanitizedPadId === padId) {
|
||||
// the pad id was fine, so just render it
|
||||
next();
|
||||
} else {
|
||||
// the pad id was sanitized, so we redirect to the sanitized version
|
||||
var real_url = sanitizedPadId;
|
||||
let real_url = sanitizedPadId;
|
||||
real_url = encodeURIComponent(real_url);
|
||||
var query = url.parse(req.url).query;
|
||||
if ( query ) real_url += '?' + query;
|
||||
const query = url.parse(req.url).query;
|
||||
if (query) real_url += `?${query}`;
|
||||
res.header('Location', real_url);
|
||||
res.status(302).send('You should be redirected to <a href="' + real_url + '">' + real_url + '</a>');
|
||||
res.status(302).send(`You should be redirected to <a href="${real_url}">${real_url}</a>`);
|
||||
}
|
||||
});
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
const express = require("../express");
|
||||
const express = require('../express');
|
||||
const proxyaddr = require('proxy-addr');
|
||||
var settings = require('../../utils/Settings');
|
||||
var socketio = require('socket.io');
|
||||
var socketIORouter = require("../../handler/SocketIORouter");
|
||||
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
|
||||
const settings = require('../../utils/Settings');
|
||||
const socketio = require('socket.io');
|
||||
const socketIORouter = require('../../handler/SocketIORouter');
|
||||
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
|
||||
var padMessageHandler = require("../../handler/PadMessageHandler");
|
||||
const padMessageHandler = require('../../handler/PadMessageHandler');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
//init socket.io and redirect all requests to the MessageHandler
|
||||
// init socket.io and redirect all requests to the MessageHandler
|
||||
// there shouldn't be a browser that isn't compatible to all
|
||||
// transports in this list at once
|
||||
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
|
||||
var io = socketio({
|
||||
transports: settings.socketTransportProtocols
|
||||
const io = socketio({
|
||||
transports: settings.socketTransportProtocols,
|
||||
}).listen(args.server, {
|
||||
/*
|
||||
* Do not set the "io" cookie.
|
||||
|
@ -61,17 +61,17 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
// https://github.com/Automattic/socket.io/wiki/Migrating-to-1.0
|
||||
// This debug logging environment is set in Settings.js
|
||||
|
||||
//minify socket.io javascript
|
||||
// minify socket.io javascript
|
||||
// Due to a shitty decision by the SocketIO team minification is
|
||||
// no longer available, details available at:
|
||||
// http://stackoverflow.com/questions/23981741/minify-socket-io-socket-io-js-with-1-0
|
||||
// if(settings.minify) io.enable('browser client minification');
|
||||
|
||||
//Initalize the Socket.IO Router
|
||||
// Initalize the Socket.IO Router
|
||||
socketIORouter.setSocketIO(io);
|
||||
socketIORouter.addComponent("pad", padMessageHandler);
|
||||
socketIORouter.addComponent('pad', padMessageHandler);
|
||||
|
||||
hooks.callAll("socketio", {"app": args.app, "io": io, "server": args.server});
|
||||
hooks.callAll('socketio', {app: args.app, io, server: args.server});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,83 +1,81 @@
|
|||
var path = require('path');
|
||||
var eejs = require('ep_etherpad-lite/node/eejs');
|
||||
var toolbar = require("ep_etherpad-lite/node/utils/toolbar");
|
||||
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
var settings = require('../../utils/Settings');
|
||||
const path = require('path');
|
||||
const eejs = require('ep_etherpad-lite/node/eejs');
|
||||
const toolbar = require('ep_etherpad-lite/node/utils/toolbar');
|
||||
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
const settings = require('../../utils/Settings');
|
||||
const webaccess = require('./webaccess');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
// expose current stats
|
||||
args.app.get('/stats', function(req, res) {
|
||||
res.json(require('ep_etherpad-lite/node/stats').toJSON())
|
||||
})
|
||||
args.app.get('/stats', (req, res) => {
|
||||
res.json(require('ep_etherpad-lite/node/stats').toJSON());
|
||||
});
|
||||
|
||||
//serve index.html under /
|
||||
args.app.get('/', function(req, res) {
|
||||
// serve index.html under /
|
||||
args.app.get('/', (req, res) => {
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/index.html', {req}));
|
||||
});
|
||||
|
||||
//serve javascript.html
|
||||
args.app.get('/javascript', function(req, res) {
|
||||
// serve javascript.html
|
||||
args.app.get('/javascript', (req, res) => {
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/javascript.html', {req}));
|
||||
});
|
||||
|
||||
|
||||
//serve robots.txt
|
||||
args.app.get('/robots.txt', function(req, res) {
|
||||
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "robots.txt");
|
||||
res.sendFile(filePath, function(err) {
|
||||
//there is no custom robots.txt, send the default robots.txt which dissallows all
|
||||
if(err)
|
||||
{
|
||||
filePath = path.join(settings.root, "src", "static", "robots.txt");
|
||||
// serve robots.txt
|
||||
args.app.get('/robots.txt', (req, res) => {
|
||||
let filePath = path.join(settings.root, 'src', 'static', 'skins', settings.skinName, 'robots.txt');
|
||||
res.sendFile(filePath, (err) => {
|
||||
// there is no custom robots.txt, send the default robots.txt which dissallows all
|
||||
if (err) {
|
||||
filePath = path.join(settings.root, 'src', 'static', 'robots.txt');
|
||||
res.sendFile(filePath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//serve pad.html under /p
|
||||
args.app.get('/p/:pad', function(req, res, next) {
|
||||
// serve pad.html under /p
|
||||
args.app.get('/p/:pad', (req, res, next) => {
|
||||
// The below might break for pads being rewritten
|
||||
const isReadOnly =
|
||||
req.url.indexOf("/p/r.") === 0 || !webaccess.userCanModify(req.params.pad, req);
|
||||
req.url.indexOf('/p/r.') === 0 || !webaccess.userCanModify(req.params.pad, req);
|
||||
|
||||
hooks.callAll("padInitToolbar", {
|
||||
toolbar: toolbar,
|
||||
isReadOnly: isReadOnly
|
||||
hooks.callAll('padInitToolbar', {
|
||||
toolbar,
|
||||
isReadOnly,
|
||||
});
|
||||
|
||||
res.send(eejs.require("ep_etherpad-lite/templates/pad.html", {
|
||||
req: req,
|
||||
toolbar: toolbar,
|
||||
isReadOnly: isReadOnly
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/pad.html', {
|
||||
req,
|
||||
toolbar,
|
||||
isReadOnly,
|
||||
}));
|
||||
});
|
||||
|
||||
//serve timeslider.html under /p/$padname/timeslider
|
||||
args.app.get('/p/:pad/timeslider', function(req, res, next) {
|
||||
hooks.callAll("padInitToolbar", {
|
||||
toolbar: toolbar
|
||||
// serve timeslider.html under /p/$padname/timeslider
|
||||
args.app.get('/p/:pad/timeslider', (req, res, next) => {
|
||||
hooks.callAll('padInitToolbar', {
|
||||
toolbar,
|
||||
});
|
||||
|
||||
res.send(eejs.require("ep_etherpad-lite/templates/timeslider.html", {
|
||||
req: req,
|
||||
toolbar: toolbar
|
||||
res.send(eejs.require('ep_etherpad-lite/templates/timeslider.html', {
|
||||
req,
|
||||
toolbar,
|
||||
}));
|
||||
});
|
||||
|
||||
//serve favicon.ico from all path levels except as a pad name
|
||||
args.app.get( /\/favicon.ico$/, function(req, res) {
|
||||
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "favicon.ico");
|
||||
// serve favicon.ico from all path levels except as a pad name
|
||||
args.app.get(/\/favicon.ico$/, (req, res) => {
|
||||
let filePath = path.join(settings.root, 'src', 'static', 'skins', settings.skinName, 'favicon.ico');
|
||||
|
||||
res.sendFile(filePath, function(err) {
|
||||
//there is no custom favicon, send the default favicon
|
||||
if(err)
|
||||
{
|
||||
filePath = path.join(settings.root, "src", "static", "favicon.ico");
|
||||
res.sendFile(filePath, (err) => {
|
||||
// there is no custom favicon, send the default favicon
|
||||
if (err) {
|
||||
filePath = path.join(settings.root, 'src', 'static', 'favicon.ico');
|
||||
res.sendFile(filePath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
var minify = require('../../utils/Minify');
|
||||
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugin_defs");
|
||||
var CachingMiddleware = require('../../utils/caching_middleware');
|
||||
var settings = require("../../utils/Settings");
|
||||
var Yajsml = require('etherpad-yajsml');
|
||||
var _ = require("underscore");
|
||||
const minify = require('../../utils/Minify');
|
||||
const plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs');
|
||||
const CachingMiddleware = require('../../utils/caching_middleware');
|
||||
const settings = require('../../utils/Settings');
|
||||
const Yajsml = require('etherpad-yajsml');
|
||||
const _ = require('underscore');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
|
||||
// Cache both minified and static.
|
||||
var assetCache = new CachingMiddleware;
|
||||
const assetCache = new CachingMiddleware();
|
||||
args.app.all(/\/javascripts\/(.*)/, assetCache.handle);
|
||||
|
||||
// Minify will serve static files compressed (minify enabled). It also has
|
||||
|
@ -18,43 +17,42 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
// Setup middleware that will package JavaScript files served by minify for
|
||||
// CommonJS loader on the client-side.
|
||||
// Hostname "invalid.invalid" is a dummy value to allow parsing as a URI.
|
||||
var jsServer = new (Yajsml.Server)({
|
||||
rootPath: 'javascripts/src/'
|
||||
, rootURI: 'http://invalid.invalid/static/js/'
|
||||
, libraryPath: 'javascripts/lib/'
|
||||
, libraryURI: 'http://invalid.invalid/static/plugins/'
|
||||
, requestURIs: minify.requestURIs // Loop-back is causing problems, this is a workaround.
|
||||
const jsServer = new (Yajsml.Server)({
|
||||
rootPath: 'javascripts/src/',
|
||||
rootURI: 'http://invalid.invalid/static/js/',
|
||||
libraryPath: 'javascripts/lib/',
|
||||
libraryURI: 'http://invalid.invalid/static/plugins/',
|
||||
requestURIs: minify.requestURIs, // Loop-back is causing problems, this is a workaround.
|
||||
});
|
||||
|
||||
var StaticAssociator = Yajsml.associators.StaticAssociator;
|
||||
var associations =
|
||||
const StaticAssociator = Yajsml.associators.StaticAssociator;
|
||||
const associations =
|
||||
Yajsml.associators.associationsForSimpleMapping(minify.tar);
|
||||
var associator = new StaticAssociator(associations);
|
||||
const associator = new StaticAssociator(associations);
|
||||
jsServer.setAssociator(associator);
|
||||
|
||||
args.app.use(jsServer.handle.bind(jsServer));
|
||||
|
||||
// serve plugin definitions
|
||||
// not very static, but served here so that client can do require("pluginfw/static/js/plugin-definitions.js");
|
||||
args.app.get('/pluginfw/plugin-definitions.json', function (req, res, next) {
|
||||
args.app.get('/pluginfw/plugin-definitions.json', (req, res, next) => {
|
||||
const clientParts = _(plugins.parts)
|
||||
.filter((part) => _(part).has('client_hooks'));
|
||||
|
||||
var clientParts = _(plugins.parts)
|
||||
.filter(function(part){ return _(part).has('client_hooks') });
|
||||
|
||||
var clientPlugins = {};
|
||||
const clientPlugins = {};
|
||||
|
||||
_(clientParts).chain()
|
||||
.map(function(part){ return part.plugin })
|
||||
.uniq()
|
||||
.each(function(name){
|
||||
clientPlugins[name] = _(plugins.plugins[name]).clone();
|
||||
delete clientPlugins[name]['package'];
|
||||
});
|
||||
.map((part) => part.plugin)
|
||||
.uniq()
|
||||
.each((name) => {
|
||||
clientPlugins[name] = _(plugins.plugins[name]).clone();
|
||||
delete clientPlugins[name].package;
|
||||
});
|
||||
|
||||
res.header("Content-Type","application/json; charset=utf-8");
|
||||
res.write(JSON.stringify({"plugins": clientPlugins, "parts": clientParts}));
|
||||
res.header('Content-Type', 'application/json; charset=utf-8');
|
||||
res.write(JSON.stringify({plugins: clientPlugins, parts: clientParts}));
|
||||
res.end();
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
var path = require("path")
|
||||
, npm = require("npm")
|
||||
, fs = require("fs")
|
||||
, util = require("util");
|
||||
const path = require('path');
|
||||
const npm = require('npm');
|
||||
const fs = require('fs');
|
||||
const util = require('util');
|
||||
|
||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||
args.app.get('/tests/frontend/specs_list.js', async function(req, res) {
|
||||
let [coreTests, pluginTests] = await Promise.all([
|
||||
args.app.get('/tests/frontend/specs_list.js', async (req, res) => {
|
||||
const [coreTests, pluginTests] = await Promise.all([
|
||||
exports.getCoreTests(),
|
||||
exports.getPluginTests()
|
||||
exports.getPluginTests(),
|
||||
]);
|
||||
|
||||
// merge the two sets of results
|
||||
|
@ -16,79 +16,77 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
// Keep only *.js files
|
||||
files = files.filter((f) => f.endsWith('.js'));
|
||||
|
||||
console.debug("Sent browser the following test specs:", files);
|
||||
console.debug('Sent browser the following test specs:', files);
|
||||
res.setHeader('content-type', 'text/javascript');
|
||||
res.end("var specs_list = " + JSON.stringify(files) + ";\n");
|
||||
res.end(`var specs_list = ${JSON.stringify(files)};\n`);
|
||||
});
|
||||
|
||||
// path.join seems to normalize by default, but we'll just be explicit
|
||||
var rootTestFolder = path.normalize(path.join(npm.root, "../tests/frontend/"));
|
||||
const rootTestFolder = path.normalize(path.join(npm.root, '../tests/frontend/'));
|
||||
|
||||
var url2FilePath = function(url) {
|
||||
var subPath = url.substr("/tests/frontend".length);
|
||||
if (subPath == "") {
|
||||
subPath = "index.html"
|
||||
const url2FilePath = function (url) {
|
||||
let subPath = url.substr('/tests/frontend'.length);
|
||||
if (subPath == '') {
|
||||
subPath = 'index.html';
|
||||
}
|
||||
subPath = subPath.split("?")[0];
|
||||
subPath = subPath.split('?')[0];
|
||||
|
||||
var filePath = path.normalize(path.join(rootTestFolder, subPath));
|
||||
let filePath = path.normalize(path.join(rootTestFolder, subPath));
|
||||
|
||||
// make sure we jail the paths to the test folder, otherwise serve index
|
||||
if (filePath.indexOf(rootTestFolder) !== 0) {
|
||||
filePath = path.join(rootTestFolder, "index.html");
|
||||
filePath = path.join(rootTestFolder, 'index.html');
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
};
|
||||
|
||||
args.app.get('/tests/frontend/specs/*', function (req, res) {
|
||||
var specFilePath = url2FilePath(req.url);
|
||||
var specFileName = path.basename(specFilePath);
|
||||
args.app.get('/tests/frontend/specs/*', (req, res) => {
|
||||
const specFilePath = url2FilePath(req.url);
|
||||
const specFileName = path.basename(specFilePath);
|
||||
|
||||
fs.readFile(specFilePath, function(err, content) {
|
||||
fs.readFile(specFilePath, (err, content) => {
|
||||
if (err) { return res.send(500); }
|
||||
|
||||
content = "describe(" + JSON.stringify(specFileName) + ", function(){ " + content + " });";
|
||||
content = `describe(${JSON.stringify(specFileName)}, function(){ ${content} });`;
|
||||
|
||||
res.send(content);
|
||||
});
|
||||
});
|
||||
|
||||
args.app.get('/tests/frontend/*', function (req, res) {
|
||||
var filePath = url2FilePath(req.url);
|
||||
args.app.get('/tests/frontend/*', (req, res) => {
|
||||
const filePath = url2FilePath(req.url);
|
||||
res.sendFile(filePath);
|
||||
});
|
||||
|
||||
args.app.get('/tests/frontend', function (req, res) {
|
||||
args.app.get('/tests/frontend', (req, res) => {
|
||||
res.redirect('/tests/frontend/index.html');
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
||||
const readdir = util.promisify(fs.readdir);
|
||||
|
||||
exports.getPluginTests = async function(callback) {
|
||||
const moduleDir = "node_modules/";
|
||||
const specPath = "/static/tests/frontend/specs/";
|
||||
const staticDir = "/static/plugins/";
|
||||
exports.getPluginTests = async function (callback) {
|
||||
const moduleDir = 'node_modules/';
|
||||
const specPath = '/static/tests/frontend/specs/';
|
||||
const staticDir = '/static/plugins/';
|
||||
|
||||
let pluginSpecs = [];
|
||||
const pluginSpecs = [];
|
||||
|
||||
let plugins = await readdir(moduleDir);
|
||||
let promises = plugins
|
||||
.map(plugin => [ plugin, moduleDir + plugin + specPath] )
|
||||
.filter(([plugin, specDir]) => fs.existsSync(specDir)) // check plugin exists
|
||||
.map(([plugin, specDir]) => {
|
||||
return readdir(specDir)
|
||||
.then(specFiles => specFiles.map(spec => {
|
||||
pluginSpecs.push(staticDir + plugin + specPath + spec);
|
||||
}));
|
||||
});
|
||||
const plugins = await readdir(moduleDir);
|
||||
const promises = plugins
|
||||
.map((plugin) => [plugin, moduleDir + plugin + specPath])
|
||||
.filter(([plugin, specDir]) => fs.existsSync(specDir)) // check plugin exists
|
||||
.map(([plugin, specDir]) => readdir(specDir)
|
||||
.then((specFiles) => specFiles.map((spec) => {
|
||||
pluginSpecs.push(staticDir + plugin + specPath + spec);
|
||||
})));
|
||||
|
||||
return Promise.all(promises).then(() => pluginSpecs);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getCoreTests = function() {
|
||||
exports.getCoreTests = function () {
|
||||
// get the core test specs
|
||||
return readdir('tests/frontend/specs');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
var languages = require('languages4translatewiki')
|
||||
, fs = require('fs')
|
||||
, path = require('path')
|
||||
, _ = require('underscore')
|
||||
, npm = require('npm')
|
||||
, plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs.js').plugins
|
||||
, semver = require('semver')
|
||||
, existsSync = require('../utils/path_exists')
|
||||
, settings = require('../utils/Settings')
|
||||
const languages = require('languages4translatewiki');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const _ = require('underscore');
|
||||
const npm = require('npm');
|
||||
const plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs.js').plugins;
|
||||
const semver = require('semver');
|
||||
const existsSync = require('../utils/path_exists');
|
||||
const settings = require('../utils/Settings')
|
||||
;
|
||||
|
||||
|
||||
// returns all existing messages merged together and grouped by langcode
|
||||
// {es: {"foo": "string"}, en:...}
|
||||
function getAllLocales() {
|
||||
var locales2paths = {};
|
||||
const locales2paths = {};
|
||||
|
||||
// Puts the paths of all locale files contained in a given directory
|
||||
// into `locales2paths` (files from various dirs are grouped by lang code)
|
||||
// (only json files with valid language code as name)
|
||||
function extractLangs(dir) {
|
||||
if(!existsSync(dir)) return;
|
||||
var stat = fs.lstatSync(dir);
|
||||
if (!existsSync(dir)) return;
|
||||
let stat = fs.lstatSync(dir);
|
||||
if (!stat.isDirectory() || stat.isSymbolicLink()) return;
|
||||
|
||||
fs.readdirSync(dir).forEach(function(file) {
|
||||
fs.readdirSync(dir).forEach((file) => {
|
||||
file = path.resolve(dir, file);
|
||||
stat = fs.lstatSync(file);
|
||||
if (stat.isDirectory() || stat.isSymbolicLink()) return;
|
||||
|
||||
var ext = path.extname(file)
|
||||
, locale = path.basename(file, ext).toLowerCase();
|
||||
const ext = path.extname(file);
|
||||
const locale = path.basename(file, ext).toLowerCase();
|
||||
|
||||
if ((ext == '.json') && languages.isValid(locale)) {
|
||||
if(!locales2paths[locale]) locales2paths[locale] = [];
|
||||
if (!locales2paths[locale]) locales2paths[locale] = [];
|
||||
locales2paths[locale].push(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//add core supported languages first
|
||||
extractLangs(npm.root+"/ep_etherpad-lite/locales");
|
||||
// add core supported languages first
|
||||
extractLangs(`${npm.root}/ep_etherpad-lite/locales`);
|
||||
|
||||
//add plugins languages (if any)
|
||||
for(var pluginName in plugins) extractLangs(path.join(npm.root, pluginName, 'locales'));
|
||||
// add plugins languages (if any)
|
||||
for (const pluginName in plugins) extractLangs(path.join(npm.root, pluginName, 'locales'));
|
||||
|
||||
// Build a locale index (merge all locale data other than user-supplied overrides)
|
||||
var locales = {}
|
||||
_.each (locales2paths, function(files, langcode) {
|
||||
locales[langcode]={};
|
||||
const locales = {};
|
||||
_.each(locales2paths, (files, langcode) => {
|
||||
locales[langcode] = {};
|
||||
|
||||
files.forEach(function(file) {
|
||||
files.forEach((file) => {
|
||||
let fileContents;
|
||||
try {
|
||||
fileContents = JSON.parse(fs.readFileSync(file,'utf8'));
|
||||
fileContents = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
} catch (err) {
|
||||
console.error(`failed to read JSON file ${file}: ${err}`);
|
||||
throw err;
|
||||
|
@ -64,17 +64,17 @@ function getAllLocales() {
|
|||
// Add custom strings from settings.json
|
||||
// Since this is user-supplied, we'll do some extra sanity checks
|
||||
const wrongFormatErr = Error(
|
||||
"customLocaleStrings in wrong format. See documentation " +
|
||||
"for Customization for Administrators, under Localization.")
|
||||
'customLocaleStrings in wrong format. See documentation ' +
|
||||
'for Customization for Administrators, under Localization.');
|
||||
if (settings.customLocaleStrings) {
|
||||
if (typeof settings.customLocaleStrings !== "object") throw wrongFormatErr
|
||||
_.each(settings.customLocaleStrings, function(overrides, langcode) {
|
||||
if (typeof overrides !== "object") throw wrongFormatErr
|
||||
_.each(overrides, function(localeString, key) {
|
||||
if (typeof localeString !== "string") throw wrongFormatErr
|
||||
locales[langcode][key] = localeString
|
||||
})
|
||||
})
|
||||
if (typeof settings.customLocaleStrings !== 'object') throw wrongFormatErr;
|
||||
_.each(settings.customLocaleStrings, (overrides, langcode) => {
|
||||
if (typeof overrides !== 'object') throw wrongFormatErr;
|
||||
_.each(overrides, (localeString, key) => {
|
||||
if (typeof localeString !== 'string') throw wrongFormatErr;
|
||||
locales[langcode][key] = localeString;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return locales;
|
||||
|
@ -83,45 +83,44 @@ function getAllLocales() {
|
|||
// returns a hash of all available languages availables with nativeName and direction
|
||||
// e.g. { es: {nativeName: "español", direction: "ltr"}, ... }
|
||||
function getAvailableLangs(locales) {
|
||||
var result = {};
|
||||
_.each(_.keys(locales), function(langcode) {
|
||||
const result = {};
|
||||
_.each(_.keys(locales), (langcode) => {
|
||||
result[langcode] = languages.getLanguageInfo(langcode);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// returns locale index that will be served in /locales.json
|
||||
var generateLocaleIndex = function (locales) {
|
||||
var result = _.clone(locales) // keep English strings
|
||||
_.each(_.keys(locales), function(langcode) {
|
||||
if (langcode != 'en') result[langcode]='locales/'+langcode+'.json';
|
||||
const generateLocaleIndex = function (locales) {
|
||||
const result = _.clone(locales); // keep English strings
|
||||
_.each(_.keys(locales), (langcode) => {
|
||||
if (langcode != 'en') result[langcode] = `locales/${langcode}.json`;
|
||||
});
|
||||
return JSON.stringify(result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
exports.expressCreateServer = function(n, args, cb) {
|
||||
|
||||
//regenerate locales on server restart
|
||||
var locales = getAllLocales();
|
||||
var localeIndex = generateLocaleIndex(locales);
|
||||
exports.expressCreateServer = function (n, args, cb) {
|
||||
// regenerate locales on server restart
|
||||
const locales = getAllLocales();
|
||||
const localeIndex = generateLocaleIndex(locales);
|
||||
exports.availableLangs = getAvailableLangs(locales);
|
||||
|
||||
args.app.get ('/locales/:locale', function(req, res) {
|
||||
//works with /locale/en and /locale/en.json requests
|
||||
var locale = req.params.locale.split('.')[0];
|
||||
args.app.get('/locales/:locale', (req, res) => {
|
||||
// works with /locale/en and /locale/en.json requests
|
||||
const locale = req.params.locale.split('.')[0];
|
||||
if (exports.availableLangs.hasOwnProperty(locale)) {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.send('{"'+locale+'":'+JSON.stringify(locales[locale])+'}');
|
||||
res.send(`{"${locale}":${JSON.stringify(locales[locale])}}`);
|
||||
} else {
|
||||
res.status(404).send('Language not available');
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
args.app.get('/locales.json', function(req, res) {
|
||||
args.app.get('/locales.json', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.send(localeIndex);
|
||||
})
|
||||
});
|
||||
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue