Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2024-04-27 10:50:25 +02:00
parent 2bcf05ca45
commit 0a8a0ee771
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
12 changed files with 146 additions and 128 deletions

2
go.mod
View file

@ -52,7 +52,7 @@ require (
github.com/rs/cors v1.11.0 github.com/rs/cors v1.11.0
github.com/rs/xid v1.5.0 github.com/rs/xid v1.5.0
github.com/rs/zerolog v1.32.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/shirou/gopsutil/v3 v3.24.3
github.com/spf13/afero v1.11.0 github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0

4
go.sum
View file

@ -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/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 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= 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.20240426175227-52f492b8b83b h1:BazWPub9GBUKvfM2O6MHhAwd9JbPD1i3UudhmHfGc2w=
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/go.mod h1:AWoY2YYe/P1ymfTlRER/meERQjCcZZTbgVPGcPQgaqc=
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= 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/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=

View file

@ -112,7 +112,7 @@ $ sftpgo portable
Please take a look at the usage below to customize the serving parameters`, Please take a look at the usage below to customize the serving parameters`,
Run: func(_ *cobra.Command, _ []string) { Run: func(_ *cobra.Command, _ []string) {
portableDir := directoryToServe portableDir := directoryToServe
fsProvider := sdk.GetProviderByName(portableFsProvider) fsProvider := dataprovider.GetProviderFromValue(convertFsProvider())
if !filepath.IsAbs(portableDir) { if !filepath.IsAbs(portableDir) {
if fsProvider == sdk.LocalFilesystemProvider { if fsProvider == sdk.LocalFilesystemProvider {
portableDir, _ = filepath.Abs(portableDir) portableDir, _ = filepath.Abs(portableDir)
@ -227,7 +227,7 @@ Please take a look at the usage below to customize the serving parameters`,
}, },
}, },
FsConfig: vfs.Filesystem{ FsConfig: vfs.Filesystem{
Provider: sdk.GetProviderByName(portableFsProvider), Provider: fsProvider,
S3Config: vfs.S3FsConfig{ S3Config: vfs.S3FsConfig{
BaseS3FsConfig: sdk.BaseS3FsConfig{ BaseS3FsConfig: sdk.BaseS3FsConfig{
Bucket: portableS3Bucket, Bucket: portableS3Bucket,
@ -282,8 +282,9 @@ Please take a look at the usage below to customize the serving parameters`,
DisableCouncurrentReads: portableSFTPDisableConcurrentReads, DisableCouncurrentReads: portableSFTPDisableConcurrentReads,
BufferSize: portableSFTPDBufferSize, BufferSize: portableSFTPDBufferSize,
}, },
Password: kms.NewPlainSecret(portableSFTPPassword), Password: kms.NewPlainSecret(portableSFTPPassword),
PrivateKey: kms.NewPlainSecret(portableSFTPPrivateKey), PrivateKey: kms.NewPlainSecret(portableSFTPPrivateKey),
KeyPassphrase: kms.NewEmptySecret(),
}, },
}, },
}, },
@ -524,3 +525,22 @@ func getFileContents(name string) (string, error) {
} }
return string(contents), nil 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
}
}

View file

@ -319,32 +319,6 @@ type PasswordValidation struct {
Users PasswordValidationRules `json:"users" mapstructure:"users"` 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 { type wrappedFolder struct {
Folder vfs.BaseVirtualFolder Folder vfs.BaseVirtualFolder
} }
@ -1014,6 +988,20 @@ func GetBackupsPath() string {
return config.BackupsPath 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 { func initializeHashingAlgo(cnf *Config) error {
parallelism := cnf.PasswordHashing.Argon2Options.Parallelism parallelism := cnf.PasswordHashing.Argon2Options.Parallelism
if parallelism == 0 { if parallelism == 0 {

View file

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

View file

@ -183,13 +183,6 @@ const (
I18nOIDCTokenInvalidRoleAdmin = "oidc.role_admin_err" I18nOIDCTokenInvalidRoleAdmin = "oidc.role_admin_err"
I18nOIDCTokenInvalidRoleUser = "oidc.role_user_err" I18nOIDCTokenInvalidRoleUser = "oidc.role_user_err"
I18nOIDCErrGetUser = "oidc.get_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" I18nErrorInvalidQuotaSize = "user.invalid_quota_size"
I18nErrorTimeOfDayInvalid = "user.time_of_day_invalid" I18nErrorTimeOfDayInvalid = "user.time_of_day_invalid"
I18nErrorTimeOfDayConflict = "user.time_of_day_conflict" I18nErrorTimeOfDayConflict = "user.time_of_day_conflict"

View file

@ -58,25 +58,29 @@ func FindSharedDataPath(name, searchDir string) string {
// LoadTemplate parses the given template paths. // LoadTemplate parses the given template paths.
// It behaves like template.Must but it writes a log before exiting. // 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 { func LoadTemplate(base *template.Template, paths ...string) *template.Template {
var t *template.Template
var err error
if base != nil { if base != nil {
base, err = base.Clone() baseTmpl, err := base.Clone()
if err == nil { if err != nil {
t, err = base.ParseFiles(paths...) showTemplateLoadingError(err)
} }
} else { t, err := baseTmpl.ParseFiles(paths...)
t, err = template.ParseFiles(paths...) if err != nil {
showTemplateLoadingError(err)
}
return t
} }
t, err := template.ParseFiles(paths...)
if err != nil { if err != nil {
logger.ErrorToConsole("error loading required template: %v", err) showTemplateLoadingError(err)
logger.ErrorToConsole(templateLoadErrorHints)
logger.Error(logSender, "", "error loading required template: %v", err)
os.Exit(1)
} }
return t 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)
}

View file

@ -278,6 +278,38 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
return window.location.protocol+"//"+window.location.hostname; 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 () { KTUtil.onDOMContentLoaded(function () {
var dismissErrorBtn = $('#id_dismiss_error_msg'); var dismissErrorBtn = $('#id_dismiss_error_msg');
if (dismissErrorBtn){ if (dismissErrorBtn){

View file

@ -137,13 +137,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
{{- define "extra_js"}} {{- define "extra_js"}}
<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/formrepeater/formrepeater.bundle.js"></script>
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}> <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(){ $(document).on("i18nload", function(){
onFilesystemChanged('{{.Folder.FsConfig.Provider.Name}}'); onFilesystemChanged('{{.Folder.FsConfig.Provider}}');
$('#idFilesystem').on("change", function(){ $('#idFilesystem').on("change", function(){
onFilesystemChanged(this.value); onFilesystemChanged(this.value);

View file

@ -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> <label for="idFilesystem" data-i18n="storage.label" class="col-md-3 col-form-label">Storage</label>
<div class="col-md-9"> <div class="col-md-9">
<select id="idFilesystem" name="fs_provider" class="form-select" data-control="i18n-select2" data-hide-search="true"> <select id="idFilesystem" name="fs_provider" class="form-select" data-control="i18n-select2" data-hide-search="true">
{{- range ListFSProviders }} <option value="0" data-i18n="storage.local" {{if eq .Provider 0 }}selected{{end}}>Local</option>
<option value="{{.Name}}" data-i18n="{{.I18nString}}" {{if eq .FilesystemProvider $.Provider }}selected{{end}}>{{.ShortInfo}}</option> <option value="4" data-i18n="storage.encrypted" {{if eq .Provider 4 }}selected{{end}}>Local encrypted</option>
{{- end}} <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> </select>
</div> </div>
</div> </div>
@ -46,7 +50,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
</div> </div>
</div> </div>
{{- end}} {{- 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> <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"> <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" /> <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> </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> <label for="idS3Bucket" data-i18n="storage.bucket" class="col-md-3 col-form-label">Bucket</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3Bucket" type="text" class="form-control" name="s3_bucket" value="{{.S3Config.Bucket}}" /> <input id="idS3Bucket" type="text" class="form-control" name="s3_bucket" value="{{.S3Config.Bucket}}" />
</div> </div>
</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> <label for="idS3Region" data-i18n="storage.region" class="col-md-3 col-form-label">Region</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3Region" type="text" class="form-control" name="s3_region" value="{{.S3Config.Region}}" maxlength="512" /> <input id="idS3Region" type="text" class="form-control" name="s3_region" value="{{.S3Config.Region}}" maxlength="512" />
</div> </div>
</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> <label for="idS3AccessKey" data-i18n="storage.access_key" class="col-md-3 col-form-label">Access Key</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3AccessKey" type="text" class="form-control" name="s3_access_key" value="{{.S3Config.AccessKey}}" maxlength="512" spellcheck="false" /> <input id="idS3AccessKey" type="text" class="form-control" name="s3_access_key" value="{{.S3Config.AccessKey}}" maxlength="512" spellcheck="false" />
</div> </div>
</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> <label for="idS3AccessSecret" data-i18n="storage.access_secret" class="col-md-3 col-form-label">Access Secret</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3AccessSecret" type="password" class="form-control" name="s3_access_secret" autocomplete="new-password" spellcheck="false" <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> </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> <label for="idS3KeyPrefix" data-i18n="storage.key_prefix" class="col-md-3 col-form-label">Key Prefix</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3KeyPrefix" type="text" class="form-control" name="s3_key_prefix" value="{{.S3Config.KeyPrefix}}" aria-describedby="idS3KeyPrefixHelp"/> <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> </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> <label for="idS3Endpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3Endpoint" type="text" class="form-control" name="s3_endpoint" value="{{.S3Config.Endpoint}}" aria-describedby="idS3EndpointHelp"/> <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> </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> <label for="idS3RoleARN" data-i18n="storage.role_arn" class="col-md-3 col-form-label">Role ARN</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idS3RoleARN" type="text" class="form-control" name="s3_role_arn" value="{{.S3Config.RoleARN}}" aria-describedby="idS3RoleARNHelp"/> <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> </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> <label for="idS3StorageClass" data-i18n="storage.class" class="col-md-3 col-form-label">Storage Class</label>
<div class="col-md-3"> <div class="col-md-3">
<input id="idS3StorageClass" type="text" class="form-control" name="s3_storage_class" value="{{.S3Config.StorageClass}}" aria-describedby="idS3StorageClassHelp" /> <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> </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> <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"> <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" /> <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> </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> <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"> <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" /> <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> </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> <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"> <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" /> <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> </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="col-md-5">
<div class="form-check form-switch form-check-custom form-check-solid"> <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}}/> <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> </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> <label for="idGCSBucket" data-i18n="storage.bucket" class="col-md-3 col-form-label">Bucket</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idGCSBucket" type="text" class="form-control" name="gcs_bucket" value="{{.GCSConfig.Bucket}}" /> <input id="idGCSBucket" type="text" class="form-control" name="gcs_bucket" value="{{.GCSConfig.Bucket}}" />
</div> </div>
</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> <label for="idGCSCredentialFile" data-i18n="storage.credentials_file" class="col-md-3 col-form-label">Credential files</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idGCSCredentialFile" type="file" accept="application/json" class="form-control" name="gcs_credential_file" aria-describedby="idGCSCredentialFileHelp" /> <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> </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> <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="col-md-9">
<div class="form-check form-switch form-check-custom form-check-solid"> <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> </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> <label for="idGCSKeyPrefix" data-i18n="storage.key_prefix" class="col-md-3 col-form-label">Key Prefix</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idGCSKeyPrefix" type="text" class="form-control" name="gcs_key_prefix" value="{{.GCSConfig.KeyPrefix}}" aria-describedby="idGCSKeyPrefixHelp" /> <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> </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> <label for="idGCSStorageClass" data-i18n="storage.class" class="col-md-3 col-form-label">Storage Class</label>
<div class="col-md-3"> <div class="col-md-3">
<input id="idGCSStorageClass" type="text" class="form-control" name="gcs_storage_class" value="{{.GCSConfig.StorageClass}}" aria-describedby="idGCSStorageClassHelp" /> <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> </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> <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"> <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" /> <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> </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> <label for="idAzContainer" data-i18n="storage.container" class="col-md-3 col-form-label">Container</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idAzContainer" type="text" class="form-control" name="az_container" value="{{.AzBlobConfig.Container}}" /> <input id="idAzContainer" type="text" class="form-control" name="az_container" value="{{.AzBlobConfig.Container}}" />
</div> </div>
</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> <label for="idAzAccountName" data-i18n="storage.account_name" class="col-md-3 col-form-label">Account Name</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idAzAccountName" type="text" class="form-control" name="az_account_name" value="{{.AzBlobConfig.AccountName}}" /> <input id="idAzAccountName" type="text" class="form-control" name="az_account_name" value="{{.AzBlobConfig.AccountName}}" />
</div> </div>
</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> <label for="idAzAccountKey" data-i18n="storage.account_key" class="col-md-3 col-form-label">Account Key</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idAzAccountKey" type="password" class="form-control" name="az_account_key" autocomplete="new-password" spellcheck="false" <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> </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> <label for="idAzSASURL" data-i18n="storage.sas_url" class="col-md-3 col-form-label">SAS URL</label>
<div class="col-md-9"> <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" <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> </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> <label for="idAzKeyPrefix" data-i18n="storage.key_prefix" class="col-md-3 col-form-label">Key Prefix</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idAzKeyPrefix" type="text" class="form-control" name="az_key_prefix" value="{{.AzBlobConfig.KeyPrefix}}" aria-describedby="idAzKeyPrefixHelp" /> <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> </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> <label for="idAzAccessTier" data-i18n="storage.class" class="col-md-3 col-form-label">Storage Class</label>
<div class="col-md-9"> <div class="col-md-9">
<select id="idAzAccessTier" name="az_access_tier" class="form-select" data-control="i18n-select2" data-hide-search="true"> <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> </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> <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"> <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" /> <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> </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> <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"> <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" /> <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> </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> <label for="idAzEndpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idAzEndpoint" type="text" class="form-control" name="az_endpoint" value="{{.AzBlobConfig.Endpoint}}" aria-describedby="idAzEndpointHelp" /> <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> </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> <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="col-md-9">
<div class="form-check form-switch form-check-custom form-check-solid"> <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> </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> <label for="idCryptPassphrase" data-i18n="storage.passphrase" class="col-md-3 col-form-label">Passphrase</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idCryptPassphrase" type="password" class="form-control" name="crypt_passphrase" autocomplete="new-password" spellcheck="false" aria-describedby="idCryptPassphraseHelp" <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> </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> <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"> <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" /> <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> </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> <label for="idSFTPEndpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idSFTPEndpoint" type="text" class="form-control" name="sftp_endpoint" value="{{.SFTPConfig.Endpoint}}" aria-describedby="idSFTPEndpointHelp"/> <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> </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> <label for="idSFTPUsername" data-i18n="login.username" class="col-md-3 col-form-label">Username</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idSFTPUsername" type="text" class="form-control" name="sftp_username" value="{{.SFTPConfig.Username}}" spellcheck="false" /> <input id="idSFTPUsername" type="text" class="form-control" name="sftp_username" value="{{.SFTPConfig.Username}}" spellcheck="false" />
</div> </div>
</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> <label for="idSFTPPassword" data-i18n="login.password" class="col-md-3 col-form-label">Password</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idSFTPPassword" type="password" class="form-control" name="sftp_password" autocomplete="new-password" spellcheck="false" <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> </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> <label for="idSFTPPrivateKey" data-i18n="general.private_key" class="col-md-3 col-form-label">Private key</label>
<div class="col-md-9"> <div class="col-md-9">
<textarea class="form-control" id="idSFTPPrivateKey" name="sftp_private_key" spellcheck="false" <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> </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> <label for="idSFTPPassphrase" data-i18n="storage.passphrase" class="col-md-3 col-form-label">Passphrase</label>
<div class="col-md-9"> <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" <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> </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> <label for="idSFTPPrefix" data-i18n="storage.sftp_home_dir" class="col-md-3 col-form-label">Root directory</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idSFTPPrefix" type="text" class="form-control" name="sftp_prefix" value="{{.SFTPConfig.Prefix}}" aria-describedby="idSFTPPrefixHelp"/> <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> </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> <label for="idSFTPFingerprints" data-i18n="storage.fingerprints" class="col-md-3 col-form-label">Fingerprints</label>
<div class="col-md-9"> <div class="col-md-9">
<textarea class="form-control" id="idSFTPFingerprints" name="sftp_fingerprints" spellcheck="false" aria-describedby="idSFTPFingerprintsHelp" <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> </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> <label for="idSFTPUploadBufferSize" data-i18n="storage.sftp_buffer" class="col-md-3 col-form-label">Buffer size (MB)</label>
<div class="col-md-9"> <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" /> <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> </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="col-md-5">
<div class="form-check form-switch form-check-custom form-check-solid"> <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}}/> <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> </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> <label for="idHTTPEndpoint" data-i18n="storage.endpoint" class="col-md-3 col-form-label">Endpoint</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idHTTPEndpoint" type="text" class="form-control" name="http_endpoint" value="{{.HTTPConfig.Endpoint}}"/> <input id="idHTTPEndpoint" type="text" class="form-control" name="http_endpoint" value="{{.HTTPConfig.Endpoint}}"/>
</div> </div>
</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> <label for="idHTTPUsername" data-i18n="login.username" class="col-md-3 col-form-label">Username</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idHTTPUsername" type="text" class="form-control" name="http_username" value="{{.HTTPConfig.Username}}" spellcheck="false" /> <input id="idHTTPUsername" type="text" class="form-control" name="http_username" value="{{.HTTPConfig.Username}}" spellcheck="false" />
</div> </div>
</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> <label for="idHTTPPassword" data-i18n="login.password" class="col-md-3 col-form-label">Password</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idHTTPPassword" type="password" class="form-control" name="http_password" autocomplete="new-password" spellcheck="false" <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> </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> <label for="idHTTPAPIKey" data-i18n="storage.api_key" class="col-md-3 col-form-label">API Key</label>
<div class="col-md-9"> <div class="col-md-9">
<input id="idHTTPAPIKey" type="password" class="form-control" name="http_api_key" autocomplete="new-password" spellcheck="false" <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> </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="col-md-5">
<div class="form-check form-switch form-check-custom form-check-solid"> <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}} /> <input class="form-check-input" type="checkbox" id="idHTTPSkipTLSVerify" name="http_skip_tls_verify" {{if .HTTPConfig.SkipTLSVerify}}checked{{end}} />

View file

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

View file

@ -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/formrepeater/formrepeater.bundle.js"></script>
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/flatpickr/l10n/it.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}}> <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(){ $(document).on("i18nload", function(){
onFilesystemChanged('{{.User.FsConfig.Provider.Name}}'); onFilesystemChanged('{{.User.FsConfig.Provider}}');
$('#idFilesystem').on("change", function(){ $('#idFilesystem').on("change", function(){
onFilesystemChanged(this.value); onFilesystemChanged(this.value);