Commit 465413f6 authored by Sascha Pfeiffer's avatar Sascha Pfeiffer

added digital ocean spaces as file repository

Signed-off-by: 's avatarSascha Pfeiffer <sascha.pfeiffer@psono.com>
parent f7f9a328
......@@ -240,6 +240,7 @@ var build = function(build_path, type) {
"src/common/data/js/service/api-client.js",
"src/common/data/js/service/api-gcp.js",
"src/common/data/js/service/api-do.js",
"src/common/data/js/service/api-aws.js",
"src/common/data/js/service/api-fileserver.js",
"src/common/data/js/service/api-pwnedpasswords.js",
......
......@@ -246,6 +246,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -162,6 +162,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -480,6 +480,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -231,6 +231,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -363,6 +363,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -237,6 +237,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -559,6 +559,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -121,6 +121,39 @@
return;
}
if ($scope.selected_type === 'do_spaces' && !$scope.storage_config['do_space']) {
$scope.errors.push('SPACE_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'do_spaces' && !$scope.storage_config['do_region']) {
$scope.errors.push('REGION_IS_REQUIRED');
return;
}
var do_spaces_regions = [
'ams3',
'fra1',
'nyc3',
'sfo2',
'sgp1'
];
if ($scope.selected_type === 'do_spaces' && do_spaces_regions.indexOf($scope.storage_config['do_region']) === -1) {
$scope.errors.push('REGION_IS_INVALID');
return;
}
if ($scope.selected_type === 'do_spaces' && !$scope.storage_config['do_key']) {
$scope.errors.push('KEY_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'do_spaces' && !$scope.storage_config['do_secret']) {
$scope.errors.push('SECRET_IS_REQUIRED');
return;
}
if ($scope.modalCreateFileRepositoryForm.$invalid) {
return;
......@@ -141,7 +174,11 @@
$scope.storage_config['aws_s3_bucket'],
$scope.storage_config['aws_s3_region'],
$scope.storage_config['aws_s3_access_key_id'],
$scope.storage_config['aws_s3_secret_access_key']
$scope.storage_config['aws_s3_secret_access_key'],
$scope.storage_config['do_space'],
$scope.storage_config['do_region'],
$scope.storage_config['do_key'],
$scope.storage_config['do_secret']
)
.then(onSuccess, onError);
}
......
......@@ -113,6 +113,26 @@
return;
}
if ($scope.file_repository.type === 'do_spaces' && !$scope.file_repository['do_space']) {
$scope.errors.push('SPACE_IS_REQUIRED');
return;
}
if ($scope.file_repository.type === 'do_spaces' && !$scope.file_repository['do_region']) {
$scope.errors.push('REGION_IS_REQUIRED');
return;
}
if ($scope.file_repository.type === 'do_spaces' && !$scope.file_repository['do_key']) {
$scope.errors.push('KEY_IS_REQUIRED');
return;
}
if ($scope.file_repository.type === 'do_spaces' && !$scope.file_repository['do_secret']) {
$scope.errors.push('SECRET_IS_REQUIRED');
return;
}
if ($scope.modalEditFileRepositoryForm.$invalid) {
return;
}
......@@ -135,7 +155,11 @@
$scope.file_repository['aws_s3_bucket'],
$scope.file_repository['aws_s3_region'],
$scope.file_repository['aws_s3_access_key_id'],
$scope.file_repository['aws_s3_secret_access_key']
$scope.file_repository['aws_s3_secret_access_key'],
$scope.file_repository['do_space'],
$scope.file_repository['do_region'],
$scope.file_repository['do_key'],
$scope.file_repository['do_secret']
)
.then(onSuccess, onError);
}
......
......@@ -2319,10 +2319,17 @@
* @param {string} [aws_s3_region] (optional) The s3 region
* @param {string} [aws_s3_access_key_id] (optional) The s3 access key
* @param {string} [aws_s3_secret_access_key] (optional) The s3 secret key
* @param {string} [do_space] (optional) The digital ocean space
* @param {string} [do_region] (optional) The digital ocean region
* @param {string} [do_key] (optional) The digital ocean key
* @param {string} [do_secret] (optional) The digital ocean secret
*
* @returns {promise} promise
*/
var create_file_repository = function (token, session_secret_key, title, type, gcp_cloud_storage_bucket, gcp_cloud_storage_json_key, aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key) {
var create_file_repository = function (token, session_secret_key, title, type,
gcp_cloud_storage_bucket, gcp_cloud_storage_json_key,
aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key,
do_space, do_region, do_key, do_secret) {
var endpoint = '/file-repository/';
var connection_type = "PUT";
......@@ -2334,7 +2341,11 @@
aws_s3_bucket: aws_s3_bucket,
aws_s3_region: aws_s3_region,
aws_s3_access_key_id: aws_s3_access_key_id,
aws_s3_secret_access_key: aws_s3_secret_access_key
aws_s3_secret_access_key: aws_s3_secret_access_key,
do_space: do_space,
do_region: do_region,
do_key: do_key,
do_secret: do_secret
};
var headers = {
......@@ -2363,11 +2374,18 @@
* @param {string} [aws_s3_region] (optional) The s3 region
* @param {string} [aws_s3_access_key_id] (optional) The s3 access key
* @param {string} [aws_s3_secret_access_key] (optional) The s3 secret key
* @param {string} [do_space] (optional) The digital ocean space
* @param {string} [do_region] (optional) The digital ocean region
* @param {string} [do_key] (optional) The digital ocean key
* @param {string} [do_secret] (optional) The digital ocean secret
* @param {bool} active Active or not
*
* @returns {promise} Returns a promise which can succeed or fail
*/
var update_file_repository = function (token, session_secret_key, file_repository_id, title, type, gcp_cloud_storage_bucket, gcp_cloud_storage_json_key, active, aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key) {
var update_file_repository = function (token, session_secret_key, file_repository_id, title, type,
gcp_cloud_storage_bucket, gcp_cloud_storage_json_key, active,
aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key,
do_space, do_region, do_key, do_secret) {
var endpoint = '/file-repository/';
var connection_type = "POST";
var data = {
......@@ -2380,7 +2398,11 @@
aws_s3_bucket: aws_s3_bucket,
aws_s3_region: aws_s3_region,
aws_s3_access_key_id: aws_s3_access_key_id,
aws_s3_secret_access_key: aws_s3_secret_access_key
aws_s3_secret_access_key: aws_s3_secret_access_key,
do_space: do_space,
do_region: do_region,
do_key: do_key,
do_secret: do_secret
};
var headers = {
......
(function(angular) {
'use strict';
/**
* @ngdoc service
* @name psonocli.apiDO
* @requires $http
* @requires $q
* @requires psonocli.converter
*
* @description
* Service to talk to the psono REST api
*/
var apiDO = function($http, $q, converter) {
var call = function(fileserver_url, connection_type, endpoint, data, headers, transformRequest, responseType) {
if (!transformRequest) {
transformRequest = $http.defaults.transformRequest;
}
var req = {
method: connection_type,
url: fileserver_url + endpoint,
data: data,
transformRequest: transformRequest,
responseType: responseType
};
req.headers = headers;
return $q(function(resolve, reject) {
var onSuccess = function(data) {
return resolve(data);
};
var onError = function(data) {
return reject(data);
};
$http(req)
.then(onSuccess, onError);
});
};
/**
* @ngdoc
* @name psonocli.apiDO#upload
* @methodOf psonocli.apiDO
*
* @description
* Ajax PUT request to upload a file chunk to AWS S3
*
* @param {string} signed_url The signed ulr
* @param {object} fields Array of fields that need to be part of the request
* @param {Blob} chunk The content of the chunk to upload
*
* @returns {promise} promise
*/
var upload = function (signed_url, fields, chunk) {
var endpoint = ''; // the signed url already has everything
var connection_type = "POST";
var data = new FormData();
for (var field_name in fields) {
if (!fields.hasOwnProperty(field_name)) {
continue;
}
data.append(field_name, fields[field_name]);
}
data.append('file', chunk);
var headers = {
'Content-Type': undefined
};
return call(signed_url, connection_type, endpoint, data, headers, angular.identity);
};
/**
* @ngdoc
* @name psonocli.apiDO#download
* @methodOf psonocli.apiDO
*
* @description
* Ajax GET request to download a file chunk from AWS S3
*
* @param {string} signed_url The signed ulr
*
* @returns {promise} promise with the data
*/
var download = function (signed_url) {
var endpoint = ''; // the signed url already has everything
var connection_type = "GET";
var data = null;
var headers = {
};
return call(signed_url, connection_type, endpoint, data, headers, undefined, 'arraybuffer').then(function(data) {
return data
},function(data) {
if (data.status === 400) {
data.data = JSON.parse(converter.bytes_to_string(data.data));
}
return $q.reject(data)
});
};
return {
upload: upload,
download: download
};
};
var app = angular.module('psonocli');
app.factory("apiDO", ['$http', '$q', 'converter', apiDO]);
}(angular));
......@@ -168,7 +168,8 @@
var get_possible_types = function() {
return [
{value: 'aws_s3', title: 'AWS S3'},
{value: 'gcp_cloud_storage', title: 'GCP Cloud Storage'}
{value: 'gcp_cloud_storage', title: 'GCP Cloud Storage'},
{value: 'do_spaces', title: 'Digital Ocean Spaces'}
];
};
......@@ -242,10 +243,17 @@
* @param {string} [aws_s3_region] (optional) The s3 region
* @param {string} [aws_s3_access_key_id] (optional) The s3 access key
* @param {string} [aws_s3_secret_access_key] (optional) The s3 secret key
* @param {string} [do_space] (optional) The digital ocean space
* @param {string} [do_region] (optional) The digital ocean region
* @param {string} [do_key] (optional) The digital ocean key
* @param {string} [do_secret] (optional) The digital ocean secret
*
* @returns {promise} Promise with the new id
*/
var create_file_repository = function(title, type, gcp_cloud_storage_bucket, gcp_cloud_storage_json_key, aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key) {
var create_file_repository = function(title, type,
gcp_cloud_storage_bucket, gcp_cloud_storage_json_key,
aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key,
do_space, do_region, do_key, do_secret) {
var onSuccess = function (result) {
var file_repository_id = result.data['file_repository_id'];
......@@ -267,7 +275,11 @@
aws_s3_bucket,
aws_s3_region,
aws_s3_access_key_id,
aws_s3_secret_access_key
aws_s3_secret_access_key,
do_space,
do_region,
do_key,
do_secret
)
.then(onSuccess, onError);
};
......@@ -289,12 +301,17 @@
* @param {string} [aws_s3_region] (optional) The s3 region
* @param {string} [aws_s3_access_key_id] (optional) The s3 access key
* @param {string} [aws_s3_secret_access_key] (optional) The s3 secret key
* @param {string} [do_space] (optional) The digital ocean space
* @param {string} [do_region] (optional) The digital ocean region
* @param {string} [do_key] (optional) The digital ocean key
* @param {string} [do_secret] (optional) The digital ocean secret
* @param {bool} active
*
* @returns {promise} Promise with the new id
*/
var update_file_repository = function(file_repository_id, title, type, gcp_cloud_storage_bucket, gcp_cloud_storage_json_key, active,
aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key) {
aws_s3_bucket, aws_s3_region, aws_s3_access_key_id, aws_s3_secret_access_key,
do_space, do_region, do_key, do_secret) {
return apiClient.update_file_repository(
managerBase.get_token(),
......@@ -308,7 +325,11 @@
aws_s3_bucket,
aws_s3_region,
aws_s3_access_key_id,
aws_s3_secret_access_key
aws_s3_secret_access_key,
do_space,
do_region,
do_key,
do_secret
)
};
......
......@@ -14,13 +14,14 @@
* @requires psonocli.apiClient
* @requires psonocli.apiFileserver
* @requires psonocli.apiGCP
* @requires psonocli.apiDO
* @requires psonocli.apiAWS
*
* @description
* Service to manage everything around file transfer
*/
var managerFileTransfer = function($q, helper, storage, managerBase, browserClient, cryptoLibrary , converter, apiClient, apiFileserver, apiGCP, apiAWS) {
var managerFileTransfer = function($q, helper, storage, managerBase, browserClient, cryptoLibrary , converter, apiClient, apiFileserver, apiGCP, apiDO, apiAWS) {
var registrations = {};
......@@ -221,6 +222,48 @@
};
/**
* @ngdoc
* @name psonocli.managerFileTransfer#upload_file_repository_do_spaces
* @methodOf psonocli.managerFileTransfer
*
* @description
* Triggered once someone wants to actually upload the file to Digital ocean spaces
*
* @param {Blob} chunk The content of the chunk to upload
* @param {uuid} file_transfer_id The id of the file transfer
* @param {string} file_transfer_secret_key The file transfer secret key
* @param {int} chunk_size The size of the complete chunk in bytes
* @param {int} chunk_position The sequence number of the chunk to determine the order
* @param {string} hash_checksum The sha512 hash
*
* @returns {promise} promise
*/
var upload_file_repository_do_spaces = function(chunk, file_transfer_id, file_transfer_secret_key, chunk_size, chunk_position, hash_checksum) {
var onError = function(result) {
return $q.reject(result.data)
};
var onSuccess = function(result) {
var onError = function(result) {
return $q.reject(result.data)
};
var onSuccess = function(result) {
return result;
};
return apiDO.upload(result.data.url, result.data.fields, chunk)
.then(onSuccess, onError);
};
return apiClient.file_repository_upload(file_transfer_id, file_transfer_secret_key, chunk_size, chunk_position, hash_checksum)
.then(onSuccess, onError);
};
/**
* @ngdoc
* @name psonocli.managerFileTransfer#upload
......@@ -246,6 +289,8 @@
return upload_shard(chunk, file_transfer_id, file_transfer_secret_key, chunk_position, shard, hash_checksum);
} else if (typeof(file_repository) !== 'undefined' && file_repository['type'] === 'gcp_cloud_storage') {
return upload_file_repository_gcp_cloud_storage(chunk, file_transfer_id, file_transfer_secret_key, chunk_size, chunk_position, hash_checksum);
} else if (typeof(file_repository) !== 'undefined' && file_repository['type'] === 'do_spaces') {
return upload_file_repository_do_spaces(chunk, file_transfer_id, file_transfer_secret_key, chunk_size, chunk_position, hash_checksum);
} else if (typeof(file_repository) !== 'undefined' && file_repository['type'] === 'aws_s3') {
return upload_file_repository_aws_s3(chunk, file_transfer_id, file_transfer_secret_key, chunk_size, chunk_position, hash_checksum);
}
......@@ -473,6 +518,9 @@
} else if(result.data.type === 'gcp_cloud_storage') {
return apiGCP.download(result.data.url)
.then(onSuccess, onError);
} else if(result.data.type === 'do_spaces') {
return apiDO.download(result.data.url)
.then(onSuccess, onError);
} else {
return $q.reject('UNKNOW_FILE_REPOSITORY_TYPE');
}
......@@ -715,6 +763,6 @@
};
var app = angular.module('psonocli');
app.factory("managerFileTransfer", ['$q', 'helper', 'storage', 'managerBase', 'browserClient', 'cryptoLibrary', 'converter', 'apiClient', 'apiFileserver', 'apiGCP', 'apiAWS', managerFileTransfer]);
app.factory("managerFileTransfer", ['$q', 'helper', 'storage', 'managerBase', 'browserClient', 'cryptoLibrary', 'converter', 'apiClient', 'apiFileserver', 'apiGCP', 'apiDO', 'apiAWS', managerFileTransfer]);
}(angular, saveAs));
\ No newline at end of file
......@@ -322,6 +322,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -334,6 +334,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -209,6 +209,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -435,6 +435,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -202,6 +202,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -295,6 +295,7 @@
<script src="js/service/api-client.js" type="application/javascript"></script>
<script src="js/service/api-gcp.js" type="application/javascript"></script>
<script src="js/service/api-do.js" type="application/javascript"></script>
<script src="js/service/api-aws.js" type="application/javascript"></script>
<script src="js/service/api-fileserver.js" type="application/javascript"></script>
<script src="js/service/api-pwnedpasswords.js" type="application/javascript"></script>
......
......@@ -289,6 +289,7 @@ self.addEventListener('install', function(event) {
'./js/service/api-client.js',
'./js/service/api-gcp.js',
'./js/service/api-do.js',
'./js/service/api-aws.js',
'./js/service/api-fileserver.js',
'./js/service/api-pwnedpasswords.js',
......
{
"SECRET": "Secret",
"SPACE": "Space",
"KEY_IS_REQUIRED": "Der Key ist erforderlich",
"SECRET_IS_REQUIRED": "Das Secret ist erforderlich",
"ACCOUNT_NOT_VERIFIED": "Account nicht verifiziert",
"USER_INACTIVE_OR_DELETED": "Benutzer inaktiv oder gelöscht",
"FILE_TRANSFER_INVALID": "Ungültiger Datei Transfer",
......@@ -67,6 +71,7 @@
"UNKNOWN_TYPE": "Unbekannter Typ",
"JSON_KEY_IS_INVALID": "JSON Key ist nicht korrekt",
"TYPE_IS_REQUIRED": "Typ ist erforderlich",
"SPACE_IS_REQUIRED": "Space ist erforderlich",
"BUCKET_IS_REQUIRED": "Bucket ist erforderlich",
"REGION_IS_REQUIRED": "Region ist erforderlich",
"REGION_IS_INVALID": "Region ist ungültig",
......
{
"SECRET": "Secret",
"SPACE": "Space",
"KEY_IS_REQUIRED": "The key is required",
"SECRET_IS_REQUIRED": "The secret is required",
"ACCOUNT_NOT_VERIFIED": "Account not verified",
"USER_INACTIVE_OR_DELETED": "User inactive or deleted",
"FILE_TRANSFER_INVALID": "File transfer invalid",
......@@ -67,6 +71,7 @@
"UNKNOWN_TYPE": "Unknown type",
"JSON_KEY_IS_INVALID": "JSON key is invalid",
"TYPE_IS_REQUIRED": "Type is required",
"SPACE_IS_REQUIRED": "Space is required",
"BUCKET_IS_REQUIRED": "Bucket is required",
"REGION_IS_REQUIRED": "Region is required",
"REGION_IS_INVALID": "Region is invalid",
......
......@@ -45,6 +45,22 @@
</div>
</div>
<div ng-if="selected_type === 'do_spaces'">
<div class="form-group">
<input type="text" name="do_space" class="form-control" id="do_space" placeholder="{{'SPACE' | translate}}" ng-model="storage_config.do_space">
</div>
<div class="form-group">
<input type="text" name="do_region" class="form-control" id="do_region" placeholder="{{'REGION' | translate}}" ng-model="storage_config.do_region">
</div>
<div class="form-group">
<input type="text" name="do_key" class="form-control" id="do_key" placeholder="{{'KEY' | translate}}" ng-model="storage_config.do_key">
</div>
<div class="form-group">
<input type="text" name="do_secret" class="form-control" id="do_secret" placeholder="{{'SECRET' | translate}}" ng-model="storage_config.do_secret">
</div>
</div>
<div class="form-group alert alert-danger" ng-repeat="e in errors">
<strong>{{'ERROR' | translate}}:</strong> <span translate="{{ e | translate}}"></span>
</div>
......
......@@ -14,7 +14,7 @@
<input type="text" name="title" class="form-control" id="folderName" placeholder="{{'TITLE' | translate}}" ng-model="file_repository.title" required autofocus>
<p class="help-block" ng-show="submitted && modalEditFileRepositoryForm.title.$error.required">{{'TITLE_IS_REQUIRED' | translate}}</p>
</div>
<pre>{{ file_repository | json }}</pre>
<div class="form-group">
<select class="form-control" ng-model="file_repository.type">
<option ng-repeat="x in types" value="{{x.value}}">{{x.title}}</option>
......@@ -35,7 +35,6 @@
</div>
</div>
<div ng-if="file_repository.type === 'aws_s3'">
<div class="form-group">
<input type="text" name="aws_s3_bucket" class="form-control" id="aws_s3_bucket" placeholder="{{'BUCKET' | translate}}" ng-model="file_repository.aws_s3_bucket">
......@@ -51,6 +50,22 @@
</div>
</div>
<div ng-if="file_repository.type === 'do_spaces'">
<div class="form-group">
<input type="text" name="do_space" class="form-control" id="do_space" placeholder="{{'SPACE' | translate}}" ng-model="file_repository.do_space">
</div>
<div class="form-group">
<input type="text" name="do_region" class="form-control" id="do_region" placeholder="{{'REGION' | translate}}" ng-model="file_repository.do_region">
</div>
<div class="form-group">
<input type="text" name="do_key" class="form-control" id="do_key" placeholder="{{'KEY' | translate}}" ng-model="file_repository.do_key">
</div>
<div class="form-group">
<input type="text" name="do_secret" class="form-control" id="do_secret" placeholder="{{'SECRET' | translate}}" ng-model="file_repository.do_secret">
</div>
</div>
<div class="form-group">
<input type="checkbox" ng-model="file_repository.active">
{{'ACTIVE' | translate}}
......
......@@ -134,6 +134,7 @@
"../src/common/data/js/controller/Enforce2FaCtrl.js",
"../src/common/data/js/service/api-client.js",
"../src/common/data/js/service/api-gcp.js",
"../src/common/data/js/service/api-do.js",
"../src/common/data/js/service/api-aws.js",
"../src/common/data/js/service/api-fileserver.js",
"../src/common/data/js/service/api-pwnedpasswords.js",
......
......@@ -138,6 +138,7 @@
"../src/common/data/js/controller/Enforce2FaCtrl.js",
"../src/common/data/js/service/api-client.js",
"../src/common/data/js/service/api-gcp.js",
"../src/common/data/js/service/api-do.js",
"../src/common/data/js/service/api-aws.js",
"../src/common/data/js/service/api-fileserver.js",