diff --git a/.github/update.log b/.github/update.log index 3f21cbf576..0b2df56a08 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1189,3 +1189,4 @@ Update On Tue Nov 18 19:40:59 CET 2025 Update On Wed Nov 19 19:39:59 CET 2025 Update On Thu Nov 20 19:39:36 CET 2025 Update On Fri Nov 21 19:35:09 CET 2025 +Update On Sat Nov 22 19:36:29 CET 2025 diff --git a/clash-meta/adapter/outbound/mieru.go b/clash-meta/adapter/outbound/mieru.go index 8ef9cfd758..d9feeba08f 100644 --- a/clash-meta/adapter/outbound/mieru.go +++ b/clash-meta/adapter/outbound/mieru.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net" + "net/netip" "strconv" "sync" @@ -40,6 +41,20 @@ type MieruOption struct { HandshakeMode string `proxy:"handshake-mode,omitempty"` } +type mieruPacketDialer struct { + C.Dialer +} + +var _ mierucommon.PacketDialer = (*mieruPacketDialer)(nil) + +func (pd mieruPacketDialer) ListenPacket(ctx context.Context, network, laddr, raddr string) (net.PacketConn, error) { + rAddrPort, err := netip.ParseAddrPort(raddr) + if err != nil { + return nil, fmt.Errorf("invalid address %s: %w", raddr, err) + } + return pd.Dialer.ListenPacket(ctx, network, laddr, rAddrPort) +} + // DialContext implements C.ProxyAdapter func (m *Mieru) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) { if err := m.ensureClientIsRunning(); err != nil { @@ -102,6 +117,7 @@ func (m *Mieru) ensureClientIsRunning() error { return err } config.Dialer = dialer + config.PacketDialer = mieruPacketDialer{Dialer: dialer} if err := m.client.Store(config); err != nil { return err } @@ -158,23 +174,21 @@ func (m *Mieru) Close() error { } func metadataToMieruNetAddrSpec(metadata *C.Metadata) mierumodel.NetAddrSpec { + spec := mierumodel.NetAddrSpec{ + Net: metadata.NetWork.String(), + } if metadata.Host != "" { - return mierumodel.NetAddrSpec{ - AddrSpec: mierumodel.AddrSpec{ - FQDN: metadata.Host, - Port: int(metadata.DstPort), - }, - Net: "tcp", + spec.AddrSpec = mierumodel.AddrSpec{ + FQDN: metadata.Host, + Port: int(metadata.DstPort), } } else { - return mierumodel.NetAddrSpec{ - AddrSpec: mierumodel.AddrSpec{ - IP: metadata.DstIP.AsSlice(), - Port: int(metadata.DstPort), - }, - Net: "tcp", + spec.AddrSpec = mierumodel.AddrSpec{ + IP: metadata.DstIP.AsSlice(), + Port: int(metadata.DstPort), } } + return spec } func buildMieruClientConfig(option MieruOption) (*mieruclient.ClientConfig, error) { @@ -182,7 +196,13 @@ func buildMieruClientConfig(option MieruOption) (*mieruclient.ClientConfig, erro return nil, fmt.Errorf("failed to validate mieru option: %w", err) } - transportProtocol := mierupb.TransportProtocol_TCP.Enum() + var transportProtocol = mierupb.TransportProtocol_UNKNOWN_TRANSPORT_PROTOCOL.Enum() + switch option.Transport { + case "TCP": + transportProtocol = mierupb.TransportProtocol_TCP.Enum() + case "UDP": + transportProtocol = mierupb.TransportProtocol_UDP.Enum() + } var server *mierupb.ServerEndpoint if net.ParseIP(option.Server) != nil { // server is an IP address @@ -284,8 +304,8 @@ func validateMieruOption(option MieruOption) error { } } - if option.Transport != "TCP" { - return fmt.Errorf("transport must be TCP") + if option.Transport != "TCP" && option.Transport != "UDP" { + return fmt.Errorf("transport must be TCP or UDP") } if option.UserName == "" { return fmt.Errorf("username is empty") diff --git a/clash-meta/adapter/outbound/mieru_test.go b/clash-meta/adapter/outbound/mieru_test.go index 086b791044..d80b27696c 100644 --- a/clash-meta/adapter/outbound/mieru_test.go +++ b/clash-meta/adapter/outbound/mieru_test.go @@ -34,7 +34,7 @@ func TestNewMieru(t *testing.T) { Name: "test", Server: "example.com", Port: 10003, - Transport: "TCP", + Transport: "UDP", UserName: "test", Password: "test", }, diff --git a/clash-meta/docs/config.yaml b/clash-meta/docs/config.yaml index e71b06f482..8a5ec1f7d3 100644 --- a/clash-meta/docs/config.yaml +++ b/clash-meta/docs/config.yaml @@ -1027,7 +1027,7 @@ proxies: # socks5 server: 1.2.3.4 port: 2999 # port-range: 2090-2099 #(不可同时填写 port 和 port-range) - transport: TCP # 只支持 TCP + transport: TCP # 支持 TCP 或者 UDP udp: true # 支持 UDP over TCP username: user password: password diff --git a/clash-meta/go.mod b/clash-meta/go.mod index 90362be0c6..2047d0eb11 100644 --- a/clash-meta/go.mod +++ b/clash-meta/go.mod @@ -6,7 +6,7 @@ require ( github.com/bahlo/generic-list-go v0.2.0 github.com/coreos/go-iptables v0.8.0 github.com/dlclark/regexp2 v1.11.5 - github.com/enfein/mieru/v3 v3.22.1 + github.com/enfein/mieru/v3 v3.23.0 github.com/go-chi/chi/v5 v5.2.3 github.com/go-chi/render v1.0.3 github.com/gobwas/ws v1.4.0 diff --git a/clash-meta/go.sum b/clash-meta/go.sum index 0bec36121a..bc29d7fef7 100644 --- a/clash-meta/go.sum +++ b/clash-meta/go.sum @@ -23,8 +23,8 @@ 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/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/enfein/mieru/v3 v3.22.1 h1:/XGYYXpEhEJlxosmtbpEJkhtRLHB8IToG7LB8kU2ZDY= -github.com/enfein/mieru/v3 v3.22.1/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM= +github.com/enfein/mieru/v3 v3.23.0 h1:f/dd3UAoi36FD9DZ9x49t6Ps0oHeSjrVSgWzvEstn0E= +github.com/enfein/mieru/v3 v3.23.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM= github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 h1:kXYqH/sL8dS/FdoFjr12ePjnLPorPo2FsnrHNuXSDyo= github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I= github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g= diff --git a/clash-meta/listener/inbound/common_test.go b/clash-meta/listener/inbound/common_test.go index 72874c7b54..4178035b27 100644 --- a/clash-meta/listener/inbound/common_test.go +++ b/clash-meta/listener/inbound/common_test.go @@ -59,11 +59,13 @@ func init() { } type TestTunnel struct { - HandleTCPConnFn func(conn net.Conn, metadata *C.Metadata) - HandleUDPPacketFn func(packet C.UDPPacket, metadata *C.Metadata) - NatTableFn func() C.NatTable - CloseFn func() error - DoTestFn func(t *testing.T, proxy C.ProxyAdapter) + HandleTCPConnFn func(conn net.Conn, metadata *C.Metadata) + HandleUDPPacketFn func(packet C.UDPPacket, metadata *C.Metadata) + NatTableFn func() C.NatTable + CloseFn func() error + DoTestFn func(t *testing.T, proxy C.ProxyAdapter) + DoSequentialTestFn func(t *testing.T, proxy C.ProxyAdapter) + DoConcurrentTestFn func(t *testing.T, proxy C.ProxyAdapter) } func (tt *TestTunnel) HandleTCPConn(conn net.Conn, metadata *C.Metadata) { @@ -86,6 +88,14 @@ func (tt *TestTunnel) DoTest(t *testing.T, proxy C.ProxyAdapter) { tt.DoTestFn(t, proxy) } +func (tt *TestTunnel) DoSequentialTest(t *testing.T, proxy C.ProxyAdapter) { + tt.DoSequentialTestFn(t, proxy) +} + +func (tt *TestTunnel) DoConcurrentTest(t *testing.T, proxy C.ProxyAdapter) { + tt.DoConcurrentTestFn(t, proxy) +} + type TestTunnelListener struct { ch chan net.Conn ctx context.Context @@ -213,6 +223,40 @@ func NewHttpTestTunnel() *TestTunnel { } assert.Equal(t, httpData[:size], data) } + + sequentialTestFn := func(t *testing.T, proxy C.ProxyAdapter) { + // Sequential testing for debugging + t.Run("Sequential", func(t *testing.T) { + testFn(t, proxy, "http", len(httpData)) + testFn(t, proxy, "https", len(httpData)) + }) + } + + concurrentTestFn := func(t *testing.T, proxy C.ProxyAdapter) { + // Concurrent testing to detect stress + t.Run("Concurrent", func(t *testing.T) { + wg := sync.WaitGroup{} + num := len(httpData) / 1024 + for i := 1; i <= num; i++ { + i := i + wg.Add(1) + go func() { + testFn(t, proxy, "https", i*1024) + defer wg.Done() + }() + } + for i := 1; i <= num; i++ { + i := i + wg.Add(1) + go func() { + testFn(t, proxy, "http", i*1024) + defer wg.Done() + }() + } + wg.Wait() + }) + } + tunnel := &TestTunnel{ HandleTCPConnFn: func(conn net.Conn, metadata *C.Metadata) { defer conn.Close() @@ -252,36 +296,11 @@ func NewHttpTestTunnel() *TestTunnel { }, CloseFn: ln.Close, DoTestFn: func(t *testing.T, proxy C.ProxyAdapter) { - - // Sequential testing for debugging - t.Run("Sequential", func(t *testing.T) { - testFn(t, proxy, "http", len(httpData)) - testFn(t, proxy, "https", len(httpData)) - }) - - // Concurrent testing to detect stress - t.Run("Concurrent", func(t *testing.T) { - wg := sync.WaitGroup{} - num := len(httpData) / 1024 - for i := 1; i <= num; i++ { - i := i - wg.Add(1) - go func() { - testFn(t, proxy, "https", i*1024) - defer wg.Done() - }() - } - for i := 1; i <= num; i++ { - i := i - wg.Add(1) - go func() { - testFn(t, proxy, "http", i*1024) - defer wg.Done() - }() - } - wg.Wait() - }) + sequentialTestFn(t, proxy) + concurrentTestFn(t, proxy) }, + DoSequentialTestFn: sequentialTestFn, + DoConcurrentTestFn: concurrentTestFn, } return tunnel } diff --git a/clash-meta/listener/inbound/mieru_test.go b/clash-meta/listener/inbound/mieru_test.go index d163b49dcc..12aa680ccc 100644 --- a/clash-meta/listener/inbound/mieru_test.go +++ b/clash-meta/listener/inbound/mieru_test.go @@ -149,12 +149,18 @@ func TestNewMieru(t *testing.T) { } func TestInboundMieru(t *testing.T) { - t.Run("HANDSHAKE_STANDARD", func(t *testing.T) { + t.Run("TCP_HANDSHAKE_STANDARD", func(t *testing.T) { testInboundMieruTCP(t, "HANDSHAKE_STANDARD") }) - t.Run("HANDSHAKE_NO_WAIT", func(t *testing.T) { + t.Run("TCP_HANDSHAKE_NO_WAIT", func(t *testing.T) { testInboundMieruTCP(t, "HANDSHAKE_NO_WAIT") }) + t.Run("UDP_HANDSHAKE_STANDARD", func(t *testing.T) { + testInboundMieruUDP(t, "HANDSHAKE_STANDARD") + }) + t.Run("UDP_HANDSHAKE_NO_WAIT", func(t *testing.T) { + testInboundMieruUDP(t, "HANDSHAKE_NO_WAIT") + }) } func testInboundMieruTCP(t *testing.T, handshakeMode string) { @@ -168,7 +174,7 @@ func testInboundMieruTCP(t *testing.T, handshakeMode string) { inboundOptions := inbound.MieruOption{ BaseOption: inbound.BaseOption{ - NameStr: "mieru_inbound", + NameStr: "mieru_inbound_tcp", Listen: "127.0.0.1", Port: strconv.Itoa(port), }, @@ -194,7 +200,7 @@ func testInboundMieruTCP(t *testing.T, handshakeMode string) { return } outboundOptions := outbound.MieruOption{ - Name: "mieru_outbound", + Name: "mieru_outbound_tcp", Server: addrPort.Addr().String(), Port: int(addrPort.Port()), Transport: "TCP", @@ -210,3 +216,57 @@ func testInboundMieruTCP(t *testing.T, handshakeMode string) { tunnel.DoTest(t, out) } + +func testInboundMieruUDP(t *testing.T, handshakeMode string) { + t.Parallel() + l, err := net.ListenPacket("udp", "127.0.0.1:0") + if !assert.NoError(t, err) { + return + } + port := l.LocalAddr().(*net.UDPAddr).Port + l.Close() + + inboundOptions := inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + NameStr: "mieru_inbound_udp", + Listen: "127.0.0.1", + Port: strconv.Itoa(port), + }, + Transport: "UDP", + Users: map[string]string{"test": "password"}, + } + in, err := inbound.NewMieru(&inboundOptions) + if !assert.NoError(t, err) { + return + } + + tunnel := NewHttpTestTunnel() + defer tunnel.Close() + + err = in.Listen(tunnel) + if !assert.NoError(t, err) { + return + } + defer in.Close() + + addrPort, err := netip.ParseAddrPort(in.Address()) + if !assert.NoError(t, err) { + return + } + outboundOptions := outbound.MieruOption{ + Name: "mieru_outbound_udp", + Server: addrPort.Addr().String(), + Port: int(addrPort.Port()), + Transport: "UDP", + UserName: "test", + Password: "password", + HandshakeMode: handshakeMode, + } + out, err := outbound.NewMieru(outboundOptions) + if !assert.NoError(t, err) { + return + } + defer out.Close() + + tunnel.DoSequentialTest(t, out) +} diff --git a/clash-meta/tunnel/dns_dialer.go b/clash-meta/tunnel/dns_dialer.go index c141d96648..364cba699d 100644 --- a/clash-meta/tunnel/dns_dialer.go +++ b/clash-meta/tunnel/dns_dialer.go @@ -70,7 +70,9 @@ func (d *DNSDialer) DialContext(ctx context.Context, network, addr string) (net. } else { var ok bool proxyAdapter, ok = Proxies()[proxyName] - if !ok { + if ok { + metadata.SpecialProxy = proxyName // just for log + } else { opts = append(opts, dialer.WithInterface(proxyName)) } } @@ -158,7 +160,9 @@ func (d *DNSDialer) ListenPacket(ctx context.Context, network, addr string) (net } else { var ok bool proxyAdapter, ok = Proxies()[proxyName] - if !ok { + if ok { + metadata.SpecialProxy = proxyName // just for log + } else { opts = append(opts, dialer.WithInterface(proxyName)) } } diff --git a/clash-meta/tunnel/tunnel.go b/clash-meta/tunnel/tunnel.go index fc901eb354..1b2f41365e 100644 --- a/clash-meta/tunnel/tunnel.go +++ b/clash-meta/tunnel/tunnel.go @@ -627,7 +627,7 @@ func logMetadataErr(metadata *C.Metadata, rule C.Rule, proxy C.ProxyAdapter, err func logMetadata(metadata *C.Metadata, rule C.Rule, remoteConn C.Connection) { switch { case metadata.SpecialProxy != "": - log.Infoln("[%s] %s --> %s using %s", strings.ToUpper(metadata.NetWork.String()), metadata.SourceDetail(), metadata.RemoteAddress(), metadata.SpecialProxy) + log.Infoln("[%s] %s --> %s using %s", strings.ToUpper(metadata.NetWork.String()), metadata.SourceDetail(), metadata.RemoteAddress(), remoteConn.Chains().String()) case rule != nil: if rule.Payload() != "" { log.Infoln("[%s] %s --> %s match %s using %s", strings.ToUpper(metadata.NetWork.String()), metadata.SourceDetail(), metadata.RemoteAddress(), fmt.Sprintf("%s(%s)", rule.RuleType().String(), rule.Payload()), remoteConn.Chains().String()) @@ -639,7 +639,7 @@ func logMetadata(metadata *C.Metadata, rule C.Rule, remoteConn C.Connection) { case mode == Direct: log.Infoln("[%s] %s --> %s using DIRECT", strings.ToUpper(metadata.NetWork.String()), metadata.SourceDetail(), metadata.RemoteAddress()) default: - log.Infoln("[%s] %s --> %s doesn't match any rule using %s", strings.ToUpper(metadata.NetWork.String()), metadata.SourceDetail(), metadata.RemoteAddress(), remoteConn.Chains().Last()) + log.Infoln("[%s] %s --> %s doesn't match any rule using %s", strings.ToUpper(metadata.NetWork.String()), metadata.SourceDetail(), metadata.RemoteAddress(), remoteConn.Chains().String()) } } diff --git a/filebrowser/CHANGELOG.md b/filebrowser/CHANGELOG.md index 5f7ccd26ae..49f40267a7 100644 --- a/filebrowser/CHANGELOG.md +++ b/filebrowser/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. +## [2.49.0](https://github.com/filebrowser/filebrowser/compare/v2.48.2...v2.49.0) (2025-11-22) + + +### Features + +* add "copy download link to clipboard" button to Share prompt ([#5173](https://github.com/filebrowser/filebrowser/issues/5173)) ([d48f566](https://github.com/filebrowser/filebrowser/commit/d48f5665d6975c4cbbdf9be20dc2e0106db02f01)) +* add Bulgarian language ([8db2411](https://github.com/filebrowser/filebrowser/commit/8db2411cd43a23ae3292a817e3524cfdb5ae9b86)) +* Updates for project File Browser ([#5566](https://github.com/filebrowser/filebrowser/issues/5566)) ([54306bd](https://github.com/filebrowser/filebrowser/commit/54306bdc8700fac489326ae81e28ac5db0580d13)) + + +### Bug Fixes + +* display friendly error message for password validation on signup ([#5563](https://github.com/filebrowser/filebrowser/issues/5563)) ([6d5aa35](https://github.com/filebrowser/filebrowser/commit/6d5aa355e433d613e5a3ae137f410c63baeddf0f)) + ## [2.48.2](https://github.com/filebrowser/filebrowser/compare/v2.48.1...v2.48.2) (2025-11-18) diff --git a/filebrowser/frontend/pnpm-lock.yaml b/filebrowser/frontend/pnpm-lock.yaml index f3ebe665ae..8b38a2a40f 100644 --- a/filebrowser/frontend/pnpm-lock.yaml +++ b/filebrowser/frontend/pnpm-lock.yaml @@ -82,7 +82,7 @@ importers: version: 4.5.5(@vueuse/core@14.0.0(vue@3.5.24(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.24(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.24(typescript@5.9.3)) vue-i18n: specifier: ^11.1.10 - version: 11.1.12(vue@3.5.24(typescript@5.9.3)) + version: 11.2.1(vue@3.5.24(typescript@5.9.3)) vue-lazyload: specifier: ^3.0.0 version: 3.0.0 @@ -98,7 +98,7 @@ importers: devDependencies: '@intlify/unplugin-vue-i18n': specifier: ^11.0.1 - version: 11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) + version: 11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) '@tsconfig/node24': specifier: ^24.0.2 version: 24.0.3 @@ -122,7 +122,7 @@ importers: version: 10.2.0(eslint@9.39.1)(prettier@3.6.2) '@vue/eslint-config-typescript': specifier: ^14.6.0 - version: 14.6.0(eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3) + version: 14.6.0(eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3) '@vue/tsconfig': specifier: ^0.8.1 version: 0.8.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) @@ -140,7 +140,7 @@ importers: version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2) eslint-plugin-vue: specifier: ^10.5.1 - version: 10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)) + version: 10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)) postcss: specifier: ^8.5.6 version: 8.5.6 @@ -887,18 +887,22 @@ packages: vue-i18n: optional: true - '@intlify/core-base@11.1.12': - resolution: {integrity: sha512-whh0trqRsSqVLNEUCwU59pyJZYpU8AmSWl8M3Jz2Mv5ESPP6kFh4juas2NpZ1iCvy7GlNRffUD1xr84gceimjg==} + '@intlify/core-base@11.2.1': + resolution: {integrity: sha512-2V1A4yaN9ElAnQ6ih3HHEc+jZ+sHV6BlQHjCsnIVlOotL5NCUgJElIxgUFiJs6zV4puoAq3hHuQIfWNp+J+8yQ==} engines: {node: '>= 16'} - '@intlify/message-compiler@11.1.12': - resolution: {integrity: sha512-Fv9iQSJoJaXl4ZGkOCN1LDM3trzze0AS2zRz2EHLiwenwL6t0Ki9KySYlyr27yVOj5aVz0e55JePO+kELIvfdQ==} + '@intlify/message-compiler@11.2.1': + resolution: {integrity: sha512-J2454D3Agg3Kvgaj14gxTleJU8/H06Sisz7C2BwiHF0/i5Soyfb5ySpwn8GCL6yscDbOGj6xM+lUe6gO6BFQyg==} engines: {node: '>= 16'} '@intlify/shared@11.1.12': resolution: {integrity: sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==} engines: {node: '>= 16'} + '@intlify/shared@11.2.1': + resolution: {integrity: sha512-O67LZM4dbfr70WCsZLW+g+pIXdgQ66laLVd/FicW7iYgP/RuH0X1FDGSh+Hr9Gou/8TeldUE6KmTGdLwX2ufIA==} + engines: {node: '>= 16'} + '@intlify/unplugin-vue-i18n@11.0.1': resolution: {integrity: sha512-nH5NJdNjy/lO6Ne8LDtZzv4SbpVsMhPE+LbvBDmMeIeJDiino8sOJN2QB3MXzTliYTnqe3aB9Fw5+LJ/XVaXCg==} engines: {node: '>= 20'} @@ -1664,8 +1668,8 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-vue@10.5.1: - resolution: {integrity: sha512-SbR9ZBUFKgvWAbq3RrdCtWaW0IKm6wwUiApxf3BVTNfqUIo4IQQmreMg2iHFJJ6C/0wss3LXURBJ1OwS/MhFcQ==} + eslint-plugin-vue@10.6.0: + resolution: {integrity: sha512-TsoFluWxOpsJlE/l2jJygLQLWBPJ3Qdkesv7tBIunICbTcG0dS1/NBw/Ol4tJw5kHWlAVds4lUmC29/vlPUcEQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -2144,8 +2148,8 @@ packages: resolution: {integrity: sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==} hasBin: true - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} postcss-value-parser@4.2.0: @@ -2492,8 +2496,8 @@ packages: focus-trap: '>=7.2.0' vue: '>=3.2.0' - vue-i18n@11.1.12: - resolution: {integrity: sha512-BnstPj3KLHLrsqbVU2UOrPmr0+Mv11bsUZG0PyCOzsawCivk8W00GMXHeVUWIDOgNaScCuZah47CZFE+Wnl8mw==} + vue-i18n@11.2.1: + resolution: {integrity: sha512-cc3Wx4eJZac9WMS8mxhfYiCipm9PBQ2Dz15piWYm7DwNcCehaKRgpolEdiqrjjT27T3Wijz3xJ7NeIc8ofIWAA==} engines: {node: '>= 16'} peerDependencies: vue: ^3.0.0 @@ -3355,9 +3359,9 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@intlify/bundle-utils@11.0.1(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))': + '@intlify/bundle-utils@11.0.1(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))': dependencies: - '@intlify/message-compiler': 11.1.12 + '@intlify/message-compiler': 11.2.1 '@intlify/shared': 11.1.12 acorn: 8.15.0 esbuild: 0.25.12 @@ -3367,26 +3371,28 @@ snapshots: source-map-js: 1.2.1 yaml-eslint-parser: 1.2.3 optionalDependencies: - vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3)) + vue-i18n: 11.2.1(vue@3.5.24(typescript@5.9.3)) - '@intlify/core-base@11.1.12': + '@intlify/core-base@11.2.1': dependencies: - '@intlify/message-compiler': 11.1.12 - '@intlify/shared': 11.1.12 + '@intlify/message-compiler': 11.2.1 + '@intlify/shared': 11.2.1 - '@intlify/message-compiler@11.1.12': + '@intlify/message-compiler@11.2.1': dependencies: - '@intlify/shared': 11.1.12 + '@intlify/shared': 11.2.1 source-map-js: 1.2.1 '@intlify/shared@11.1.12': {} - '@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': + '@intlify/shared@11.2.1': {} + + '@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) - '@intlify/bundle-utils': 11.0.1(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3))) + '@intlify/bundle-utils': 11.0.1(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3))) '@intlify/shared': 11.1.12 - '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) + '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) '@rollup/pluginutils': 5.3.0(rollup@4.53.3) '@typescript-eslint/scope-manager': 8.46.4 '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) @@ -3397,7 +3403,7 @@ snapshots: unplugin: 2.3.10 vue: 3.5.24(typescript@5.9.3) optionalDependencies: - vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3)) + vue-i18n: 11.2.1(vue@3.5.24(typescript@5.9.3)) transitivePeerDependencies: - '@vue/compiler-dom' - eslint @@ -3405,14 +3411,14 @@ snapshots: - supports-color - typescript - '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': + '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': dependencies: '@babel/parser': 7.28.5 optionalDependencies: '@intlify/shared': 11.1.12 '@vue/compiler-dom': 3.5.24 vue: 3.5.24(typescript@5.9.3) - vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3)) + vue-i18n: 11.2.1(vue@3.5.24(typescript@5.9.3)) '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -3886,11 +3892,11 @@ snapshots: transitivePeerDependencies: - '@types/eslint' - '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3) eslint: 9.39.1 - eslint-plugin-vue: 10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)) + eslint-plugin-vue: 10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)) fast-glob: 3.3.3 typescript-eslint: 8.37.0(eslint@9.39.1)(typescript@5.9.3) vue-eslint-parser: 10.2.0(eslint@9.39.1) @@ -4223,13 +4229,13 @@ snapshots: optionalDependencies: eslint-config-prettier: 10.1.8(eslint@9.39.1) - eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)): + eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)): dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) eslint: 9.39.1 natural-compare: 1.4.0 nth-check: 2.1.1 - postcss-selector-parser: 6.1.2 + postcss-selector-parser: 7.1.0 semver: 7.7.3 vue-eslint-parser: 10.2.0(eslint@9.39.1) xml-name-validator: 4.0.0 @@ -4673,7 +4679,7 @@ snapshots: dependencies: '@babel/runtime': 7.28.4 - postcss-selector-parser@6.1.2: + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -5015,10 +5021,10 @@ snapshots: focus-trap: 7.6.2 vue: 3.5.24(typescript@5.9.3) - vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)): + vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)): dependencies: - '@intlify/core-base': 11.1.12 - '@intlify/shared': 11.1.12 + '@intlify/core-base': 11.2.1 + '@intlify/shared': 11.2.1 '@vue/devtools-api': 6.6.4 vue: 3.5.24(typescript@5.9.3) diff --git a/filebrowser/frontend/src/components/prompts/Share.vue b/filebrowser/frontend/src/components/prompts/Share.vue index 3ce2b1fda1..282902fb68 100644 --- a/filebrowser/frontend/src/components/prompts/Share.vue +++ b/filebrowser/frontend/src/components/prompts/Share.vue @@ -12,6 +12,7 @@ {{ $t("settings.shareDuration") }} + @@ -24,7 +25,7 @@ + + +