Added UI for Filejump

This commit is contained in:
Kenneth Skovhede
2025-04-09 16:30:10 +02:00
parent c016bcaf26
commit e6c2a4eb3c
4 changed files with 90 additions and 3 deletions
@@ -318,7 +318,7 @@ namespace Duplicati.Library.Backend
if (string.IsNullOrWhiteSpace(folderPath) || folderPath == "/")
return null;
var pathParts = folderPath.Trim('/').Split('/');
var pathParts = folderPath.Trim('/').Split('/', StringSplitOptions.RemoveEmptyEntries);
long? currentParentId = null;
foreach (var part in pathParts)
@@ -475,7 +475,7 @@ namespace Duplicati.Library.Backend
throw new InvalidOperationException("Backend not initialized correctly");
long? currentParentId = null;
var pathParts = m_path.Trim('/').Split('/');
var pathParts = m_path.Trim('/').Split('/', StringSplitOptions.RemoveEmptyEntries);
var newFolder = false;
foreach (var part in pathParts)
@@ -38,6 +38,7 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
EditUriBackendConfig.templates['smb'] = 'templates/backends/smb.html';
EditUriBackendConfig.templates['cifs'] = 'templates/backends/smb.html';
EditUriBackendConfig.templates['filen'] = 'templates/backends/filen.html';
EditUriBackendConfig.templates['filejump'] = 'templates/backends/filejump.html';
EditUriBackendConfig.testers['s3'] = function(scope, callback) {
@@ -639,7 +640,6 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
EditUriBackendConfig.parsers['cifs'] = EditUriBackendConfig.parsers['smb'];
EditUriBackendConfig.parsers['filen'] = function (scope, module, server, path, port, options) {
console.log("filen parser", scope, module, server, path, port, options);
var p1 = server ?? '';
var p2 = path ?? '';
var combined = p1;
@@ -648,6 +648,18 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
scope.Path = combined;
};
EditUriBackendConfig.parsers['filejump'] = function (scope, module, server, path, port, options) {
console.log("filejump parser", scope, module, server, path, port, options);
var p1 = server ?? '';
var p2 = path ?? '';
var combined = p1;
if (p1.length > 0 && p2.length > 0)
combined += '/' + p2;
scope.Path = combined;
scope.ApiToken = options['--api-token'];
scope.UsernamePasswordAuth = (scope.ApiToken || '').trim() == '';
}
// Builders take the scope and produce the uri output
EditUriBackendConfig.builders['s3'] = function (scope) {
var opts = {
@@ -1033,6 +1045,33 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
);
}
EditUriBackendConfig.builders['filejump'] = function (scope) {
var opts = {};
EditUriBackendConfig.merge_in_advanced_options(scope, opts, true);
// Remove trailing and leading slashes
if (scope.Path)
scope.Path = scope.Path.replace(/^[/\\]+/, '').replace(/[/\\]+$/, '');
else
scope.Path = '';
if (scope.UsernamePasswordAuth)
{
delete opts['api-token'];
}
else
{
opts['api-token'] = scope.ApiToken;
delete opts['auth-username'];
delete opts['auth-password'];
}
return AppUtils.format('{0}://{1}{2}',
scope.Backend.Key,
scope.Path,
AppUtils.encodeDictAsUrl(opts)
);
}
EditUriBackendConfig.validaters['smb'] = function (scope, continuation) {
if (EditUriBackendConfig.require_server(scope)
&& EditUriBackendConfig.require_username(scope)
@@ -1047,6 +1086,19 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
EditUriBackendConfig.recommend_path(scope, continuation);
};
EditUriBackendConfig.validaters['filejump'] = function (scope, continuation) {
if (scope.UsernamePasswordAuth)
{
if (EditUriBackendConfig.require_username_and_password(scope))
EditUriBackendConfig.recommend_path(scope, continuation);
}
else
{
if (EditUriBackendConfig.require_field(scope, 'ApiToken', gettextCatalog.getString('API Token')))
EditUriBackendConfig.recommend_path(scope, continuation);
}
};
EditUriBackendConfig.validaters['file'] = function (scope, continuation) {
if (EditUriBackendConfig.require_path(scope))
continuation();
@@ -80,6 +80,7 @@ backupApp.service('SystemInfo', function($rootScope, $timeout, $cookies, AppServ
'aliyunoss': null,
'pcloud': null,
'filen': null,
'filejump': null
}
};
@@ -0,0 +1,34 @@
<div class="input text">
<label for="generic_path" translate>Path on server</label>
<input type="text" name="generic_path" id="generic_path" ng-model="$parent.Path" placeholder="{{'Destination path' | translate}}" />
</div>
<div ng-show="!$parent.UsernamePasswordAuth" class="input text">
<label for="filejump_api_token">
<a href="https://drive.filejump.com/account-settings" target="_blank" translate>Filejump API token</a>
</label>
<input type="password" name="filejump_api_token" id="filejump_api_token" ng-model="$parent.ApiToken" placeholder="{{'Click the Filejump API token link to set up an API token' | translate}}" />
</div>
<div ng-show="$parent.UsernamePasswordAuth" class="input buttons" style="padding-top: 0px;">
<span class="warning" style="float:left" translate>
Username and password authentication is not recommended and does not work with MFA/2FA enabled accounts.
Use the API token if possible.
</span>
</div>
<div ng-show="$parent.UsernamePasswordAuth" class="input text">
<label for="generic_username" translate>Username</label>
<input type="text" name="generic_username" id="generic_username" ng-model="$parent.Username" placeholder="{{'Authentication username' | translate}}" />
</div>
<div ng-show="$parent.UsernamePasswordAuth" class="input password">
<label for="generic_password" translate>Password</label>
<input autocomplete="new-password" type="password" name="generic_password" id="generic_password" ng-model="$parent.Password" placeholder="{{'Authentication password' | translate}}" />
</div>
<div class="input buttons">
<button ng-click="$parent.UsernamePasswordAuth = !$parent.UsernamePasswordAuth" class="button" translate>
<span ng-show="!$parent.UsernamePasswordAuth" translate="">Use username and password authentication</span>
<span ng-show="$parent.UsernamePasswordAuth" translate>Use API token authentication (recommended)</span>
</button>
</div>