Normally I would let `eslint --fix` do this for me, but there's a bug
that causes:
const x = function ()
{
// ...
};
to become:
const x = ()
=> {
// ...
};
which ESLint thinks is a syntax error. (It probably is; I don't know
enough about the automatic semicolon insertion rules to be confident.)
Rather than reinvent the wheel, use a well-tested library to parse and
write cookies. This should also help prevent XSS vulnerabilities
because the library handles special characters such as semicolon.
* `src/node/server.js` can now be run as a script (for normal
operation) or imported as a module (for tests).
* Move shutdown actions to `src/node/server.js` to be close to the
startup actions.
* Put startup and shutdown in functions so that tests can call them.
* Use `await` instead of callbacks.
* Block until the HTTP server is listening to avoid races during
test startup.
* Add a new `shutdown` hook.
* Use the `shutdown` hook to:
* close the HTTP server
* call `end()` on the stats collection to cancel its timers
* call `terminate()` on the Threads.Pool to stop the workers
* Exit with exit code 0 (instead of 1) on SIGTERM.
* Export the HTTP server so that tests can get the HTTP server's
port via `server.address().port` when `settings.port` is 0.
1. Introduce contentcollector.js backend tests
1. Fix issue with OL LI items not being properly numbered after import
1. Fix issue with nested OL LI items being improperly numbered on export
1. Fix issue with new lines not being introduced after lists in on import #3961
1. Sanitize HTML on the way in (import)
1. Fix ExportHTML CSS because it needs to support OL > LI > OL not OL > OL [The latter being the correct format]
1. Fix backend tests.
4177b3f943 moved the font-face declarations from src/static/css/pad.css to two
imported files (src/static/css/pad/fonts.css, src/static/css/pad/toolbar.css)
in a different directory.
This results in the font files being invoked from CSSes residing in different
directories in the minified and un-minified case. URLs in the src attribute are
relative to the stylesheet path [0], and so we have to start requiring clean-css
to rebase them.
Before this change, the non minified casse worked by chance, because there were
a lot of "..", which ended up resolving to the root of the site anyways.
Fixes#3956
[0] https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src
By specification [0], the if-modified-since HTTP header sent by browsers does
not include milliseconds.
Before this patch, let's say a file was generate at time:
t_real-file = 2020-03-22T02:15:53.548Z (note the fractional seconds)
When issuing a conditional request, the browser would truncate the fractional
part, and only request an if-modified-since with this contents:
t_if-modified-since = 2020-03-22T02:15:53.000Z
The minify() function would return HTTP/304 only if
t_if-modified-since >= t_real-file, but this would never be true unless, by
chance, a file was generated at XX.000Z.
This resulted in that file being minified/compressed again and resent to the
client for no reason. After this patch, the server correctly responds with
HTTP/304 without doing any computation, and the browser uses the cached file.
[0] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since
CleanCSS 3.4.19 had a Regex Denial of Service vulnerability and has to be
updated. The major version bump requires the following changes:
1. Disabling rebase is necessary because otherwise the URLs for the web fonts
become wrong;
EXAMPLE 1:
/static/css/src/static/font/fontawesome-etherpad.woff
instead of
/static/font/fontawesome-etherpad.woff
EXAMPLE 2 (this is more surprising):
/p/src/static/font/opendyslexic.otf
instead of
/static/font/opendyslexic.otf
2. CleanCSS.minify() can either receive a string containing the CSS, or an array
of strings. In that case each array element is interpreted as an absolute
local path from which the CSS file is read.
In version 4.x, CleanCSS API was simplified, eliminating the relativeTo
parameter, and thus we cannot use our already loaded "content" argument, but
we have to wrap the absolute path to the CSS in an array and ask the library
to read it by itself.
Fixes#3616.
In this way the only external call to statFile() provides an explicit value for
"dirStatLimit", and thus the initial check on "undefined" at the start of the
function could be removed (just added a comment for now).
This is documented to be more performant.
The substitution was made on frontend code, too (i.e., the one in /static),
because Date.now() is supported since IE 9, and we are life supporting only
IE 11.
Commands:
find . -name *.js | xargs sed --in-place "s/new Date().getTime()/Date.now()/g"
find . -name *.js | xargs sed --in-place "s/(new Date()).getTime()/Date.now()/g"
Not done on jQuery.
The hostname:port of URIs used in Minify are currently bogus and refer
to localhost only for historical reasons; there's no reason to retain
them and omitting them avoids generating an invalid URI when "port" is
not an integer.
Context: settings.port is passed to express's listen; if not numeric, it
is used a filename for a Unix domain socket.
This allows e.g. starting a server to be reverse-proxied on a multi-user
system, using the filesystem to handle access control and avoiding need
to allocate port numbers.
Before this change, etherpad-lite starts without error when configured
to listen on a Unix domain socket in this manner. However, `pad.js` and
`ace2_common.js` are generated incorrecting, causing an error
"Uncaught Error: The module at "ep_etherpad-lite/static/js/rjquery" does not exist."
when loading the editor:
When settings.port is a non-numeric string, e.g. `etherpad.sock`, a URI
of the form `http://localhost:etherpad.sock/static/js/rjquery.js` is
generated and parsed to find the file needed. In this case, the file
searched for is `:etherpad.sock/static/js/rjquery.js`, rather than the
expected `static/js/rjquery.js`. No such file exists, and the required
code is silently omitted from the bundle.
As a workaround, hard-code a (meaningless) hostname which can be parsed
correctly, since the current code makes no use of it anyway.
This meant plumbing a callback through to `compressCSS()`, which meant that
I had to alter the innards of `getFileCompressed()`. I tried to leave that
function looking more understandable than when I found it; for example, I
flattened out the nested `if`.
I went ahead and upgraded the version of `clean-css` while I was in the
territory.