Skip to content

Commit fa32d63

Browse files
committed
Migrate to Express v5
1 parent 2caddca commit fa32d63

6 files changed

Lines changed: 386 additions & 103 deletions

File tree

lib/create-app.mjs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ function createApp (argv = {}) {
117117
}
118118

119119
// Options handler
120-
app.options('/*', options)
120+
app.options(/.*/, options)
121121

122122
// Set up API
123123
if (argv.apiApps) {
@@ -138,20 +138,11 @@ function createApp (argv = {}) {
138138

139139
// https://stackoverflow.com/questions/51741383/nodejs-express-return-405-for-un-supported-method
140140
app.use(function (req, res, next) {
141-
const AllLayers = app._router.stack
142-
const Layers = AllLayers.filter(x => x.name === 'bound dispatch' && x.regexp.test(req.path))
141+
const router = app._router || app.router
142+
const Methods = allowedMethodsForPath(router?.stack || [], req.path)
143143

144-
const Methods = []
145-
Layers.forEach(layer => {
146-
for (const method in layer.route.methods) {
147-
if (layer.route.methods[method] === true) {
148-
Methods.push(method.toUpperCase())
149-
}
150-
}
151-
})
152-
153-
if (Layers.length !== 0 && !Methods.includes(req.method)) {
154-
// res.setHeader('Allow', Methods.join(','))
144+
if (Methods.length !== 0 && !Methods.includes(req.method)) {
145+
res.setHeader('Allow', Methods.join(', '))
155146

156147
if (req.method === 'OPTIONS') {
157148
return res.send(Methods.join(', '))
@@ -369,4 +360,34 @@ function sessionSettings (secureCookies, host) {
369360
return sessionSettings
370361
}
371362

363+
function allowedMethodsForPath (layers, path, methods = new Set()) {
364+
for (const layer of layers) {
365+
if (layer.route && layerMatchesPath(layer, path)) {
366+
for (const method in layer.route.methods) {
367+
if (layer.route.methods[method] === true) {
368+
methods.add(method.toUpperCase())
369+
if (method === 'get') methods.add('HEAD')
370+
}
371+
}
372+
} else if (layer.handle?.stack && layerMatchesPath(layer, path)) {
373+
allowedMethodsForPath(layer.handle.stack, path, methods)
374+
}
375+
}
376+
377+
return orderMethods([...methods])
378+
}
379+
380+
function layerMatchesPath (layer, path) {
381+
if (typeof layer.match === 'function') {
382+
return layer.match(path)
383+
}
384+
385+
return layer.regexp?.test(path)
386+
}
387+
388+
function orderMethods (methods) {
389+
const methodOrder = ['OPTIONS', 'HEAD', 'GET', 'PATCH', 'POST', 'PUT', 'DELETE']
390+
return methodOrder.filter(method => methods.includes(method))
391+
}
392+
372393
export default createApp

lib/create-server.mjs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function createServer (argv, app) {
8585
redirectHttpFroms.forEach(redirectHttpFrom => {
8686
debug.settings('will redirect from port ' + redirectHttpFrom + ' to port ' + argv.port)
8787
const redirectingServer = express()
88-
redirectingServer.get('*', function (req, res) {
88+
redirectingServer.get(/.*/, function (req, res) {
8989
const host = req.headers.host.split(':') // ignore port
9090
debug.server(host, '=> https://' + host + portStr + req.url)
9191
res.redirect('https://' + host + portStr + req.url)
@@ -96,7 +96,7 @@ function createServer (argv, app) {
9696

9797
// Setup Express app
9898
if (ldp.live) {
99-
const solidWs = SolidWs(server, ldpApp)
99+
const solidWs = SolidWs(server, express5WildcardCompat(ldpApp))
100100
ldpApp.locals.ldp.live = solidWs.publish.bind(solidWs)
101101
}
102102

@@ -125,4 +125,15 @@ function createServer (argv, app) {
125125
return server
126126
}
127127

128+
function express5WildcardCompat (app) {
129+
const wrappedApp = Object.create(app)
130+
for (const method of ['post', 'patch', 'put', 'delete']) {
131+
wrappedApp[method] = function (path, ...handlers) {
132+
const route = path === '/*' ? /.*/ : path
133+
return app[method](route, ...handlers)
134+
}
135+
}
136+
return wrappedApp
137+
}
138+
128139
export default createServer

lib/handlers/auth-proxy.mjs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ function addAuthProxyHandler (app, sourcePath, target) {
3838

3939
// Activate the proxy
4040
const proxy = createProxyMiddleware(settings)
41+
const route = sourcePathRoute(sourcePath)
4142
for (const action in REQUIRED_PERMISSIONS) {
4243
const permissions = REQUIRED_PERMISSIONS[action]
43-
app[action](`${sourcePath}*`, setOriginalUrl, ...permissions.map(allow), proxy)
44+
app[action](route, setOriginalUrl, ...permissions.map(allow), proxy)
4445
}
4546
}
4647

48+
function sourcePathRoute (sourcePath) {
49+
const escapedPath = sourcePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
50+
return new RegExp(`^${escapedPath}(?:/.*)?$`)
51+
}
52+
4753
// Adds a headers with authentication information
4854
function addAuthHeaders (proxyReq, req) {
4955
const { session = {}, headers = {} } = req

lib/ldp-middleware.mjs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import notify from './handlers/notify.mjs'
1212

1313
export default function LdpMiddleware (corsSettings, prep) {
1414
const router = express.Router('/')
15+
const allResources = /.*/
1516

1617
// Add Link headers
1718
router.use(linksHandler)
@@ -20,18 +21,18 @@ export default function LdpMiddleware (corsSettings, prep) {
2021
router.use(corsSettings)
2122
}
2223

23-
router.copy('/*', allow('Write'), copy)
24-
router.get('/*', index, allow('Read'), addPermissions, get)
25-
router.post('/*', allow('Append'), post)
26-
router.patch('/*', allow('Append'), patch)
27-
router.put('/*', allow('Append'), put)
28-
router.delete('/*', allow('Write'), del)
24+
router.copy(allResources, allow('Write'), copy)
25+
router.get(allResources, index, allow('Read'), addPermissions, get)
26+
router.post(allResources, allow('Append'), post)
27+
router.patch(allResources, allow('Append'), patch)
28+
router.put(allResources, allow('Append'), put)
29+
router.delete(allResources, allow('Write'), del)
2930

3031
if (prep) {
31-
router.post('/*', notify)
32-
router.patch('/*', notify)
33-
router.put('/*', notify)
34-
router.delete('/*', notify)
32+
router.post(allResources, notify)
33+
router.patch(allResources, notify)
34+
router.put(allResources, notify)
35+
router.delete(allResources, notify)
3536
}
3637

3738
return router

0 commit comments

Comments
 (0)