diff --git a/README.md b/README.md index 2303093..b32f87b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ To run filething, run ```BASH bun --cwd=./ui install -bun --bun --cwd=./ui run generate +RENDERING_MODE=static bun --bun --cwd=./ui run generate go build -tags netgo -ldflags=-s DB_HOST=localhost:5432 DB_NAME=filething DB_USER=postgres STORAGE_PATH=data ./filething ``` diff --git a/go.mod b/go.mod index b4b0442..13410ad 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/bytedance/sonic v1.12.3 github.com/gofiber/fiber/v3 v3.0.0-beta.3 github.com/google/uuid v1.6.0 + github.com/yeqown/fasthttp-reverse-proxy/v2 v2.2.3 ) require ( @@ -14,30 +15,18 @@ require ( github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/fasthttp/websocket v1.5.8 // indirect - github.com/gofiber/contrib v1.0.1 // indirect - github.com/gofiber/contrib/websocket v1.3.2 // indirect - github.com/gofiber/fiber/v2 v2.52.5 // indirect github.com/gofiber/utils/v2 v2.0.0-beta.4 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/philhofer/fwd v1.1.2 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/rivo/uniseg v0.2.0 // indirect github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect - github.com/tinylib/msgp v1.1.8 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/fasthttp v1.55.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - github.com/yeqown/fasthttp-reverse-proxy v0.0.0-20200930023507-ed73ac32bc64 // indirect - github.com/yeqown/fasthttp-reverse-proxy/v2 v2.2.3 // indirect - github.com/yeqown/log v1.0.3 // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect ) require ( github.com/dustin/go-humanize v1.0.1 - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/labstack/echo/v4 v4.12.0 github.com/labstack/gommon v0.4.2 // indirect @@ -56,6 +45,5 @@ require ( golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.5.0 // indirect mellium.im/sasl v0.3.1 // indirect ) diff --git a/go.sum b/go.sum index 3c7b0d6..9b48b13 100644 --- a/go.sum +++ b/go.sum @@ -14,30 +14,18 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/fasthttp/websocket v1.4.1 h1:fisgNMCNCbIPM5GRRRTAckRrynbSzf76fevcJYJYnSM= -github.com/fasthttp/websocket v1.4.1/go.mod h1:toetUvZ3KISxtZERe0wzPPpnaN8GZCKHCowWctwA50o= github.com/fasthttp/websocket v1.5.8 h1:k5DpirKkftIF/w1R8ZzjSgARJrs54Je9YJK37DL/Ah8= github.com/fasthttp/websocket v1.5.8/go.mod h1:d08g8WaT6nnyvg9uMm8K9zMYyDjfKyj3170AtPRuVU0= -github.com/gofiber/contrib v1.0.1 h1:pQ8pQ2e8qBQ4koUGRZ4+wCSHUOip8FpjmPOhRTp+DlU= -github.com/gofiber/contrib v1.0.1/go.mod h1:e15MOdipEOlXrU5SUT5p0tfkZkhzDqfdiT2kfRYy1c0= -github.com/gofiber/contrib/websocket v1.3.2 h1:AUq5PYeKwK50s0nQrnluuINYeep1c4nRCJ0NWsV3cvg= -github.com/gofiber/contrib/websocket v1.3.2/go.mod h1:07u6QGMsvX+sx7iGNCl5xhzuUVArWwLQ3tBIH24i+S8= -github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo= -github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= github.com/gofiber/fiber/v3 v3.0.0-beta.3 h1:7Q2I+HsIqnIEEDB+9oe7Gadpakh6ZLhXpTYz/L20vrg= github.com/gofiber/fiber/v3 v3.0.0-beta.3/go.mod h1:kcMur0Dxqk91R7p4vxEpJfDWZ9u5IfvrtQc8Bvv/JmY= github.com/gofiber/utils/v2 v2.0.0-beta.4 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co= github.com/gofiber/utils/v2 v2.0.0-beta.4/go.mod h1:sdRsPU1FXX6YiDGGxd+q2aPJRMzpsxdzCXo9dz+xtOY= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= @@ -50,34 +38,21 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= -github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/savsgio/gotils v0.0.0-20190714152828-365999d0a274 h1:F52t1X2ziOrMcQMVHo8ZxwOrDTMAq6MrlKtL1Atu2wU= -github.com/savsgio/gotils v0.0.0-20190714152828-365999d0a274/go.mod h1:w803/Fg1m0hrp1ZT9KNfQe4E4+WOMMFLcgzPvOcye10= github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8= github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= -github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= @@ -90,69 +65,30 @@ github.com/uptrace/bun/driver/pgdriver v1.2.3 h1:VA5TKB0XW7EtreQq2R8Qu/vCAUX2ECa github.com/uptrace/bun/driver/pgdriver v1.2.3/go.mod h1:yDiYTZYd4FfXFtV01m4I/RkI33IGj9N254jLStaeJLs= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.4.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8= github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/yeqown/fasthttp-reverse-proxy v0.0.0-20200930023507-ed73ac32bc64 h1:4dmnKp9YO5u6MACmB2p4FrEtDV8MNx438A9/N0kPIfg= -github.com/yeqown/fasthttp-reverse-proxy v0.0.0-20200930023507-ed73ac32bc64/go.mod h1:hgX6t+JE03QfTU4mpF0ls1FJa+Y/49wcG7++6d6apu8= github.com/yeqown/fasthttp-reverse-proxy/v2 v2.2.3 h1:qAWBk2OIFbtM3jB6ujXMwNybdV5h4XnRzGhJ/RkLXZQ= github.com/yeqown/fasthttp-reverse-proxy/v2 v2.2.3/go.mod h1:hiv7dfheax7undE0lIpPI8OaMBCVT9nWfxRP8KWz4o0= -github.com/yeqown/log v1.0.3 h1:kWwBMytMSkYkr2fmi20PLgDuJNXkq3mOpVbfsTS1soI= -github.com/yeqown/log v1.0.3/go.mod h1:RTslXFTg+8Uj5AizIxdfichvBZi/OOKao6yP3tMtTns= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go index f03b7e3..0a1a3ad 100644 --- a/main.go +++ b/main.go @@ -40,6 +40,7 @@ func main() { JSONDecoder: sonic.Unmarshal, DisablePreParseMultipartForm: true, BodyLimit: 100 * 1024 * 1024 * 1024, + StreamRequestBody: true, }) app.Use(pprof.New()) @@ -67,6 +68,7 @@ func main() { api.Get("/user", routes.GetUser) api.Post("/files/upload*", routes.UploadFile) + // api.Post("/files/upload/chunked*", routes.UploadFileInChunks) api.Get("/files/get/*", routes.GetFiles) api.Get("/files/download*", routes.GetFile) api.Post("/files/delete*", routes.DeleteFiles) @@ -85,7 +87,7 @@ func main() { // redirects to the proper pages if you are trying to access one that expects you have/dont have an api key // this isnt explicitly required, but it provides a better experience than doing this same thing clientside - app.Use(middleware.AuthCheckMiddleware) + app.Use(middleware.AuthCheckMiddleware(db)) // calls out to a function set by either server.go server_dev.go based on the presence of the dev tag, and hosts // either the static files that get embedded into the binary in ui/embed.go or proxies the dev server that gets diff --git a/middleware/route.go b/middleware/route.go index 6c1a29c..5d00125 100644 --- a/middleware/route.go +++ b/middleware/route.go @@ -1,9 +1,14 @@ package middleware import ( + "context" + "filething/models" + "fmt" "strings" "github.com/gofiber/fiber/v3" + "github.com/google/uuid" + "github.com/uptrace/bun" ) var unauthenticatedPages = []string{ @@ -14,36 +19,62 @@ var unauthenticatedPages = []string{ var authenticatedPages = []string{ "/home", + "/admin", } -func AuthCheckMiddleware(c fiber.Ctx) error { - path := c.Path() +func AuthCheckMiddleware(db *bun.DB) func(c fiber.Ctx) error { + return func(c fiber.Ctx) error { + path := c.Path() + + // bypass auth checks for static and dev resources + if strings.HasPrefix(path, "/_nuxt/") || strings.HasSuffix(path, ".js") || strings.HasSuffix(path, ".css") { + return c.Next() + } + + var authenticated bool = true + sessionToken := c.Cookies("sessionToken") + if sessionToken == "" { + authenticated = false + } + + // Parse session ID + sessionId, err := uuid.Parse(sessionToken) + if err != nil { + authenticated = false + } + + // Fetch session from database + session := &models.Session{ + ID: sessionId, + } + err = db.NewSelect().Model(session).WherePK().Scan(context.Background()) + + if err != nil { + authenticated = false + } + + if Contains(unauthenticatedPages, path) && authenticated { + fmt.Println("unauthenticated page", path, authenticated) + return c.Redirect().To("/home") + } + + if Contains(authenticatedPages, path) && !authenticated { + fmt.Println("authenticated page", path, authenticated) + return c.Redirect().To("/login") + } + + if strings.Contains(path, "/home") && !authenticated { + fmt.Println("home page", path, authenticated) + return c.Redirect().To("/login") + } + + if strings.Contains(path, "/admin") && !authenticated { + fmt.Println("admin page", path, authenticated) + return c.Redirect().To("/login") + } - // bypass auth checks for static and dev resources - if strings.HasPrefix(path, "/_nuxt/") || strings.HasSuffix(path, ".js") || strings.HasSuffix(path, ".css") { return c.Next() } - - cookie := c.Cookies("sessionToken") - authenticated := cookie != "" - - if Contains(unauthenticatedPages, path) && authenticated { - return c.Redirect().To("/home") - } - - if Contains(authenticatedPages, path) && !authenticated { - return c.Redirect().To("/login") - } - - if strings.Contains(path, "/home") && !authenticated { - return c.Redirect().To("/login") - } - - if strings.Contains(path, "/admin") && !authenticated { - return c.Redirect().To("/login") - } - - return c.Next() } func Contains(s []string, element string) bool { diff --git a/routes/files.go b/routes/files.go index 590783d..a5722ff 100644 --- a/routes/files.go +++ b/routes/files.go @@ -6,6 +6,9 @@ import ( "filething/models" "fmt" "io" + "log" + "mime" + "mime/multipart" "net/http" "net/url" "os" @@ -44,8 +47,7 @@ func UploadFile(c fiber.Ctx) error { } } - form, err := c.MultipartForm() - if err != nil { + if string(c.Request().Header.ContentType()) == "application/json" { if err == http.ErrNotMultipart { if directoryExists { // Directories exist, but no file was uploaded @@ -75,9 +77,20 @@ func UploadFile(c fiber.Ctx) error { return err } - file := form.File["file"][0] + _, params, err := mime.ParseMediaType(string(c.Request().Header.ContentType())) + if err != nil { + log.Fatal(err) + } - filepath := filepath.Join(basePath, file.Filename) + reader := multipart.NewReader(c.Request().BodyStream(), params["boundary"]) + + part, err := reader.NextPart() + if err != nil { + fmt.Println(err) + return err + } + + filepath := filepath.Join(basePath, part.FileName()) if _, err = os.Stat(filepath); err == nil { return c.Status(http.StatusConflict).JSON(fiber.Map{"message": "File with that name already exists"}) @@ -94,14 +107,8 @@ func UploadFile(c fiber.Ctx) error { buffer := make([]byte, 1*1024*1024) totalSize := int64(0) - fd, err := file.Open() - if err != nil { - fmt.Println(err) - return err - } - for { - n, readErr := fd.Read(buffer) + n, readErr := part.Read(buffer) if readErr != nil && readErr == io.ErrUnexpectedEOF { dst.Close() diff --git a/server.go b/server.go index 5e0f2a1..f700255 100644 --- a/server.go +++ b/server.go @@ -5,10 +5,11 @@ package main import ( "filething/ui" - "fmt" "io/fs" + "net/http" "path/filepath" "strings" + "time" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/static" @@ -22,59 +23,57 @@ type embeddedFS struct { func (fs *embeddedFS) Open(name string) (fs.File, error) { // Prepend the prefix to the requested file name publicPath := filepath.Join(fs.prefix, name) - fmt.Println("Reading file:", publicPath) file, err := fs.baseFS.Open(publicPath) if err != nil { - return nil, fmt.Errorf("file not found: %s", publicPath) + return nil, fiber.ErrNotFound } - fmt.Println("File found:", publicPath, file) - return file, err } var publicFS = &embeddedFS{ baseFS: ui.DistDir, - prefix: "public/", + prefix: ".output/public/", } func init() { initUi = func(app *fiber.App) { - app.Get("/*", static.New("", static.Config{ - FS: publicFS, + app.Use("/", static.New("", static.Config{ + FS: publicFS, + CacheDuration: 10 * time.Hour, })) + // 404 handler app.Use(func(c fiber.Ctx) error { err := c.Next() if err == nil { return nil } - if fiber.ErrNotFound == err { - path := c.Path() - if !strings.HasPrefix(path, "/api") { - file, err := publicFS.Open("404.html") - if err != nil { - c.App().Server().Logger.Printf("Error opening 404.html: %s", err) - return err - } - defer file.Close() - - fileInfo, err := file.Stat() - if err != nil { - c.App().Server().Logger.Printf("An error occurred while getting the file info: %s", err) - return err - } - - fileBuf := make([]byte, fileInfo.Size()) - _, err = file.Read(fileBuf) - if err != nil { - c.App().Server().Logger.Printf("An error occurred while reading the file: %s", err) - return err - } - - return c.Status(fiber.StatusNotFound).SendString(string(fileBuf)) + path := c.Path() + if !strings.HasPrefix(path, "/api") { + file, err := publicFS.Open("404.html") + if err != nil { + c.App().Server().Logger.Printf("Error opening 404.html: %s", err) + return err } + defer file.Close() + + fileInfo, err := file.Stat() + if err != nil { + c.App().Server().Logger.Printf("An error occurred while getting the file info: %s", err) + return err + } + + fileBuf := make([]byte, fileInfo.Size()) + _, err = file.Read(fileBuf) + if err != nil { + c.App().Server().Logger.Printf("An error occurred while reading the file: %s", err) + return err + } + + c.Context().SetContentType("text/html") + return c.Status(http.StatusOK).SendString(string(fileBuf)) } return err }) diff --git a/server_dev.go b/server_dev.go index 4d5604e..dc6b5f8 100644 --- a/server_dev.go +++ b/server_dev.go @@ -11,6 +11,10 @@ import ( fastProxy "github.com/yeqown/fasthttp-reverse-proxy/v2" ) +var ( + proxyServer, _ = fastProxy.NewWSReverseProxyWith(fastProxy.WithURL_OptionWS("ws://localhost:3000/_nuxt/")) +) + func init() { initUi = func(app *fiber.App) { if !fiber.IsChild() { @@ -18,39 +22,20 @@ func init() { } target := "localhost:3000" + app.Get("/_nuxt/", func(c fiber.Ctx) error { + proxyServer.ServeHTTP(c.Context()) + return nil + }) + app.All("/*", func(c fiber.Ctx) error { path := c.Path() if strings.HasPrefix(path, "/api") { return c.Next() } - request := c.Request().URI() - if string(request.RequestURI()) == "/_nuxt/" { - return proxyWebSocket(c, target) - } + requestUri := string(c.Request().URI().RequestURI()) - return proxy.Do(c, "http://"+target+string(request.RequestURI())) + return proxy.Do(c, "http://"+target+requestUri) }) } } - -var proxyServer *fastProxy.ReverseProxy - -func proxyWebSocket(c fiber.Ctx, target string) error { - path := c.Path() - // proxyServer, err := fastProxy.NewWSReverseProxyWith( - // fastProxy.WithURL_OptionWS("ws://localhost:3000"+path), - // fastProxy.WithDynamicPath_OptionWS(true, fastProxy.DefaultOverrideHeader), - // ) - if proxyServer == nil { - proxyServer, err = fastProxy.NewWSReverseProxyWith( - fastProxy.WithURL_OptionWS("ws://localhost:3000"+path), - fastProxy.WithDynamicPath_OptionWS(true, fastProxy.DefaultOverrideHeader), - ) - if err != nil { - panic(err) - } - } - proxyServer.ServeHTTP(c.Context()) - return nil -} diff --git a/server_ssr.go b/server_ssr.go index 2f6cf0c..b07c128 100644 --- a/server_ssr.go +++ b/server_ssr.go @@ -15,34 +15,6 @@ import ( "github.com/gofiber/fiber/v3/middleware/proxy" ) -// func init() { -// initUi = func(app *fiber.App) { -// tmpDir, err := os.MkdirTemp("", "filething-ssr") -// if err != nil { -// panic(err) -// } - -// err = copyEmbeddedFiles(ui.DistDir, ".output", tmpDir) -// if err != nil { -// panic(err) -// } - -// path := filepath.Join(tmpDir, "server/index.mjs") -// spawnProcess("node", []string{path}, app) - -// // target := "localhost:3000" -// // e.Group("/*").Use(echoMiddleware.ProxyWithConfig(echoMiddleware.ProxyConfig{ -// // Balancer: echoMiddleware.NewRoundRobinBalancer([]*echoMiddleware.ProxyTarget{ -// // {URL: &url.URL{ -// // Scheme: "http", -// // Host: target, -// // }}, -// // }), -// // })) -// app.Get("/*", proxy.Forward("http://localhost:3000")) -// } -// } - func init() { initUi = func(app *fiber.App) { if !fiber.IsChild() { @@ -58,6 +30,7 @@ func init() { path := filepath.Join(tmpDir, "server/index.mjs") + // bun is nice, but it still has issues with memory leaks spawnProcess("node", []string{path}, app) } diff --git a/ui/assets/css/main.css b/ui/assets/css/main.css index 63b63d9..a1bdaf4 100644 --- a/ui/assets/css/main.css +++ b/ui/assets/css/main.css @@ -61,4 +61,31 @@ html, body { *:focus-visible { outline: none; +} + +/* input */ +input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="submit"], [type="reset"], [type="button"]), +textarea { + padding: 0.5rem 1rem 0.5rem 1rem; + resize: none; + background-color: rgb(var(--color-overlay)); + border-radius: 0.375rem; + border-width: 1px; + transition: border-color 150ms cubic-bezier(0.4, 0, 0.2, 1); + max-width: 16rem; +} + +input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="submit"], [type="reset"], [type="button"]):hover, +textarea:hover { + border-color: rgb(var(--color-muted) / 0.4); +} + +input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="submit"], [type="reset"], [type="button"]):focus, +textarea:focus { + border-color: rgb(var(--color-muted) / 0.6); +} + +::placeholder { + font-style: italic; + color: rgb(var(--color-subtle)); } \ No newline at end of file diff --git a/ui/components/Input.vue b/ui/components/Input.vue deleted file mode 100644 index 41494c0..0000000 --- a/ui/components/Input.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - \ No newline at end of file diff --git a/ui/layouts/admin.vue b/ui/layouts/admin.vue index 69df947..1058012 100644 --- a/ui/layouts/admin.vue +++ b/ui/layouts/admin.vue @@ -2,10 +2,6 @@ import { useUser } from '~/composables/useUser' const { getUser } = useUser() -definePageMeta({ - middleware: ["auth", "admin"] -}); - const user = await getUser(); const route = useRoute(); diff --git a/ui/middleware/admin.ts b/ui/middleware/admin.ts index 246afbc..964951d 100644 --- a/ui/middleware/admin.ts +++ b/ui/middleware/admin.ts @@ -5,7 +5,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => { const { getUser } = useUser() const user = await getUser() - if (!user || !user.is_admin) { + if (!user.id || !user.is_admin) { return navigateTo('/home') } }) diff --git a/ui/nuxt.config.ts b/ui/nuxt.config.ts index ceae8a9..c76dbaf 100644 --- a/ui/nuxt.config.ts +++ b/ui/nuxt.config.ts @@ -1,6 +1,8 @@ // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ - ssr: true, + // in SSG mode, we dont want to prerender pages since that will do actual API calls + // and cause pages like /admin to literally be a redirect to /login + ssr: process.env.RENDERING_MODE !== 'static', compatibilityDate: '2024-04-03', css: ['~/assets/css/main.css'], @@ -12,7 +14,10 @@ export default defineNuxtConfig({ nitro: { routeRules: { '/api/**': { proxy: 'http://localhost:1323/api/**' }, - '/test/**': { proxy: 'http://localhost:1323/api/**' }, + }, + // these routes never change so we can statically prerender them + prerender: { + routes: ['/login', '/signup', '/'] } }, diff --git a/ui/pages/admin/index.vue b/ui/pages/admin/index.vue index 9a86cf8..8be3ac6 100644 --- a/ui/pages/admin/index.vue +++ b/ui/pages/admin/index.vue @@ -2,7 +2,7 @@ import type { NuxtError } from '#app'; definePageMeta({ - middleware: ["auth", "admin"], + // middleware: ["auth", "admin"], layout: "admin" }); diff --git a/ui/pages/admin/users/[id]/edit.vue b/ui/pages/admin/users/[id]/edit.vue index eb43cd5..a14e5d5 100644 --- a/ui/pages/admin/users/[id]/edit.vue +++ b/ui/pages/admin/users/[id]/edit.vue @@ -45,12 +45,12 @@ let { data: plans } = await useFetch('/api/admin/plans');
- + - +
- +

Leave the password empty to keep it unchanged

diff --git a/ui/pages/admin/users/new.vue b/ui/pages/admin/users/new.vue index 29ba997..ca62c27 100644 --- a/ui/pages/admin/users/new.vue +++ b/ui/pages/admin/users/new.vue @@ -46,11 +46,11 @@ onUnmounted(() => {
- + - + - +

{{ error }}

diff --git a/ui/pages/signup.vue b/ui/pages/signup.vue index e8bfa14..4722d86 100644 --- a/ui/pages/signup.vue +++ b/ui/pages/signup.vue @@ -45,9 +45,9 @@ onUnmounted(() => {

Signup

- - - + + +

{{ error }}

diff --git a/ui/tailwind.config.js b/ui/tailwind.config.js index 7e1455e..c10a021 100644 --- a/ui/tailwind.config.js +++ b/ui/tailwind.config.js @@ -28,7 +28,7 @@ module.exports = { }, transitionProperty: { bg: "background-color", - }, + } }, }, future: {