Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e8f47fd
Hand these commands their arguments instead of a command line
Sep 27, 2026
bfa04d4
Tell a failed OIDC sign-in apart, and come back to the right address
Sep 26, 2026
3698d6c
Say what the cache directory holds, and what the process is costing
Sep 26, 2026
31ed5c4
Let the preview's ceiling be set, and stop a proxy keeping a listing
Sep 26, 2026
dd0bf16
Open the database once, and compile a statement once
Sep 26, 2026
6e2d75c
Remember a folder's sort and view as rows, not as one value per account
Sep 26, 2026
1b34959
Ask where to put something, and offer the folders somebody actually uses
Sep 26, 2026
d87820f
Give the archive bounds a number, and read a size written with a capi…
Sep 26, 2026
d545ab4
Ask the filesystem how full it is, instead of asking a shell
Sep 26, 2026
cf736a6
What a share permits, and what its owner can see of it
Sep 27, 2026
86d1434
Catalogue a folder named build, and say how a result was found
Sep 27, 2026
f340db3
Hand chown its arguments instead of a command line, and let a rule hi…
Sep 27, 2026
704f62e
Say that an account is locked out, and let an administrator unlock it
Sep 27, 2026
ac7b648
Say what kind of file this is, and what a folder weighs
Sep 27, 2026
9d4d8ee
Move what pointed at a folder with the folder, and forget it with the…
Sep 27, 2026
6cd2332
A copy that says how far it has got, and can be stopped
Sep 27, 2026
e3e64fb
Fall back to chunks when the direct upload is refused, and only then
Sep 27, 2026
2ef2a28
Write a folder's address with its slashes, and keep each guard a func…
Sep 27, 2026
d4673f3
Restore somewhere else, and put a version back without losing the file
Sep 27, 2026
c65bf3d
Render a long Markdown document in pieces, and keep the scroll where …
Sep 27, 2026
55fa434
Say what a deletion will actually do, before it does it
Sep 27, 2026
12af3bd
Say what went wrong in words the reader can act on
Sep 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ const express = require('express');
const cookieParser = require('cookie-parser');

const { configureTrustProxy } = require('./middleware/trustProxy');
const { forwardedAddressWarning } = require('./utils/clientAddress');
const { configureSecurityHeaders } = require('./middleware/securityHeaders');
const { requestContextMiddleware } = require('./utils/requestContext');
const { uploads } = require('./config/index');
const { configureHttpLogging } = require('./middleware/logging');
const { configureCors } = require('./middleware/cors');
const { configureOidc } = require('./middleware/oidc');
const { configureHttpsWarning } = require('./middleware/httpsWarning');
const { requestContextMiddleware } = require('./utils/requestContext');
const { forwardedAddressWarning } = require('./utils/clientAddress');
const authMiddleware = require('./middleware/authMiddleware');
const { heldRequestLogger } = require('./middleware/heldRequests');
const registerRoutes = require('./routes');
const { configureStaticFiles } = require('./utils/staticServer');
const { bootstrap } = require('./utils/bootstrap');
const { configureSession } = require('./middleware/session');
const logger = require('./utils/logger');
const { errorHandler, notFoundHandler } = require('./middleware/errorHandler');
const { uploads } = require('./config');

/**
* Creates and configures the Express application.
Expand Down Expand Up @@ -51,16 +52,46 @@ const createApp = async (options = {}) => {
// a client this server was not told to believe: without it every recorded
// address is the proxy's and nothing anywhere says why.
app.use(forwardedAddressWarning);
// Opens the per-request scratch space early, so everything downstream can
// memoize work that must not be reused by the next request.
app.use(requestContextMiddleware);
configureSecurityHeaders(app);
configureHttpLogging(app);

configureCors(app);
// Large enough to carry back whatever the text editor was allowed to open;
// see the reasoning beside the two limits in the configuration.

// Before everything that could hold a request, so that what it reports is
// the whole of the chain below it.
app.use(heldRequestLogger);

// Liveness, before anything that could hold a request.
//
// These were mounted with the rest of the routes, which put them behind the
// session store, the OpenID Connect middleware and the authorization layer.
// A probe that travels through all of that does not answer "is this
// container alive" — it answers "is the identity provider reachable, and is
// the session store responding", and a container was reported unhealthy for
// ten minutes while the application it runs was serving pages perfectly.
//
// Nothing here reads a cookie, a database or the network, so there is no
// state it could wait on.
app.use('/', require('./routes/health'));

// A selection of a few thousand files is a normal request here, and its list
// of paths outgrows the 100 kB Express allows by default.
app.use(express.json({ limit: uploads.maxJsonBodyBytes }));
app.use(express.urlencoded({ extended: true, limit: uploads.maxJsonBodyBytes }));

// Express 5 leaves `req.body` undefined when no parser above matched the
// request's content type, where Express 4 left an empty object. Every route
// in this application was written against the empty object — and the ones
// asking `'field' in req.body` do not fail politely, they throw a TypeError
// and answer 500 to a request whose only fault is a missing header.
app.use((req, _res, next) => {
if (req.body === undefined) req.body = {};
next();
});
app.use(cookieParser());
app.use(requestContextMiddleware);
logger.debug('Mounted cookie parser middleware');

if (!skipBootstrap) {
Expand Down
242 changes: 187 additions & 55 deletions backend/src/config/env.js

Large diffs are not rendered by default.

Loading
Loading