allow masks to support | without having to surround with parenthesis
Massimo Melina committed
Mar 23, 2023 at 21:17 UTC
25ef194ce462dd6fb19086d5052973b0ec387df6
6 files changed
+17
-19
plugins/vhosting/plugin.js
+2
-2
@@ -18,7 +18,7 @@ exports.config = {
18
}
19
20
exports.init = api => {
21
- const { isMatch } = api.require('micromatch')
21
+ const { matches } = api.require('./misc')
22
return {
23
middleware(ctx) {
24
let toModify = ctx
@@ -33,7 +33,7 @@ exports.init = api => {
33
const hosts = api.getConfig('hosts')
34
if (!hosts?.length) return
35
for (const row of hosts)
36
- if (isMatch(ctx.host, row.host)) {
36
+ if (matches(ctx.host, row.host)) {
37
toModify.path = row.root + toModify.path
38
return
39
}
src/api.vfs.ts
+2
-3
@@ -5,12 +5,11 @@ import _ from 'lodash'
5
import { stat } from 'fs/promises'
6
import { ApiError, ApiHandlers } from './apiMiddleware'
7
import { dirname, join, resolve } from 'path'
8
-import { dirStream, isWindowsDrive, newObj } from './misc'
8
+import { dirStream, isWindowsDrive, matches, newObj } from './misc'
9
import {
10
IS_WINDOWS,
11
HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR, HTTP_CONFLICT, HTTP_NOT_ACCEPTABLE,
12
} from './const'
13
-import { isMatch } from 'micromatch'
13
import { getDrives } from './util-os'
14
import { Stats } from 'fs'
15
@@ -173,7 +172,7 @@ const apis: ApiHandlers = {
172
return
173
try {
174
if (!isDir)
176
- if (!files || fileMask && !isMatch(name, fileMask))
175
+ if (!files || fileMask && !matches(name, fileMask))
176
continue
177
const stats = await stat(join(path, name))
178
yield {
src/misc.ts
+5
-5
@@ -172,15 +172,15 @@ export function isLocalHost(c: Connection | Koa.Context) {
172
return ip && (ip === '::1' || ip.endsWith('127.0.0.1'))
173
}
174
175
-export function matchesNet(ip: Koa.Context | string, mask: string, emptyReturns=false) {
176
- if (!mask)
177
- return emptyReturns
175
+export function matchesNet(ip: Koa.Context | string, mask: string, emptyMaskReturns=false) {
176
if (typeof ip !== 'string')
177
ip = ip.ip
180
- return matches(ip, mask)
178
+ return matches(ip, mask, emptyMaskReturns)
179
}
180
183
-function matches(s: string, mask: string) {
181
+export function matches(s: string, mask: string, emptyMaskReturns=false) {
182
+ if (!mask)
183
+ return emptyMaskReturns
184
return isMatch(s, '(' + mask + ')') // adding () will allow us to use the pipe at root level
185
}
186
src/serveFile.ts
+4
-4
@@ -14,7 +14,7 @@ import {
14
import { getNodeName, MIME_AUTO, VfsNode } from './vfs'
15
import mimetypes from 'mime-types'
16
import { defineConfig } from './config'
17
-import { isMatch } from 'micromatch'
17
+import { matches } from './misc'
18
import _ from 'lodash'
19
import path from 'path'
20
import { promisify } from 'util'
@@ -25,12 +25,12 @@ export function serveFileNode(ctx: Koa.Context, node: VfsNode) {
25
const { source, mime } = node
26
const name = getNodeName(node)
27
const mimeString = typeof mime === 'string' ? mime
28
- : _.find(mime, (val,mask) => isMatch(name, mask))
28
+ : _.find(mime, (val,mask) => matches(name, mask))
29
const allowed = allowedReferer.get()
30
if (allowed) {
31
const ref = /\/\/([^:/]+)/.exec(ctx.get('referer'))?.[1] // extract host from url
32
if (ref && ref !== host() // automatic accept if referer is basically the hosting domain
33
- && !isMatch(ref, allowed))
33
+ && !matches(ref, allowed))
34
return ctx.status = HTTP_FORBIDDEN
35
36
function host() {
@@ -51,7 +51,7 @@ export async function serveFile(ctx: Koa.Context, source:string, mime?:string, c
51
const fn = path.basename(source)
52
if ('dl' in ctx.params) // please, download
53
ctx.attachment(fn)
54
- mime = mime ?? _.find(mimeCfg.get(), (v,k) => k>'' && isMatch(fn, k)) // isMatch throws on an empty string
54
+ mime = mime ?? _.find(mimeCfg.get(), (v,k) => matches(fn, k, ))
55
if (mime === MIME_AUTO)
56
mime = mimetypes.lookup(source) || ''
57
if (mime)
src/vfs.ts
+3
-4
@@ -2,8 +2,7 @@
2
3
import fs from 'fs/promises'
4
import { basename, dirname, join, resolve } from 'path'
5
-import { isMatch } from 'micromatch'
6
-import { dirStream, dirTraversal, enforceFinal, getOrSet, isDirectory, typedKeys } from './misc'
5
+import { matches, dirStream, dirTraversal, enforceFinal, getOrSet, isDirectory, typedKeys } from './misc'
6
import Koa from 'koa'
7
import _ from 'lodash'
8
import { defineConfig, setConfig } from './config'
@@ -246,8 +245,8 @@ function applyMasks(item: VfsNode, parent: VfsNode, virtualBasename: string) {
245
const { masks } = parent
246
if (!masks) return
247
for (const [k,v] of Object.entries(masks))
249
- if (k.startsWith('**/') && isMatch(virtualBasename, k.slice(3))
250
- || !k.includes('/') && isMatch(virtualBasename, k))
248
+ if (k.startsWith('**/') && matches(virtualBasename, k.slice(3))
249
+ || !k.includes('/') && matches(virtualBasename, k))
250
_.defaults(item, v)
251
}
252
tests/config.yaml
+1
-1
@@ -62,7 +62,7 @@ vfs:
62
- name: cantReadPage
63
source: tests
64
masks:
65
- (page|*.ts|*.yaml):
65
+ page|*.ts|*.yaml:
66
can_read: false
67
can_list: false
68
- name: cantReadRealFolder