Start server without paths.
parent
798543fb45
commit
8926677a66
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"presets": ["@babel/preset-env"]
|
||||||
|
}
|
|
@ -32,4 +32,4 @@ src/bin/installDeps.sh "$@" || exit 1
|
||||||
# Move to the node folder and start
|
# Move to the node folder and start
|
||||||
log "Starting Etherpad..."
|
log "Starting Etherpad..."
|
||||||
|
|
||||||
exec node src/node/server.js "$@"
|
exec node src/dist/node/server.js "$@"
|
||||||
|
|
|
@ -109,11 +109,15 @@ export const createServer = async () => {
|
||||||
'variable to production by using: export NODE_ENV=production');
|
'variable to production by using: export NODE_ENV=production');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
export const app = express();
|
||||||
|
|
||||||
|
import http from 'http'
|
||||||
|
import https from 'https'
|
||||||
|
|
||||||
export const restartServer = async () => {
|
export const restartServer = async () => {
|
||||||
await closeServer();
|
await closeServer();
|
||||||
|
|
||||||
const app = express(); // New syntax for express v3
|
// New syntax for express v3
|
||||||
|
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
console.log('SSL -- enabled');
|
console.log('SSL -- enabled');
|
||||||
|
@ -133,11 +137,8 @@ export const restartServer = async () => {
|
||||||
options.ca.push(fs.readFileSync(caFileName));
|
options.ca.push(fs.readFileSync(caFileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const https = require('https');
|
|
||||||
server = https.createServer(options, app);
|
server = https.createServer(options, app);
|
||||||
} else {
|
} else {
|
||||||
const http = require('http');
|
|
||||||
server = http.createServer(app);
|
server = http.createServer(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,5 +44,5 @@ export const expressPreSession = async (hookName, {app}) => {
|
||||||
// Provide a possibility to query the latest available API version
|
// Provide a possibility to query the latest available API version
|
||||||
app.get('/api', (req, res) => {
|
app.get('/api', (req, res) => {
|
||||||
res.json({currentVersion: latestApiVersion});
|
res.json({currentVersion: latestApiVersion});
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ export const userCanModify = (padId, req) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exported so that tests can set this to 0 to avoid unnecessary test slowness.
|
// Exported so that tests can set this to 0 to avoid unnecessary test slowness.
|
||||||
export const authnFailureDelayMs = 1000;
|
export let authnFailureDelayMs = 1000;
|
||||||
|
|
||||||
export const checkAccess = async (req, res, next) => {
|
export const checkAccess = async (req, res, next) => {
|
||||||
const requireAdmin = req.path.toLowerCase().startsWith('/admin');
|
const requireAdmin = req.path.toLowerCase().startsWith('/admin');
|
||||||
|
@ -204,3 +204,8 @@ export const checkAccess = async (req, res, next) => {
|
||||||
export const checkAccess2 = (req, res, next) => {
|
export const checkAccess2 = (req, res, next) => {
|
||||||
checkAccess(req, res, next).catch((err) => next(err || new Error(err)));
|
checkAccess(req, res, next).catch((err) => next(err || new Error(err)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
export const setauthnFailureDelayMs = (value) => {
|
||||||
|
authnFailureDelayMs = value;
|
||||||
|
}
|
||||||
|
|
|
@ -51,9 +51,7 @@ import {createServer, server} from './hooks/express';
|
||||||
import hooks = require('../static/js/pluginfw/hooks');
|
import hooks = require('../static/js/pluginfw/hooks');
|
||||||
import pluginDefs = require('../static/js/pluginfw/plugin_defs');
|
import pluginDefs = require('../static/js/pluginfw/plugin_defs');
|
||||||
import plugins = require('../static/js/pluginfw/plugins');
|
import plugins = require('../static/js/pluginfw/plugins');
|
||||||
import stats = require('./stats');
|
|
||||||
import {createCollection} from "./stats";
|
import {createCollection} from "./stats";
|
||||||
|
|
||||||
const logger = log4js.getLogger('server');
|
const logger = log4js.getLogger('server');
|
||||||
console.log = logger.info.bind(logger); // do the same for others - console.debug, etc.
|
console.log = logger.info.bind(logger); // do the same for others - console.debug, etc.
|
||||||
|
|
||||||
|
@ -152,7 +150,7 @@ export const start = async () => {
|
||||||
logger.debug(`Installed parts:\n${plugins.formatParts()}`);
|
logger.debug(`Installed parts:\n${plugins.formatParts()}`);
|
||||||
logger.debug(`Installed server-side hooks:\n${plugins.formatHooks('hooks', false)}`);
|
logger.debug(`Installed server-side hooks:\n${plugins.formatHooks('hooks', false)}`);
|
||||||
await hooks.aCallAll('loadSettings', {settings});
|
await hooks.aCallAll('loadSettings', {settings});
|
||||||
await hooks.aCallAll(createServer())
|
await hooks.aCallAll(createServer());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Error occurred while starting Etherpad');
|
logger.error('Error occurred while starting Etherpad');
|
||||||
state = State.STATE_TRANSITION_FAILED;
|
state = State.STATE_TRANSITION_FAILED;
|
||||||
|
|
|
@ -109,12 +109,12 @@ export const skinVariants = 'super-light-toolbar super-light-editor light-backgr
|
||||||
/**
|
/**
|
||||||
* The IP ep-lite should listen to
|
* The IP ep-lite should listen to
|
||||||
*/
|
*/
|
||||||
export const ip:String = '0.0.0.0';
|
export let ip:String = '0.0.0.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Port ep-lite should listen to
|
* The Port ep-lite should listen to
|
||||||
*/
|
*/
|
||||||
export const port = process.env.PORT || 9001;
|
export let port = process.env.PORT || 9001;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should we suppress Error messages from being in Pad Contents
|
* Should we suppress Error messages from being in Pad Contents
|
||||||
|
@ -125,7 +125,7 @@ export const suppressErrorsInPadText = false;
|
||||||
* The SSL signed server key and the Certificate Authority's own certificate
|
* The SSL signed server key and the Certificate Authority's own certificate
|
||||||
* default case: ep-lite does *not* use SSL. A signed server key is not required in this case.
|
* default case: ep-lite does *not* use SSL. A signed server key is not required in this case.
|
||||||
*/
|
*/
|
||||||
export const ssl = false;
|
export let ssl = false;
|
||||||
|
|
||||||
export const sslKeys = {
|
export const sslKeys = {
|
||||||
cert: undefined,
|
cert: undefined,
|
||||||
|
@ -319,7 +319,7 @@ export let sessionKey: string|boolean = false;
|
||||||
/*
|
/*
|
||||||
* Trust Proxy, whether or not trust the x-forwarded-for header.
|
* Trust Proxy, whether or not trust the x-forwarded-for header.
|
||||||
*/
|
*/
|
||||||
export const trustProxy = false;
|
export let trustProxy = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Settings controlling the session cookie issued by Etherpad.
|
* Settings controlling the session cookie issued by Etherpad.
|
||||||
|
@ -412,7 +412,7 @@ export const setUsers = (newUsers:any) => {
|
||||||
*
|
*
|
||||||
* See https://github.com/nfriedly/express-rate-limit for more options
|
* See https://github.com/nfriedly/express-rate-limit for more options
|
||||||
*/
|
*/
|
||||||
export const importExportRateLimiting = {
|
export let importExportRateLimiting = {
|
||||||
// duration of the rate limit window (milliseconds)
|
// duration of the rate limit window (milliseconds)
|
||||||
windowMs: 90000,
|
windowMs: 90000,
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ export const importExportRateLimiting = {
|
||||||
*
|
*
|
||||||
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
|
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
|
||||||
*/
|
*/
|
||||||
export const commitRateLimiting = {
|
export let commitRateLimiting = {
|
||||||
// duration of the rate limit window (seconds)
|
// duration of the rate limit window (seconds)
|
||||||
duration: 1,
|
duration: 1,
|
||||||
|
|
||||||
|
@ -884,3 +884,27 @@ export const exportedForTestingOnly = {
|
||||||
reloadSettings();
|
reloadSettings();
|
||||||
|
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
export const setPort = (value: number) => {
|
||||||
|
port = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setIp = (value: string) => {
|
||||||
|
ip = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setTrustProxy = (value: boolean) => {
|
||||||
|
trustProxy = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setSsl = (value: boolean) => {
|
||||||
|
ssl = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setimportExportRateLimiting = (value: any) => {
|
||||||
|
importExportRateLimiting = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setCommitRateLimiting = (value: any) => {
|
||||||
|
commitRateLimiting = value;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -78,18 +78,22 @@
|
||||||
"etherpad-lite": "node/server.js"
|
"etherpad-lite": "node/server.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/cli": "^7.22.5",
|
||||||
|
"@babel/core": "^7.22.5",
|
||||||
|
"@babel/preset-env": "^7.22.5",
|
||||||
|
"@babel/register": "^7.22.5",
|
||||||
"@types/cross-spawn": "^6.0.2",
|
"@types/cross-spawn": "^6.0.2",
|
||||||
"@types/express": "4.17.17",
|
"@types/express": "4.17.17",
|
||||||
"@types/jquery": "^3.5.16",
|
"@types/jquery": "^3.5.16",
|
||||||
"@types/js-cookie": "^3.0.3",
|
"@types/js-cookie": "^3.0.3",
|
||||||
"i18next": "^23.2.3",
|
|
||||||
"i18next-fs-backend": "^2.1.5",
|
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.3.1",
|
||||||
"@types/underscore": "^1.11.5",
|
"@types/underscore": "^1.11.5",
|
||||||
"concurrently": "^8.2.0",
|
"concurrently": "^8.2.0",
|
||||||
"eslint": "^8.14.0",
|
"eslint": "^8.14.0",
|
||||||
"eslint-config-etherpad": "^3.0.13",
|
"eslint-config-etherpad": "^3.0.13",
|
||||||
"etherpad-cli-client": "^2.0.1",
|
"etherpad-cli-client": "^2.0.1",
|
||||||
|
"i18next": "^23.2.3",
|
||||||
|
"i18next-fs-backend": "^2.1.5",
|
||||||
"mocha": "^9.2.2",
|
"mocha": "^9.2.2",
|
||||||
"mocha-froth": "^0.2.10",
|
"mocha-froth": "^0.2.10",
|
||||||
"nodeify": "^1.0.1",
|
"nodeify": "^1.0.1",
|
||||||
|
@ -112,7 +116,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"test": "mocha --timeout 120000 --recursive tests/backend/specs ../node_modules/ep_*/static/tests/backend/specs",
|
"test": "mocha --require @babel/register --timeout 120000 --recursive tests/backend/specs ../node_modules/ep_*/static/tests/backend/specs",
|
||||||
"test-container": "mocha --timeout 5000 tests/container/specs/api",
|
"test-container": "mocha --timeout 5000 tests/container/specs/api",
|
||||||
"dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/server.js\""
|
"dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/server.js\""
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {hooks} from './plugin_defs';
|
import {hooks} from './plugin_defs';
|
||||||
|
import {getLogger} from "log4js";
|
||||||
|
|
||||||
// Maps the name of a server-side hook to a string explaining the deprecation
|
// Maps the name of a server-side hook to a string explaining the deprecation
|
||||||
// (e.g., 'use the foo hook instead').
|
// (e.g., 'use the foo hook instead').
|
||||||
|
@ -347,10 +348,15 @@ const callHookFnAsync = async (hook, context) => {
|
||||||
// If cb is non-null, this function resolves to the value returned by cb.
|
// If cb is non-null, this function resolves to the value returned by cb.
|
||||||
export const aCallAll = async (hookName, context?, cb = null) => {
|
export const aCallAll = async (hookName, context?, cb = null) => {
|
||||||
if (cb != null) return await attachCallback(aCallAll(hookName, context), cb);
|
if (cb != null) return await attachCallback(aCallAll(hookName, context), cb);
|
||||||
if (context == null) context = {};
|
if (context == null) {
|
||||||
|
context = {};
|
||||||
|
}
|
||||||
const hooksResult = hooks[hookName] || [];
|
const hooksResult = hooks[hookName] || [];
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
hooksResult.map(async (hook) => normalizeValue(await callHookFnAsync(hook, context))));
|
hooksResult.map(async (hook) => {
|
||||||
|
getLogger().info(`Calling hook ${hook.hook_name} asynchronously`);
|
||||||
|
return normalizeValue(await callHookFnAsync(hook, context))
|
||||||
|
}));
|
||||||
return flatten1(results);
|
return flatten1(results);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ export const update = async () => {
|
||||||
}));
|
}));
|
||||||
logger.info(`Loaded ${Object.keys(packages).length} plugins`);
|
logger.info(`Loaded ${Object.keys(packages).length} plugins`);
|
||||||
|
|
||||||
logger.info(parts)
|
|
||||||
setPlugins(plugins);
|
setPlugins(plugins);
|
||||||
setParts(sortParts(parts))
|
setParts(sortParts(parts))
|
||||||
setHooks(extractHooks(parts, 'hooks', pathNormalization));
|
setHooks(extractHooks(parts, 'hooks', pathNormalization));
|
||||||
|
@ -129,12 +128,13 @@ const getPackages = async () => {
|
||||||
logger.info("After exportCMD")
|
logger.info("After exportCMD")
|
||||||
const {dependencies = {}} = JSON.parse(cmdReturn as string);
|
const {dependencies = {}} = JSON.parse(cmdReturn as string);
|
||||||
await Promise.all(Object.entries(dependencies).map(async ([pkg, info]) => {
|
await Promise.all(Object.entries(dependencies).map(async ([pkg, info]) => {
|
||||||
|
logger.info(`Found plugin ${pkg}`)
|
||||||
if (!pkg.startsWith(prefix)) {
|
if (!pkg.startsWith(prefix)) {
|
||||||
delete dependencies[pkg];
|
delete dependencies[pkg];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const mappedInfo = info as PluginInfo
|
const mappedInfo = info as PluginInfo
|
||||||
|
logger.info(`Found plugin ${pkg} at ${mappedInfo.path}`)
|
||||||
mappedInfo.realPath = await fs.realpath(mappedInfo.path);
|
mappedInfo.realPath = await fs.realpath(mappedInfo.path);
|
||||||
}));
|
}));
|
||||||
return dependencies;
|
return dependencies;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {parts} from './plugin_defs';
|
import {parts} from './plugin_defs';
|
||||||
|
import {getLogger} from "log4js";
|
||||||
|
|
||||||
const disabledHookReasons = {
|
const disabledHookReasons = {
|
||||||
hooks: {
|
hooks: {
|
||||||
|
@ -35,6 +36,7 @@ export const loadFn = (path, hookName) => {
|
||||||
|
|
||||||
export const extractHooks = (parts: any[], hookSetName, normalizer) => {
|
export const extractHooks = (parts: any[], hookSetName, normalizer) => {
|
||||||
const hooks = {};
|
const hooks = {};
|
||||||
|
const logger = getLogger('pluginfw:shared')
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
for (const [hookName, regHookFnName] of Object.entries(part[hookSetName] || {})) {
|
for (const [hookName, regHookFnName] of Object.entries(part[hookSetName] || {})) {
|
||||||
/* On the server side, you can't just
|
/* On the server side, you can't just
|
||||||
|
@ -45,10 +47,10 @@ export const extractHooks = (parts: any[], hookSetName, normalizer) => {
|
||||||
|
|
||||||
const disabledReason = (disabledHookReasons[hookSetName] || {})[hookName];
|
const disabledReason = (disabledHookReasons[hookSetName] || {})[hookName];
|
||||||
if (disabledReason) {
|
if (disabledReason) {
|
||||||
console.error(`Hook ${hookSetName}/${hookName} is disabled. Reason: ${disabledReason}`);
|
logger.error(`Hook ${hookSetName}/${hookName} is disabled. Reason: ${disabledReason}`);
|
||||||
console.error(`The hook function ${hookFnName} from plugin ${part.plugin} ` +
|
logger.error(`The hook function ${hookFnName} from plugin ${part.plugin} ` +
|
||||||
'will never be called, which may cause the plugin to fail');
|
'will never be called, which may cause the plugin to fail');
|
||||||
console.error(`Please update the ${part.plugin} plugin to not use the ${hookName} hook`);
|
logger.error(`Please update the ${part.plugin} plugin to not use the ${hookName} hook`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let hookFn;
|
let hookFn;
|
||||||
|
@ -56,7 +58,7 @@ export const extractHooks = (parts: any[], hookSetName, normalizer) => {
|
||||||
hookFn = loadFn(hookFnName, hookName);
|
hookFn = loadFn(hookFnName, hookName);
|
||||||
if (!hookFn) throw new Error('Not a function');
|
if (!hookFn) throw new Error('Not a function');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Failed to load hook function "${hookFnName}" for plugin "${part.plugin}" ` +
|
logger.error(`Failed to load hook function "${hookFnName}" for plugin "${part.plugin}" ` +
|
||||||
`part "${part.name}" hook set "${hookSetName}" hook "${hookName}": ` +
|
`part "${part.name}" hook set "${hookSetName}" hook "${hookName}": ` +
|
||||||
`${err.stack || err}`);
|
`${err.stack || err}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,28 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const AttributePool = require('../../static/js/AttributePool');
|
import {AttributePool} from '../../static/js/AttributePool';
|
||||||
const apiHandler = require('../../node/handler/APIHandler');
|
import {exportedForTestingOnly as aExportedForTestingOnly} from '../../node/handler/APIHandler';
|
||||||
const assert = require('assert').strict;
|
import assert, {strict} from 'assert'
|
||||||
const io = require('socket.io-client');
|
import io from 'socket.io-client';
|
||||||
const log4js = require('log4js');
|
import log4js from 'log4js';
|
||||||
const {padutils} = require('../../static/js/pad_utils');
|
import {padutils} from '../../static/js/pad_utils';
|
||||||
const process = require('process');
|
import processA from 'process';
|
||||||
const server = require('../../node/server');
|
import {} from '../../node/server';
|
||||||
const setCookieParser = require('set-cookie-parser');
|
import setCookieParser from 'set-cookie-parser';
|
||||||
const settings = require('../../node/utils/Settings');
|
import {setCommitRateLimiting, setimportExportRateLimiting, setIp, setPort} from '../../node/utils/Settings';
|
||||||
const supertest = require('supertest');
|
import supertest from 'supertest';
|
||||||
const webaccess = require('../../node/hooks/express/webaccess');
|
import {authnFailureDelayMs, setauthnFailureDelayMs} from '../../node/hooks/express/webaccess';
|
||||||
|
import { before,after } from 'mocha';
|
||||||
|
import * as settings from '../../node/utils/Settings';
|
||||||
|
import {server} from "../../node/hooks/express";
|
||||||
|
|
||||||
const backups = {};
|
const backups:{
|
||||||
|
settings?:any,
|
||||||
|
authnFailureDelayMs?:any
|
||||||
|
} = {};
|
||||||
let agentPromise = null;
|
let agentPromise = null;
|
||||||
|
|
||||||
exports.apiKey = apiHandler.exportedForTestingOnly.apiKey;
|
exports.apiKey = aExportedForTestingOnly.apiKey;
|
||||||
exports.agent = null;
|
exports.agent = null;
|
||||||
exports.baseUrl = null;
|
exports.baseUrl = null;
|
||||||
exports.httpServer = null;
|
exports.httpServer = null;
|
||||||
|
@ -27,7 +33,7 @@ const logLevel = logger.level;
|
||||||
|
|
||||||
// Mocha doesn't monitor unhandled Promise rejections, so convert them to uncaught exceptions.
|
// Mocha doesn't monitor unhandled Promise rejections, so convert them to uncaught exceptions.
|
||||||
// https://github.com/mochajs/mocha/issues/2640
|
// https://github.com/mochajs/mocha/issues/2640
|
||||||
process.on('unhandledRejection', (reason, promise) => { throw reason; });
|
processA.on('unhandledRejection', (reason, promise) => { throw reason; });
|
||||||
|
|
||||||
before(async function () {
|
before(async function () {
|
||||||
this.timeout(60000);
|
this.timeout(60000);
|
||||||
|
@ -42,31 +48,29 @@ exports.init = async function () {
|
||||||
if (!logLevel.isLessThanOrEqualTo(log4js.levels.DEBUG)) {
|
if (!logLevel.isLessThanOrEqualTo(log4js.levels.DEBUG)) {
|
||||||
logger.warn('Disabling non-test logging for the duration of the test. ' +
|
logger.warn('Disabling non-test logging for the duration of the test. ' +
|
||||||
'To enable non-test logging, change the loglevel setting to DEBUG.');
|
'To enable non-test logging, change the loglevel setting to DEBUG.');
|
||||||
log4js.setGlobalLogLevel(log4js.levels.OFF);
|
|
||||||
logger.setLevel(logLevel);
|
logger.setLevel(logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: This is only a shallow backup.
|
// Note: This is only a shallow backup.
|
||||||
backups.settings = Object.assign({}, settings);
|
backups.settings = Object.assign({}, settings);
|
||||||
// Start the Etherpad server on a random unused port.
|
// Start the Etherpad server on a random unused port.
|
||||||
settings.port = 0;
|
setPort(0)
|
||||||
settings.ip = 'localhost';
|
setIp('localhost')
|
||||||
settings.importExportRateLimiting = {max: 0};
|
setimportExportRateLimiting({max: 0})
|
||||||
settings.commitRateLimiting = {duration: 0.001, points: 1e6};
|
setCommitRateLimiting({duration: 0.001, points: 1e6});
|
||||||
exports.httpServer = await server.start();
|
exports.httpServer = await server.start();
|
||||||
exports.baseUrl = `http://localhost:${exports.httpServer.address().port}`;
|
exports.baseUrl = `http://localhost:${exports.httpServer.address().port}`;
|
||||||
logger.debug(`HTTP server at ${exports.baseUrl}`);
|
logger.debug(`HTTP server at ${exports.baseUrl}`);
|
||||||
// Create a supertest user agent for the HTTP server.
|
// Create a supertest user agent for the HTTP server.
|
||||||
exports.agent = supertest(exports.baseUrl);
|
exports.agent = supertest(exports.baseUrl);
|
||||||
// Speed up authn tests.
|
// Speed up authn tests.
|
||||||
backups.authnFailureDelayMs = webaccess.authnFailureDelayMs;
|
backups.authnFailureDelayMs = authnFailureDelayMs;
|
||||||
webaccess.authnFailureDelayMs = 0;
|
setauthnFailureDelayMs(0)
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
webaccess.authnFailureDelayMs = backups.authnFailureDelayMs;
|
setauthnFailureDelayMs(backups.authnFailureDelayMs);
|
||||||
// Note: This does not unset settings that were added.
|
// Note: This does not unset settings that were added.
|
||||||
Object.assign(settings, backups.settings);
|
Object.assign(settings, backups.settings);
|
||||||
log4js.setGlobalLogLevel(logLevel);
|
|
||||||
await server.exit();
|
await server.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,7 +97,7 @@ exports.waitForSocketEvent = async (socket, event) => {
|
||||||
const handlers = new Map();
|
const handlers = new Map();
|
||||||
let cancelTimeout;
|
let cancelTimeout;
|
||||||
try {
|
try {
|
||||||
const timeoutP = new Promise((resolve, reject) => {
|
const timeoutP = new Promise<void>((resolve, reject) => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
reject(new Error(`timed out waiting for ${event} event`));
|
reject(new Error(`timed out waiting for ${event} event`));
|
||||||
cancelTimeout = () => {};
|
cancelTimeout = () => {};
|
||||||
|
@ -139,9 +143,11 @@ exports.waitForSocketEvent = async (socket, event) => {
|
||||||
*/
|
*/
|
||||||
exports.connect = async (res = null) => {
|
exports.connect = async (res = null) => {
|
||||||
// Convert the `set-cookie` header(s) into a `cookie` header.
|
// Convert the `set-cookie` header(s) into a `cookie` header.
|
||||||
const resCookies = (res == null) ? {} : setCookieParser.parse(res, {map: true});
|
const resCookies:{
|
||||||
const reqCookieHdr = Object.entries(resCookies).map(
|
[key:string]:{value:string}
|
||||||
([name, cookie]) => `${name}=${encodeURIComponent(cookie.value)}`).join('; ');
|
} = (res == null) ? {} : setCookieParser.parse(res, {map: true});
|
||||||
|
const reqCookieHdr = Object.entries(resCookies)
|
||||||
|
.map(([name, cookie]) => `${name}=${encodeURIComponent(cookie.value)}`).join('; ');
|
||||||
|
|
||||||
logger.debug('socket.io connecting...');
|
logger.debug('socket.io connecting...');
|
||||||
let padId = null;
|
let padId = null;
|
||||||
|
@ -191,7 +197,7 @@ exports.handshake = async (socket, padId, token = padutils.generateAuthorToken()
|
||||||
/**
|
/**
|
||||||
* Convenience wrapper around `socket.send()` that waits for acknowledgement.
|
* Convenience wrapper around `socket.send()` that waits for acknowledgement.
|
||||||
*/
|
*/
|
||||||
exports.sendMessage = async (socket, message) => await new Promise((resolve, reject) => {
|
exports.sendMessage = async (socket, message) => await new Promise<void>((resolve, reject) => {
|
||||||
socket.send(message, (errInfo) => {
|
socket.send(message, (errInfo) => {
|
||||||
if (errInfo != null) {
|
if (errInfo != null) {
|
||||||
const {name, message} = errInfo;
|
const {name, message} = errInfo;
|
Loading…
Reference in New Issue