fix: ipv6 wasn't working

Massimo Melina committed Mar 18, 2022 at 15:50 UTC da616fe7ffa65ce6ec17b1f60ecd9fd5482ad87c
4 files changed +22 -12
server/src/adminApis.ts
+5 -1
@@ -109,6 +109,10 @@ for (const k in adminApis) {
109 }
110
111 export function ctxAdminAccess(ctx: Koa.Context) {
112 - return ctx.ip === '127.0.0.1'
112 + return isLocalHost(ctx.ip)
113 || getFromAccount(ctx.state.account, a => a.admin)
114 }
115 +
116 +function isLocalHost(s: string) {
117 + return s === '127.0.0.1' || s == '::1'
118 +}
server/src/listen.ts
+2 -2
@@ -81,7 +81,7 @@ async function considerHttps() {
81 }
82
83 interface StartServer { port: number, net?:string }
84 -function startServer(srv: typeof httpSrv, { port, net='0.0.0.0' }: StartServer) {
84 +function startServer(srv: typeof httpSrv, { port, net }: StartServer) {
85 return new Promise<number>((resolve, reject) => {
86 try {
87 if (port < 0)
@@ -94,7 +94,7 @@ function startServer(srv: typeof httpSrv, { port, net='0.0.0.0' }: StartServer)
94 srv.close()
95 return reject('type of socket not supported')
96 }
97 - console.log(srv.name, "serving on", net, ':', ad.port)
97 + console.log(srv.name, "serving on", net||"anything", ':', ad.port)
98 resolve(ad.port)
99 }).on('error', async e => {
100 srv.error = String(e)
server/src/middlewares.ts
-7
@@ -58,13 +58,6 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
58 const { path } = ctx
59 if (ctx.body)
60 return next()
61 - const allowedRef = getConfig('allowed_referer')
62 - if (allowedRef) {
63 - const ref = /\/\/([^:/]+)/.exec(ctx.get('referer'))?.[1] // extract host from url
64 - if (ref && ref !== ctx.get('host')?.split(':')[0] // automatic accept if referer is basically the hosting domain
65 - && !isMatch(ref, allowedRef))
66 - return ctx.status = FORBIDDEN
67 - }
61 if (path.startsWith(FRONTEND_URI))
62 return serveFrontendPrefixed(ctx,next)
63 if (path+'/' === ADMIN_URI)
server/src/serveFile.ts
+15 -2
@@ -3,7 +3,7 @@
3 import Koa from 'koa'
4 import { createReadStream, stat } from 'fs'
5 import fs from 'fs/promises'
6 -import { METHOD_NOT_ALLOWED, NO_CONTENT } from './const'
6 +import { FORBIDDEN, METHOD_NOT_ALLOWED, NO_CONTENT } from './const'
7 import { getNodeName, MIME_AUTO, VfsNode } from './vfs'
8 import mimetypes from 'mime-types'
9 import { defineConfig, getConfig } from './config'
@@ -11,7 +11,7 @@ import mm, { isMatch } from 'micromatch'
11 import _ from 'lodash'
12 import path from 'path'
13 import { promisify } from 'util'
14 -import { socket2connection, updateConnection } from './connections'
14 +import { updateConnection } from './connections'
15
16 export function serveFileNode(node: VfsNode) : Koa.Middleware {
17 const { source, mime } = node
@@ -19,6 +19,19 @@ export function serveFileNode(node: VfsNode) : Koa.Middleware {
19 const mimeString = typeof mime === 'string' ? mime
20 : _.find(mime, (val,mask) => isMatch(name, mask))
21 return (ctx, next) => {
22 + const allowedRef = getConfig('allowed_referer')
23 + if (allowedRef) {
24 + const ref = /\/\/([^:/]+)/.exec(ctx.get('referer'))?.[1] // extract host from url
25 + if (ref && ref !== host() // automatic accept if referer is basically the hosting domain
26 + && !isMatch(ref, allowedRef))
27 + return ctx.status = FORBIDDEN
28 +
29 + function host() {
30 + const s = ctx.get('host')
31 + return s[0] === '[' ? s.slice(1, s.indexOf(']')) : s?.split(':')[0]
32 + }
33 + }
34 +
35 ctx.vfsNode = node // useful to tell service files from files shared by the user
36 return serveFile(source||'', mimeString)(ctx, next)
37 }