mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-21 23:20:24 +00:00
WebAdmin: use the new UI for user pages
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
ca880f6cbb
commit
e1b5d2fe39
22 changed files with 2615 additions and 1775 deletions
58
go.mod
58
go.mod
|
@ -9,15 +9,15 @@ require (
|
|||
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5
|
||||
github.com/alexedwards/argon2id v1.0.0
|
||||
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.2
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.13
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.9
|
||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.5
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.3
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.14
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11
|
||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.1
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.3.5
|
||||
github.com/coreos/go-oidc/v3 v3.9.0
|
||||
|
@ -39,7 +39,7 @@ require (
|
|||
github.com/jackc/pgx/v5 v5.5.1
|
||||
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
|
||||
github.com/klauspost/compress v1.17.4
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.18
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.19
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7
|
||||
github.com/mattn/go-sqlite3 v1.14.19
|
||||
github.com/mhale/smtpd v0.8.1
|
||||
|
@ -68,13 +68,13 @@ require (
|
|||
go.etcd.io/bbolt v1.3.8
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
gocloud.dev v0.36.0
|
||||
golang.org/x/crypto v0.17.0
|
||||
golang.org/x/net v0.19.0
|
||||
golang.org/x/oauth2 v0.15.0
|
||||
golang.org/x/sys v0.15.0
|
||||
golang.org/x/term v0.15.0
|
||||
golang.org/x/crypto v0.18.0
|
||||
golang.org/x/net v0.20.0
|
||||
golang.org/x/oauth2 v0.16.0
|
||||
golang.org/x/sys v0.16.0
|
||||
golang.org/x/term v0.16.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/api v0.154.0
|
||||
google.golang.org/api v0.155.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
)
|
||||
|
||||
|
@ -86,16 +86,16 @@ require (
|
|||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
|
||||
github.com/aws/smithy-go v1.19.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
|
@ -165,16 +165,16 @@ require (
|
|||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
|
||||
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.16.1 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
|
||||
google.golang.org/grpc v1.60.1 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
|
113
go.sum
113
go.sum
|
@ -33,46 +33,46 @@ github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHc
|
|||
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
|
||||
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 h1:I9YN9WMo3SUh7p/4wKeNvD/IQla3U3SUa61U7ul+xM4=
|
||||
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964/go.mod h1:eFiR01PwTcpbzXtdMces7zxg6utvFM5puiWHpWB8D/k=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.9 h1:5zA8qVCXMPGt6YneFnll5B157SfdK2SewU85PH9/yM0=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.9/go.mod h1:t4gy210hPxkbtYM8xOzrWdxVq1PyekR76OOKXy3s0Vs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.3 h1:dKuc2jdp10y13dEEvPqWxqLoc0vF3Z9FC45MvuQSxOA=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.3/go.mod h1:Bxgi+DeeswYofcYO0XyGClwlrq3DZEXli0kLf4hkGA0=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.14 h1:mMDTwwYO9A0/JbOCOG7EOZHtYM+o7OfGWfu0toa23VE=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.14/go.mod h1:cniAUh3ErQPHtCQGPT5ouvSAQ0od8caTO9OOuufZOAE=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 h1:I6lAa3wBWfCz/cKkOpAcumsETRkFAl70sWi8ItcMEsM=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11/go.mod h1:be1NIO30kJA23ORBLqPo1LttEM6tPNSEcjkd1eKzNW0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 h1:ugD6qzjYtB7zM5PN/ZIeaAIyefPaD82G8+SJopgvUpw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9/go.mod h1:YD0aYBWCrPENpHolhKw2XDlTIWae2GKXT1T4o6N6hiM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 h1:5oE2WzJE56/mVveuDZPJESKlg/00AaS2pY2QZcnxg4M=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10/go.mod h1:FHbKWQtRBYUz4vO5WBWjzMD2by126ny5y/1EoaWoLfI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 h1:/90OR2XbSYfXucBMJ4U14wrjlfleq/0SB6dZDPncgmo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9/go.mod h1:dN/Of9/fNZet7UrQQ6kTDo/VSwKPIq94vjlU16bRARc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJR8CSImIVCONRi4g0Su3J+TSTbS7G0pUeMU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 h1:iEAeF6YC3l4FzlJPP9H3Ko1TXpdjdqWffxXjp8SY6uk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9/go.mod h1:kjsXoK23q9Z/tLBrckZLLyvjhZoS+AGrzqzUfEClvMM=
|
||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.5 h1:Fp3Gcbp3lAJAxeFRVSxc6tWOUPSG8iSkJEiFl3eZZ3o=
|
||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.5/go.mod h1:XABJbVXMa0xnVqaGbhkfUeVV0GrPsc3Jqscu87IovXU=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7 h1:o0ASbVwUAIrfp/WcCac+6jioZt4Hd8k/1X8u7GJ/QeM=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7/go.mod h1:vADO6Jn+Rq4nDtfwNjhgR84qkZwiC6FqCaXdw/kYwjA=
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 h1:dPCRgAL4WD9tSMaDglRNGOiAtSTjkwNiUW5GDpWFfHA=
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0/go.mod h1:4Ae1NCLK6ghmjzd45Tc33GgCKhUWD2ORAlULtMO1Cbs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 h1:L0ai8WICYHozIKK+OtPzVJBugL7culcuM4E4JOpIEm8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10/go.mod h1:byqfyxJBshFk0fF9YmK0M0ugIO8OWjzH2T3bPG4eGuA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 h1:KOxnQeWy5sXyS37fdKEvAsGHOr9fa/qvwxfJurR/BzE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10/go.mod h1:jMx5INQFYFYB3lQD9W0D8Ohgq6Wnl7NYOJ2TQndbulI=
|
||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6 h1:JWy+uLKZQR/9a3gQ+jQa28FEJ/41Z0spdbbQodaXFeA=
|
||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6/go.mod h1:T2NcfuIuXWcuwVwg3rBIW6h1cfzCdrzSn4Hs0KltND8=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 h1:PJTdBMsyvra6FtED7JZtDpQrIAflYDHFoZAu/sKYkwU=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0/go.mod h1:4qXHrG1Ne3VGIMZPCB8OjH/pLFO94sKABIusjh0KWPU=
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.1 h1:Sn3MAV9YeACCULaxNWWYFH1a6G4wYFwBn3/TA5MwE2Q=
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.1/go.mod h1:qutL00aW8GSo2D0I6UEOqMvRS3ZyuBrOC1BLe5D2jPc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 h1:Yf2MIo9x+0tyv76GljxzqA3WtC5mw7NmazD2chwjxE4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
|
||||
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
|
||||
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
|
@ -105,7 +105,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
|
@ -264,9 +263,8 @@ github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJG
|
|||
github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
|
||||
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
|
||||
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.18 h1:HHZkYS5wWDDyAiNBwztEtDoX07WDhGEdixm8G06R50o=
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.18/go.mod h1:fAJ+k5eTgKdDqanzCuK6DAt3W7n3cs2/FX7JhQdk83U=
|
||||
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.19 h1:ekv1qEZE6BVct89QA+pRF6+4pCpfVrOnEJnTnT4RXoY=
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.19/go.mod h1:l3im3coce1lL2cDeAjqmaR+Awx+X8Ih+2k8BuHNJ4CU=
|
||||
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
|
||||
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
|
@ -432,8 +430,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
|
|||
gocloud.dev v0.36.0 h1:q5zoXux4xkOZP473e1EZbG8Gq9f0vlg1VNH5Du/ybus=
|
||||
gocloud.dev v0.36.0/go.mod h1:bLxah6JQVKBaIxzsr5BQLYB4IYdWHkMZdzCXlo6F0gg=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
|
||||
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
|
@ -452,19 +450,19 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
|||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
|
||||
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
|
||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -479,7 +477,6 @@ golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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=
|
||||
|
@ -490,14 +487,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
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=
|
||||
|
@ -525,8 +524,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
google.golang.org/api v0.154.0 h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050=
|
||||
google.golang.org/api v0.154.0/go.mod h1:qhSMkM85hgqiokIYsrRyKxrjfBeIhgl4Z2JmeRkYylc=
|
||||
google.golang.org/api v0.155.0 h1:vBmGhCYs0djJttDNynWo44zosHlPvHmA0XiN2zP2DtA=
|
||||
google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
|
@ -534,12 +533,12 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ
|
|||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos=
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 h1:s1w3X6gQxwrLEpxnLd/qXTVLgQE2yXwaOaoa6IlY/+o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA=
|
||||
google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 h1:/IWabOtPziuXTEtI1KYCpM6Ss7vaAkeMxk+uXV/xvZs=
|
||||
google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
|
|
|
@ -307,6 +307,32 @@ type PasswordValidation struct {
|
|||
Users PasswordValidationRules `json:"users" mapstructure:"users"`
|
||||
}
|
||||
|
||||
// FilesystemProvider defines the supported storage filesystems
|
||||
type FilesystemProvider struct {
|
||||
sdk.FilesystemProvider
|
||||
}
|
||||
|
||||
// I18nString returns the translation key
|
||||
func (p FilesystemProvider) I18nString() string {
|
||||
switch p.FilesystemProvider {
|
||||
case sdk.LocalFilesystemProvider:
|
||||
return util.I18nStorageLocal
|
||||
case sdk.S3FilesystemProvider:
|
||||
return util.I18nStorageS3
|
||||
case sdk.GCSFilesystemProvider:
|
||||
return util.I18nStorageGCS
|
||||
case sdk.AzureBlobFilesystemProvider:
|
||||
return util.I18nStorageAzureBlob
|
||||
case sdk.CryptedFilesystemProvider:
|
||||
return util.I18nStorageLocalEncrypted
|
||||
case sdk.SFTPFilesystemProvider:
|
||||
return util.I18nStorageSFTP
|
||||
case sdk.HTTPFilesystemProvider:
|
||||
return util.I18nStorageHTTP
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type wrappedFolder struct {
|
||||
Folder vfs.BaseVirtualFolder
|
||||
}
|
||||
|
|
|
@ -1682,6 +1682,8 @@ func (s *httpdServer) setupWebAdminRoutes() {
|
|||
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers), s.refreshCookie).
|
||||
Get(webUsersPath, s.handleGetWebUsers)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers), s.refreshCookie).
|
||||
Get(webUsersPath+"/json", getAllUsers)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminAddUsers), s.refreshCookie).
|
||||
Get(webUserPath, s.handleWebAddUserGet)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers), s.refreshCookie).
|
||||
|
|
|
@ -170,11 +170,6 @@ type basePage struct {
|
|||
Branding UIBranding
|
||||
}
|
||||
|
||||
type usersPage struct {
|
||||
basePage
|
||||
Users []dataprovider.User
|
||||
}
|
||||
|
||||
type adminsPage struct {
|
||||
basePage
|
||||
Admins []dataprovider.Admin
|
||||
|
@ -228,7 +223,7 @@ type userPage struct {
|
|||
basePage
|
||||
User *dataprovider.User
|
||||
RootPerms []string
|
||||
Error string
|
||||
Error *util.I18nError
|
||||
ValidPerms []string
|
||||
ValidLoginMethods []string
|
||||
ValidProtocols []string
|
||||
|
@ -405,9 +400,8 @@ func loadAdminTemplates(templatesPath string) {
|
|||
filepath.Join(templatesPath, templateAdminDir, templateUsers),
|
||||
}
|
||||
userPaths := []string{
|
||||
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
||||
filepath.Join(templatesPath, templateCommonDir, templateCommonBase),
|
||||
filepath.Join(templatesPath, templateAdminDir, templateBase),
|
||||
filepath.Join(templatesPath, templateAdminDir, templateSharedComponents),
|
||||
filepath.Join(templatesPath, templateAdminDir, templateFsConfig),
|
||||
filepath.Join(templatesPath, templateAdminDir, templateUser),
|
||||
}
|
||||
|
@ -566,10 +560,15 @@ func loadAdminTemplates(templatesPath string) {
|
|||
}
|
||||
|
||||
fsBaseTpl := template.New("fsBaseTemplate").Funcs(template.FuncMap{
|
||||
"ListFSProviders": func() []sdk.FilesystemProvider {
|
||||
return []sdk.FilesystemProvider{sdk.LocalFilesystemProvider, sdk.CryptedFilesystemProvider,
|
||||
sdk.S3FilesystemProvider, sdk.GCSFilesystemProvider, sdk.AzureBlobFilesystemProvider,
|
||||
sdk.SFTPFilesystemProvider, sdk.HTTPFilesystemProvider,
|
||||
"ListFSProviders": func() []dataprovider.FilesystemProvider {
|
||||
return []dataprovider.FilesystemProvider{
|
||||
{FilesystemProvider: sdk.LocalFilesystemProvider},
|
||||
{FilesystemProvider: sdk.CryptedFilesystemProvider},
|
||||
{FilesystemProvider: sdk.S3FilesystemProvider},
|
||||
{FilesystemProvider: sdk.GCSFilesystemProvider},
|
||||
{FilesystemProvider: sdk.AzureBlobFilesystemProvider},
|
||||
{FilesystemProvider: sdk.SFTPFilesystemProvider},
|
||||
{FilesystemProvider: sdk.HTTPFilesystemProvider},
|
||||
}
|
||||
},
|
||||
"HumanizeBytes": util.ByteCountSI,
|
||||
|
@ -948,20 +947,20 @@ func (s *httpdServer) getUserPageTitleAndURL(mode userPageMode, username string)
|
|||
var title, currentURL string
|
||||
switch mode {
|
||||
case userPageModeAdd:
|
||||
title = "Add a new user"
|
||||
title = util.I18nAddUserTitle
|
||||
currentURL = webUserPath
|
||||
case userPageModeUpdate:
|
||||
title = "Update user"
|
||||
title = util.I18nUpdateUserTitle
|
||||
currentURL = fmt.Sprintf("%v/%v", webUserPath, url.PathEscape(username))
|
||||
case userPageModeTemplate:
|
||||
title = "User template"
|
||||
title = util.I18nTemplateUserTitle
|
||||
currentURL = webTemplateUser
|
||||
}
|
||||
return title, currentURL
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderUserPage(w http.ResponseWriter, r *http.Request, user *dataprovider.User,
|
||||
mode userPageMode, errorString string, admin *dataprovider.Admin,
|
||||
mode userPageMode, err error, admin *dataprovider.Admin,
|
||||
) {
|
||||
user.SetEmptySecretsIfNil()
|
||||
title, currentURL := s.getUserPageTitleAndURL(mode, user.Username)
|
||||
|
@ -985,24 +984,28 @@ func (s *httpdServer) renderUserPage(w http.ResponseWriter, r *http.Request, use
|
|||
}
|
||||
var roles []dataprovider.Role
|
||||
if basePage.LoggedUser.Role == "" {
|
||||
var err error
|
||||
roles, err = s.getWebRoles(w, r, 10, true)
|
||||
if err != nil {
|
||||
var errRoles error
|
||||
roles, errRoles = s.getWebRoles(w, r, 10, true)
|
||||
if errRoles != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
folders, err := s.getWebVirtualFolders(w, r, defaultQueryLimit, true)
|
||||
if err != nil {
|
||||
folders, errFolders := s.getWebVirtualFolders(w, r, defaultQueryLimit, true)
|
||||
if errFolders != nil {
|
||||
return
|
||||
}
|
||||
groups, err := s.getWebGroups(w, r, defaultQueryLimit, true)
|
||||
if err != nil {
|
||||
groups, errGroups := s.getWebGroups(w, r, defaultQueryLimit, true)
|
||||
if errGroups != nil {
|
||||
return
|
||||
}
|
||||
var errI18n *util.I18nError
|
||||
if err != nil {
|
||||
errI18n = util.NewI18nError(err, util.I18nError500Message)
|
||||
}
|
||||
data := userPage{
|
||||
basePage: basePage,
|
||||
Mode: mode,
|
||||
Error: errorString,
|
||||
Error: errI18n,
|
||||
User: user,
|
||||
ValidPerms: dataprovider.ValidPerms,
|
||||
ValidLoginMethods: dataprovider.ValidLoginMethods,
|
||||
|
@ -1469,7 +1472,7 @@ func getFiltersFromUserPostFields(r *http.Request) (sdk.BaseUserFilters, error)
|
|||
}
|
||||
maxFileSize, err := util.ParseBytes(r.Form.Get("max_upload_file_size"))
|
||||
if err != nil {
|
||||
return filters, fmt.Errorf("invalid max upload file size: %w", err)
|
||||
return filters, util.NewI18nError(fmt.Errorf("invalid max upload file size: %w", err), util.I18nErrorInvalidMaxFilesize)
|
||||
}
|
||||
defaultSharesExpiration, err := strconv.Atoi(r.Form.Get("default_shares_expiration"))
|
||||
if err != nil {
|
||||
|
@ -1960,7 +1963,7 @@ func getTransferLimits(r *http.Request) (int64, int64, int64, error) {
|
|||
func getQuotaLimits(r *http.Request) (int64, int, error) {
|
||||
quotaSize, err := util.ParseBytes(r.Form.Get("quota_size"))
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("invalid quota size: %w", err)
|
||||
return 0, 0, util.NewI18nError(fmt.Errorf("invalid quota size: %w", err), util.I18nErrorInvalidQuotaSize)
|
||||
}
|
||||
quotaFiles, err := strconv.Atoi(r.Form.Get("quota_files"))
|
||||
if err != nil {
|
||||
|
@ -1973,7 +1976,7 @@ func getUserFromPostFields(r *http.Request) (dataprovider.User, error) {
|
|||
user := dataprovider.User{}
|
||||
err := r.ParseMultipartForm(maxRequestSize)
|
||||
if err != nil {
|
||||
return user, err
|
||||
return user, util.NewI18nError(err, util.I18nErrorInvalidForm)
|
||||
}
|
||||
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
||||
uid, err := strconv.Atoi(r.Form.Get("uid"))
|
||||
|
@ -2916,6 +2919,28 @@ func (s *httpdServer) handleWebDefenderPage(w http.ResponseWriter, r *http.Reque
|
|||
renderAdminTemplate(w, templateDefender, data)
|
||||
}
|
||||
|
||||
func getAllUsers(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
claims, err := getTokenClaims(r)
|
||||
if err != nil || claims.Username == "" {
|
||||
sendAPIResponse(w, r, nil, util.I18nErrorDirList403, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
users := make([]dataprovider.User, 0, defaultQueryLimit)
|
||||
for {
|
||||
u, err := dataprovider.GetUsers(defaultQueryLimit, len(users), dataprovider.OrderASC, claims.Role)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, getI18NErrorString(err, util.I18nError500Message), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
users = append(users, u...)
|
||||
if len(u) < defaultQueryLimit {
|
||||
break
|
||||
}
|
||||
}
|
||||
render.JSON(w, r, users)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleGetWebUsers(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
claims, err := getTokenClaims(r)
|
||||
|
@ -2923,32 +2948,7 @@ func (s *httpdServer) handleGetWebUsers(w http.ResponseWriter, r *http.Request)
|
|||
s.renderBadRequestPage(w, r, errors.New("invalid token claims"))
|
||||
return
|
||||
}
|
||||
var limit int
|
||||
if _, ok := r.URL.Query()["qlimit"]; ok {
|
||||
var err error
|
||||
limit, err = strconv.Atoi(r.URL.Query().Get("qlimit"))
|
||||
if err != nil {
|
||||
limit = defaultQueryLimit
|
||||
}
|
||||
} else {
|
||||
limit = defaultQueryLimit
|
||||
}
|
||||
users := make([]dataprovider.User, 0, limit)
|
||||
for {
|
||||
u, err := dataprovider.GetUsers(limit, len(users), dataprovider.OrderASC, claims.Role)
|
||||
if err != nil {
|
||||
s.renderInternalServerErrorPage(w, r, err)
|
||||
return
|
||||
}
|
||||
users = append(users, u...)
|
||||
if len(u) < limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
data := usersPage{
|
||||
basePage: s.getBasePageData(pageUsersTitle, webUsersPath, r),
|
||||
Users: users,
|
||||
}
|
||||
data := s.getBasePageData(pageUsersTitle, webUsersPath, r)
|
||||
renderAdminTemplate(w, templateUsers, data)
|
||||
}
|
||||
|
||||
|
@ -3053,7 +3053,7 @@ func (s *httpdServer) handleWebTemplateUserGet(w http.ResponseWriter, r *http.Re
|
|||
if user.ExpirationDate == 0 && admin.Filters.Preferences.DefaultUsersExpiration > 0 {
|
||||
user.ExpirationDate = util.GetTimeAsMsSinceEpoch(time.Now().Add(24 * time.Hour * time.Duration(admin.Filters.Preferences.DefaultUsersExpiration)))
|
||||
}
|
||||
s.renderUserPage(w, r, &user, userPageModeTemplate, "", &admin)
|
||||
s.renderUserPage(w, r, &user, userPageModeTemplate, nil, &admin)
|
||||
} else if errors.Is(err, util.ErrNotFound) {
|
||||
s.renderNotFoundPage(w, r, err)
|
||||
} else {
|
||||
|
@ -3069,7 +3069,7 @@ func (s *httpdServer) handleWebTemplateUserGet(w http.ResponseWriter, r *http.Re
|
|||
if admin.Filters.Preferences.DefaultUsersExpiration > 0 {
|
||||
user.ExpirationDate = util.GetTimeAsMsSinceEpoch(time.Now().Add(24 * time.Hour * time.Duration(admin.Filters.Preferences.DefaultUsersExpiration)))
|
||||
}
|
||||
s.renderUserPage(w, r, &user, userPageModeTemplate, "", &admin)
|
||||
s.renderUserPage(w, r, &user, userPageModeTemplate, nil, &admin)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3148,7 +3148,7 @@ func (s *httpdServer) handleWebAddUserGet(w http.ResponseWriter, r *http.Request
|
|||
if admin.Filters.Preferences.DefaultUsersExpiration > 0 {
|
||||
user.ExpirationDate = util.GetTimeAsMsSinceEpoch(time.Now().Add(24 * time.Hour * time.Duration(admin.Filters.Preferences.DefaultUsersExpiration)))
|
||||
}
|
||||
s.renderUserPage(w, r, &user, userPageModeAdd, "", &admin)
|
||||
s.renderUserPage(w, r, &user, userPageModeAdd, nil, &admin)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebUpdateUserGet(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -3161,7 +3161,7 @@ func (s *httpdServer) handleWebUpdateUserGet(w http.ResponseWriter, r *http.Requ
|
|||
username := getURLParam(r, "username")
|
||||
user, err := dataprovider.UserExists(username, claims.Role)
|
||||
if err == nil {
|
||||
s.renderUserPage(w, r, &user, userPageModeUpdate, "", nil)
|
||||
s.renderUserPage(w, r, &user, userPageModeUpdate, nil, nil)
|
||||
} else if errors.Is(err, util.ErrNotFound) {
|
||||
s.renderNotFoundPage(w, r, err)
|
||||
} else {
|
||||
|
@ -3178,7 +3178,7 @@ func (s *httpdServer) handleWebAddUserPost(w http.ResponseWriter, r *http.Reques
|
|||
}
|
||||
user, err := getUserFromPostFields(r)
|
||||
if err != nil {
|
||||
s.renderUserPage(w, r, &user, userPageModeAdd, err.Error(), nil)
|
||||
s.renderUserPage(w, r, &user, userPageModeAdd, err, nil)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
|
@ -3200,7 +3200,7 @@ func (s *httpdServer) handleWebAddUserPost(w http.ResponseWriter, r *http.Reques
|
|||
}
|
||||
err = dataprovider.AddUser(&user, claims.Username, ipAddr, claims.Role)
|
||||
if err != nil {
|
||||
s.renderUserPage(w, r, &user, userPageModeAdd, err.Error(), nil)
|
||||
s.renderUserPage(w, r, &user, userPageModeAdd, err, nil)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, webUsersPath, http.StatusSeeOther)
|
||||
|
@ -3224,7 +3224,7 @@ func (s *httpdServer) handleWebUpdateUserPost(w http.ResponseWriter, r *http.Req
|
|||
}
|
||||
updatedUser, err := getUserFromPostFields(r)
|
||||
if err != nil {
|
||||
s.renderUserPage(w, r, &user, userPageModeUpdate, err.Error(), nil)
|
||||
s.renderUserPage(w, r, &user, userPageModeUpdate, err, nil)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
|
@ -3257,7 +3257,7 @@ func (s *httpdServer) handleWebUpdateUserPost(w http.ResponseWriter, r *http.Req
|
|||
|
||||
err = dataprovider.UpdateUser(&updatedUser, claims.Username, ipAddr, claims.Role)
|
||||
if err != nil {
|
||||
s.renderUserPage(w, r, &updatedUser, userPageModeUpdate, err.Error(), nil)
|
||||
s.renderUserPage(w, r, &updatedUser, userPageModeUpdate, err, nil)
|
||||
return
|
||||
}
|
||||
if r.Form.Get("disconnect") != "" {
|
||||
|
|
|
@ -48,6 +48,9 @@ const (
|
|||
I18nError500Title = "title.error500"
|
||||
I18nErrorPDFTitle = "title.errorPDF"
|
||||
I18nErrorEditorTitle = "title.error_editor"
|
||||
I18nAddUserTitle = "title.add_user"
|
||||
I18nUpdateUserTitle = "title.update_user"
|
||||
I18nTemplateUserTitle = "title.template_user"
|
||||
I18nErrorSetupInstallCode = "setup.install_code_mismatch"
|
||||
I18nInvalidAuth = "general.invalid_auth_request"
|
||||
I18nError429Message = "general.error429"
|
||||
|
@ -149,6 +152,15 @@ const (
|
|||
I18nOIDCTokenInvalidRoleAdmin = "oidc.role_admin_err"
|
||||
I18nOIDCTokenInvalidRoleUser = "oidc.role_user_err"
|
||||
I18nOIDCErrGetUser = "oidc.get_user_err"
|
||||
I18nStorageLocal = "storage.local"
|
||||
I18nStorageLocalEncrypted = "storage.encrypted"
|
||||
I18nStorageS3 = "storage.s3"
|
||||
I18nStorageGCS = "storage.gcs"
|
||||
I18nStorageAzureBlob = "storage.azblob"
|
||||
I18nStorageSFTP = "storage.sftp"
|
||||
I18nStorageHTTP = "storage.http"
|
||||
I18nErrorInvalidQuotaSize = "user.invalid_quota_size"
|
||||
I18nErrorInvalidMaxFilesize = "filters.max_upload_size_invalid"
|
||||
)
|
||||
|
||||
// NewI18nError returns a I18nError wrappring the provided error
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
NFPM_VERSION=2.35.1
|
||||
NFPM_VERSION=2.35.2
|
||||
NFPM_ARCH=${NFPM_ARCH:-amd64}
|
||||
if [ -z ${SFTPGO_VERSION} ]
|
||||
then
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -44,7 +44,10 @@
|
|||
"configs": "Configurations",
|
||||
"logs": "Logs",
|
||||
"maintenance": "Maintenance",
|
||||
"status": "Status"
|
||||
"status": "Status",
|
||||
"add_user": "Add user",
|
||||
"update_user": "Update user",
|
||||
"template_user": "User template"
|
||||
},
|
||||
"setup": {
|
||||
"desc": "To start using SFTPGo you need to create an administrator user",
|
||||
|
@ -103,7 +106,6 @@
|
|||
"confirm_logout": "Are you sure you want to sign out?",
|
||||
"wait": "Please wait...",
|
||||
"ok": "OK",
|
||||
"none": "None",
|
||||
"cancel": "No, back",
|
||||
"submit": "Save",
|
||||
"back": "Back",
|
||||
|
@ -150,7 +152,8 @@
|
|||
"verify": "Verify",
|
||||
"problems": "Having problems?",
|
||||
"allowed_ip_mask": "Allowed IP/Mask",
|
||||
"allowed_ip_mask_help": "Comma separated IP/Mask in CIDR format, for example \"192.168.1.0/24,10.8.0.100/32\"",
|
||||
"denied_ip_mask": "Denied IP/Mask",
|
||||
"ip_mask_help": "Comma separated IP/Mask in CIDR format, for example \"192.168.1.0/24,10.8.0.100/32\"",
|
||||
"allowed_ip_mask_invalid": "Invalid allowed IP/Mask",
|
||||
"username_required": "The username is required",
|
||||
"foldername_required": "The folder name is required",
|
||||
|
@ -169,14 +172,44 @@
|
|||
"share_ok": "Share access successful, you can now use your link",
|
||||
"qr_code": "QR Code",
|
||||
"copy_link": "Copy link",
|
||||
"copied": "Copied"
|
||||
"copied": "Copied",
|
||||
"active": "Active",
|
||||
"inactive": "Inactive",
|
||||
"colvis": "Column visibility",
|
||||
"actions": "Actions",
|
||||
"template": "Use as a template",
|
||||
"quota_scan": "Quota scan",
|
||||
"quota_scan_started": "Quota scan started. It can take a while depending on the number of files to check",
|
||||
"quota_scan_conflit": "Another scan is already in progress",
|
||||
"quota_scan_error": "Unable to start quota scan",
|
||||
"role": "Role",
|
||||
"role_placeholder": "Select a role",
|
||||
"group_placeholder": "Select a group",
|
||||
"folder_placeholder": "Select a folder",
|
||||
"blank_default_help": "Leave blank for default",
|
||||
"skip_tls_verify": "Skip TLS verify. This should be used only for testing",
|
||||
"advanced_settings": "Advanced settings",
|
||||
"default": "Default",
|
||||
"private_key": "Private key",
|
||||
"acls": "ACLs",
|
||||
"quota_limits": "Disk quota and bandwidth limits",
|
||||
"expiration": "Expiration",
|
||||
"expiration_help": "Pick an expiration date",
|
||||
"additional_info": "Additional info",
|
||||
"permissions": "Permissions",
|
||||
"visible": "Visible",
|
||||
"hidden": "Hidden",
|
||||
"allowed": "Allowed",
|
||||
"denied": "Denied",
|
||||
"zero_no_limit_help": "0 means no limit",
|
||||
"global_settings": "Global settings",
|
||||
"mandatory_encryption": "Mandatory encryption"
|
||||
},
|
||||
"fs": {
|
||||
"view_file": "View file \"{{- path}}\"",
|
||||
"edit_file": "Edit file \"{{- path}}\"",
|
||||
"new_folder": "New Folder",
|
||||
"select_across_pages": "Select across pages",
|
||||
"actions": "Actions",
|
||||
"download": "Download",
|
||||
"download_ready": "Your download is ready",
|
||||
"move_copy": "Move or copy",
|
||||
|
@ -330,8 +363,6 @@
|
|||
"paths": "Paths",
|
||||
"path_help": "file or directory path, i.e. /dir or /dir/file.txt",
|
||||
"password_help": "If set the share will be password-protected",
|
||||
"expiration": "Expiration",
|
||||
"expiration_help": "Pick an expiration date",
|
||||
"max_tokens": "Max tokens",
|
||||
"max_tokens_help": "Maximum number of times this share can be accessed. 0 means no limit",
|
||||
"view_manage": "View and manage shares",
|
||||
|
@ -405,7 +436,7 @@
|
|||
"folder_overlapped": "Overlapping virtual folders detected",
|
||||
"folder_quota_size_invalid": "The quota as size of virtual folders must be greater than or equal to -1",
|
||||
"folder_quota_file_invalid": "The quota as files of virtual folders must be greater than or equal to -1",
|
||||
"folder_quota_invalid": "Quotas as size and as number of files of virtual folders must be both -1 or greater or equal than zero",
|
||||
"folder_quota_invalid": "Quotas as size and as number of files of virtual folders must be both -1 or greater or equal than 0",
|
||||
"ip_filters_invalid": "Invalid IP filters, make sure they respect CIDR notation, for example 192.168.1.0/24",
|
||||
"src_bw_limits_invalid": "Invalid per-source bandwidth speed limits",
|
||||
"share_expiration_invalid": "The expiration for shares must be greater than or equal to the defined default value",
|
||||
|
@ -413,7 +444,98 @@
|
|||
"file_pattern_duplicated": "Duplicated file name pattern filters detected",
|
||||
"file_pattern_invalid": "Invalid file name pattern filters",
|
||||
"disable_active_2fa": "Two-factor authentication cannot be disabled for a user with an active configuration",
|
||||
"pwd_change_conflict": "It is not possible to request a password change and at the same time prevent the password from being changed"
|
||||
"pwd_change_conflict": "It is not possible to request a password change and at the same time prevent the password from being changed",
|
||||
"status": "Status",
|
||||
"last_login": "Last login",
|
||||
"role_help": "Users with a role can be managed by global administrators and administrators with the same role",
|
||||
"require_pwd_change": "Require password change",
|
||||
"require_pwd_change_help": "The user will need to change the password from WebClient to activate the account",
|
||||
"groups_help": "Groups membership impart the groups settings with the exception of membership only groups",
|
||||
"primary_group": "Primary group",
|
||||
"secondary_groups": "Secondary groups",
|
||||
"membership_groups": "Membership groups",
|
||||
"template_help": "For each user set the username and at least one of the password and public key",
|
||||
"virtual_folders_help": "Quota size/files -1 means included within user quota, 0 unlimited. Don't set -1 for shared folders. You can use MB/GB/TB suffix. Without suffix we assume bytes",
|
||||
"disconnect": "Disconnect the user after the update",
|
||||
"disconnect_help": "This way you force the user to login again, if connected, and so to use the new configuration",
|
||||
"submit_generate": "Generate and save users",
|
||||
"submit_export": "Generate and export users",
|
||||
"invalid_quota_size": "Invalid quota size"
|
||||
},
|
||||
"virtual_folders": {
|
||||
"mount_path": "mount path, i.e. /vfolder",
|
||||
"quota_size": "Quota size",
|
||||
"quota_size_help": "0 means no limit. You can use MB/GB/TB suffix",
|
||||
"quota_files": "Quota files"
|
||||
},
|
||||
"storage": {
|
||||
"title": "File system",
|
||||
"label": "Storage",
|
||||
"local": "Local disk",
|
||||
"s3": "S3 (Compatible)",
|
||||
"gcs": "GCS",
|
||||
"azblob": "Azure Blob",
|
||||
"encrypted": "Encrypted local disk",
|
||||
"sftp": "SFTP",
|
||||
"http": "HTTP",
|
||||
"home_dir": "Root directory",
|
||||
"home_dir_placeholder": "Absolute path to a directory on local disk",
|
||||
"home_dir_help1": "Leave blank for an appropriate default",
|
||||
"home_dir_help2": "Leave blank and storage to \"Local disk\" to not override the root directory",
|
||||
"home_dir_help3": "Required for local disk storage providers. For other storage providers this folder will be used for temporary files, you can leave it blank for an appropriate default",
|
||||
"sftp_home_dir": "SFTP root directory",
|
||||
"sftp_home_help": "Restrict access to this SFTP path. Example: \"/somedir/subdir\"",
|
||||
"os_read_buffer": "Download buffer (MB)",
|
||||
"os_buffer_help": "0 means no buffer",
|
||||
"os_write_buffer": "Upload buffer (MB)",
|
||||
"bucket": "Bucket",
|
||||
"region": "Region",
|
||||
"access_key": "Access Key",
|
||||
"access_secret": "Access Secret",
|
||||
"endpoint": "Endpoint",
|
||||
"endpoint_help": "For AWS S3, leave blank to use the default endpoint for the specified region",
|
||||
"sftp_endpoint_help": "Endpoint as host:port. The port is always required",
|
||||
"ul_part_size": "Upload Part Size (MB)",
|
||||
"part_size_help": "0 means the default (5 MB). Minimum is 5",
|
||||
"gcs_part_size_help": "0 means the default (16 MB)",
|
||||
"ul_concurrency": "Upload Concurrency",
|
||||
"ul_concurrency_help": "How many parts are uploaded in parallel. 0 means the default (5)",
|
||||
"dl_part_size": "Download Part Size (MB)",
|
||||
"dl_concurrency": "Download Concurrency",
|
||||
"dl_concurrency_help": "How many parts are downloaded in parallel. 0 means the default (5)",
|
||||
"ul_part_timeout": "Upload Part timeout",
|
||||
"ul_part_timeout_help": "Max time limit, in seconds, to upload a single part. 0 means no limit",
|
||||
"gcs_ul_part_timeout_help": "Max time limit, in seconds, to upload a single part. 0 means the default (32)",
|
||||
"dl_part_timeout": "Download Part timeout",
|
||||
"dl_part_timeout_help": "Max time limit, in seconds, to download a single part. 0 means no limit",
|
||||
"key_prefix": "Key Prefix",
|
||||
"key_prefix_help": "Restrict access to keys with the specified prefix. Example: \"somedir/subdir/\"",
|
||||
"class": "Storage class",
|
||||
"acl": "ACL",
|
||||
"role_arn": "Role ARN",
|
||||
"role_arn_help": "Optional IAM Role ARN to assume",
|
||||
"s3_path_style": "Use path-style addressing, i.e. \"endpoint/BUCKET/KEY\"",
|
||||
"credentials_file": "Credentials file",
|
||||
"credentials_file_help": "Add or update credentials from a JSON file",
|
||||
"auto_credentials": "Automatic credentials",
|
||||
"auto_credentials_help": "Use default application credentials or credentials from environment variables",
|
||||
"container": "Container",
|
||||
"account_name": "Account Name",
|
||||
"account_key": "Account Key",
|
||||
"sas_url": "SAS URL",
|
||||
"sas_url_help": "Shared Access Signature URL can be used instead of account name/key",
|
||||
"emulator": "Use emulator",
|
||||
"passphrase": "Passphrase",
|
||||
"passphrase_help": "Passphrase used to derive the per-object encryption key",
|
||||
"passphrase_key_help": "Passphrase used to protect your private key, if any",
|
||||
"fingerprints": "Fingerprints",
|
||||
"fingerprints_help": "SHA256 fingerprints to be validated when connecting to the external SFTP server, one per line. If empty any host key will be accepted: this is a security risk!",
|
||||
"sftp_buffer": "Buffer size (MB)",
|
||||
"sftp_buffer_help": "A buffer size greater than 0 enables concurrent transfers",
|
||||
"sftp_concurrent_reads": "Disable concurrent reads",
|
||||
"relaxed_equality_check": "Relaxed equality check",
|
||||
"relaxed_equality_check_help": "Enable to consider only the endpoint to determine if different configurations point to the same server. By default, both the endpoint and username must match",
|
||||
"api_key": "API key"
|
||||
},
|
||||
"oidc": {
|
||||
"token_expired": "Your OpenID token has expired, please log in again",
|
||||
|
@ -424,5 +546,57 @@
|
|||
"role_admin_err": "Incorrect OpenID role, logged in user is not an administrator",
|
||||
"role_user_err": "Incorrect OpenID role, logged in user is an administrator",
|
||||
"get_user_err": "Failed to get user associated with OpenID token"
|
||||
},
|
||||
"filters": {
|
||||
"password_strength": "Password strength",
|
||||
"password_strength_help": "Values in the 50-70 range are suggested for common use cases. 0 means disabled, any password will be accepted",
|
||||
"password_expiration": "Password expiration",
|
||||
"password_expiration_help": "Password expiration as number of days. 0 means no expiration",
|
||||
"default_shares_expiration": "Default shares expiration",
|
||||
"default_shares_expiration_help": "Default expiration for new shares as number of days",
|
||||
"max_shares_expiration": "Maximum shares expiration",
|
||||
"max_shares_expiration_help": "Maximum allowed expiration, as number of days, when a user creates or updates a share",
|
||||
"directory_permissions": "Per-directory permissions",
|
||||
"directory_permissions_help": "Wildcards are supported in paths, for example \"/incoming/*\" matches any directory within \"/incoming\"",
|
||||
"directory_path_help": "directory path, i.e. /dir",
|
||||
"directory_patterns": "Per-directory name patterns restrictions",
|
||||
"directory_patterns_help": "Comma separated denied or allowed files/directories, based on shell patterns. The match is case insensitive",
|
||||
"max_sessions": "Max sessions",
|
||||
"max_sessions_help": "Maximun number of concurrent sessions. 0 means no limit",
|
||||
"denied_protocols": "Denied protocols",
|
||||
"denied_login_methods": "Denied login methods",
|
||||
"denied_login_methods_help": "\"password\" is valid for all supported protocols, \"password-over-SSH\" only for SSH/SFTP/SCP",
|
||||
"web_client_options": "Web client/REST API",
|
||||
"max_upload_size": "Max upload size",
|
||||
"max_upload_size_help": "Maximum upload size for a single file. 0 means no limit. You can use MB/GB/TB suffix",
|
||||
"max_upload_size_invalid": "Invalid maximum upload file size",
|
||||
"upload_bandwidth": "Bandwidth UL (KB/s)",
|
||||
"download_bandwidth": "Bandwidth DL (KB/s)",
|
||||
"upload_bandwidth_help": "UL (KB/s). 0 means no limit",
|
||||
"download_bandwidth_help": "DL (KB/s). 0 means no limit",
|
||||
"src_bandwidth_limit": "Per-source bandwidth speed limits",
|
||||
"upload_data_transfer": "Upload data transfer (MB)",
|
||||
"upload_data_transfer_help": "Maximum data transfer allowed for uploads. 0 means no limit",
|
||||
"download_data_transfer": "Download data transfer (MB)",
|
||||
"download_data_transfer_help": "Maximum data transfer allowed for downloads. 0 means no limit",
|
||||
"total_data_transfer": "Total data transfer (MB)",
|
||||
"total_data_transfer_help": "Maximum data transfer allowed for uploads + downloads. Replace the individual limits. 0 means no limit",
|
||||
"start_directory": "Initial directory",
|
||||
"start_directory_help": "Alternate initial directory to use instead of \"/\". Supported for SFTP/FTP/HTTP",
|
||||
"tls_username": "TLS username",
|
||||
"tls_username_help": "Defines the TLS certificate field to use as username. Ignored if mutual TLS is disabled",
|
||||
"ftp_security": "FTP security",
|
||||
"ftp_security_help": "Ignored if TLS is already globally required for all FTP users",
|
||||
"hooks": "Hooks",
|
||||
"hook_ext_auth_disabled": "External auth disabled",
|
||||
"hook_pre_login_disabled": "Pre-login disabled",
|
||||
"hook_check_password_disabled": "Check password disabled",
|
||||
"is_anonymous": "Anonymous user",
|
||||
"is_anonymous_help": "Anonymous users are supported for FTP and WebDAV protocols and have read-only access",
|
||||
"disable_fs_checks": "Disable filesystem checks",
|
||||
"disable_fs_checks_help": "Disable checks for existence and automatic creation of home directory and virtual folders",
|
||||
"api_key_auth_help": "Allow to impersonate this user, in REST API, with an API key",
|
||||
"external_auth_cache_time": "External auth cache time",
|
||||
"external_auth_cache_time_help": "Cache time, in seconds, for users authenticated using an external auth hook. 0 means no cache"
|
||||
}
|
||||
}
|
|
@ -44,7 +44,10 @@
|
|||
"configs": "Configurazioni",
|
||||
"logs": "Registro eventi",
|
||||
"maintenance": "Manutenzione",
|
||||
"status": "Stato"
|
||||
"status": "Stato",
|
||||
"add_user": "Aggiungi utente",
|
||||
"update_user": "Aggiorna utente",
|
||||
"template_user": "Modello utente"
|
||||
},
|
||||
"setup": {
|
||||
"desc": "Per iniziare a utilizzare SFTPGo devi creare un utente amministratore",
|
||||
|
@ -103,7 +106,6 @@
|
|||
"confirm_logout": "Sei sicuro di volerti disconnettere?",
|
||||
"wait": "Attendere prego...",
|
||||
"ok": "OK",
|
||||
"none": "Nessuna",
|
||||
"cancel": "No, indietro",
|
||||
"submit": "Salva",
|
||||
"back": "Indietro",
|
||||
|
@ -150,14 +152,15 @@
|
|||
"verify": "Verifica",
|
||||
"problems": "Hai problemi?",
|
||||
"allowed_ip_mask": "IP/Reti permesse",
|
||||
"allowed_ip_mask_help": "IP/reti separate da virgola in formato CIDR, ad esempio \"192.168.1.0/24,10.8.0.100/32\"",
|
||||
"denied_ip_mask": "IP/Reti non permesse",
|
||||
"ip_mask_help": "IP/reti separate da virgola in formato CIDR, ad esempio \"192.168.1.0/24,10.8.0.100/32\"",
|
||||
"allowed_ip_mask_invalid": "IP/reti permesse non valide",
|
||||
"username_required": "Il nome utente è obbligatorio",
|
||||
"foldername_required": "Il nome della cartella è obbligatorio",
|
||||
"err_user": "Errore validazione utente",
|
||||
"err_protocol_forbidden": "Il protocollo HTTP non è consentito per il tuo utente",
|
||||
"pwd_login_forbidden": "Il metodo di accesso tramite password non è consentito per il tuo utente",
|
||||
"ip_forbidden": "Accesso non consentito da questo indirizzo IP",
|
||||
"ip_forbidden": "Accesso non permesso da questo indirizzo IP",
|
||||
"email_invalid": "L'indirizzo e-mail non è valido",
|
||||
"err_password_complexity": "La password fornita non soddisfa i requisiti di complessità",
|
||||
"no_oidc_feature": "Questa funzionalità non è disponibile se hai effettuato l'accesso con OpenID",
|
||||
|
@ -169,14 +172,44 @@
|
|||
"share_ok": "Accesso alla condivisione riuscito, ora puoi utilizzare il tuo collegamento",
|
||||
"qr_code": "Codice QR",
|
||||
"copy_link": "Copia collegamento",
|
||||
"copied": "Copiato"
|
||||
"copied": "Copiato",
|
||||
"active": "Attivo",
|
||||
"inactive": "Inattivo",
|
||||
"colvis": "Visibilità colonne",
|
||||
"actions": "Azioni",
|
||||
"template": "Usa come modello",
|
||||
"quota_scan": "Ricalcolo quota",
|
||||
"quota_scan_started": "Ricalcolo quota avviato. Potrebbe richiedere del tempo a seconda del numero di file da controllare",
|
||||
"quota_scan_conflit": "Un'altra scansione è già in corso",
|
||||
"quota_scan_error": "Impossibile avviare ricalcolo quota",
|
||||
"role": "Ruolo",
|
||||
"role_placeholder": "Seleziona un ruolo",
|
||||
"group_placeholder": "Seleziona un gruppo",
|
||||
"folder_placeholder": "Seleziona una cartella",
|
||||
"blank_default_help": "Lascio vuoto per l'impostazione predefinita",
|
||||
"skip_tls_verify": "Salta la verifica TLS. Dovrebbe essere usato solo per test",
|
||||
"advanced_settings": "Impostazioni avanzate",
|
||||
"default": "Predefinito",
|
||||
"private_key": "Chiave privata",
|
||||
"acls": "ACLs",
|
||||
"quota_limits": "Quota disco e limitazioni di larghezza di banda",
|
||||
"expiration": "Scadenza",
|
||||
"expiration_help": "Scegli una data di scadenza",
|
||||
"additional_info": "Informazioni aggiuntive",
|
||||
"permissions": "Permessi",
|
||||
"visible": "Visibile",
|
||||
"hidden": "Nascosto",
|
||||
"allowed": "Permesso",
|
||||
"denied": "Negato",
|
||||
"zero_no_limit_help": "0 significa nessun limite",
|
||||
"global_settings": "Impostazioni globali",
|
||||
"mandatory_encryption": "Crittografia obbligatoria"
|
||||
},
|
||||
"fs": {
|
||||
"view_file": "Visualizza file \"{{- path}}\"",
|
||||
"edit_file": "Modifica file \"{{- path}}\"",
|
||||
"new_folder": "Nuova cartella",
|
||||
"select_across_pages": "Seleziona tra le pagine",
|
||||
"actions": "Azioni",
|
||||
"download": "Scarica",
|
||||
"download_ready": "Il tuo download è pronto",
|
||||
"move_copy": "Sposta o copia",
|
||||
|
@ -330,8 +363,6 @@
|
|||
"paths": "Percorsi",
|
||||
"path_help": "percorso di un file o di una directory, ad esempio /dir o /dir/file.txt",
|
||||
"password_help": "Se impostata, la condivisione sarà protetta da password",
|
||||
"expiration": "Scadenza",
|
||||
"expiration_help": "Scegli una data di scadenza",
|
||||
"max_tokens": "Token massimi",
|
||||
"max_tokens_help": "Numero massimo di volte in cui è possibile accedere a questa condivisione. 0 significa nessun limite",
|
||||
"view_manage": "Visualizza e gestisci condivisioni",
|
||||
|
@ -405,7 +436,7 @@
|
|||
"folder_overlapped": "Rilevate cartelle virtuali sovrapposte",
|
||||
"folder_quota_size_invalid": "La quota come dimensione delle cartelle virtuali deve essere maggiore o uguale a -1",
|
||||
"folder_quota_file_invalid": "La quota come numero di file delle cartelle virtuali deve essere maggiore o uguale a -1",
|
||||
"folder_quota_invalid": "Le quote come dimensione e numero di file delle cartelle virtuali devono essere entrambe -1 o maggiore o uguale di zero",
|
||||
"folder_quota_invalid": "Le quote come dimensione e numero di file delle cartelle virtuali devono essere entrambe -1 o maggiore o uguale di 0",
|
||||
"ip_filters_invalid": "Filtri IP non validi, assicurati che rispettino la notazione CIDR, ad esempio 192.168.1.0/24",
|
||||
"src_bw_limits_invalid": "Limiti di velocità della larghezza di banda per origine non validi",
|
||||
"share_expiration_invalid": "La scadenza per le condivisioni deve essere maggiore o uguale al valore di default definito",
|
||||
|
@ -413,7 +444,98 @@
|
|||
"file_pattern_duplicated": "Rilevati filtri su modelli di nome file duplicati",
|
||||
"file_pattern_invalid": "Filtri su modelli di nome file non validi",
|
||||
"disable_active_2fa": "L'autenticazione a due fattori non può essere disabilitata per un utente con una configurazione attiva",
|
||||
"pwd_change_conflict": "Non è possibile richiedere la modifica della password e allo stesso tempo impedire la modifica della password"
|
||||
"pwd_change_conflict": "Non è possibile richiedere la modifica della password e allo stesso tempo impedire la modifica della password",
|
||||
"status": "Stato",
|
||||
"last_login": "Ultimo accesso",
|
||||
"role_help": "Gli utenti con un ruolo possono essere gestiti da amministratori globali e amministratori con lo stesso ruolo",
|
||||
"require_pwd_change": "Richiedi modifica password",
|
||||
"require_pwd_change_help": "L'utente dovrà modificare la password dal WebClient per attivare l'account",
|
||||
"groups_help": "L'appartenenza ai gruppi conferisce le impostazioni dei gruppi ad eccezione dei gruppi di sola appartenenza",
|
||||
"primary_group": "Gruppo primario",
|
||||
"secondary_groups": "Gruppi secondari",
|
||||
"membership_groups": "Gruppi di appartenenza",
|
||||
"template_help": "Per ogni utente impostare il nome utente e almeno una tra password e chiave pubblica",
|
||||
"virtual_folders_help": "Dimensione quota/numero file -1 significa incluso nella quota utente, 0 illimitato. Non impostare -1 per le cartelle condivise. È possibile utilizzare il suffisso MB/GB/TB. Senza suffisso assumiamo byte",
|
||||
"disconnect": "Disconnettere l'utente dopo l'aggiornamento",
|
||||
"disconnect_help": "In questo modo si obbliga l'utente a effettuare nuovamente il login, se connesso, e quindi ad utilizzare la nuova configurazione",
|
||||
"submit_generate": "Genera e salva utenti",
|
||||
"submit_export": "Genera ed esporta utenti",
|
||||
"invalid_quota_size": "Quota (dimensione) non valida"
|
||||
},
|
||||
"virtual_folders": {
|
||||
"mount_path": "percorso, es. /vfolder",
|
||||
"quota_size": "Quota (dimensione)",
|
||||
"quota_size_help": "0 significa nessun limite. E' possibile utilizzare il suffisso MB/GB/TB",
|
||||
"quota_files": "Quota (numero file)"
|
||||
},
|
||||
"storage": {
|
||||
"title": "File system",
|
||||
"label": "Archiviazione",
|
||||
"local": "Disco locale",
|
||||
"s3": "S3 (Compatible)",
|
||||
"gcs": "GCS",
|
||||
"azblob": "Azure Blob",
|
||||
"encrypted": "Disco locale criptato",
|
||||
"sftp": "SFTP",
|
||||
"http": "HTTP",
|
||||
"home_dir": "Cartella principale",
|
||||
"home_dir_placeholder": "Percorso assoluto di una directory su disco locale",
|
||||
"home_dir_help1": "Lasciare vuoto per un valore predefinito appropriato",
|
||||
"home_dir_help2": "Lascia vuoto e archiviazione su \"Disco locale\" per non sovrascrivere la directory principale",
|
||||
"home_dir_help3": "Obbligatorio per i provider di archiviazione su disco locale. Per gli altri provider di archiviazione questa cartella sarà usata per i file temporanei, puoi lasciare vuoto per un valore predefinito appropriato",
|
||||
"sftp_home_dir": "Cartella principale SFTP",
|
||||
"sftp_home_help": "Limitare l'accesso a questo percorso SFTP. Esempio: \"/somedir/subdir\"",
|
||||
"os_read_buffer": "Buffer download (MB)",
|
||||
"os_buffer_help": "0 significa nessun buffer",
|
||||
"os_write_buffer": "Buffer upload (MB)",
|
||||
"bucket": "Bucket",
|
||||
"region": "Regione",
|
||||
"access_key": "Chiave di accesso",
|
||||
"access_secret": "Chiave di accesso segreta",
|
||||
"endpoint": "Endpoint",
|
||||
"endpoint_help": "Per AWS S3, lasciare vuoto per utilizzare l'endpoint predefinito per la regione specificata",
|
||||
"sftp_endpoint_help": "Endpoint come host:porta. La porta è sempre richiesta",
|
||||
"ul_part_size": "Dimensioni parte per upload (MB)",
|
||||
"part_size_help": "0 significa il default (5 MB). Il minimo è 5",
|
||||
"gcs_part_size_help": "0 significa il default (16 MB)",
|
||||
"ul_concurrency": "Concorrenza upload",
|
||||
"ul_concurrency_help": "Numero di parti caricate in parallelo. 0 significa il default (5)",
|
||||
"dl_part_size": "Dimensioni parte per download (MB)",
|
||||
"dl_concurrency": "Concorrenza download",
|
||||
"dl_concurrency_help": "Numero di parti scaricate in parallelo. 0 significa il default (5)",
|
||||
"ul_part_timeout": "Timeout per upload parte",
|
||||
"ul_part_timeout_help": "Limite, in secondi, per caricare una singola parte. 0 significa nessun limite",
|
||||
"gcs_ul_part_timeout_help": "Limite, in secondi, per caricare una singola parte. 0 significa il default (32)",
|
||||
"dl_part_timeout": "Timeout per download parte",
|
||||
"dl_part_timeout_help": "Limite, in secondi, per scaricare una singola parte. 0 significa nessun limite",
|
||||
"key_prefix": "Prefisso chiave",
|
||||
"key_prefix_help": "Limitare l'accesso alle chiavi con il prefisso specificato. Esempio: \"somedir/subdir/\"",
|
||||
"class": "Classe archiviazione",
|
||||
"acl": "ACL",
|
||||
"role_arn": "Ruolo ARN",
|
||||
"role_arn_help": "ARN del ruolo IAM da assumere (opzionale)",
|
||||
"s3_path_style": "Utilizza l'indirizzamento in stile percorso, ad esempio \"endpoint/BUCKET/KEY\"",
|
||||
"credentials_file": "File delle credenziali",
|
||||
"credentials_file_help": "Aggiungi o aggiorna le credenziali da un file JSON",
|
||||
"auto_credentials": "Credenziali automatiche",
|
||||
"auto_credentials_help": "Utilizza le credenziali predefinite dell'applicazione o le credenziali dalle variabili di ambiente",
|
||||
"container": "Contenitore",
|
||||
"account_name": "Nome account",
|
||||
"account_key": "Chiave di accesso",
|
||||
"sas_url": "SAS URL",
|
||||
"sas_url_help": "È possibile utilizzare l'URL SAS al posto del nome account e chiave di accesso",
|
||||
"emulator": "Utilizza emulatore",
|
||||
"passphrase": "Passphrase",
|
||||
"passphrase_help": "Passphrase usata per derivare la chiave di crittografia per oggetto",
|
||||
"passphrase_key_help": "Passphrase utilizzata per proteggere la tua chiave privata, se necessaria",
|
||||
"fingerprints": "Impronte chiavi",
|
||||
"fingerprints_help": "Impronte SHA256 da convalidare durante la connessione al server SFTP esterno, una per linea. Se vuoto verrà accettata qualsiasi chiave host: questo è un rischio per la sicurezza!",
|
||||
"sftp_buffer": "Dimensione buffer (MB)",
|
||||
"sftp_buffer_help": "Un buffer maggiore di 0 abilita i trasferimenti concorrenti",
|
||||
"sftp_concurrent_reads": "Disabilitare letture concorrenti",
|
||||
"relaxed_equality_check": "Controllo di uguaglianza non rigoroso",
|
||||
"relaxed_equality_check_help": "Abilitare per considerare solo l'endpoint per determinare se diverse configurazioni puntano allo stesso server. Per impostazione predefinita, sia l'endpoint che il nome utente devono corrispondere",
|
||||
"api_key": "Chiave API"
|
||||
},
|
||||
"oidc": {
|
||||
"token_expired": "Il tuo token OpenID è scaduto, effettua nuovamente l'accesso",
|
||||
|
@ -424,5 +546,57 @@
|
|||
"role_admin_err": "Ruolo OpenID errato, l'utente che ha effettuato l'accesso non è un amministratore",
|
||||
"role_user_err": "Ruolo OpenID errato, l'utente che ha effettuato l'accesso è un amministratore",
|
||||
"get_user_err": "Impossibile ottenere l'utente associato al token OpenID"
|
||||
},
|
||||
"filters": {
|
||||
"password_strength": "Sicurezza password",
|
||||
"password_strength_help": "I valori nell'intervallo 50-70 sono suggeriti per i casi d'uso comuni. 0 significa disabilitato, verrà accettata qualsiasi password",
|
||||
"password_expiration": "Scadenza password",
|
||||
"password_expiration_help": "Scadenza della password espressa in numero di giorni. 0 significa nessuna scadenza",
|
||||
"default_shares_expiration": "Scadenza delle condivisioni",
|
||||
"default_shares_expiration_help": "Scadenza predefinita per le nuove condivisioni come numero di giorni",
|
||||
"max_shares_expiration": "Scadenza massima condivisioni",
|
||||
"max_shares_expiration_help": "Scadenza massima consentita, come numero di giorni, quando un utente crea o aggiorna una condivisione",
|
||||
"directory_permissions": "Permessi per cartella",
|
||||
"directory_permissions_help": "I caratteri jolly sono supportati nei percorsi, ad esempio \"/incoming/*\" corrisponde a qualsiasi directory all'interno di \"/incoming\"",
|
||||
"directory_path_help": "percorso cartella, es. /dir",
|
||||
"directory_patterns": "Restrizioni sui modelli di nome per directory",
|
||||
"directory_patterns_help": "File/directory consentiti o negati, in base ad espressioni regolari shell, separati da virgole. La corrispondenza non fa distinzione tra maiuscole e minuscole",
|
||||
"max_sessions": "Sessioni massime",
|
||||
"max_sessions_help": "Massimo numero di sessioni contemporanee. 0 significa nessun limite",
|
||||
"denied_protocols": "Protocolli non permessi",
|
||||
"denied_login_methods": "Metodi di accesso non permessi",
|
||||
"denied_login_methods_help": "\"password\" è valido per tutti i protocolli supportati, \"password-over-SSH\" solo per SSH/SFTP/SCP",
|
||||
"web_client_options": "Client Web/REST API",
|
||||
"max_upload_size": "Dimensione massima upload",
|
||||
"max_upload_size_help": "Dimensione massima per l'upload di un singolo file. 0 significa nessun limite. È possibile utilizzare il suffisso MB/GB/TB",
|
||||
"max_upload_size_invalid": "Dimensione massima upload file non valida",
|
||||
"upload_bandwidth": "Banda upload (KB/s)",
|
||||
"download_bandwidth": "Banda download (KB/s)",
|
||||
"upload_bandwidth_help": "UL (KB/s). 0 significa nessun limite",
|
||||
"download_bandwidth_help": "DL (KB/s). 0 significa nessun limite",
|
||||
"src_bandwidth_limit": "Limiti di velocità della larghezza di banda per sorgente",
|
||||
"upload_data_transfer": "Trasferimento dati upload (MB)",
|
||||
"upload_data_transfer_help": "Trasferimento dati massimo consentito per gli upload. 0 significa nessun limite",
|
||||
"download_data_transfer": "Trasferimento dati download (MB)",
|
||||
"download_data_transfer_help": "Trasferimento dati massimo consentito per i download. 0 significa nessun limite",
|
||||
"total_data_transfer": "Trasferimento dati totale (MB)",
|
||||
"total_data_transfer_help": "Trasferimento dati massimo consentito per upload + download. Sostituire i limiti individuali. 0 significa nessun limite",
|
||||
"start_directory": "Directory iniziale",
|
||||
"start_directory_help": "Directory iniziale alternativa da utilizzare al posto di \"/\". Supportato per SFTP/FTP/HTTP",
|
||||
"tls_username": "Username per TLS",
|
||||
"tls_username_help": "Definisce il campo del certificato TLS da utilizzare come nome utente. Ignorato se il TLS reciproco è disabilitato",
|
||||
"ftp_security": "Sicurezza FTP",
|
||||
"ftp_security_help": "Ignorato se TLS è già richiesto a livello globale per tutti gli utenti FTP",
|
||||
"hooks": "Hooks",
|
||||
"hook_ext_auth_disabled": "Autenticazione esterna disabilitata",
|
||||
"hook_pre_login_disabled": "Pre-login disabilitato",
|
||||
"hook_check_password_disabled": "Check password disabilitato",
|
||||
"is_anonymous": "Utente anonimo",
|
||||
"is_anonymous_help": "Gli utenti anonimi sono supportati per i protocolli FTP e WebDAV e hanno accesso di sola lettura",
|
||||
"disable_fs_checks": "Disabilita i controlli del filesystem",
|
||||
"disable_fs_checks_help": "Disabilita i controlli sull'esistenza e la creazione automatica della directory home e delle cartelle virtuali",
|
||||
"api_key_auth_help": "Permetti di impersonare questo utente nelle API REST utilizzando una chiave API",
|
||||
"external_auth_cache_time": "Cache per autenticazione esterna",
|
||||
"external_auth_cache_time_help": "Tempo di memorizzazione nella cache, in secondi, per gli utenti autenticati utilizzando un hook di autenticazione esterno. 0 significa nessuna cache"
|
||||
}
|
||||
}
|
|
@ -103,6 +103,14 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
initEmpty: false,
|
||||
|
||||
show: function () {
|
||||
$(this).find('.select-repetear').each(function(){
|
||||
initializeSelect2El(this);
|
||||
let el = $(this);
|
||||
if (el.hasClass('select-first')){
|
||||
let firstVal = el.find("option:first-child").val();
|
||||
el.val(firstVal).trigger('change');
|
||||
}
|
||||
});
|
||||
$(this).localize();
|
||||
$(this).slideDown();
|
||||
$(this).find('[data-repeater-delete]').on("click", function(e){
|
||||
|
@ -114,6 +122,10 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
$(this).slideUp(deleteElement);
|
||||
}
|
||||
});
|
||||
|
||||
$(selector).find('.select-repetear').each(function(){
|
||||
initializeSelect2El(this);
|
||||
});
|
||||
}
|
||||
|
||||
function clearChilds(el) {
|
||||
|
@ -122,6 +134,39 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
}
|
||||
|
||||
function initializeSelect2El(element) {
|
||||
if (element.getAttribute("data-kt-initialized") === "1") {
|
||||
return;
|
||||
}
|
||||
let options = {
|
||||
dir: document.body.getAttribute('direction'),
|
||||
language: {
|
||||
noResults: function () {
|
||||
return $.t('select2.no_results');
|
||||
},
|
||||
searching: function () {
|
||||
return $.t('select2.searching');
|
||||
},
|
||||
removeAllItems: function () {
|
||||
return $.t('select2.removeall');
|
||||
},
|
||||
removeItem: function () {
|
||||
return $.t('select2.remove');
|
||||
},
|
||||
search: function() {
|
||||
return $.t('general.search');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (element.getAttribute('data-hide-search') == 'true') {
|
||||
options.minimumResultsForSearch = Infinity;
|
||||
}
|
||||
|
||||
$(element).select2(options);
|
||||
element.setAttribute("data-kt-initialized", "1");
|
||||
}
|
||||
|
||||
const lngs = {
|
||||
en: { nativeName: 'English' },
|
||||
it: { nativeName: 'Italiano' }
|
||||
|
@ -132,36 +177,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
$('body').localize();
|
||||
let select2elements = [].slice.call(document.querySelectorAll('[data-control="i18n-select2"]'));
|
||||
select2elements.map(function (element){
|
||||
if (element.getAttribute("data-kt-initialized") === "1") {
|
||||
return;
|
||||
}
|
||||
let options = {
|
||||
dir: document.body.getAttribute('direction'),
|
||||
language: {
|
||||
noResults: function () {
|
||||
return $.t('select2.no_results');
|
||||
},
|
||||
searching: function () {
|
||||
return $.t('select2.searching');
|
||||
},
|
||||
removeAllItems: function () {
|
||||
return $.t('select2.removeall');
|
||||
},
|
||||
removeItem: function () {
|
||||
return $.t('select2.remove');
|
||||
},
|
||||
search: function() {
|
||||
return $.t('general.search');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (element.getAttribute('data-hide-search') == 'true') {
|
||||
options.minimumResultsForSearch = Infinity;
|
||||
}
|
||||
|
||||
$(element).select2(options);
|
||||
element.setAttribute("data-kt-initialized", "1");
|
||||
initializeSelect2El(element);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -229,9 +245,10 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
|
||||
function handlePasswordInputVisibility(el) {
|
||||
let pwdVisibility = el.querySelector('[data-password-control="visibility"]');
|
||||
let pwdVisibility = $(el.querySelector('[data-password-control="visibility"]'));
|
||||
let passwordInput = el.querySelector('[data-password-control="input"]');
|
||||
pwdVisibility.addEventListener('click', function(){
|
||||
pwdVisibility.off("click");
|
||||
pwdVisibility.on('click', function(){
|
||||
let visibleIcon = this.querySelector(':scope > i:not(.d-none)');
|
||||
let hiddenIcon = this.querySelector(':scope > i.d-none');
|
||||
visibleIcon.classList.add('d-none');
|
||||
|
@ -632,7 +649,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
|
||||
{{- define "theme-switcher"}}
|
||||
<div class="d-flex align-items-center ms-2 ms-lg-3">
|
||||
<a href="#" class="btn btn-icon btn-active-light-primary w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="click" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<a href="#" class="btn btn-icon btn-active-light-primary w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="{default:'click', lg: 'hover'}" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<i class="ki-duotone ki-night-day theme-light-show fs-2">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
@ -834,11 +851,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="toast-container position-fixed top-0 end-0 p-3">
|
||||
<div id="toast_container" class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="false">
|
||||
<div class="toast-body border-0 d-flex align-items-center">
|
||||
<i class="ki-duotone ki-information-5 fs-3x text-warning me-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
</i>
|
||||
<span id="toast_icon"></span>
|
||||
<span id="toast_msg" class="fs-5 fw-semibold text-gray-800 me-auto"></span>
|
||||
<button data-i18n="[aria-label]general.close" type="button" class="btn btn-icon btn-sm btn-active-light-primary position-absolute position-sm-relative m-2 m-sm-0 top-0 end-0 ms-sm-auto" data-bs-dismiss="toast" aria-label="Close">
|
||||
<i class="ki-solid ki-cross fs-2x text-gray-700"></i>
|
||||
|
@ -955,8 +968,20 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
}();
|
||||
|
||||
function showToast(msg, options) {
|
||||
function showToast(status, msg, options) {
|
||||
const toast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast_container'));
|
||||
if (status === 1){
|
||||
$("#toast_icon").html(`<i class="ki-duotone ki-check-square fs-3x text-success me-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
</i>`);
|
||||
} else {
|
||||
$("#toast_icon").html(`<i class="ki-duotone ki-information-5 fs-3x text-warning me-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
</i>`);
|
||||
}
|
||||
setI18NData($('#toast_msg'), msg, options)
|
||||
toast.show();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- block "additionalnavitems" .}}{{- end}}
|
||||
{{- template "theme-switcher"}}
|
||||
<div class="d-flex align-items-center ms-2 ms-lg-3">
|
||||
<div class="btn btn-icon btn-active-light-primary w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="click" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<div class="btn btn-icon btn-active-light-primary w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="{default:'click', lg: 'hover'}" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<i class="ki-duotone ki-user fs-2">
|
||||
<i class="path1"></i>
|
||||
<i class="path2"></i>
|
||||
|
@ -162,12 +162,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion {{- if .IsIPManagerPage}} here show{{- end}}">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="ki-duotone ki-security-check fs-1">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
<span class="path4"></span>
|
||||
</i>
|
||||
<i class="ki-solid ki-shield fs-1"></i>
|
||||
</span>
|
||||
<span data-i18n="title.ip_manager" class="menu-title">IP Manager</span>
|
||||
<span class="menu-arrow"></span>
|
||||
|
@ -200,10 +195,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="menu-item">
|
||||
<a class="menu-link {{- if eq .CurrentURL .AdminsURL}} active{{- end}}" href="{{.AdminsURL}}">
|
||||
<span class="menu-icon">
|
||||
<i class="ki-duotone ki-security-user fs-1">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
</i>
|
||||
<i class="ki-solid ki-security-user fs-1"></i>
|
||||
</span>
|
||||
<span data-i18n="title.admins" class="menu-title">Admins</span>
|
||||
</a>
|
||||
|
|
|
@ -1,642 +1,511 @@
|
|||
<!--
|
||||
Copyright (C) 2019 Nicola Murino
|
||||
Copyright (C) 2024 Nicola Murino
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, version 3.
|
||||
This WebUI uses the KeenThemes Mega Bundle, a proprietary theme:
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
https://keenthemes.com/products/templates-mega-bundle
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
KeenThemes HTML/CSS/JS components are allowed for use only within the
|
||||
SFTPGo product and restricted to be used in a resealable HTML template
|
||||
that can compete with KeenThemes products anyhow.
|
||||
|
||||
This WebUI is allowed for use only within the SFTPGo product and
|
||||
therefore cannot be used in derivative works/products without an
|
||||
explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||
-->
|
||||
{{define "fshtml"}}
|
||||
<div class="card bg-light mb-3 {{if .IsHidden}}d-none{{end}}">
|
||||
<div class="card-header">
|
||||
<b>Filesystem</b>
|
||||
{{- define "fshtml"}}
|
||||
<div class="card mt-10 {{if .IsHidden}}d-none{{end}}">
|
||||
<div class="card-header bg-light">
|
||||
<h3 data-i18n="storage.title" class="card-title section-title-inner">File system</h3>
|
||||
</div>
|
||||
<div class="card-body pb-1">
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label for="idFilesystem" class="col-sm-2 col-form-label">Storage</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control selectpicker" id="idFilesystem" name="fs_provider"
|
||||
onchange="onFilesystemChanged(this.value)">
|
||||
{{ range ListFSProviders }}
|
||||
<option value="{{.Name}}" {{if eq . $.Provider }}selected{{end}}>{{.ShortInfo}}</option>
|
||||
{{end}}
|
||||
<label for="idFilesystem" data-i18n="storage.label" class="col-md-3 col-form-label">Storage</label>
|
||||
<div class="col-md-9">
|
||||
<select id="idFilesystem" name="fs_provider" class="form-select" data-control="i18n-select2" data-hide-search="true">
|
||||
{{- range ListFSProviders }}
|
||||
<option value="{{.Name}}" data-i18n="{{.I18nString}}" {{if eq .FilesystemProvider $.Provider }}selected{{end}}>{{.ShortInfo}}</option>
|
||||
{{- end}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{if or .IsUserPage .IsGroupPage}}
|
||||
<div class="form-group row">
|
||||
<label for="idHomeDir" class="col-sm-2 col-form-label">Home Dir</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idHomeDir" name="home_dir" placeholder="Absolute path to a local directory"
|
||||
value="{{.DirPath}}" aria-describedby="homeDirHelpBlock">
|
||||
<small id="homeDirHelpBlock" class="form-text text-muted">
|
||||
{{if not .DirPath}}{{if .HasUsersBaseDir}}Leave blank for an appropriate default{{else}}{{if .IsGroupPage}}Leave blank and the storage to "local" to not override the root filesystem{{else}}Required for local storage providers. For non-local filesystems it will store temporary files, you can leave blank for an appropriate default{{end}}{{end}}{{end}}
|
||||
</small>
|
||||
{{- if or .IsUserPage .IsGroupPage}}
|
||||
<div class="form-group row mt-10">
|
||||
<label for="idHomeDir" data-i18n="storage.home_dir" class="col-md-3 col-form-label">Home Dir</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idHomeDir" type="text" data-i18n="[placeholder]storage.home_dir_placeholder" class="form-control" name="home_dir" value="{{.DirPath}}" aria-describedby="idHomeDirHelp" />
|
||||
<div id="idHomeDirHelp" class="form-text" {{if not .DirPath}}{{if .HasUsersBaseDir}}data-i18n="storage.home_dir_help1"{{else}}{{if .IsGroupPage}}data-i18n="storage.home_dir_help2"{{else}}data-i18n="storage.home_dir_help3"{{end}}{{end}}{{end}}></div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="form-group row">
|
||||
<label for="idMappedPath" class="col-sm-2 col-form-label">Home Dir</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idMappedPath" name="mapped_path" placeholder="Absolute path to a local directory"
|
||||
value="{{.DirPath}}" aria-describedby="mappedPathHelpBlock">
|
||||
<small id="mappedPathHelpBlock" class="form-text text-muted">
|
||||
Required for local storage providers. For non-local filesystems it will store temporary files, you can leave blank for an appropriate default
|
||||
</small>
|
||||
{{- else}}
|
||||
<div class="form-group row mt-10">
|
||||
<label for="idMappedPath" data-i18n="storage.home_dir" class="col-md-3 col-form-label">Home Dir</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idMappedPath" type="text" data-i18n="[placeholder]storage.home_dir_placeholder" class="form-control" name="mapped_path" value="{{.DirPath}}" aria-describedby="idMappedPathHelp" />
|
||||
<div id="idMappedPathHelp" class="form-text" {{if not .DirPath}}{{if .HasUsersBaseDir}}data-i18n="storage.home_dir_help1"{{else}}{{if .IsGroupPage}}data-i18n="storage.home_dir_help2"{{else}}data-i18n="storage.home_dir_help3"{{end}}{{end}}{{end}}></div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="form-group row fsconfig fsconfig-osfs">
|
||||
<label for="idOsReadBufferSize" class="col-sm-2 col-form-label">Read buffer (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idOsReadBufferSize" name="osfs_read_buffer_size" placeholder=""
|
||||
value="{{.OSConfig.ReadBufferSize}}" min="0" max="10" aria-describedby="OSReadBufferSizeHelpBlock">
|
||||
<small id="OSReadBufferSizeHelpBlock" class="form-text text-muted">
|
||||
Buffer size for downloads. 0 means no buffer, that's fine in most use cases.
|
||||
</small>
|
||||
{{- end}}
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-osfs">
|
||||
<label for="idOsReadBufferSize" data-i18n="storage.os_read_buffer" class="col-md-3 col-form-label">Read buffer (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idOsReadBufferSize" type="number" min="0" max="10" class="form-control" name="osfs_read_buffer_size" value="{{.OSConfig.ReadBufferSize}}" aria-describedby="idOsReadBufferSizeHelp" />
|
||||
<div id="idOsReadBufferSizeHelp" class="form-text" data-i18n="storage.os_buffer_help"></div>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idOsWriteBufferSize" class="col-sm-2 col-form-label">Write buffer (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idOsWriteBufferSize" name="osfs_write_buffer_size" placeholder=""
|
||||
value="{{.OSConfig.WriteBufferSize}}" min="0" max="10" aria-describedby="OSWriteBufferSizeHelpBlock">
|
||||
<small id="OSWriteBufferSizeHelpBlock" class="form-text text-muted">
|
||||
Buffer size for uploads. 0 means no buffer, that's fine in most use cases.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3Bucket" class="col-sm-2 col-form-label">Bucket</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idS3Bucket" name="s3_bucket" placeholder=""
|
||||
value="{{.S3Config.Bucket}}" maxlength="512">
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idOsWriteBufferSize" data-i18n="storage.os_write_buffer" class="col-md-2 col-form-label">Write buffer (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idOsWriteBufferSize" type="number" min="0" max="10" class="form-control" name="osfs_write_buffer_size" value="{{.OSConfig.WriteBufferSize}}" aria-describedby="idOsWriteBufferSizeHelp" />
|
||||
<div id="idOsWriteBufferSizeHelp" class="form-text" data-i18n="storage.os_buffer_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3Region" class="col-sm-2 col-form-label">Region</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idS3Region" name="s3_region" placeholder=""
|
||||
value="{{.S3Config.Region}}" maxlength="255">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3Bucket" data-i18n="storage.bucket" class="col-md-3 col-form-label">Bucket</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3Bucket" type="text" class="form-control" name="s3_bucket" value="{{.S3Config.Bucket}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3AccessKey" class="col-sm-2 col-form-label">Access Key</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idS3AccessKey" name="s3_access_key" placeholder=""
|
||||
value="{{.S3Config.AccessKey}}" maxlength="512" spellcheck="false">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3Region" data-i18n="storage.region" class="col-md-3 col-form-label">Region</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3Region" type="text" class="form-control" name="s3_region" value="{{.S3Config.Region}}" maxlength="512" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3AccessSecret" class="col-sm-2 col-form-label">Access Secret</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idS3AccessSecret" name="s3_access_secret" placeholder="" autocomplete="new-password" spellcheck="false"
|
||||
value="{{if .S3Config.AccessSecret.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.S3Config.AccessSecret.GetPayload}}{{end}}">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3AccessKey" data-i18n="storage.access_key" class="col-md-3 col-form-label">Access Key</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3AccessKey" type="text" class="form-control" name="s3_access_key" value="{{.S3Config.AccessKey}}" maxlength="512" spellcheck="false" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3Endpoint" class="col-sm-2 col-form-label">Endpoint</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idS3Endpoint" name="s3_endpoint" placeholder=""
|
||||
value="{{.S3Config.Endpoint}}" maxlength="512" aria-describedby="S3EndpointHelpBlock">
|
||||
<small id="S3EndpointHelpBlock" class="form-text text-muted">
|
||||
For AWS S3, leave blank to use the default endpoint for the specified region
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3AccessSecret" data-i18n="storage.access_secret" class="col-md-3 col-form-label">Access Secret</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3AccessSecret" type="password" class="form-control" name="s3_access_secret" autocomplete="off" spellcheck="false"
|
||||
value="{{if .S3Config.AccessSecret.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.S3Config.AccessSecret.GetPayload}}{{end}}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3PartSize" class="col-sm-2 col-form-label">UL Part Size (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idS3PartSize" name="s3_upload_part_size" placeholder=""
|
||||
value="{{.S3Config.UploadPartSize}}" aria-describedby="S3PartSizeHelpBlock">
|
||||
<small id="S3PartSizeHelpBlock" class="form-text text-muted">
|
||||
The buffer size for multipart uploads. Zero means the default (5 MB). Minimum is 5
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idS3UploadConcurrency" class="col-sm-2 col-form-label">UL Concurrency</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idS3UploadConcurrency" name="s3_upload_concurrency"
|
||||
placeholder="" value="{{.S3Config.UploadConcurrency}}" min="0"
|
||||
aria-describedby="S3ConcurrencyHelpBlock">
|
||||
<small id="S3ConcurrencyHelpBlock" class="form-text text-muted">
|
||||
How many parts are uploaded in parallel. Zero means the default (5)
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3KeyPrefix" data-i18n="storage.key_prefix" class="col-md-3 col-form-label">Key Prefix</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3KeyPrefix" type="text" class="form-control" name="s3_key_prefix" value="{{.S3Config.KeyPrefix}}" aria-describedby="idS3KeyPrefixHelp"/>
|
||||
<div id="idS3KeyPrefixHelp" class="form-text" data-i18n="storage.key_prefix_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3DLPartSize" class="col-sm-2 col-form-label">DL Part Size (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idS3DLPartSize" name="s3_download_part_size" placeholder=""
|
||||
value="{{.S3Config.DownloadPartSize}}" aria-describedby="S3DLPartSizeHelpBlock">
|
||||
<small id="S3DLPartSizeHelpBlock" class="form-text text-muted">
|
||||
The buffer size for multipart downloads. Zero means the default (5 MB). Minimum is 5
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idS3DownloadConcurrency" class="col-sm-2 col-form-label">DL Concurrency</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idS3DownloadConcurrency" name="s3_download_concurrency"
|
||||
placeholder="" value="{{.S3Config.DownloadConcurrency}}" min="0"
|
||||
aria-describedby="S3DLConcurrencyHelpBlock">
|
||||
<small id="S3DLConcurrencyHelpBlock" class="form-text text-muted">
|
||||
How many parts are downloaded in parallel. Zero means the default (5)
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3Endpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3Endpoint" type="text" class="form-control" name="s3_endpoint" value="{{.S3Config.Endpoint}}" aria-describedby="idS3EndpointHelp"/>
|
||||
<div id="idS3EndpointHelp" class="form-text" data-i18n="storage.endpoint_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3UploadTimeout" class="col-sm-2 col-form-label">UL Part Timeout (secs)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idS3UploadTimeout" name="s3_upload_part_max_time"
|
||||
placeholder="" value="{{.S3Config.UploadPartMaxTime}}" min="0"
|
||||
aria-describedby="S3UploadTimeoutHelpBlock">
|
||||
<small id="S3UploadTimeoutHelpBlock" class="form-text text-muted">
|
||||
Max time limit, in seconds, to upload a single part. 0 means no limit
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idS3DownloadTimeout" class="col-sm-2 col-form-label">DL Part Timeout (secs)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idS3DownloadTimeout" name="s3_download_part_max_time"
|
||||
placeholder="" value="{{.S3Config.DownloadPartMaxTime}}" min="0"
|
||||
aria-describedby="S3DownloadTimeoutHelpBlock">
|
||||
<small id="S3DownloadTimeoutHelpBlock" class="form-text text-muted">
|
||||
Max time limit, in seconds, to download a single part. 0 means no limit
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3RoleARN" data-i18n="storage.role_arn" class="col-md-3 col-form-label">Role ARN</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idS3RoleARN" type="text" class="form-control" name="s3_role_arn" value="{{.S3Config.RoleARN}}" aria-describedby="idS3RoleARNHelp"/>
|
||||
<div id="idS3RoleARNHelp" class="form-text" data-i18n="storage.role_arn_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3StorageClass" class="col-sm-2 col-form-label">Storage Class</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" id="idS3StorageClass" name="s3_storage_class" placeholder=""
|
||||
value="{{.S3Config.StorageClass}}" maxlength="255" aria-describedby="S3StorageClassHelpBlock">
|
||||
<small id="S3StorageClassHelpBlock" class="form-text text-muted">
|
||||
Leave blank for default
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3StorageClass" data-i18n="storage.class" class="col-md-3 col-form-label">Storage Class</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3StorageClass" type="text" class="form-control" name="s3_storage_class" value="{{.S3Config.StorageClass}}" aria-describedby="idS3StorageClassHelp" />
|
||||
<div id="idS3StorageClassHelp" class="form-text" data-i18n="general.blank_default_help"></div>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idS3ACL" class="col-sm-2 col-form-label">ACL</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" id="idS3ACL" name="s3_acl" placeholder=""
|
||||
value="{{.S3Config.ACL}}" maxlength="255" aria-describedby="S3ACLHelpBlock">
|
||||
<small id="S3ACLHelpBlock" class="form-text text-muted">
|
||||
Leave blank for default. More <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl" target="_blank">info</a>.
|
||||
</small>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idS3ACL" data-i18n="storage.acl" class="col-md-2 col-form-label">ACL</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3ACL" type="text" class="form-control" name="s3_acl" value="{{.S3Config.ACL}}" aria-describedby="idS3ACLHelp" />
|
||||
<div id="idS3ACLHelp" class="form-text" data-i18n="general.blank_default_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3RoleARN" class="col-sm-2 col-form-label">Role ARN</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idS3RoleARN" name="s3_role_arn" placeholder=""
|
||||
value="{{.S3Config.RoleARN}}" aria-describedby="S3RoleARNHelpBlock">
|
||||
<small id="S3RoleARNHelpBlock" class="form-text text-muted">
|
||||
Optional IAM Role ARN to assume
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3PartSize" data-i18n="storage.ul_part_size" class="col-md-3 col-form-label">Upload Part Size (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3PartSize" type="number" min="0" class="form-control" name="s3_upload_part_size" value="{{.S3Config.UploadPartSize}}" aria-describedby="idS3PartSizeHelp" />
|
||||
<div id="idS3PartSizeHelp" class="form-text" data-i18n="storage.part_size_help"></div>
|
||||
</div>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idS3UploadConcurrency" data-i18n="storage.ul_concurrency" class="col-md-2 col-form-label">Upload concurrency</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3UploadConcurrency" type="number" min="0" class="form-control" name="s3_upload_concurrency" value="{{.S3Config.UploadConcurrency}}" aria-describedby="idS3UploadConcurrencyHelp" />
|
||||
<div id="idS3UploadConcurrencyHelp" class="form-text" data-i18n="storage.ul_concurrency_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-s3fs">
|
||||
<label for="idS3KeyPrefix" class="col-sm-2 col-form-label">Key Prefix</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idS3KeyPrefix" name="s3_key_prefix" placeholder=""
|
||||
value="{{.S3Config.KeyPrefix}}" aria-describedby="S3KeyPrefixHelpBlock">
|
||||
<small id="S3KeyPrefixHelpBlock" class="form-text text-muted">
|
||||
Similar to a chroot for local filesystem. Example: "somedir/subdir/".
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3DLPartSize" data-i18n="storage.dl_part_size" class="col-md-3 col-form-label">Download Part Size (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3DLPartSize" type="number" min="0" class="form-control" name="s3_download_part_size" value="{{.S3Config.DownloadPartSize}}" aria-describedby="idS3DLPartSizeHelp" />
|
||||
<div id="idS3DLPartSizeHelp" class="form-text" data-i18n="storage.part_size_help"></div>
|
||||
</div>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idS3DownloadConcurrency" data-i18n="storage.dl_concurrency" class="col-md-2 col-form-label">Download concurrency</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3DownloadConcurrency" type="number" min="0" class="form-control" name="s3_download_concurrency" value="{{.S3Config.DownloadConcurrency}}" aria-describedby="idS3DownloadConcurrencyHelp" />
|
||||
<div id="idS3DownloadConcurrencyHelp" class="form-text" data-i18n="storage.dl_concurrency_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-s3fs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idS3ForcePathStyle" name="s3_force_path_style"
|
||||
{{if .S3Config.ForcePathStyle}}checked{{end}}>
|
||||
<label for="idS3ForcePathStyle" class="form-check-label" aria-describedby="S3PathStyleHelpBlock">Use path-style addressing, i.e., "`endpoint`/BUCKET/KEY"</label>
|
||||
<small id="S3PathStyleHelpBlock" class="form-text text-muted">
|
||||
It is required for some compatible S3 backends
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||
<label for="idS3UploadTimeout" data-i18n="storage.ul_part_timeout" class="col-md-3 col-form-label">UL Part Timeout (secs)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3UploadTimeout" type="number" min="0" class="form-control" name="s3_upload_part_max_time" value="{{.S3Config.DownloadPartSize}}" aria-describedby="idS3UploadTimeoutHelp" />
|
||||
<div id="idS3UploadTimeoutHelp" class="form-text" data-i18n="storage.ul_part_timeout_help"></div>
|
||||
</div>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idS3DownloadTimeout" data-i18n="storage.dl_part_timeout" class="col-md-2 col-form-label">DL Part Timeout (secs)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idS3DownloadTimeout" type="number" min="0" class="form-control" name="s3_download_part_max_time" value="{{.S3Config.DownloadConcurrency}}" aria-describedby="idS3DownloadTimeoutHelp" />
|
||||
<div id="idS3DownloadTimeoutHelp" class="form-text" data-i18n="storage.dl_part_timeout_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-s3fs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idS3SkipTLSVerify" name="s3_skip_tls_verify"
|
||||
{{if .S3Config.SkipTLSVerify}}checked{{end}}>
|
||||
<label for="idS3SkipTLSVerify" class="form-check-label" aria-describedby="S3SkipTLSVerifyHelpBlock">Skip TLS verify</label>
|
||||
<small id="S3SkipTLSVerifyHelpBlock" class="form-text text-muted">
|
||||
In this mode, TLS is susceptible to man-in-the-middle attacks. This should be used only for testing
|
||||
</small>
|
||||
<div class="form-group row align-items-center mt-10 fsconfig fsconfig-s3fs">
|
||||
<div class="col-md-5">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idS3ForcePathStyle" name="s3_force_path_style" {{if .S3Config.ForcePathStyle}}checked{{end}}/>
|
||||
<label data-i18n="storage.s3_path_style" class="form-check-label fw-semibold text-gray-800" for="idS3ForcePathStyle">
|
||||
Use path-style addressing, i.e., "`endpoint`/BUCKET/KEY"
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md-5">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idS3SkipTLSVerify" name="s3_skip_tls_verify" {{if .S3Config.SkipTLSVerify}}checked{{end}}/>
|
||||
<label data-i18n="general.skip_tls_verify" class="form-check-label fw-semibold text-gray-800" for="idS3SkipTLSVerify">
|
||||
Skip TLS verify. This should be used only for testing
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSBucket" class="col-sm-2 col-form-label">Bucket</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idGCSBucket" name="gcs_bucket" placeholder=""
|
||||
value="{{.GCSConfig.Bucket}}" maxlength="255">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSBucket" data-i18n="storage.bucket" class="col-md-3 col-form-label">Bucket</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idGCSBucket" type="text" class="form-control" name="gcs_bucket" value="{{.GCSConfig.Bucket}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSCredentialFile" class="col-sm-2 col-form-label">Credentials file</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="file" class="form-control-file" id="idGCSCredentialFile" name="gcs_credential_file"
|
||||
aria-describedby="GCSCredentialsHelpBlock">
|
||||
<small id="GCSCredentialsHelpBlock" class="form-text text-muted">
|
||||
Add or update credentials from a JSON file
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-sm-1"></div>
|
||||
<label for="idGCSStorageClass" class="col-sm-2 col-form-label">Storage Class</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" id="idGCSStorageClass" name="gcs_storage_class" placeholder=""
|
||||
value="{{.GCSConfig.StorageClass}}" maxlength="255" aria-describedby="GCSStorageClassHelpBlock">
|
||||
<small id="GCSStorageClassHelpBlock" class="form-text text-muted">
|
||||
Leave blank for default
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSCredentialFile" data-i18n="storage.credentials_file" class="col-md-3 col-form-label">Credential files</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idGCSCredentialFile" type="file" accept="application/json" class="form-control" name="gcs_credential_file" aria-describedby="idGCSCredentialFileHelp" />
|
||||
<div id="idGCSCredentialFileHelp" class="form-text" data-i18n="storage.credentials_file_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSUploadPartSize" class="col-sm-2 col-form-label">UL Part Size (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idGCSUploadPartSize" name="gcs_upload_part_size" placeholder=""
|
||||
value="{{.GCSConfig.UploadPartSize}}" aria-describedby="GCSPartSizeHelpBlock">
|
||||
<small id="GCSPartSizeHelpBlock" class="form-text text-muted">
|
||||
The buffer size for multipart uploads. Zero means the default (16 MB)
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idGCSUploadTimeout" class="col-sm-2 col-form-label">UL Part Timeout (secs)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idGCSUploadTimeout" name="gcs_upload_part_max_time"
|
||||
placeholder="" value="{{.GCSConfig.UploadPartMaxTime}}" min="0"
|
||||
aria-describedby="GCSUploadTimeoutHelpBlock">
|
||||
<small id="GCSUploadTimeoutHelpBlock" class="form-text text-muted">
|
||||
Max time limit, in seconds, to upload a single part. 0 means the default (32 secs)
|
||||
</small>
|
||||
<div class="form-group row align-items-center mt-10 fsconfig fsconfig-gcsfs">
|
||||
<label data-i18n="storage.auto_credentials" class="col-md-3 col-form-label" for="idGCSAutoCredentials">Automatic credentials</label>
|
||||
<div class="col-md-9">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idGCSAutoCredentials" name="gcs_auto_credentials" {{if gt .GCSConfig.AutomaticCredentials 0}}checked{{end}}/>
|
||||
<label data-i18n="storage.auto_credentials_help" class="form-check-label fw-semibold text-gray-800" for="idGCSAutoCredentials">
|
||||
Use default application credentials or credentials from environment
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-gcsfs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idGCSAutoCredentials" name="gcs_auto_credentials"
|
||||
aria-describedby="GCSAutoCredentialsHelpBlock" {{if gt .GCSConfig.AutomaticCredentials 0}}checked{{end}}>
|
||||
<label for="idGCSAutoCredentials" class="form-check-label">Automatic credentials</label>
|
||||
<small id="GCSAutoCredentialsHelpBlock" class="form-text text-muted">
|
||||
Use default application credentials or credentials from environment
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSKeyPrefix" data-i18n="storage.key_prefix" class="col-md-3 col-form-label">Key Prefix</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idGCSKeyPrefix" type="text" class="form-control" name="gcs_key_prefix" value="{{.GCSConfig.KeyPrefix}}" aria-describedby="idGCSKeyPrefixHelp" />
|
||||
<div id="idGCSKeyPrefixHelp" class="form-text" data-i18n="storage.key_prefix_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSKeyPrefix" class="col-sm-2 col-form-label">Key Prefix</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idGCSKeyPrefix" name="gcs_key_prefix" placeholder=""
|
||||
value="{{.GCSConfig.KeyPrefix}}" aria-describedby="GCSKeyPrefixHelpBlock">
|
||||
<small id="GCSKeyPrefixHelpBlock" class="form-text text-muted">
|
||||
Similar to a chroot for local filesystem. Example: "somedir/subdir/".
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSStorageClass" data-i18n="storage.class" class="col-md-3 col-form-label">Storage Class</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idGCSStorageClass" type="text" class="form-control" name="gcs_storage_class" value="{{.GCSConfig.StorageClass}}" aria-describedby="idGCSStorageClassHelp" />
|
||||
<div id="idGCSStorageClassHelp" class="form-text" data-i18n="general.blank_default_help"></div>
|
||||
</div>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idGCSACL" data-i18n="storage.acl" class="col-md-2 col-form-label">ACL</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idGCSACL" type="text" class="form-control" name="gcs_acl" value="{{.GCSConfig.ACL}}" aria-describedby="idGCSACLHelp"/>
|
||||
<div id="idGCSACLHelp" class="form-text" data-i18n="general.blank_default_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSACL" class="col-sm-2 col-form-label">ACL</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idGCSACL" name="gcs_acl" placeholder=""
|
||||
value="{{.GCSConfig.ACL}}" maxlength="255" aria-describedby="GCSACLHelpBlock">
|
||||
<small id="GCSACLHelpBlock" class="form-text text-muted">
|
||||
ACL for uploaded objects. Leave blank for default. For more info refer to the JSON API <a href="https://cloud.google.com/storage/docs/access-control/lists#predefined-acl" target="_blank">here</a>
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
|
||||
<label for="idGCSUploadPartSize" data-i18n="storage.ul_part_size" class="col-md-3 col-form-label">Upload Part Size (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idGCSUploadPartSize" type="number" min="0" class="form-control" name="gcs_upload_part_size" value="{{.GCSConfig.UploadPartSize}}" aria-describedby="idGCSUploadPartSizeHelp" />
|
||||
<div id="idGCSUploadPartSizeHelp" class="form-text" data-i18n="storage.gcs_part_size_help"></div>
|
||||
</div>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idGCSUploadTimeout" data-i18n="storage.ul_part_timeout" class="col-md-2 col-form-label">UL Part Timeout (secs)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idGCSUploadTimeout" type="number" min="0" class="form-control" name="gcs_upload_part_max_time" value="{{.GCSConfig.UploadPartMaxTime}}" aria-describedby="idGCSUploadTimeoutHelp" />
|
||||
<div id="idGCSUploadTimeoutHelp" class="form-text" data-i18n="storage.gcs_ul_part_timeout_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzContainer" class="col-sm-2 col-form-label">Container</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idAzContainer" name="az_container" placeholder=""
|
||||
value="{{.AzBlobConfig.Container}}" maxlength="512">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzContainer" data-i18n="storage.container" class="col-md-3 col-form-label">Container</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idAzContainer" type="text" class="form-control" name="az_container" value="{{.AzBlobConfig.Container}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzAccountName" class="col-sm-2 col-form-label">Account Name</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idAzAccountName" name="az_account_name" placeholder=""
|
||||
spellcheck="false" value="{{.AzBlobConfig.AccountName}}" maxlength="512">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzAccountName" data-i18n="storage.account_name" class="col-md-3 col-form-label">Account Name</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idAzAccountName" type="text" class="form-control" name="az_account_name" value="{{.AzBlobConfig.AccountName}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzAccountKey" class="col-sm-2 col-form-label">Account Key</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idAzAccountKey" name="az_account_key" placeholder="" autocomplete="new-password" spellcheck="false"
|
||||
value="{{if .AzBlobConfig.AccountKey.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.AzBlobConfig.AccountKey.GetPayload}}{{end}}">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzAccountKey" data-i18n="storage.account_key" class="col-md-3 col-form-label">Account Key</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idAzAccountKey" type="password" class="form-control" name="az_account_key" autocomplete="off" spellcheck="false"
|
||||
value="{{if .AzBlobConfig.AccountKey.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.AzBlobConfig.AccountKey.GetPayload}}{{end}}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzSASURL" class="col-sm-2 col-form-label">SAS URL</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idAzSASURL" name="az_sas_url" placeholder="" aria-describedby="AzSASURLHelpBlock"
|
||||
autocomplete="new-password" spellcheck="false" value="{{if .AzBlobConfig.SASURL.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.AzBlobConfig.SASURL.GetPayload}}{{end}}">
|
||||
<small id="AzSASURLHelpBlock" class="form-text text-muted">
|
||||
Shared Access Signature URL can be used instead of account name/key
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzEndpoint" class="col-sm-2 col-form-label">Endpoint</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idAzEndpoint" name="az_endpoint" placeholder=""
|
||||
aria-describedby="AzEndpointHelpBlock" value="{{.AzBlobConfig.Endpoint}}" maxlength="512">
|
||||
<small id="AzEndpointHelpBlock" class="form-text text-muted">
|
||||
Optional endpoint
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzSASURL" data-i18n="storage.sas_url" class="col-md-3 col-form-label">SAS URL</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idAzSASURL" type="password" class="form-control" name="az_sas_url" autocomplete="off" spellcheck="false" aria-describedby="idAzSASURLHelp"
|
||||
value="{{if .AzBlobConfig.SASURL.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.AzBlobConfig.SASURL.GetPayload}}{{end}}"/>
|
||||
<div id="idAzSASURLHelp" class="form-text" data-i18n="storage.sas_url_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzAccessTier" class="col-sm-2 col-form-label">Access Tier</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control selectpicker" id="idAzAccessTier" name="az_access_tier">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzKeyPrefix" data-i18n="storage.key_prefix" class="col-md-3 col-form-label">Key Prefix</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idAzKeyPrefix" type="text" class="form-control" name="az_key_prefix" value="{{.AzBlobConfig.KeyPrefix}}" aria-describedby="idAzKeyPrefixHelp" />
|
||||
<div id="idAzKeyPrefixHelp" class="form-text" data-i18n="storage.key_prefix_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzAccessTier" data-i18n="storage.class" class="col-md-3 col-form-label">Storage Class</label>
|
||||
<div class="col-md-9">
|
||||
<select id="idAzAccessTier" name="az_access_tier" class="form-select" data-control="i18n-select2" data-hide-search="true">
|
||||
<option value="" {{if eq .AzBlobConfig.AccessTier "" }}selected{{end}}>Default</option>
|
||||
<option value="Hot" {{if eq .AzBlobConfig.AccessTier "Hot" }}selected{{end}}>Hot</option>
|
||||
<option value="Cool" {{if eq .AzBlobConfig.AccessTier "Cool" }}selected{{end}}>Cool</option>
|
||||
<option value="Archive" {{if eq .AzBlobConfig.AccessTier "Archive" }}selected{{end}}>Archive
|
||||
</option>
|
||||
<option value="Archive" {{if eq .AzBlobConfig.AccessTier "Archive" }}selected{{end}}>Archive</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzUploadPartSize" class="col-sm-2 col-form-label">UL Part Size (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idAzUploadPartSize" name="az_upload_part_size" placeholder=""
|
||||
value="{{.AzBlobConfig.UploadPartSize}}" aria-describedby="AzDLPartSizeHelpBlock">
|
||||
<small id="AzDLPartSizeHelpBlock" class="form-text text-muted">
|
||||
The buffer size for multipart uploads. Zero means the default (5 MB)
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzUploadPartSize" data-i18n="storage.ul_part_size" class="col-md-3 col-form-label">Upload Part Size (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idAzUploadPartSize" type="number" min="0" class="form-control" name="az_upload_part_size" value="{{.AzBlobConfig.UploadPartSize}}" aria-describedby="idAzUploadPartSizeHelp" />
|
||||
<div id="idAzUploadPartSizeHelp" class="form-text" data-i18n="storage.part_size_help"></div>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idAzUploadConcurrency" class="col-sm-2 col-form-label">UL Concurrency</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idAzUploadConcurrency" name="az_upload_concurrency"
|
||||
placeholder="" value="{{.AzBlobConfig.UploadConcurrency}}" min="0"
|
||||
aria-describedby="AzULConcurrencyHelpBlock">
|
||||
<small id="AzULConcurrencyHelpBlock" class="form-text text-muted">
|
||||
How many parts are uploaded in parallel. Zero means the default (5)
|
||||
</small>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idAzUploadConcurrency" data-i18n="storage.ul_concurrency" class="col-md-2 col-form-label">Upload concurrency</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idAzUploadConcurrency" type="number" min="0" class="form-control" name="az_upload_concurrency" value="{{.AzBlobConfig.UploadConcurrency}}" aria-describedby="idAzUploadConcurrencyHelp" />
|
||||
<div id="idAzUploadConcurrencyHelp" class="form-text" data-i18n="storage.ul_concurrency_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzDownloadPartSize" class="col-sm-2 col-form-label">DL Part Size (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idAzDownloadPartSize" name="az_download_part_size" placeholder=""
|
||||
value="{{.AzBlobConfig.DownloadPartSize}}" aria-describedby="AzDLPartSizeHelpBlock">
|
||||
<small id="AzDLPartSizeHelpBlock" class="form-text text-muted">
|
||||
The buffer size for multipart downloads. Zero means the default (5 MB)
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzDownloadPartSize" data-i18n="storage.dl_part_size" class="col-md-3 col-form-label">Download Part Size (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idAzDownloadPartSize" type="number" min="0" class="form-control" name="az_download_part_size" value="{{.AzBlobConfig.DownloadPartSize}}" aria-describedby="idAzDownloadPartSizeHelp" />
|
||||
<div id="idAzDownloadPartSizeHelp" class="form-text" data-i18n="storage.part_size_help"></div>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idAzDownloadConcurrency" class="col-sm-2 col-form-label">DL Concurrency</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idAzDownloadConcurrency" name="az_download_concurrency"
|
||||
placeholder="" value="{{.AzBlobConfig.DownloadConcurrency}}" min="0"
|
||||
aria-describedby="AzDLConcurrencyHelpBlock">
|
||||
<small id="AzDLConcurrencyHelpBlock" class="form-text text-muted">
|
||||
How many parts are downloaded in parallel. Zero means the default (5)
|
||||
</small>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idAzDownloadConcurrency" data-i18n="storage.dl_concurrency" class="col-md-2 col-form-label">Download concurrency</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idAzDownloadConcurrency" type="number" min="0" class="form-control" name="az_download_concurrency" value="{{.AzBlobConfig.DownloadConcurrency}}" aria-describedby="idAzDownloadConcurrencyHelp"/>
|
||||
<div id="idAzDownloadConcurrencyHelp" class="form-text" data-i18n="storage.dl_concurrency_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzKeyPrefix" class="col-sm-2 col-form-label">Key Prefix</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idAzKeyPrefix" name="az_key_prefix" placeholder=""
|
||||
value="{{.AzBlobConfig.KeyPrefix}}" aria-describedby="AzKeyPrefixHelpBlock">
|
||||
<small id="AzKeyPrefixHelpBlock" class="form-text text-muted">
|
||||
Similar to a chroot for local filesystem. Example: "somedir/subdir/".
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label for="idAzEndpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idAzEndpoint" type="text" class="form-control" name="az_endpoint" value="{{.AzBlobConfig.Endpoint}}" aria-describedby="idAzEndpointHelp" />
|
||||
<div id="idAzEndpointHelp" class="form-text" data-i18n="general.blank_default_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-azblobfs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idUseEmulator" name="az_use_emulator" {{if
|
||||
.AzBlobConfig.UseEmulator}}checked{{end}}>
|
||||
<label for="idUseEmulator" class="form-check-label">Use Azure Blob emulator</label>
|
||||
<div class="form-group row align-items-center mt-10 fsconfig fsconfig-azblobfs">
|
||||
<label data-i18n="storage.emulator" class="col-md-3 col-form-label" for="idUseEmulator">Use Azure Blob emulator</label>
|
||||
<div class="col-md-9">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idUseEmulator" name="az_use_emulator" {{if .AzBlobConfig.UseEmulator}}checked{{end}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-cryptfs">
|
||||
<label for="idCryptPassphrase" class="col-sm-2 col-form-label">Passphrase</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idCryptPassphrase" name="crypt_passphrase"
|
||||
placeholder="" autocomplete="new-password" aria-describedby="CryptPassphraseHelpBlock"
|
||||
value="{{if .CryptConfig.Passphrase.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.CryptConfig.Passphrase.GetPayload}}{{end}}">
|
||||
<small id="CryptPassphraseHelpBlock" class="form-text text-muted">
|
||||
Passphrase to derive the per-object encryption key
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-cryptfs">
|
||||
<label for="idCryptPassphrase" data-i18n="storage.passphrase" class="col-md-3 col-form-label">Passphrase</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idCryptPassphrase" type="password" class="form-control" name="crypt_passphrase" autocomplete="off" spellcheck="false" aria-describedby="idCryptPassphraseHelp"
|
||||
value="{{if .CryptConfig.Passphrase.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.CryptConfig.Passphrase.GetPayload}}{{end}}"/>
|
||||
<div id="idCryptPassphraseHelp" class="form-text" data-i18n="storage.passphrase_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-cryptfs">
|
||||
<label for="idCryptFsReadBufferSize" class="col-sm-2 col-form-label">Read buffer (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idCryptFsReadBufferSize" name="cryptfs_read_buffer_size" placeholder=""
|
||||
value="{{.CryptConfig.ReadBufferSize}}" min="0" max="10" aria-describedby="CryptFsReadBufferSizeHelpBlock">
|
||||
<small id="CryptFsReadBufferSizeHelpBlock" class="form-text text-muted">
|
||||
Buffer size for downloads. 0 means no buffer, that's fine in most use cases.
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-cryptfs">
|
||||
<label for="idCryptFsReadBufferSize" data-i18n="storage.os_read_buffer" class="col-md-3 col-form-label">Read buffer (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idCryptFsReadBufferSize" type="number" min="0" max="10" class="form-control" name="cryptfs_read_buffer_size" value="{{.CryptConfig.ReadBufferSize}}" aria-describedby="idCryptFsReadBufferSizeHelp" />
|
||||
<div id="idCryptFsReadBufferSizeHelp" class="form-text" data-i18n="storage.os_buffer_help"></div>
|
||||
</div>
|
||||
<div class="col-sm-2"></div>
|
||||
<label for="idCryptFsWriteBufferSize" class="col-sm-2 col-form-label">Write buffer (MB)</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="number" class="form-control" id="idCryptFsWriteBufferSize" name="cryptfs_write_buffer_size" placeholder=""
|
||||
value="{{.CryptConfig.WriteBufferSize}}" min="0" max="10" aria-describedby="CryptFsWriteBufferSizeHelpBlock">
|
||||
<small id="CryptFsWriteBufferSizeHelpBlock" class="form-text text-muted">
|
||||
Buffer size for uploads. 0 means no buffer, that's fine in most use cases.
|
||||
</small>
|
||||
<div class="col-md-1"></div>
|
||||
<label for="idCryptFsWriteBufferSize" data-i18n="storage.os_write_buffer" class="col-md-2 col-form-label">Write buffer (MB)</label>
|
||||
<div class="col-md-3">
|
||||
<input id="idCryptFsWriteBufferSize" type="number" min="0" max="10" class="form-control" name="cryptfs_write_buffer_size" value="{{.CryptConfig.WriteBufferSize}}" aria-describedby="idCryptFsWriteBufferSizeHelp" />
|
||||
<div id="idCryptFsWriteBufferSizeHelp" class="form-text" data-i18n="storage.os_buffer_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPEndpoint" class="col-sm-2 col-form-label">Endpoint</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idSFTPEndpoint" name="sftp_endpoint" placeholder=""
|
||||
value="{{.SFTPConfig.Endpoint}}" maxlength="255" aria-describedby="SFTPEndpointHelpBlock">
|
||||
<small id="SFTPEndpointHelpBlock" class="form-text text-muted">
|
||||
Endpoint as host:port, port is always required
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPEndpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idSFTPEndpoint" type="text" class="form-control" name="sftp_endpoint" value="{{.SFTPConfig.Endpoint}}" aria-describedby="idSFTPEndpointHelp"/>
|
||||
<div id="idSFTPEndpointHelp" class="form-text" data-i18n="storage.sftp_endpoint_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPUsername" class="col-sm-2 col-form-label">Username</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idSFTPUsername" name="sftp_username" placeholder=""
|
||||
value="{{.SFTPConfig.Username}}" maxlength="512" spellcheck="false">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPUsername" data-i18n="login.username" class="col-md-3 col-form-label">Username</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idSFTPUsername" type="text" class="form-control" name="sftp_username" value="{{.SFTPConfig.Username}}" spellcheck="false" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPassword" class="col-sm-2 col-form-label">Password</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idSFTPPassword" name="sftp_password" placeholder="" autocomplete="new-password" spellcheck="false"
|
||||
value="{{if .SFTPConfig.Password.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.SFTPConfig.Password.GetPayload}}{{end}}">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPassword" data-i18n="login.password" class="col-md-3 col-form-label">Password</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idSFTPPassword" type="password" class="form-control" name="sftp_password" autocomplete="off" spellcheck="false"
|
||||
value="{{if .SFTPConfig.Password.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.SFTPConfig.Password.GetPayload}}{{end}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPrivateKey" class="col-sm-2 col-form-label">Private key</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPrivateKey" data-i18n="general.private_key" class="col-md-3 col-form-label">Private key</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" id="idSFTPPrivateKey" name="sftp_private_key" spellcheck="false"
|
||||
rows="3">{{if .SFTPConfig.PrivateKey.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.SFTPConfig.PrivateKey.GetPayload}}{{end}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPassphrase" class="col-sm-2 col-form-label">Key Passphrase</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idSFTPPassphrase" name="sftp_key_passphrase" autocomplete="new-password" placeholder="" spellcheck="false"
|
||||
value="{{if .SFTPConfig.KeyPassphrase.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.SFTPConfig.KeyPassphrase.GetPayload}}{{end}}"
|
||||
aria-describedby="SFTPPassphraseHelpBlock">
|
||||
<small id="SFTPPassphraseHelpBlock" class="form-text text-muted">
|
||||
Passphrase used to protect your private key, if any
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPassphrase" data-i18n="storage.passphrase" class="col-md-3 col-form-label">Passphrase</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idSFTPPassphrase" type="password" class="form-control" name="sftp_key_passphrase" autocomplete="off" spellcheck="false" aria-describedby="idSFTPPassphraseHelp"
|
||||
value="{{if .SFTPConfig.KeyPassphrase.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.SFTPConfig.KeyPassphrase.GetPayload}}{{end}}" />
|
||||
<div id="idSFTPPassphraseHelp" class="form-text" data-i18n="storage.passphrase_key_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPrefix" class="col-sm-2 col-form-label">Prefix</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idSFTPPrefix" name="sftp_prefix" placeholder=""
|
||||
value="{{.SFTPConfig.Prefix}}" aria-describedby="SFTPPrefixHelpBlock">
|
||||
<small id="SFTPPrefixHelpBlock" class="form-text text-muted">
|
||||
Similar to a chroot for local filesystem. Example: "/somedir/subdir".
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPPrefix" data-i18n="storage.sftp_home_dir" class="col-md-3 col-form-label">Roor directory</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idSFTPPrefix" type="text" class="form-control" name="sftp_prefix" value="{{.SFTPConfig.Prefix}}" aria-describedby="idSFTPPrefixHelp"/>
|
||||
<div id="idSFTPPrefixHelp" class="form-text" data-i18n="storage.sftp_home_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPFingerprints" class="col-sm-2 col-form-label">Fingerprints</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" id="idSFTPFingerprints" name="sftp_fingerprints" rows="3"
|
||||
aria-describedby="SFTPFingerprintsHelpBlock">{{range .SFTPConfig.Fingerprints}}{{.}}
{{end}}</textarea>
|
||||
<small id="SFTPFingerprintsHelpBlock" class="form-text text-muted">
|
||||
SHA256 fingerprints to validate when connecting to the external SFTP server, one per line. If empty any host key will be accepted: this is a security risk!
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPFingerprints" data-i18n="storage.fingerprints" class="col-md-3 col-form-label">Fingerprints</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" id="idSFTPFingerprints" name="sftp_fingerprints" spellcheck="false" aria-describedby="idSFTPFingerprintsHelp"
|
||||
rows="3">{{- range .SFTPConfig.Fingerprints}}{{.}}
{{- end}}</textarea>
|
||||
<div id="idSFTPFingerprintsHelp" class="form-text" data-i18n="storage.fingerprints_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPUploadBufferSize" class="col-sm-2 col-form-label">Buffer size (MB)</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" class="form-control" id="idSFTPBufferSize" name="sftp_buffer_size" placeholder=""
|
||||
value="{{.SFTPConfig.BufferSize}}" min="0" max="16" aria-describedby="SFTPBufferHelpBlock">
|
||||
<small id="SFTPBufferHelpBlock" class="form-text text-muted">
|
||||
A buffer size > 0 enables concurrent transfers
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
|
||||
<label for="idSFTPUploadBufferSize" data-i18n="storage.sftp_buffer" class="col-md-3 col-form-label">Buffer size (MB)</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idSFTPUploadBufferSize" type="number" min="0" max="16" class="form-control" name="sftp_buffer_size" value="{{.SFTPConfig.BufferSize}}" aria-describedby="idSFTPUploadBufferSizeHelp" />
|
||||
<div id="idSFTPUploadBufferSizeHelp" class="form-text" data-i18n="storage.os_buffer_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-sftpfs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idDisableConcurrentReads"
|
||||
name="sftp_disable_concurrent_reads" {{if .SFTPConfig.DisableCouncurrentReads}}checked{{end}}>
|
||||
<label for="idDisableConcurrentReads" class="form-check-label">Disable concurrent reads</label>
|
||||
<div class="form-group row align-items-center mt-10 fsconfig fsconfig-sftpfs">
|
||||
<div class="col-md-5">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idDisableConcurrentReads" name="sftp_disable_concurrent_reads" {{if .SFTPConfig.DisableCouncurrentReads}}checked{{end}}/>
|
||||
<label data-i18n="storage.sftp_concurrent_reads" class="form-check-label fw-semibold text-gray-800" for="idDisableConcurrentReads">
|
||||
Disable concurrent reads
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md-5">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idSFTPEqualityCheckMode" name="sftp_equality_check_mode" {{if eq .SFTPConfig.EqualityCheckMode 1}}checked{{end}}/>
|
||||
<label data-i18n="storage.relaxed_equality_check" class="form-check-label fw-semibold text-gray-800" for="idSFTPEqualityCheckMode">
|
||||
Relaxed equality check
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-sftpfs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idSFTPEqualityCheckMode" aria-describedby="SFTPEqualityCheckHelpBlock"
|
||||
name="sftp_equality_check_mode" {{if eq .SFTPConfig.EqualityCheckMode 1}}checked{{end}}>
|
||||
<label for="idSFTPEqualityCheckMode" class="form-check-label">Relaxed equality check mode</label>
|
||||
<small id="SFTPEqualityCheckHelpBlock" class="form-text text-muted">
|
||||
Enable to consider only the endpoint to determine if different configs point to the same server. By default, both the endpoint and the username must match. Renaming between different configs is allowed if they point to the same server
|
||||
</small>
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPEndpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idHTTPEndpoint" type="text" class="form-control" name="http_endpoint" value="{{.HTTPConfig.Endpoint}}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPEndpoint" class="col-sm-2 col-form-label">Endpoint</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idHTTPEndpoint" name="http_endpoint" placeholder=""
|
||||
value="{{.HTTPConfig.Endpoint}}" maxlength="255">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPUsername" data-i18n="login.username" class="col-md-3 col-form-label">Username</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idHTTPUsername" type="text" class="form-control" name="http_username" value="{{.HTTPConfig.Username}}" spellcheck="false" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPUsername" class="col-sm-2 col-form-label">Username</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="idHTTPUsername" name="http_username" placeholder="" spellcheck="false"
|
||||
value="{{.HTTPConfig.Username}}" maxlength="255">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPPassword" data-i18n="login.password" class="col-md-3 col-form-label">Password</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idHTTPPassword" type="password" class="form-control" name="http_password" autocomplete="off" spellcheck="false"
|
||||
value="{{if .HTTPConfig.Password.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.HTTPConfig.Password.GetPayload}}{{end}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPPassword" class="col-sm-2 col-form-label">Password</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idHTTPPassword" name="http_password" autocomplete="new-password" placeholder="" spellcheck="false"
|
||||
value="{{if .HTTPConfig.Password.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.HTTPConfig.Password.GetPayload}}{{end}}">
|
||||
<div class="form-group row mt-10 fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPAPIKey" data-i18n="storage.api_key" class="col-md-3 col-form-label">API Key</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idHTTPAPIKey" type="password" class="form-control" name="http_api_key" autocomplete="off" spellcheck="false"
|
||||
value="{{if .HTTPConfig.APIKey.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.HTTPConfig.APIKey.GetPayload}}{{end}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row fsconfig fsconfig-httpfs">
|
||||
<label for="idHTTPAPIKey" class="col-sm-2 col-form-label">API Key</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="idHTTPAPIKey" name="http_api_key" autocomplete="new-password" placeholder="" spellcheck="false"
|
||||
value="{{if .HTTPConfig.APIKey.IsEncrypted}}{{.RedactedSecret}}{{else}}{{.HTTPConfig.APIKey.GetPayload}}{{end}}">
|
||||
<div class="form-group row align-items-center mt-10 fsconfig fsconfig-httpfs">
|
||||
<div class="col-md-5">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idHTTPSkipTLSVerify" name="http_skip_tls_verify" {{if .HTTPConfig.SkipTLSVerify}}checked{{end}} />
|
||||
<label data-i18n="general.skip_tls_verify" class="form-check-label fw-semibold text-gray-800" for="idHTTPSkipTLSVerify">
|
||||
Skip TLS verify. This should be used only for testing
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md-5">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idHTTPEqualityCheckMode" name="http_equality_check_mode" {{if eq .HTTPConfig.EqualityCheckMode 1}}checked{{end}}/>
|
||||
<label data-i18n="storage.relaxed_equality_check" class="form-check-label fw-semibold text-gray-800" for="idHTTPEqualityCheckMode">
|
||||
Relaxed equality check
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-httpfs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idHTTPSkipTLSVerify"
|
||||
name="http_skip_tls_verify" {{if .HTTPConfig.SkipTLSVerify}}checked{{end}}>
|
||||
<label for="idHTTPSkipTLSVerify" class="form-check-label">Skip TLS verify</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group fsconfig fsconfig-httpfs">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="idHTTPEqualityCheckMode" aria-describedby="HTTPEqualityCheckHelpBlock"
|
||||
name="http_equality_check_mode" {{if eq .HTTPConfig.EqualityCheckMode 1}}checked{{end}}>
|
||||
<label for="idHTTPEqualityCheckMode" class="form-check-label">Relaxed equality check mode</label>
|
||||
<small id="HTTPEqualityCheckHelpBlock" class="form-text text-muted">
|
||||
Enable to consider only the endpoint to determine if different configs point to the same server. By default, both the endpoint and the username must match. Renaming between different configs is allowed if they point to the same server
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "fsjs"}}
|
||||
<script type="text/javascript">
|
||||
function onFilesystemChanged(val){
|
||||
// each fsconfig form-group has the 'fsconfig' css class
|
||||
// as well as a 'fsconfig-{name}' class where name is the FilesystemProvider.Name
|
||||
// we're simply hiding all of them and then showing the ones that match the selected vfs provider
|
||||
$('.form-group.fsconfig').hide();
|
||||
$('.form-group.fsconfig-'+val).show();
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
{{- end}}
|
File diff suppressed because it is too large
Load diff
|
@ -20,6 +20,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- end}}
|
||||
|
||||
{{- define "page_body"}}
|
||||
{{- template "errmsg" ""}}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-light">
|
||||
<h3 data-i18n="user.view_manage" class="card-title section-title">View and manage users</h3>
|
||||
|
@ -31,7 +32,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
</div>
|
||||
<div id="card_content" class="d-none">
|
||||
<div class="d-flex flex-stack flex-wrap mb-5">
|
||||
<div class="d-flex align-items-center position-relative my-1">
|
||||
<div class="d-flex align-items-center position-relative my-2">
|
||||
<i class="ki-duotone ki-magnifier fs-1 position-absolute ms-6">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
@ -40,20 +41,89 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
class="form-control rounded-1 w-250px ps-15 me-5" placeholder="Search" />
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end" data-table-toolbar="base">
|
||||
<a href="{{.UserURL}}" class="btn btn-primary">
|
||||
<div class="d-flex justify-content-end my-2" data-table-toolbar="base">
|
||||
<button type="button" class="btn btn-light-primary rotate" data-kt-menu-trigger="click" data-kt-menu-placement="bottom" data-kt-menu-permanent="true">
|
||||
<span data-i18n="general.colvis">Column visibility</span>
|
||||
<i class="ki-duotone ki-down fs-3 rotate-180 ms-3 me-0"></i>
|
||||
</button>
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-800 menu-state-bg-light-primary fw-semibold w-auto min-w-200 mw-300px py-4" data-kt-menu="true">
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColStatus" />
|
||||
<label class="form-check-label" for="checkColStatus">
|
||||
<span data-i18n="user.status" class="text-gray-800 fs-6">Status</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColLastLogin" />
|
||||
<label class="form-check-label" for="checkColLastLogin">
|
||||
<span data-i18n="user.last_login" class="text-gray-800 fs-6">Last login</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColEmail" />
|
||||
<label class="form-check-label" for="checkColEmail">
|
||||
<span data-i18n="general.email" class="text-gray-800 fs-6">Email</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColStorage" />
|
||||
<label class="form-check-label" for="checkColStorage">
|
||||
<span data-i18n="storage.label" class="text-gray-800 fs-6">Storage</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColRole" />
|
||||
<label class="form-check-label" for="checkColRole">
|
||||
<span data-i18n="general.role" class="text-gray-800 fs-6">Role</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkCol2FA" />
|
||||
<label class="form-check-label" for="checkCol2FA">
|
||||
<span data-i18n="title.two_factor_auth_short" class="text-gray-800 fs-6">2FA</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColDiskQuota" />
|
||||
<label class="form-check-label" for="checkColDiskQuota">
|
||||
<span data-i18n="fs.quota_usage.disk" class="text-gray-800 fs-6">Disk quota</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColTransferQuota" />
|
||||
<label class="form-check-label" for="checkColTransferQuota">
|
||||
<span data-i18n="fs.quota_usage.transfer" class="text-gray-800 fs-6">Transfer quota</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="menu-item px-3 py-2 form-check form-check-sm form-check-custom form-check-solid">
|
||||
<input type="checkbox" class="form-check-input" value="" id="checkColDesc" />
|
||||
<label class="form-check-label" for="checkColDesc">
|
||||
<span data-i18n="general.description" class="text-gray-800 fs-6">Description</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{{- if .LoggedUser.HasPermission "add_users"}}
|
||||
<a href="{{.UserURL}}" class="btn btn-primary ms-5">
|
||||
<i class="ki-duotone ki-plus fs-2"></i>
|
||||
<span data-i18n="general.add">Add</span>
|
||||
</a>
|
||||
{{- end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="dataTable" class="table align-middle table-row-dashed fs-6 gy-5">
|
||||
<thead>
|
||||
<tr class="text-start text-muted fw-bold fs-6 gs-0">
|
||||
<th data-i18n="general.name">Name</th>
|
||||
<th data-i18n="share.scope">Scope</th>
|
||||
<th data-i18n="general.info">Info</th>
|
||||
<th data-i18n="login.username">Username</th>
|
||||
<th data-i18n="user.status">Status</th>
|
||||
<th data-i18n="user.last_login">Last login</th>
|
||||
<th data-i18n="general.email">Email</th>
|
||||
<th data-i18n="storage.label">Storage</th>
|
||||
<th data-i18n="general.role">Role</th>
|
||||
<th data-i18n="title.two_factor_auth_short">2FA</th>
|
||||
<th data-i18n="fs.quota_usage.disk">Disk quota</th>
|
||||
<th data-i18n="fs.quota_usage.transfer">Transfer quota</th>
|
||||
<th data-i18n="general.description">Description</th>
|
||||
<th class="min-w-100px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -62,4 +132,491 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{- end}}
|
||||
{{- define "extra_js"}}
|
||||
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js"></script>
|
||||
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
||||
function deleteAction(username) {
|
||||
ModalAlert.fire({
|
||||
text: $.t('general.delete_confirm_generic'),
|
||||
icon: "warning",
|
||||
confirmButtonText: $.t('general.delete_confirm_btn'),
|
||||
cancelButtonText: $.t('general.cancel'),
|
||||
customClass: {
|
||||
confirmButton: "btn btn-danger",
|
||||
cancelButton: 'btn btn-secondary'
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed){
|
||||
$('#loading_message').text("");
|
||||
KTApp.showPageLoading();
|
||||
let path = '{{.UserURL}}' + "/" + encodeURIComponent(username);
|
||||
|
||||
axios.delete(path, {
|
||||
timeout: 15000,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
||||
},
|
||||
validateStatus: function (status) {
|
||||
return status == 200;
|
||||
}
|
||||
}).then(function(response){
|
||||
location.reload();
|
||||
}).catch(function(error){
|
||||
KTApp.hidePageLoading();
|
||||
let errorMessage;
|
||||
if (error && error.response) {
|
||||
switch (error.response.status) {
|
||||
case 403:
|
||||
errorMessage = "general.delete_error_403";
|
||||
break;
|
||||
case 404:
|
||||
errorMessage = "general.delete_error_404";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!errorMessage){
|
||||
errorMessage = "general.delete_error_generic";
|
||||
}
|
||||
showToast(2, errorMessage);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function quotaScanAction(username) {
|
||||
$('#loading_message').text("");
|
||||
KTApp.showPageLoading();
|
||||
let path = '{{.QuotaScanURL}}' + "/" + encodeURIComponent(username);
|
||||
axios.post(path, null, {
|
||||
timeout: 15000,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
||||
},
|
||||
validateStatus: function (status) {
|
||||
return status == 202;
|
||||
}
|
||||
}).then(function (response) {
|
||||
KTApp.hidePageLoading();
|
||||
showToast(1, 'general.quota_scan_started');
|
||||
}).catch(function (error) {
|
||||
KTApp.hidePageLoading();
|
||||
let errorMessage;
|
||||
if (error && error.response) {
|
||||
switch (error.response.status) {
|
||||
case 409:
|
||||
errorMessage = "general.quota_scan_conflit";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!errorMessage) {
|
||||
errorMessage = "general.quota_scan_error";
|
||||
}
|
||||
showToast(2, errorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
var datatable = function(){
|
||||
var dt;
|
||||
|
||||
var initDatatable = function () {
|
||||
$('#errorMsg').addClass("d-none");
|
||||
dt = $('#dataTable').DataTable({
|
||||
ajax: {
|
||||
url: "{{.UsersURL}}/json",
|
||||
dataSrc: "",
|
||||
error: function ($xhr, textStatus, errorThrown) {
|
||||
$(".dataTables_processing").hide();
|
||||
let txt = "";
|
||||
if ($xhr) {
|
||||
let json = $xhr.responseJSON;
|
||||
if (json) {
|
||||
if (json.message){
|
||||
txt = json.message;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!txt){
|
||||
txt = "general.error500";
|
||||
}
|
||||
setI18NData($('#errorTxt'), txt);
|
||||
$('#errorMsg').removeClass("d-none");
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
data: "username",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
return escapeHTML(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "status",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
switch (data){
|
||||
case 1:
|
||||
return $.t('general.active');
|
||||
default:
|
||||
return $.t('general.inactive');
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "last_login",
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
if (data > 0){
|
||||
return $.t('general.datetime', {
|
||||
val: parseInt(data, 10),
|
||||
formatParams: {
|
||||
val: { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' },
|
||||
}
|
||||
});
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "email",
|
||||
visible: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
if (data){
|
||||
return escapeHTML(data);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "filesystem.provider",
|
||||
visible: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
switch (data){
|
||||
case 1:
|
||||
return $.t('storage.s3');
|
||||
case 2:
|
||||
return $.t('storage.gcs');
|
||||
case 3:
|
||||
return $.t('storage.azblob');
|
||||
case 4:
|
||||
return $.t('storage.encrypted');
|
||||
case 5:
|
||||
return $.t('storage.sftp');
|
||||
case 6:
|
||||
return $.t('storage.http');
|
||||
default:
|
||||
return $.t('storage.local');
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "role",
|
||||
visible: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
if (data){
|
||||
return escapeHTML(data);
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "filters.two_factor_protocols",
|
||||
visible: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
if (data){
|
||||
return escapeHTML(data.join());
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "quota_files",
|
||||
visible: false,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
let val = "";
|
||||
if (row.quota_size > 0) {
|
||||
let used = row.used_quota_size;
|
||||
if (!used){
|
||||
used = 0;
|
||||
}
|
||||
let usage = fileSizeIEC(used)+"/"+fileSizeIEC(row.quota_size)
|
||||
val += $.t('fs.quota_usage.size', {val: usage})+". ";
|
||||
} else if (row.used_quota_size && row.used_quota_size > 0) {
|
||||
val += $.t('fs.quota_usage.size', {val: fileSizeIEC(row.used_quota_size)})+". ";
|
||||
}
|
||||
if (row.quota_files > 0){
|
||||
let used = row.used_quota_files;
|
||||
if (!used){
|
||||
used = 0;
|
||||
}
|
||||
let usage = used+"/"+row.quota_files;
|
||||
val += $.t('fs.quota_usage.files', {val: usage});
|
||||
} else if (row.used_quota_files && row.used_quota_files > 0) {
|
||||
val += $.t('fs.quota_usage.files', {val: row.used_quota_files});
|
||||
}
|
||||
return val
|
||||
}
|
||||
return "";
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "total_data_transfer",
|
||||
visible: false,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
let val = "";
|
||||
if (row.total_data_transfer > 0) {
|
||||
let used;
|
||||
if (row.used_download_data_transfer){
|
||||
used+=row.used_download_data_transfer;
|
||||
}
|
||||
if (row.used_upload_data_transfer){
|
||||
used+=row.used_upload_data_transfer;
|
||||
}
|
||||
let usage = fileSizeIEC(used)+"/"+fileSizeIEC(row.total_data_transfer*1048576);
|
||||
val = $.t('fs.quota_usage.total', {val: usage});
|
||||
} else {
|
||||
if (row.upload_data_transfer > 0) {
|
||||
let used = row.used_upload_data_transfer;
|
||||
if (!used){
|
||||
used = 0;
|
||||
}
|
||||
let usage = fileSizeIEC(used)+"/"+fileSizeIEC(row.upload_data_transfer*1048576);
|
||||
val = $.t('fs.quota_usage.uploads', {val: usage})+". ";
|
||||
}
|
||||
if (row.download_data_transfer > 0) {
|
||||
let used = row.used_download_data_transfer;
|
||||
if (!used){
|
||||
used = 0;
|
||||
}
|
||||
let usage = fileSizeIEC(used)+"/"+fileSizeIEC(row.download_data_transfer*1048576);
|
||||
val = $.t('fs.quota_usage.downloads', {val: usage});
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "description",
|
||||
visible: false,
|
||||
defaultContent: "",
|
||||
render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
if (data){
|
||||
return escapeHTML(data);
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
className: 'text-end',
|
||||
render: function (data, type, row) {
|
||||
if (type === 'display') {
|
||||
let numActions = 0;
|
||||
let actions = `<button class="btn btn-light btn-active-light-primary btn-flex btn-center btn-sm rotate" data-kt-menu-trigger="click" data-kt-menu-placement="bottom-end">
|
||||
<span data-i18n="general.actions" class="fs-6">Actions</span>
|
||||
<i class="ki-duotone ki-down fs-5 ms-1 rotate-180"></i>
|
||||
</button>
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-6 w-200px py-4" data-kt-menu="true">`;
|
||||
|
||||
//{{- if .LoggedUser.HasPermission "edit_users"}}
|
||||
numActions++;
|
||||
actions+=`<div class="menu-item px-3">
|
||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-share-table-action="edit_row">Edit</a>
|
||||
</div>`
|
||||
//{{- end}}
|
||||
//{{- if .LoggedUser.HasPermission "manage_system"}}
|
||||
numActions++;
|
||||
actions+=`<div class="menu-item px-3">
|
||||
<a data-i18n="general.template" href="#" class="menu-link px-3" data-share-table-action="template_row">Template</a>
|
||||
</div>`
|
||||
//{{- end}}
|
||||
//{{- if .LoggedUser.HasPermission "quota_scans"}}
|
||||
numActions++;
|
||||
actions+=`<div class="menu-item px-3">
|
||||
<a data-i18n="general.quota_scan" href="#" class="menu-link px-3" data-share-table-action="quota_scan_row">Quota scan</a>
|
||||
</div>`
|
||||
//{{- end}}
|
||||
//{{- if .LoggedUser.HasPermission "del_users"}}
|
||||
numActions++;
|
||||
actions+=`<div class="menu-item px-3">
|
||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-share-table-action="delete_row">Delete</a>
|
||||
</div>`
|
||||
//{{- end}}
|
||||
if (numActions > 0){
|
||||
actions+=`</div>`;
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
},
|
||||
],
|
||||
deferRender: true,
|
||||
stateSave: true,
|
||||
stateDuration: 0,
|
||||
colReorder: {
|
||||
enable: true,
|
||||
fixedColumnsLeft: 1
|
||||
},
|
||||
stateLoadParams: function (settings, data) {
|
||||
if (data.search.search){
|
||||
const filterSearch = document.querySelector('[data-table-filter="search"]');
|
||||
filterSearch.value = data.search.search;
|
||||
}
|
||||
},
|
||||
language: {
|
||||
info: $.t('datatable.info'),
|
||||
infoEmpty: $.t('datatable.info_empty'),
|
||||
infoFiltered: $.t('datatable.info_filtered'),
|
||||
loadingRecords: "",
|
||||
processing: $.t('datatable.processing'),
|
||||
zeroRecords: "",
|
||||
emptyTable: $.t('share.no_share')
|
||||
},
|
||||
order: [[0, 'asc']],
|
||||
initComplete: function(settings, json) {
|
||||
$('#loader').addClass("d-none");
|
||||
$('#card_content').removeClass("d-none");
|
||||
let api = $.fn.dataTable.Api(settings);
|
||||
api.columns.adjust().draw("page");
|
||||
drawAction();
|
||||
}
|
||||
});
|
||||
|
||||
dt.on('draw', drawAction);
|
||||
dt.on('column-reorder', function(e, settings, details){
|
||||
drawAction();
|
||||
});
|
||||
}
|
||||
|
||||
function drawAction() {
|
||||
KTMenu.createInstances();
|
||||
handleRowActions();
|
||||
$('#table_body').localize();
|
||||
}
|
||||
|
||||
function handleColVisibilityCheckbox(el, index) {
|
||||
el.off("change");
|
||||
el.prop('checked', dt.column(index).visible());
|
||||
el.on("change", function(e){
|
||||
dt.column(index).visible($(this).is(':checked'));
|
||||
dt.draw('page');
|
||||
});
|
||||
}
|
||||
|
||||
var handleDatatableActions = function () {
|
||||
const filterSearch = $(document.querySelector('[data-table-filter="search"]'));
|
||||
filterSearch.off("keyup");
|
||||
filterSearch.on('keyup', function (e) {
|
||||
dt.rows().deselect();
|
||||
dt.search(e.target.value, true, false).draw();
|
||||
});
|
||||
handleColVisibilityCheckbox($('#checkColStatus'), 1);
|
||||
handleColVisibilityCheckbox($('#checkColLastLogin'), 2);
|
||||
handleColVisibilityCheckbox($('#checkColEmail'), 3);
|
||||
handleColVisibilityCheckbox($('#checkColStorage'), 4);
|
||||
handleColVisibilityCheckbox($('#checkColRole'), 5);
|
||||
handleColVisibilityCheckbox($('#checkCol2FA'), 6);
|
||||
handleColVisibilityCheckbox($('#checkColDiskQuota'), 7);
|
||||
handleColVisibilityCheckbox($('#checkColTransferQuota'), 8);
|
||||
handleColVisibilityCheckbox($('#checkColDesc'), 9);
|
||||
}
|
||||
|
||||
function handleRowActions() {
|
||||
const editButtons = document.querySelectorAll('[data-share-table-action="edit_row"]');
|
||||
editButtons.forEach(d => {
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
let rowData = dt.row(e.target.closest('tr')).data();
|
||||
window.location.replace('{{.UserURL}}' + "/" + encodeURIComponent(rowData['username']));
|
||||
});
|
||||
});
|
||||
|
||||
const templateButtons = document.querySelectorAll('[data-share-table-action="template_row"]');
|
||||
templateButtons.forEach(d => {
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
let rowData = dt.row(e.target.closest('tr')).data();
|
||||
window.location.replace('{{.UserTemplateURL}}' + "?from=" + encodeURIComponent(rowData['username']));
|
||||
});
|
||||
});
|
||||
|
||||
const quotaScanButtons = document.querySelectorAll('[data-share-table-action="quota_scan_row"]');
|
||||
quotaScanButtons.forEach(d => {
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
let rowData = dt.row(e.target.closest('tr')).data();
|
||||
quotaScanAction(rowData['username']);
|
||||
});
|
||||
});
|
||||
|
||||
const deleteButtons = document.querySelectorAll('[data-share-table-action="delete_row"]');
|
||||
deleteButtons.forEach(d => {
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
deleteAction(dt.row(parent).data()['username']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: function () {
|
||||
initDatatable();
|
||||
handleDatatableActions();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
$(document).on("i18nshow", function(){
|
||||
datatable.init();
|
||||
});
|
||||
</script>
|
||||
{{- end}}
|
|
@ -19,7 +19,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- template "theme-switcher"}}
|
||||
{{- end}}
|
||||
<div class="d-flex align-items-center ms-2 ms-lg-3">
|
||||
<div class="btn btn-icon btn-active-light-primary w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="click" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<div class="btn btn-icon btn-active-light-primary w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="{default:'click', lg: 'hover'}" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<i class="ki-duotone ki-user fs-2">
|
||||
<i class="path1"></i>
|
||||
<i class="path2"></i>
|
||||
|
|
|
@ -80,7 +80,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- if or .CanDownload .CanDelete}}
|
||||
<div>
|
||||
<button type="button" class="btn btn-light-primary rotate" data-kt-menu-trigger="click" data-kt-menu-placement="bottom">
|
||||
<span data-i18n="fs.actions">Actions</span>
|
||||
<span data-i18n="general.actions">Actions</span>
|
||||
<i class="ki-duotone ki-down fs-3 rotate-180 ms-3 me-0"></i>
|
||||
</button>
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-800 menu-state-bg-light-primary fw-semibold w-auto min-w-200 mw-300px py-4" data-kt-menu="true">
|
||||
|
@ -431,7 +431,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const openLinks = document.querySelectorAll('[data-dirbrowser-table-row="open"]');
|
||||
|
||||
openLinks.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
onDirBrowserClick(dt.row(parent).data()['dir_path']);
|
||||
|
@ -457,7 +459,6 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
||||
var KTDatatablesServerSide = function () {
|
||||
// Shared variables
|
||||
//var table;
|
||||
var dt;
|
||||
var lightbox;
|
||||
|
||||
|
@ -598,7 +599,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
let desc = escapeHTML(filename).replace(/"/g, '"');
|
||||
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
||||
<a href="${row['url']}" data-gallery="gallery" data-glightbox="description: <span class="fs-5 fw-bold">${desc}</span>" class="btn btn-sm btn-icon btn-light btn-active-light-primary glightbox">
|
||||
<i class="ki-duotone ki-eye fs-5 m-0">
|
||||
<i class="ki-duotone ki-eye fs-6 m-0">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
|
@ -615,7 +616,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
case "wav":
|
||||
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
||||
<a href="#" class="btn btn-sm btn-icon btn-light btn-active-light-primary" data-kt-filemanager-table-action="view_media">
|
||||
<i class="ki-duotone ki-eye fs-5 m-0">
|
||||
<i class="ki-duotone ki-eye fs-6 m-0">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
|
@ -629,7 +630,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
view_url = view_url.replace('{{.FilesURL}}','{{.ViewPDFURL}}');
|
||||
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
||||
<a href="${view_url}" target="_blank" class="btn btn-sm btn-icon btn-light btn-active-light-primary">
|
||||
<i class="ki-duotone ki-eye fs-5 m-0">
|
||||
<i class="ki-duotone ki-eye fs-6 m-0">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
|
@ -643,7 +644,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
if (data && (supportedEditExtensions.includes(extension) || supportedEditFilenames.includes(filename.toLowerCase()))){
|
||||
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
||||
<a href="${data}" target="_blank" class="btn btn-sm btn-icon btn-light btn-active-light-primary">
|
||||
<i class="ki-duotone ki-eye fs-5 m-0">
|
||||
<i class="ki-duotone ki-eye fs-6 m-0">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
<span class="path3"></span>
|
||||
|
@ -665,7 +666,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<span class="path4"></span>
|
||||
</i>
|
||||
</button>
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-7 w-150px py-4" data-kt-menu="true">
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-6 w-150px py-4" data-kt-menu="true">
|
||||
{{- if .CanRename}}
|
||||
<div class="menu-item px-3">
|
||||
<a data-i18n="general.rename" href="#" class="menu-link px-3" data-kt-filemanager-table-action="rename">Rename</a>
|
||||
|
@ -740,8 +741,6 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
order: [2, 'asc']
|
||||
});
|
||||
|
||||
//table = dt.$;
|
||||
|
||||
dt.on('draw', function () {
|
||||
//{{- if .CanAddFiles}}
|
||||
if (dt.rows().count() === 0) {
|
||||
|
@ -847,7 +846,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const renameButtons = document.querySelectorAll('[data-kt-filemanager-table-action="rename"]');
|
||||
|
||||
renameButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
renameItem(dt.row(parent).data()["meta"]);
|
||||
|
@ -857,7 +858,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const moveCopyButtons = document.querySelectorAll('[data-kt-filemanager-table-action="move_or_copy"]');
|
||||
|
||||
moveCopyButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
moveOrCopyItem(dt.row(parent).data()["meta"]);
|
||||
|
@ -867,7 +870,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const shareButtons = document.querySelectorAll('[data-kt-filemanager-table-action="share"]');
|
||||
|
||||
shareButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
shareItem(dt.row(parent).data()["meta"]);
|
||||
|
@ -877,7 +882,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const deleteButtons = document.querySelectorAll('[data-kt-filemanager-table-action="delete"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
deleteItem(dt.row(parent).data()["meta"]);
|
||||
|
@ -887,7 +894,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const viewMediaLinks = document.querySelectorAll('[data-kt-filemanager-table-action="view_media"]');
|
||||
|
||||
viewMediaLinks.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
let rowData = dt.row(parent).data();
|
||||
|
@ -918,8 +927,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
|
||||
var handleSearchDatatable = function () {
|
||||
const filterSearch = document.querySelector('[data-kt-filemanager-table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
const filterSearch = $(document.querySelector('[data-kt-filemanager-table-filter="search"]'));
|
||||
filterSearch.off("keyup");
|
||||
filterSearch.on('keyup', function (e) {
|
||||
dt.rows().deselect();
|
||||
dt.search(e.target.value, true, false).draw();
|
||||
});
|
||||
|
@ -928,7 +938,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
var initToggleToolbar = function () {
|
||||
const selectAllCheck = document.querySelector('[data-kt-filemanager-table-select="select_all_pages"]');
|
||||
if (selectAllCheck){
|
||||
selectAllCheck.addEventListener('change', function(e){
|
||||
let el = $(selectAllCheck);
|
||||
el.off("change");
|
||||
el.on('change', function(e){
|
||||
if (this.checked){
|
||||
dt.rows({ search: 'applied' }).select();
|
||||
} else {
|
||||
|
@ -946,7 +958,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
const downloadButton = document.querySelector('[data-kt-filemanager-table-select="download_selected"]');
|
||||
if (downloadButton){
|
||||
downloadButton.addEventListener('click', function(e){
|
||||
let el = $(downloadButton);
|
||||
el.off("click");
|
||||
el.on('click', function(e){
|
||||
let filesArray = [];
|
||||
dt.rows({ selected: true, search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop){
|
||||
let row = dt.row(rowIdx);
|
||||
|
@ -966,7 +980,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
|
||||
const moveOrCopyButton = document.querySelector('[data-kt-filemanager-table-select="move_or_copy_selected"]');
|
||||
if (moveOrCopyButton){
|
||||
moveOrCopyButton.addEventListener('click', function(e){
|
||||
let el = $(moveOrCopyButton);
|
||||
el.off("click");
|
||||
el.on('click', function(e){
|
||||
$('#errorMsg').addClass("d-none");
|
||||
$('#move_copy_name_container').addClass("d-none");
|
||||
$('#move_copy_source').val("");
|
||||
|
@ -977,7 +993,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
|
||||
const shareButton = document.querySelector('[data-kt-filemanager-table-select="share_selected"]');
|
||||
if (shareButton){
|
||||
shareButton.addEventListener('click', function(e){
|
||||
let el = $(shareButton);
|
||||
el.off("click");
|
||||
el.on('click', function(e){
|
||||
let filesArray = [];
|
||||
dt.rows({ selected: true, search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop){
|
||||
let row = dt.row(rowIdx);
|
||||
|
@ -993,7 +1011,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
|
||||
const deleteButton = document.querySelector('[data-kt-filemanager-table-select="delete_selected"]');
|
||||
if (deleteButton) {
|
||||
deleteButton.addEventListener('click', function(e){
|
||||
let el = $(deleteButton);
|
||||
el.off("click");
|
||||
el.on('click', function(e){
|
||||
ModalAlert.fire({
|
||||
text: $.t('general.delete_multi_confirm'),
|
||||
icon: "warning",
|
||||
|
@ -1207,7 +1227,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
items = checkMoveCopyItems(items)
|
||||
if (items.length == 0){
|
||||
showToast("fs.invalid_name");
|
||||
showToast(2, "fs.invalid_name");
|
||||
return;
|
||||
}
|
||||
keepAlive();
|
||||
|
@ -1279,7 +1299,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
if (!errorMessage){
|
||||
errorMessage = "fs.copy.err_generic";
|
||||
}
|
||||
showToast(errorMessage);
|
||||
showToast(2, errorMessage);
|
||||
copyItem();
|
||||
});
|
||||
}
|
||||
|
@ -1298,10 +1318,10 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}).then((result)=>{
|
||||
if (result.error) {
|
||||
hasError = true;
|
||||
showToast("fs.copy.err_generic");
|
||||
showToast(2, "fs.copy.err_generic");
|
||||
} else if (result.data.length > 0){
|
||||
hasError = true;
|
||||
showToast("fs.copy.err_exists");
|
||||
showToast(2, "fs.copy.err_exists");
|
||||
}
|
||||
copyItem();
|
||||
});
|
||||
|
@ -1315,7 +1335,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}
|
||||
items = checkMoveCopyItems(items)
|
||||
if (items.length == 0){
|
||||
showToast("fs.invalid_name");
|
||||
showToast(2, "fs.invalid_name");
|
||||
return;
|
||||
}
|
||||
keepAlive();
|
||||
|
@ -1387,7 +1407,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
if (!errorMessage){
|
||||
errorMessage = "fs.move.err_generic";
|
||||
}
|
||||
showToast(errorMessage);
|
||||
showToast(2, errorMessage);
|
||||
moveItem();
|
||||
});
|
||||
}
|
||||
|
@ -1406,10 +1426,10 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}).then((result)=>{
|
||||
if (result.error) {
|
||||
hasError = true;
|
||||
showToast("fs.move.err_generic");
|
||||
showToast(2, "fs.move.err_generic");
|
||||
} else if (result.data.length > 0){
|
||||
hasError = true;
|
||||
showToast("fs.move.err_exists");
|
||||
showToast(2, "fs.move.err_exists");
|
||||
}
|
||||
moveItem();
|
||||
});
|
||||
|
@ -1476,7 +1496,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
if (!errorMessage){
|
||||
errorMessage = "fs.delete.err_generic";
|
||||
}
|
||||
showToast(errorMessage, {name: itemName});
|
||||
showToast(2, errorMessage, {name: itemName});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1506,15 +1526,15 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
let oldName = getNameFromMeta(meta);
|
||||
let newName = $('#rename_new_name').val();
|
||||
if (!newName){
|
||||
showToast("general.name_required");
|
||||
showToast(2, "general.name_required");
|
||||
return;
|
||||
}
|
||||
if (newName == oldName){
|
||||
showToast("general.name_different");
|
||||
showToast(2, "general.name_different");
|
||||
return;
|
||||
}
|
||||
if (newName.includes("/")){
|
||||
showToast("fs.invalid_name");
|
||||
showToast(2, "fs.invalid_name");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1550,7 +1570,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
if (!errorMessage) {
|
||||
errorMessage = "fs.rename.err_generic";
|
||||
}
|
||||
showToast(errorMessage, { name: oldName });
|
||||
showToast(2, errorMessage, { name: oldName });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1561,12 +1581,12 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
}).then((result)=>{
|
||||
if (result.error) {
|
||||
KTApp.hidePageLoading();
|
||||
showToast("fs.rename.err_generic", { name: oldName });
|
||||
showToast(2, "fs.rename.err_generic", { name: oldName });
|
||||
return;
|
||||
}
|
||||
if (result.data.length > 0){
|
||||
KTApp.hidePageLoading();
|
||||
showToast("fs.rename.err_exists", { name: oldName });
|
||||
showToast(2, "fs.rename.err_exists", { name: oldName });
|
||||
return;
|
||||
}
|
||||
executeRename();
|
||||
|
@ -1990,7 +2010,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- define "additionalnavitems"}}
|
||||
{{- if .QuotaUsage.HasQuotaInfo}}
|
||||
<div class="d-flex align-items-center ms-2 ms-lg-3">
|
||||
<div class="btn btn-icon btn-active-light-primary position-relative w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="click" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<div class="btn btn-icon btn-active-light-primary position-relative w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="{default:'click', lg: 'hover'}" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<i class="ki-duotone {{if .QuotaUsage.IsQuotaLow}}ki-information-5 text-warning{{else}}ki-information-2{{end}} fs-2">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
|
|
@ -73,7 +73,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<label for="id_config" data-i18n="general.configuration" class="col-md-3 col-form-label">Configuration</label>
|
||||
<div class="col-md-9">
|
||||
<select id="id_config" name="config_name" class="form-select" data-control="i18n-select2" data-hide-search="true">
|
||||
<option data-i18n="general.none" value="">None</option>
|
||||
<option value="">---</option>
|
||||
{{range .TOTPConfigs}}
|
||||
<option value="{{.}}" {{if eq . $.TOTPConfig.ConfigName}}selected{{end}}>{{.}}</option>
|
||||
{{end}}
|
||||
|
|
|
@ -24,15 +24,15 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- template "errmsg" .Error}}
|
||||
<form id="page_form" action="{{.CurrentURL}}" method="POST">
|
||||
<div class="form-group row">
|
||||
<label data-i18n="general.email" class="col-md-3 col-form-label">Email</label>
|
||||
<label for="idEmail" data-i18n="general.email" class="col-md-3 col-form-label">Email</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" id="idEmail" name="email" placeholder="" spellcheck="false"
|
||||
value="{{.Email}}" maxlength="255" autocomplete="nope" {{if not .LoggedUser.CanChangeInfo}}readonly{{end}}>
|
||||
value="{{.Email}}" maxlength="255" autocomplete="off" {{if not .LoggedUser.CanChangeInfo}}readonly{{end}}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mt-10">
|
||||
<label data-i18n="general.description" class="col-md-3 col-form-label">Description</label>
|
||||
<label for="idDescription" data-i18n="general.description" class="col-md-3 col-form-label">Description</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" id="idDescription" name="description" placeholder=""
|
||||
value="{{.Description}}" maxlength="255" {{if not .LoggedUser.CanChangeInfo}}readonly{{end}}>
|
||||
|
@ -40,7 +40,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
</div>
|
||||
|
||||
<div class="form-group row align-items-center mt-10">
|
||||
<label data-i18n="general.api_key_auth" class="col-md-3 col-form-label">API key authentication</label>
|
||||
<label data-i18n="general.api_key_auth" class="col-md-3 col-form-label" for="idAllowAPIKeyAuth">API key authentication</label>
|
||||
<div class="col-md-9">
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" id="idAllowAPIKeyAuth" name="allow_api_key_auth" {{if not .LoggedUser.CanChangeAPIKeyAuth}}disabled="disabled"{{end}} {{if .AllowAPIKeyAuth}}checked="checked"{{end}}/>
|
||||
|
@ -52,7 +52,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
</div>
|
||||
|
||||
{{- if .LoggedUser.CanManagePublicKeys}}
|
||||
<div class="card card-rounded mt-10">
|
||||
<div class="card mt-10">
|
||||
<div class="card-header bg-light">
|
||||
<h3 data-i18n="general.pub_keys" class="card-title section-title-inner">Public keys</h3>
|
||||
</div>
|
||||
|
@ -63,13 +63,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- range $idx, $val := .PublicKeys}}
|
||||
<div data-repeater-item>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<textarea data-i18n="[placeholder]general.pub_key_placeholder" class="form-control mt-3 mt-md-8" name="public_key" rows="4"
|
||||
<div class="col-md-9 mt-3 mt-md-8">
|
||||
<textarea data-i18n="[placeholder]general.pub_key_placeholder" class="form-control" name="public_key" rows="4"
|
||||
placeholder="Paste your public key here">{{$val}}</textarea>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-3 mt-3 mt-md-8">
|
||||
<a href="#" data-repeater-delete
|
||||
class="btn btn-light-danger mt-3 mt-md-8">
|
||||
class="btn btn-light-danger">
|
||||
<i class="ki-duotone ki-trash fs-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
@ -85,13 +85,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- else}}
|
||||
<div data-repeater-item>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<textarea data-i18n="[placeholder]general.pub_key_placeholder" class="form-control mt-3 mt-md-8" name="public_key" rows="4"
|
||||
<div class="col-md-9 mt-3 mt-md-8">
|
||||
<textarea data-i18n="[placeholder]general.pub_key_placeholder" class="form-control" name="public_key" rows="4"
|
||||
placeholder="Paste your public key here"></textarea>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-3 mt-3 mt-md-8">
|
||||
<a href="#" data-repeater-delete
|
||||
class="btn btn-light-danger mt-3 mt-md-8">
|
||||
class="btn btn-light-danger">
|
||||
<i class="ki-duotone ki-trash fs-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
|
|
@ -27,25 +27,25 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<label for="name" data-i18n="general.name" class="col-md-3 col-form-label">Name</label>
|
||||
<div class="col-md-9">
|
||||
<input id="name" type="text" class="form-control" placeholder="" name="name" value="{{.Share.Name}}"
|
||||
maxlength="255" autocomplete="nope" required {{if not .IsAdd}}readonly{{end}} />
|
||||
maxlength="255" autocomplete="off" required {{if not .IsAdd}}readonly{{end}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mt-10">
|
||||
<label for="scope" data-i18n="share.scope" class="col-md-3 col-form-label">Scope</label>
|
||||
<div class="col-md-9">
|
||||
<select id="scope" name="scope" class="form-select" data-control="i18n-select2" data-hide-search="true">
|
||||
<select id="scope" name="scope" class="form-select" data-control="i18n-select2" data-hide-search="true" aria-describedby="scopeHelp">
|
||||
<option data-i18n="share.scope_read" value="1" {{if eq .Share.Scope 1 }}selected{{end}}>Read</option>
|
||||
<option data-i18n="share.scope_write" value="2" {{if eq .Share.Scope 2 }}selected{{end}}>Write</option>
|
||||
<option data-i18n="share.scope_read_write" value="3" {{if eq .Share.Scope 3 }}selected{{end}}>Read/Write</option>
|
||||
</select>
|
||||
<div data-i18n="share.scope_help" class="form-text">
|
||||
<div id="scopeHelp" data-i18n="share.scope_help" class="form-text">
|
||||
For scope "Write" and "Read/Write" you have to define one path and it must be a directory
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-rounded mt-10">
|
||||
<div class="card mt-10">
|
||||
<div class="card-header bg-light">
|
||||
<h3 data-i18n="share.paths" class="card-title section-title-inner">Paths</h3>
|
||||
</div>
|
||||
|
@ -56,13 +56,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- range $idx, $val := .Share.Paths}}
|
||||
<div data-repeater-item>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<input data-i18n="[placeholder]share.path_help" type="text" class="form-control mt-3 mt-md-8"
|
||||
<div class="col-md-9 mt-3 mt-md-8">
|
||||
<input data-i18n="[placeholder]share.path_help" type="text" class="form-control"
|
||||
name="path" value="{{$val}}" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-3 mt-3 mt-md-8">
|
||||
<a href="#" data-repeater-delete
|
||||
class="btn btn-light-danger mt-3 mt-md-8">
|
||||
class="btn btn-light-danger">
|
||||
<i class="ki-duotone ki-trash fs-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
@ -78,13 +78,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
{{- else}}
|
||||
<div data-repeater-item>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<input data-i18n="[placeholder]share.path_help" type="text" class="form-control mt-3 mt-md-8"
|
||||
<div class="col-md-9 mt-3 mt-md-8">
|
||||
<input data-i18n="[placeholder]share.path_help" type="text" class="form-control"
|
||||
name="path" value="" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-3 mt-3 mt-md-8">
|
||||
<a href="#" data-repeater-delete
|
||||
class="btn btn-light-danger mt-3 mt-md-8">
|
||||
class="btn btn-light-danger">
|
||||
<i class="ki-duotone ki-trash fs-5">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
@ -114,18 +114,18 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="form-group row mt-10">
|
||||
<label for="password" data-i18n="login.password" class="col-md-3 col-form-label">Password</label>
|
||||
<div class="col-md-9">
|
||||
<input id="password" type="password" class="form-control" name="password" autocomplete="new-password"
|
||||
placeholder="" spellcheck="false" value="{{.Share.Password}}" />
|
||||
<div data-i18n="share.password_help" class="form-text">
|
||||
<input id="password" type="password" class="form-control" name="password" autocomplete="off"
|
||||
placeholder="" spellcheck="false" value="{{.Share.Password}}" aria-describedby="passwordHelp" />
|
||||
<div id="passwordHelp" data-i18n="share.password_help" class="form-text">
|
||||
If set the share will be password-protected
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mt-10">
|
||||
<label for="id_expiration" data-i18n="share.expiration" class="col-md-3 col-form-label">Expiration</label>
|
||||
<label for="id_expiration" data-i18n="general.expiration" class="col-md-3 col-form-label">Expiration</label>
|
||||
<div class="col-md-9 d-flex">
|
||||
<input data-i18n="[placeholder]share.expiration_help" id="id_expiration" class="form-control" placeholder="Pick an expiration date" />
|
||||
<input data-i18n="[placeholder]general.expiration_help" id="id_expiration" class="form-control" placeholder="Pick an expiration date" />
|
||||
<button class="btn btn-icon btn-light-danger ms-2 d-none" id="id_expiration_clear">
|
||||
<i class="ki-solid ki-cross fs-1"></i>
|
||||
</button>
|
||||
|
@ -135,8 +135,8 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="form-group row mt-10">
|
||||
<label for="max_tokens" data-i18n="share.max_tokens" class="col-md-3 col-form-label">Max tokens</label>
|
||||
<div class="col-md-9">
|
||||
<input id="max_tokens" type="number" min="0" class="form-control" name="max_tokens" value="{{.Share.MaxTokens}}" />
|
||||
<div data-i18n="share.max_tokens_help" class="form-text">
|
||||
<input id="max_tokens" type="number" min="0" class="form-control" name="max_tokens" value="{{.Share.MaxTokens}}" aria-describedby="max_tokens_help" />
|
||||
<div id="max_tokens_help" data-i18n="share.max_tokens_help" class="form-text">
|
||||
Maximum number of times this share can be accessed. 0 means no limit
|
||||
</div>
|
||||
</div>
|
||||
|
@ -145,9 +145,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="form-group row mt-10">
|
||||
<label for="allowed_ip" data-i18n="general.allowed_ip_mask" class="col-md-3 col-form-label">Allowed IP/Mask</label>
|
||||
<div class="col-md-9">
|
||||
<textarea id="allowed_ip" class="form-control" name="allowed_ip" rows="3"
|
||||
<textarea id="allowed_ip" class="form-control" name="allowed_ip" rows="3" aria-describedby="allowed_ip_help"
|
||||
placeholder="">{{.Share.GetAllowedFromAsString}}</textarea>
|
||||
<div data-i18n="general.allowed_ip_mask_help" class="form-text">
|
||||
<div id="allowed_ip_help" data-i18n="general.ip_mask_help" class="form-text">
|
||||
Comma separated IP/Mask in CIDR format, for example "192.168.1.0/24,10.8.0.100/32"
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -31,7 +31,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
</div>
|
||||
<div id="card_content" class="d-none">
|
||||
<div class="d-flex flex-stack flex-wrap mb-5">
|
||||
<div class="d-flex align-items-center position-relative my-1">
|
||||
<div class="d-flex align-items-center position-relative my-2">
|
||||
<i class="ki-duotone ki-magnifier fs-1 position-absolute ms-6">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
|
@ -39,7 +39,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<input name="search" data-i18n="[placeholder]general.search" type="text" data-table-filter="search"
|
||||
class="form-control rounded-1 w-250px ps-15 me-5" placeholder="Search" />
|
||||
</div>
|
||||
<div class="d-flex justify-content-end" data-table-toolbar="base">
|
||||
<div class="d-flex justify-content-end my-2" data-table-toolbar="base">
|
||||
<a href="{{.ShareURL}}" class="btn btn-primary">
|
||||
<i class="ki-duotone ki-plus fs-2"></i>
|
||||
<span data-i18n="general.add">Add</span>
|
||||
|
@ -153,7 +153,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<span data-i18n="fs.upload.text">Upload</span>
|
||||
</a>
|
||||
</div>
|
||||
<div data-i18n="share.expired_desc" id="expiredShare">
|
||||
<div data-i18n="share.expired_desc" id="expiredShare" class="fw-semibold">
|
||||
This share is no longer accessible because it has expired
|
||||
</div>
|
||||
</div>
|
||||
|
@ -162,7 +162,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "extra_js"}}
|
||||
{{- define "extra_js"}}
|
||||
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js"></script>
|
||||
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
||||
|
||||
|
@ -208,7 +208,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
if (!errorMessage){
|
||||
errorMessage = "general.delete_error_generic";
|
||||
}
|
||||
showToast(errorMessage);
|
||||
showToast(2, errorMessage);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -349,7 +349,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<span class="path4"></span>
|
||||
</i>
|
||||
</button>
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-semibold fs-7 w-150px py-4" data-kt-menu="true">
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-6 w-150px py-4" data-kt-menu="true">
|
||||
<div class="menu-item px-3">
|
||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-share-table-action="edit_row">Edit</a>
|
||||
</div>
|
||||
|
@ -388,22 +388,23 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
$('#card_content').removeClass("d-none");
|
||||
let api = $.fn.dataTable.Api(settings);
|
||||
api.columns.adjust().draw("page");
|
||||
KTMenu.createInstances();
|
||||
handleRowActions();
|
||||
$('#table_body').localize();
|
||||
drawAction();
|
||||
}
|
||||
});
|
||||
|
||||
dt.on('draw', function () {
|
||||
KTMenu.createInstances();
|
||||
handleRowActions();
|
||||
$('#table_body').localize();
|
||||
});
|
||||
dt.on('draw', drawAction);
|
||||
}
|
||||
|
||||
function drawAction() {
|
||||
KTMenu.createInstances();
|
||||
handleRowActions();
|
||||
$('#table_body').localize();
|
||||
}
|
||||
|
||||
var handleSearchDatatable = function () {
|
||||
const filterSearch = document.querySelector('[data-table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
const filterSearch = $(document.querySelector('[data-table-filter="search"]'));
|
||||
filterSearch.off("keyup");
|
||||
filterSearch.on('keyup', function (e) {
|
||||
dt.rows().deselect();
|
||||
dt.search(e.target.value, true, false).draw();
|
||||
});
|
||||
|
@ -413,7 +414,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const editButtons = document.querySelectorAll('[data-share-table-action="edit_row"]');
|
||||
|
||||
editButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
editAction(dt.row(parent).data()[3]);
|
||||
|
@ -423,7 +426,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const deleteButtons = document.querySelectorAll('[data-share-table-action="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
const parent = e.target.closest('tr');
|
||||
deleteAction(dt.row(parent).data()[3]);
|
||||
|
@ -433,7 +438,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
const showLinkButtons = document.querySelectorAll('[data-share-table-action="show_link"]');
|
||||
|
||||
showLinkButtons.forEach(d => {
|
||||
d.addEventListener("click", function(e){
|
||||
let el = $(d);
|
||||
el.off("click");
|
||||
el.on("click", function(e){
|
||||
e.preventDefault();
|
||||
let rowData = dt.row(e.target.closest('tr')).data();
|
||||
showShareLink(rowData[3], rowData[1], rowData[4]);
|
||||
|
|
Loading…
Reference in a new issue