Bläddra i källkod

revert #450

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
Nicola Murino 1 år sedan
förälder
incheckning
0a8a0ee771

+ 1 - 1
go.mod

@@ -52,7 +52,7 @@ require (
 	github.com/rs/cors v1.11.0
 	github.com/rs/xid v1.5.0
 	github.com/rs/zerolog v1.32.0
-	github.com/sftpgo/sdk v0.1.6-0.20240409173349-421b3dff3896
+	github.com/sftpgo/sdk v0.1.6-0.20240426175227-52f492b8b83b
 	github.com/shirou/gopsutil/v3 v3.24.3
 	github.com/spf13/afero v1.11.0
 	github.com/spf13/cobra v1.8.0

+ 2 - 2
go.sum

@@ -351,8 +351,8 @@ github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4 h1:PT+ElG/UUFMfqy5HrxJ
 github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4/go.mod h1:MnkX001NG75g3p8bhFycnyIjeQoOjGL6CEIsdE/nKSY=
 github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
 github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
-github.com/sftpgo/sdk v0.1.6-0.20240409173349-421b3dff3896 h1:ykxybS9WKurHTatKJ9WjqYD+WH9YH/2QMxCkxUPTVLY=
-github.com/sftpgo/sdk v0.1.6-0.20240409173349-421b3dff3896/go.mod h1:AWoY2YYe/P1ymfTlRER/meERQjCcZZTbgVPGcPQgaqc=
+github.com/sftpgo/sdk v0.1.6-0.20240426175227-52f492b8b83b h1:BazWPub9GBUKvfM2O6MHhAwd9JbPD1i3UudhmHfGc2w=
+github.com/sftpgo/sdk v0.1.6-0.20240426175227-52f492b8b83b/go.mod h1:AWoY2YYe/P1ymfTlRER/meERQjCcZZTbgVPGcPQgaqc=
 github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
 github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
 github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=

+ 24 - 4
internal/cmd/portable.go

@@ -112,7 +112,7 @@ $ sftpgo portable
 Please take a look at the usage below to customize the serving parameters`,
 		Run: func(_ *cobra.Command, _ []string) {
 			portableDir := directoryToServe
-			fsProvider := sdk.GetProviderByName(portableFsProvider)
+			fsProvider := dataprovider.GetProviderFromValue(convertFsProvider())
 			if !filepath.IsAbs(portableDir) {
 				if fsProvider == sdk.LocalFilesystemProvider {
 					portableDir, _ = filepath.Abs(portableDir)
@@ -227,7 +227,7 @@ Please take a look at the usage below to customize the serving parameters`,
 						},
 					},
 					FsConfig: vfs.Filesystem{
-						Provider: sdk.GetProviderByName(portableFsProvider),
+						Provider: fsProvider,
 						S3Config: vfs.S3FsConfig{
 							BaseS3FsConfig: sdk.BaseS3FsConfig{
 								Bucket:            portableS3Bucket,
@@ -282,8 +282,9 @@ Please take a look at the usage below to customize the serving parameters`,
 								DisableCouncurrentReads: portableSFTPDisableConcurrentReads,
 								BufferSize:              portableSFTPDBufferSize,
 							},
-							Password:   kms.NewPlainSecret(portableSFTPPassword),
-							PrivateKey: kms.NewPlainSecret(portableSFTPPrivateKey),
+							Password:      kms.NewPlainSecret(portableSFTPPassword),
+							PrivateKey:    kms.NewPlainSecret(portableSFTPPrivateKey),
+							KeyPassphrase: kms.NewEmptySecret(),
 						},
 					},
 				},
@@ -524,3 +525,22 @@ func getFileContents(name string) (string, error) {
 	}
 	return string(contents), nil
 }
+
+func convertFsProvider() string {
+	switch portableFsProvider {
+	case "osfs", "6": // httpfs (6) is not supported in portable mode, so return the default
+		return "0"
+	case "s3fs":
+		return "1"
+	case "gcsfs":
+		return "2"
+	case "azblobfs":
+		return "3"
+	case "cryptfs":
+		return "4"
+	case "sftpfs":
+		return "5"
+	default:
+		return portableFsProvider
+	}
+}

+ 14 - 26
internal/dataprovider/dataprovider.go

@@ -319,32 +319,6 @@ 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
 }
@@ -1014,6 +988,20 @@ func GetBackupsPath() string {
 	return config.BackupsPath
 }
 
+// GetProviderFromValue returns the FilesystemProvider matching the specified value.
+// If no match is found LocalFilesystemProvider is returned.
+func GetProviderFromValue(value string) sdk.FilesystemProvider {
+	val, err := strconv.Atoi(value)
+	if err != nil {
+		return sdk.LocalFilesystemProvider
+	}
+	result := sdk.FilesystemProvider(val)
+	if sdk.IsProviderSupported(result) {
+		return result
+	}
+	return sdk.LocalFilesystemProvider
+}
+
 func initializeHashingAlgo(cnf *Config) error {
 	parallelism := cnf.PasswordHashing.Argon2Options.Parallelism
 	if parallelism == 0 {

+ 1 - 12
internal/httpd/webadmin.go

@@ -509,17 +509,6 @@ func loadAdminTemplates(templatesPath string) {
 	}
 
 	fsBaseTpl := template.New("fsBaseTemplate").Funcs(template.FuncMap{
-		"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,
 	})
 	usersTmpl := util.LoadTemplate(nil, usersPaths...)
@@ -1694,7 +1683,7 @@ func getOsConfigFromPostFields(r *http.Request, readBufferField, writeBufferFiel
 
 func getFsConfigFromPostFields(r *http.Request) (vfs.Filesystem, error) {
 	var fs vfs.Filesystem
-	fs.Provider = sdk.GetProviderByName(r.Form.Get("fs_provider"))
+	fs.Provider = dataprovider.GetProviderFromValue(r.Form.Get("fs_provider"))
 	switch fs.Provider {
 	case sdk.LocalFilesystemProvider:
 		fs.OSConfig = getOsConfigFromPostFields(r, "osfs_read_buffer_size", "osfs_write_buffer_size")

+ 0 - 7
internal/util/i18n.go

@@ -183,13 +183,6 @@ 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"
 	I18nErrorTimeOfDayInvalid          = "user.time_of_day_invalid"
 	I18nErrorTimeOfDayConflict         = "user.time_of_day_conflict"

+ 17 - 13
internal/util/resources.go

@@ -58,25 +58,29 @@ func FindSharedDataPath(name, searchDir string) string {
 
 // LoadTemplate parses the given template paths.
 // It behaves like template.Must but it writes a log before exiting.
-// You can optionally provide a base template (e.g. to define some custom functions)
 func LoadTemplate(base *template.Template, paths ...string) *template.Template {
-	var t *template.Template
-	var err error
-
 	if base != nil {
-		base, err = base.Clone()
-		if err == nil {
-			t, err = base.ParseFiles(paths...)
+		baseTmpl, err := base.Clone()
+		if err != nil {
+			showTemplateLoadingError(err)
+		}
+		t, err := baseTmpl.ParseFiles(paths...)
+		if err != nil {
+			showTemplateLoadingError(err)
 		}
-	} else {
-		t, err = template.ParseFiles(paths...)
+		return t
 	}
 
+	t, err := template.ParseFiles(paths...)
 	if err != nil {
-		logger.ErrorToConsole("error loading required template: %v", err)
-		logger.ErrorToConsole(templateLoadErrorHints)
-		logger.Error(logSender, "", "error loading required template: %v", err)
-		os.Exit(1)
+		showTemplateLoadingError(err)
 	}
 	return t
 }
+
+func showTemplateLoadingError(err error) {
+	logger.ErrorToConsole("error loading required template: %v", err)
+	logger.ErrorToConsole(templateLoadErrorHints)
+	logger.Error(logSender, "", "error loading required template: %v", err)
+	os.Exit(1)
+}

+ 32 - 0
templates/common/base.html

@@ -278,6 +278,38 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
         return window.location.protocol+"//"+window.location.hostname;
     }
 
+    function onFilesystemChanged(val){
+        const supportedFs = ["local", "s3", "gcs", "azblob", "crypt", "sftp", "http"];
+        let fsName = "local";
+        switch (val){
+            case '1':
+                fsName = "s3";
+                break;
+            case '2':
+                fsName = "gcs";
+                break;
+            case '3':
+                fsName = "azblob";
+                break;
+            case '4':
+                fsName = "crypt";
+                break;
+            case '5':
+                fsName = "sftp";
+                break;
+            case '6':
+                fsName = "http";
+                break;
+        }
+        for (let i = 0; i < supportedFs.length; i++){
+            if (supportedFs[i] == fsName){
+                $('.form-group.fsconfig-'+fsName).show();
+            } else {
+                $('.form-group.fsconfig-'+supportedFs[i]).hide();
+            }
+        }
+    }
+
     KTUtil.onDOMContentLoaded(function () {
         var dismissErrorBtn = $('#id_dismiss_error_msg');
         if (dismissErrorBtn){

+ 1 - 5
templates/webadmin/folder.html

@@ -137,13 +137,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
 {{- define "extra_js"}}
 <script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/formrepeater/formrepeater.bundle.js"></script>
 <script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
-    function onFilesystemChanged(val){
-        $('.form-group.fsconfig').hide();
-        $('.form-group.fsconfig-'+val).show();
-    }
 
     $(document).on("i18nload", function(){
-        onFilesystemChanged('{{.Folder.FsConfig.Provider.Name}}');
+        onFilesystemChanged('{{.Folder.FsConfig.Provider}}');
 
         $('#idFilesystem').on("change", function(){
             onFilesystemChanged(this.value);

+ 52 - 48
templates/webadmin/fsconfig.html

@@ -23,9 +23,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             <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}}
+                    <option value="0" data-i18n="storage.local" {{if eq .Provider 0 }}selected{{end}}>Local</option>
+                    <option value="4" data-i18n="storage.encrypted" {{if eq .Provider 4 }}selected{{end}}>Local encrypted</option>
+                    <option value="1" data-i18n="storage.s3" {{if eq .Provider 1 }}selected{{end}}>AWS S3 (Compatible)</option>
+                    <option value="2" data-i18n="storage.gcs" {{if eq .Provider 2 }}selected{{end}}>Google Cloud Storage</option>
+                    <option value="3" data-i18n="storage.azblob" {{if eq .Provider 3 }}selected{{end}}>Azure Blob Storage</option>
+                    <option value="5" data-i18n="storage.sftp" {{if eq .Provider 5 }}selected{{end}}>SFTP</option>
+                    <option value="6" data-i18n="storage.http" {{if eq .Provider 6 }}selected{{end}}>HTTP</option>
                 </select>
             </div>
         </div>
@@ -46,7 +50,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
         {{- end}}
-        <div class="form-group row mt-10 fsconfig fsconfig-osfs">
+        <div class="form-group row mt-10 fsconfig-local">
             <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" />
@@ -60,28 +64,28 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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 mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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 mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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 mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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="new-password" spellcheck="false"
@@ -89,7 +93,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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"/>
@@ -97,7 +101,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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"/>
@@ -105,7 +109,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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"/>
@@ -113,7 +117,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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" />
@@ -127,7 +131,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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" max="5000" class="form-control" name="s3_upload_part_size" value="{{.S3Config.UploadPartSize}}" aria-describedby="idS3PartSizeHelp" />
@@ -141,7 +145,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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" max="5000" class="form-control" name="s3_download_part_size" value="{{.S3Config.DownloadPartSize}}" aria-describedby="idS3DLPartSizeHelp" />
@@ -155,7 +159,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row mt-10 fsconfig-s3">
             <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.UploadPartMaxTime}}" aria-describedby="idS3UploadTimeoutHelp" />
@@ -169,7 +173,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row align-items-center mt-10 fsconfig fsconfig-s3fs">
+        <div class="form-group row align-items-center mt-10 fsconfig-s3">
             <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}}/>
@@ -189,14 +193,14 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
+        <div class="form-group row mt-10 fsconfig-gcs">
             <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 mt-10 fsconfig fsconfig-gcsfs">
+        <div class="form-group row mt-10 fsconfig-gcs">
             <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" />
@@ -204,7 +208,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row align-items-center mt-10 fsconfig fsconfig-gcsfs">
+        <div class="form-group row align-items-center mt-10 fsconfig-gcs">
             <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">
@@ -216,7 +220,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
+        <div class="form-group row mt-10 fsconfig-gcs">
             <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" />
@@ -224,7 +228,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
+        <div class="form-group row mt-10 fsconfig-gcs">
             <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" />
@@ -238,7 +242,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-gcsfs">
+        <div class="form-group row mt-10 fsconfig-gcs">
             <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" />
@@ -252,21 +256,21 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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 mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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 mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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="new-password" spellcheck="false"
@@ -274,7 +278,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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="new-password" spellcheck="false" aria-describedby="idAzSASURLHelp"
@@ -283,7 +287,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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" />
@@ -291,7 +295,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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">
@@ -303,7 +307,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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" max="100" class="form-control" name="az_upload_part_size" value="{{.AzBlobConfig.UploadPartSize}}" aria-describedby="idAzUploadPartSizeHelp" />
@@ -317,7 +321,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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" max="100" class="form-control" name="az_download_part_size" value="{{.AzBlobConfig.DownloadPartSize}}" aria-describedby="idAzDownloadPartSizeHelp" />
@@ -331,7 +335,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row mt-10 fsconfig-azblob">
             <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" />
@@ -339,7 +343,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row align-items-center mt-10 fsconfig fsconfig-azblobfs">
+        <div class="form-group row align-items-center mt-10 fsconfig-azblob">
             <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">
@@ -348,7 +352,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-cryptfs">
+        <div class="form-group row mt-10 fsconfig-crypt">
             <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="new-password" spellcheck="false" aria-describedby="idCryptPassphraseHelp"
@@ -357,7 +361,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-cryptfs">
+        <div class="form-group row mt-10 fsconfig-crypt">
             <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" />
@@ -371,7 +375,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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"/>
@@ -379,14 +383,14 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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 mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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="new-password" spellcheck="false"
@@ -394,7 +398,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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"
@@ -402,7 +406,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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="new-password" spellcheck="false" aria-describedby="idSFTPPassphraseHelp"
@@ -411,7 +415,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <label for="idSFTPPrefix" data-i18n="storage.sftp_home_dir" class="col-md-3 col-form-label">Root directory</label>
             <div class="col-md-9">
                 <input id="idSFTPPrefix" type="text" class="form-control" name="sftp_prefix" value="{{.SFTPConfig.Prefix}}" aria-describedby="idSFTPPrefixHelp"/>
@@ -419,7 +423,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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"
@@ -428,7 +432,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row mt-10 fsconfig-sftp">
             <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" />
@@ -436,7 +440,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row align-items-center mt-10 fsconfig fsconfig-sftpfs">
+        <div class="form-group row align-items-center mt-10 fsconfig-sftp">
             <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}}/>
@@ -456,21 +460,21 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-httpfs">
+        <div class="form-group row mt-10 fsconfig-http">
             <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 mt-10 fsconfig fsconfig-httpfs">
+        <div class="form-group row mt-10 fsconfig-http">
             <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 mt-10 fsconfig fsconfig-httpfs">
+        <div class="form-group row mt-10 fsconfig-http">
             <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="new-password" spellcheck="false"
@@ -478,7 +482,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row mt-10 fsconfig fsconfig-httpfs">
+        <div class="form-group row mt-10 fsconfig-http">
             <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="new-password" spellcheck="false"
@@ -486,7 +490,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
             </div>
         </div>
 
-        <div class="form-group row align-items-center mt-10 fsconfig fsconfig-httpfs">
+        <div class="form-group row align-items-center mt-10 fsconfig-http">
             <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}} />

+ 1 - 5
templates/webadmin/group.html

@@ -384,10 +384,6 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
 {{- define "extra_js"}}
 <script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/formrepeater/formrepeater.bundle.js"></script>
 <script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
-    function onFilesystemChanged(val){
-        $('.form-group.fsconfig').hide();
-        $('.form-group.fsconfig-'+val).show();
-    }
 
     $(document).on("i18nload", function(){
         initRepeater('#virtual_folders');
@@ -399,7 +395,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
         //{{- if .Error}}
         $('#accordionUser .collapse').removeAttr("data-bs-parent").collapse('show');
         //{{- end}}
-        onFilesystemChanged('{{.Group.UserSettings.FsConfig.Provider.Name}}');
+        onFilesystemChanged('{{.Group.UserSettings.FsConfig.Provider}}');
 
         $('#idFilesystem').on("change", function(){
             onFilesystemChanged(this.value);

+ 1 - 5
templates/webadmin/user.html

@@ -766,13 +766,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
 <script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/formrepeater/formrepeater.bundle.js"></script>
 <script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/flatpickr/l10n/it.js"></script>
 <script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
-    function onFilesystemChanged(val){
-        $('.form-group.fsconfig').hide();
-        $('.form-group.fsconfig-'+val).show();
-    }
 
     $(document).on("i18nload", function(){
-        onFilesystemChanged('{{.User.FsConfig.Provider.Name}}');
+        onFilesystemChanged('{{.User.FsConfig.Provider}}');
 
         $('#idFilesystem').on("change", function(){
             onFilesystemChanged(this.value);