big bug fixes
This commit is contained in:
@@ -11,7 +11,7 @@ To run filething, run
|
|||||||
|
|
||||||
```BASH
|
```BASH
|
||||||
bun --cwd=./ui install
|
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
|
go build -tags netgo -ldflags=-s
|
||||||
DB_HOST=localhost:5432 DB_NAME=filething DB_USER=postgres STORAGE_PATH=data ./filething
|
DB_HOST=localhost:5432 DB_NAME=filething DB_USER=postgres STORAGE_PATH=data ./filething
|
||||||
```
|
```
|
||||||
|
|||||||
14
go.mod
14
go.mod
@@ -6,6 +6,7 @@ require (
|
|||||||
github.com/bytedance/sonic v1.12.3
|
github.com/bytedance/sonic v1.12.3
|
||||||
github.com/gofiber/fiber/v3 v3.0.0-beta.3
|
github.com/gofiber/fiber/v3 v3.0.0-beta.3
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
|
github.com/yeqown/fasthttp-reverse-proxy/v2 v2.2.3
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -14,30 +15,18 @@ require (
|
|||||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
github.com/fasthttp/websocket v1.5.8 // 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/gofiber/utils/v2 v2.0.0-beta.4 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // indirect
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.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/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/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/valyala/fasthttp v1.55.0 // indirect
|
github.com/valyala/fasthttp v1.55.0 // indirect
|
||||||
github.com/valyala/tcplisten v1.0.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
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dustin/go-humanize v1.0.1
|
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/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/labstack/echo/v4 v4.12.0
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
github.com/labstack/gommon v0.4.2 // indirect
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
@@ -56,6 +45,5 @@ require (
|
|||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.26.0 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
golang.org/x/text v0.18.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
|
mellium.im/sasl v0.3.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
64
go.sum
64
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/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 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
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 h1:k5DpirKkftIF/w1R8ZzjSgARJrs54Je9YJK37DL/Ah8=
|
||||||
github.com/fasthttp/websocket v1.5.8/go.mod h1:d08g8WaT6nnyvg9uMm8K9zMYyDjfKyj3170AtPRuVU0=
|
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 h1:7Q2I+HsIqnIEEDB+9oe7Gadpakh6ZLhXpTYz/L20vrg=
|
||||||
github.com/gofiber/fiber/v3 v3.0.0-beta.3/go.mod h1:kcMur0Dxqk91R7p4vxEpJfDWZ9u5IfvrtQc8Bvv/JmY=
|
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 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co=
|
||||||
github.com/gofiber/utils/v2 v2.0.0-beta.4/go.mod h1:sdRsPU1FXX6YiDGGxd+q2aPJRMzpsxdzCXo9dz+xtOY=
|
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 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
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 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
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 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
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 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
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=
|
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.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 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
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 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4=
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
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 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8=
|
||||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
|
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.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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
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.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.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.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.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 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
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 h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
||||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
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=
|
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/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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
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 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
|
||||||
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
|
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 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
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 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
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 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
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 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
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 h1:qAWBk2OIFbtM3jB6ujXMwNybdV5h4XnRzGhJ/RkLXZQ=
|
||||||
github.com/yeqown/fasthttp-reverse-proxy/v2 v2.2.3/go.mod h1:hiv7dfheax7undE0lIpPI8OaMBCVT9nWfxRP8KWz4o0=
|
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 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
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 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
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 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
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.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.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 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
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 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
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/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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
|||||||
4
main.go
4
main.go
@@ -40,6 +40,7 @@ func main() {
|
|||||||
JSONDecoder: sonic.Unmarshal,
|
JSONDecoder: sonic.Unmarshal,
|
||||||
DisablePreParseMultipartForm: true,
|
DisablePreParseMultipartForm: true,
|
||||||
BodyLimit: 100 * 1024 * 1024 * 1024,
|
BodyLimit: 100 * 1024 * 1024 * 1024,
|
||||||
|
StreamRequestBody: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Use(pprof.New())
|
app.Use(pprof.New())
|
||||||
@@ -67,6 +68,7 @@ func main() {
|
|||||||
api.Get("/user", routes.GetUser)
|
api.Get("/user", routes.GetUser)
|
||||||
|
|
||||||
api.Post("/files/upload*", routes.UploadFile)
|
api.Post("/files/upload*", routes.UploadFile)
|
||||||
|
// api.Post("/files/upload/chunked*", routes.UploadFileInChunks)
|
||||||
api.Get("/files/get/*", routes.GetFiles)
|
api.Get("/files/get/*", routes.GetFiles)
|
||||||
api.Get("/files/download*", routes.GetFile)
|
api.Get("/files/download*", routes.GetFile)
|
||||||
api.Post("/files/delete*", routes.DeleteFiles)
|
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
|
// 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
|
// 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
|
// 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
|
// either the static files that get embedded into the binary in ui/embed.go or proxies the dev server that gets
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"filething/models"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
var unauthenticatedPages = []string{
|
var unauthenticatedPages = []string{
|
||||||
@@ -14,9 +19,11 @@ var unauthenticatedPages = []string{
|
|||||||
|
|
||||||
var authenticatedPages = []string{
|
var authenticatedPages = []string{
|
||||||
"/home",
|
"/home",
|
||||||
|
"/admin",
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthCheckMiddleware(c fiber.Ctx) error {
|
func AuthCheckMiddleware(db *bun.DB) func(c fiber.Ctx) error {
|
||||||
|
return func(c fiber.Ctx) error {
|
||||||
path := c.Path()
|
path := c.Path()
|
||||||
|
|
||||||
// bypass auth checks for static and dev resources
|
// bypass auth checks for static and dev resources
|
||||||
@@ -24,27 +31,51 @@ func AuthCheckMiddleware(c fiber.Ctx) error {
|
|||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie := c.Cookies("sessionToken")
|
var authenticated bool = true
|
||||||
authenticated := cookie != ""
|
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 {
|
if Contains(unauthenticatedPages, path) && authenticated {
|
||||||
|
fmt.Println("unauthenticated page", path, authenticated)
|
||||||
return c.Redirect().To("/home")
|
return c.Redirect().To("/home")
|
||||||
}
|
}
|
||||||
|
|
||||||
if Contains(authenticatedPages, path) && !authenticated {
|
if Contains(authenticatedPages, path) && !authenticated {
|
||||||
|
fmt.Println("authenticated page", path, authenticated)
|
||||||
return c.Redirect().To("/login")
|
return c.Redirect().To("/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(path, "/home") && !authenticated {
|
if strings.Contains(path, "/home") && !authenticated {
|
||||||
|
fmt.Println("home page", path, authenticated)
|
||||||
return c.Redirect().To("/login")
|
return c.Redirect().To("/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(path, "/admin") && !authenticated {
|
if strings.Contains(path, "/admin") && !authenticated {
|
||||||
|
fmt.Println("admin page", path, authenticated)
|
||||||
return c.Redirect().To("/login")
|
return c.Redirect().To("/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Contains(s []string, element string) bool {
|
func Contains(s []string, element string) bool {
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import (
|
|||||||
"filething/models"
|
"filething/models"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
|
"mime"
|
||||||
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -44,8 +47,7 @@ func UploadFile(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
form, err := c.MultipartForm()
|
if string(c.Request().Header.ContentType()) == "application/json" {
|
||||||
if err != nil {
|
|
||||||
if err == http.ErrNotMultipart {
|
if err == http.ErrNotMultipart {
|
||||||
if directoryExists {
|
if directoryExists {
|
||||||
// Directories exist, but no file was uploaded
|
// Directories exist, but no file was uploaded
|
||||||
@@ -75,9 +77,20 @@ func UploadFile(c fiber.Ctx) error {
|
|||||||
return err
|
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 {
|
if _, err = os.Stat(filepath); err == nil {
|
||||||
return c.Status(http.StatusConflict).JSON(fiber.Map{"message": "File with that name already exists"})
|
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)
|
buffer := make([]byte, 1*1024*1024)
|
||||||
totalSize := int64(0)
|
totalSize := int64(0)
|
||||||
|
|
||||||
fd, err := file.Open()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
n, readErr := fd.Read(buffer)
|
n, readErr := part.Read(buffer)
|
||||||
|
|
||||||
if readErr != nil && readErr == io.ErrUnexpectedEOF {
|
if readErr != nil && readErr == io.ErrUnexpectedEOF {
|
||||||
dst.Close()
|
dst.Close()
|
||||||
|
|||||||
19
server.go
19
server.go
@@ -5,10 +5,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"filething/ui"
|
"filething/ui"
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
"github.com/gofiber/fiber/v3/middleware/static"
|
"github.com/gofiber/fiber/v3/middleware/static"
|
||||||
@@ -22,35 +23,33 @@ type embeddedFS struct {
|
|||||||
func (fs *embeddedFS) Open(name string) (fs.File, error) {
|
func (fs *embeddedFS) Open(name string) (fs.File, error) {
|
||||||
// Prepend the prefix to the requested file name
|
// Prepend the prefix to the requested file name
|
||||||
publicPath := filepath.Join(fs.prefix, name)
|
publicPath := filepath.Join(fs.prefix, name)
|
||||||
fmt.Println("Reading file:", publicPath)
|
|
||||||
file, err := fs.baseFS.Open(publicPath)
|
file, err := fs.baseFS.Open(publicPath)
|
||||||
if err != nil {
|
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
|
return file, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var publicFS = &embeddedFS{
|
var publicFS = &embeddedFS{
|
||||||
baseFS: ui.DistDir,
|
baseFS: ui.DistDir,
|
||||||
prefix: "public/",
|
prefix: ".output/public/",
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initUi = func(app *fiber.App) {
|
initUi = func(app *fiber.App) {
|
||||||
app.Get("/*", static.New("", static.Config{
|
app.Use("/", static.New("", static.Config{
|
||||||
FS: publicFS,
|
FS: publicFS,
|
||||||
|
CacheDuration: 10 * time.Hour,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// 404 handler
|
||||||
app.Use(func(c fiber.Ctx) error {
|
app.Use(func(c fiber.Ctx) error {
|
||||||
err := c.Next()
|
err := c.Next()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if fiber.ErrNotFound == err {
|
|
||||||
path := c.Path()
|
path := c.Path()
|
||||||
if !strings.HasPrefix(path, "/api") {
|
if !strings.HasPrefix(path, "/api") {
|
||||||
file, err := publicFS.Open("404.html")
|
file, err := publicFS.Open("404.html")
|
||||||
@@ -73,8 +72,8 @@ func init() {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Status(fiber.StatusNotFound).SendString(string(fileBuf))
|
c.Context().SetContentType("text/html")
|
||||||
}
|
return c.Status(http.StatusOK).SendString(string(fileBuf))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import (
|
|||||||
fastProxy "github.com/yeqown/fasthttp-reverse-proxy/v2"
|
fastProxy "github.com/yeqown/fasthttp-reverse-proxy/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
proxyServer, _ = fastProxy.NewWSReverseProxyWith(fastProxy.WithURL_OptionWS("ws://localhost:3000/_nuxt/"))
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initUi = func(app *fiber.App) {
|
initUi = func(app *fiber.App) {
|
||||||
if !fiber.IsChild() {
|
if !fiber.IsChild() {
|
||||||
@@ -18,39 +22,20 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
target := "localhost:3000"
|
target := "localhost:3000"
|
||||||
|
app.Get("/_nuxt/", func(c fiber.Ctx) error {
|
||||||
|
proxyServer.ServeHTTP(c.Context())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
app.All("/*", func(c fiber.Ctx) error {
|
app.All("/*", func(c fiber.Ctx) error {
|
||||||
path := c.Path()
|
path := c.Path()
|
||||||
if strings.HasPrefix(path, "/api") {
|
if strings.HasPrefix(path, "/api") {
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
request := c.Request().URI()
|
requestUri := string(c.Request().URI().RequestURI())
|
||||||
if string(request.RequestURI()) == "/_nuxt/" {
|
|
||||||
return proxyWebSocket(c, target)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,34 +15,6 @@ import (
|
|||||||
"github.com/gofiber/fiber/v3/middleware/proxy"
|
"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() {
|
func init() {
|
||||||
initUi = func(app *fiber.App) {
|
initUi = func(app *fiber.App) {
|
||||||
if !fiber.IsChild() {
|
if !fiber.IsChild() {
|
||||||
@@ -58,6 +30,7 @@ func init() {
|
|||||||
|
|
||||||
path := filepath.Join(tmpDir, "server/index.mjs")
|
path := filepath.Join(tmpDir, "server/index.mjs")
|
||||||
|
|
||||||
|
// bun is nice, but it still has issues with memory leaks
|
||||||
spawnProcess("node", []string{path}, app)
|
spawnProcess("node", []string{path}, app)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,3 +62,30 @@ html, body {
|
|||||||
*:focus-visible {
|
*:focus-visible {
|
||||||
outline: none;
|
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));
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
const props = defineProps({
|
|
||||||
placeholder: String,
|
|
||||||
type: String | undefined,
|
|
||||||
})
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
|
||||||
|
|
||||||
function updateValue(value) {
|
|
||||||
emit('update:modelValue', value)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input
|
|
||||||
class="py-2 px-4 resize-none bg-overlay rounded-md border hover:border-muted/40 focus:border-muted/60 placeholder:italic placeholder:text-subtle transition-[border-color] max-w-64"
|
|
||||||
:placeholder="placeholder" :type="type" v-on:input="updateValue($event.target.value)" />
|
|
||||||
</template>
|
|
||||||
@@ -2,10 +2,6 @@
|
|||||||
import { useUser } from '~/composables/useUser'
|
import { useUser } from '~/composables/useUser'
|
||||||
const { getUser } = useUser()
|
const { getUser } = useUser()
|
||||||
|
|
||||||
definePageMeta({
|
|
||||||
middleware: ["auth", "admin"]
|
|
||||||
});
|
|
||||||
|
|
||||||
const user = await getUser();
|
const user = await getUser();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
|||||||
const { getUser } = useUser()
|
const { getUser } = useUser()
|
||||||
const user = await getUser()
|
const user = await getUser()
|
||||||
|
|
||||||
if (!user || !user.is_admin) {
|
if (!user.id || !user.is_admin) {
|
||||||
return navigateTo('/home')
|
return navigateTo('/home')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
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',
|
compatibilityDate: '2024-04-03',
|
||||||
|
|
||||||
css: ['~/assets/css/main.css'],
|
css: ['~/assets/css/main.css'],
|
||||||
@@ -12,7 +14,10 @@ export default defineNuxtConfig({
|
|||||||
nitro: {
|
nitro: {
|
||||||
routeRules: {
|
routeRules: {
|
||||||
'/api/**': { proxy: 'http://localhost:1323/api/**' },
|
'/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', '/']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { NuxtError } from '#app';
|
import type { NuxtError } from '#app';
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: ["auth", "admin"],
|
// middleware: ["auth", "admin"],
|
||||||
layout: "admin"
|
layout: "admin"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,12 @@ let { data: plans } = await useFetch<Plan[]>('/api/admin/plans');
|
|||||||
</h4>
|
</h4>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<label for="username" class="block max-w-64 text-sm">Username</label>
|
<label for="username" class="block max-w-64 text-sm">Username</label>
|
||||||
<Input v-model="username" :value="username" id="username" placeholder="Username" class="w-full mb-2" />
|
<input v-model="username" id="username" placeholder="Username" class="w-full mb-2" />
|
||||||
<label for="email" class="block max-w-64 text-sm">Email</label>
|
<label for="email" class="block max-w-64 text-sm">Email</label>
|
||||||
<Input v-model="email" :value="email" id="email" placeholder="Email" class="w-full mb-2" />
|
<input v-model="email" id="email" placeholder="Email" class="w-full mb-2" />
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label for="password" class="block max-w-64 text-sm">Password</label>
|
<label for="password" class="block max-w-64 text-sm">Password</label>
|
||||||
<Input v-model="password" id="password" placeholder="Password" class="w-full" />
|
<input v-model="password" id="password" placeholder="Password" class="w-full" />
|
||||||
<p class="text-muted text-sm">Leave the password empty to keep it unchanged</p>
|
<p class="text-muted text-sm">Leave the password empty to keep it unchanged</p>
|
||||||
</div>
|
</div>
|
||||||
<label for="plan_id" class="block max-w-64 text-sm">Plan</label>
|
<label for="plan_id" class="block max-w-64 text-sm">Plan</label>
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ onUnmounted(() => {
|
|||||||
</h4>
|
</h4>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<label for="username" class="block max-w-64 text-sm">Username</label>
|
<label for="username" class="block max-w-64 text-sm">Username</label>
|
||||||
<Input v-model="username" :value="username" id="username" placeholder="Username" autocomplete="off" class="w-full mb-2" />
|
<input v-model="username" id="username" placeholder="Username" autocomplete="off" class="w-full mb-2" />
|
||||||
<label for="email" class="block max-w-64 text-sm">Email</label>
|
<label for="email" class="block max-w-64 text-sm">Email</label>
|
||||||
<Input v-model="email" :value="email" id="email" placeholder="Email" autocomplete="off" class="w-full mb-2" />
|
<input v-model="email" id="email" placeholder="Email" autocomplete="off" class="w-full mb-2" />
|
||||||
<label for="password" class="block max-w-64 text-sm">Password</label>
|
<label for="password" class="block max-w-64 text-sm">Password</label>
|
||||||
<Input v-model="password" :value="password" id="password" type="password" placeholder="Password" autocomplete="off" class="w-full mb-2" />
|
<input v-model="password" id="password" type="password" placeholder="Password" autocomplete="off" class="w-full mb-2" />
|
||||||
<p class="text-love mb-2">{{ error }}</p>
|
<p class="text-love mb-2">{{ error }}</p>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ const downloadFiles = async () => {
|
|||||||
<div class="mb-3 flex flex-col">
|
<div class="mb-3 flex flex-col">
|
||||||
<label for="folderNameInput" class="text-sm">name</label>
|
<label for="folderNameInput" class="text-sm">name</label>
|
||||||
<!-- TODO figure out why I cant focus this when the popup opens -->
|
<!-- TODO figure out why I cant focus this when the popup opens -->
|
||||||
<Input id="folderNameInput" v-model="folderName" placeholder="Folder name" />
|
<input id="folderNameInput" v-model="folderName" placeholder="Folder name" />
|
||||||
<p class="text-love">{{ folderError }}</p>
|
<p class="text-love">{{ folderError }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-auto flex gap-x-1.5">
|
<div class="ml-auto flex gap-x-1.5">
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ onUnmounted(() => {
|
|||||||
<div class="min-h-screen min-w-screen grid place-content-center bg-base">
|
<div class="min-h-screen min-w-screen grid place-content-center bg-base">
|
||||||
<div class="flex flex-col text-center bg-surface border shadow-md px-10 py-8 rounded-2xl min-w-0 max-w-[313px]">
|
<div class="flex flex-col text-center bg-surface border shadow-md px-10 py-8 rounded-2xl min-w-0 max-w-[313px]">
|
||||||
<h2 class="font-semibold text-2xl mb-2">Login</h2>
|
<h2 class="font-semibold text-2xl mb-2">Login</h2>
|
||||||
<Input class="my-2" :value="username_or_email" v-model="username_or_email" placeholder="Username or Email..." />
|
<input class="my-2" v-model="username_or_email" placeholder="Username or Email..." />
|
||||||
<Input class="my-2" :value="password" v-model="password" type="password" placeholder="Password..." />
|
<input class="my-2" v-model="password" type="password" placeholder="Password..." />
|
||||||
<p class="text-love">{{ error }}</p>
|
<p class="text-love">{{ error }}</p>
|
||||||
<button @click="submitForm"
|
<button @click="submitForm"
|
||||||
class="py-2 px-4 my-2 bg-pine/10 text-pine rounded-md transition-colors hover:bg-pine/15 active:bg-pine/25 focus:outline-none focus:ring focus:ring-inset">Login</button>
|
class="py-2 px-4 my-2 bg-pine/10 text-pine rounded-md transition-colors hover:bg-pine/15 active:bg-pine/25 focus:outline-none focus:ring focus:ring-inset">Login</button>
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ onUnmounted(() => {
|
|||||||
<div
|
<div
|
||||||
class="flex flex-col text-center bg-surface border border-muted/20 shadow-md px-10 py-8 rounded-2xl min-w-0 max-w-[313px]">
|
class="flex flex-col text-center bg-surface border border-muted/20 shadow-md px-10 py-8 rounded-2xl min-w-0 max-w-[313px]">
|
||||||
<h2 class="font-semibold text-2xl mb-2">Signup</h2>
|
<h2 class="font-semibold text-2xl mb-2">Signup</h2>
|
||||||
<Input class="my-2" v-model="username" placeholder="Username..." />
|
<input class="my-2" v-model="username" placeholder="Username..." />
|
||||||
<Input class="my-2" v-model="email" placeholder="Email..." />
|
<input class="my-2" v-model="email" placeholder="Email..." />
|
||||||
<Input class="my-2" v-model="password" type="password" placeholder="Password..." />
|
<input class="my-2" v-model="password" type="password" placeholder="Password..." />
|
||||||
<p class="text-love">{{ error }}</p>
|
<p class="text-love">{{ error }}</p>
|
||||||
<button @click="submitForm"
|
<button @click="submitForm"
|
||||||
class="py-2 px-4 my-2 bg-pine/10 text-pine rounded-md transition-colors hover:bg-pine/15 active:bg-pine/25 focus:outline-none focus:ring focus:ring-inset">Login</button>
|
class="py-2 px-4 my-2 bg-pine/10 text-pine rounded-md transition-colors hover:bg-pine/15 active:bg-pine/25 focus:outline-none focus:ring focus:ring-inset">Login</button>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
transitionProperty: {
|
transitionProperty: {
|
||||||
bg: "background-color",
|
bg: "background-color",
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
future: {
|
future: {
|
||||||
|
|||||||
Reference in New Issue
Block a user