diff --git a/pkg/storage/sftp.go b/pkg/storage/sftp.go
index 75900fc4..d0d2ba96 100644
--- a/pkg/storage/sftp.go
+++ b/pkg/storage/sftp.go
@@ -32,7 +32,7 @@ func NewSFTP(config SFTPConfig) (Storage, error) {
if config.Timeout == 0 {
config.Timeout = 30 * time.Second
}
- config.BasePath = strings.Trim(config.BasePath, "/")
+ config.BasePath = strings.TrimSuffix(config.BasePath, "/")
if config.Username == "" || (config.Password == "" && config.PrivateKey == "") {
return nil, fmt.Errorf("username and either password or private key must be provided")
@@ -139,6 +139,11 @@ func (s *SFTP) List(path string) ([]string, error) {
}
defer cleanup()
+ // 确保基础路径存在
+ if s.config.BasePath != "" {
+ _ = client.MkdirAll(s.config.BasePath)
+ }
+
remotePath := s.getRemotePath(path)
entries, err := client.ReadDir(remotePath)
if err != nil {
diff --git a/pkg/storage/webdav.go b/pkg/storage/webdav.go
index 229f73c0..09e92b53 100644
--- a/pkg/storage/webdav.go
+++ b/pkg/storage/webdav.go
@@ -27,7 +27,7 @@ func NewWebDav(config WebDavConfig) (Storage, error) {
if config.Timeout == 0 {
config.Timeout = 30 * time.Second
}
- config.BasePath = strings.Trim(config.BasePath, "/")
+ config.BasePath = strings.TrimSuffix(config.BasePath, "/")
client := gowebdav.NewClient(config.URL, config.Username, config.Password)
client.SetTimeout(config.Timeout)
diff --git a/web/src/views/backup/AccountView.vue b/web/src/views/backup/AccountView.vue
index 934f15d4..b56fdc6f 100644
--- a/web/src/views/backup/AccountView.vue
+++ b/web/src/views/backup/AccountView.vue
@@ -21,6 +21,11 @@ const styleOptions = [
{ label: 'Path', value: 'path' }
]
+const sftpAuthOptions = [
+ { label: $gettext('Password'), value: 'password' },
+ { label: $gettext('Private Key'), value: 'private_key' }
+]
+
const defaultModel = {
type: 's3',
name: '',
@@ -33,8 +38,10 @@ const defaultModel = {
bucket: '',
host: '',
port: 22,
- user: '',
+ username: '',
password: '',
+ private_key: '',
+ auth_type: 'password',
path: ''
}
}
@@ -275,11 +282,18 @@ onMounted(() => {
-
+
+
+
+
{
:placeholder="$gettext('Enter password')"
/>
+
+
+
{
@@ -406,9 +432,19 @@ onMounted(() => {
/>
-
+
-
+
+
+
+
{
:placeholder="$gettext('Enter password')"
/>
+
+
+
{
/>
-
+