Commit 6d9088eb authored by Sascha's avatar Sascha

Merge branch 'develop' into 'master'

Preparing v1.11.0

See merge request !108
parents 8fb940c6 99326589
......@@ -231,6 +231,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-aws.js",
"src/common/data/js/service/api-fileserver.js",
"src/common/data/js/service/api-pwnedpasswords.js",
"src/common/data/js/service/helper.js",
......
......@@ -227,6 +227,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -153,6 +153,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -460,6 +460,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-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>
<script src="js/service/helper.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-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>
<script src="js/service/helper.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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -227,6 +227,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -544,6 +544,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -72,6 +72,55 @@
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_bucket']) {
$scope.errors.push('BUCKET_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_region']) {
$scope.errors.push('REGION_IS_REQUIRED');
return;
}
var aws_regions = [
'us-east-1', // USA Ost (Nord-Virginia)
'us-east-2', // USA Ost (Ohio)
'us-west-1', // USA West (Nordkalifornien)
'us-west-2', // USA West (Oregon)
'ap-south-1', // Asien-Pazifik (Mumbai)
'ap-northeast-1', // Asien-Pazifik (Tokio)
'ap-northeast-2', // Asien-Pazifik (Seoul
'ap-northeast-3', // Asien-Pazifik (Osaka-Lokal)
'ap-southeast-1', // Asien-Pazifik (Singapur)
'ap-southeast-2', // Asien-Pazifik (Sydney)
'ca-central-1', // Kanada (Zentral)
'cn-north-1', // China (Peking)
'cn-northwest-1', // China (Ningxia)
'eu-central-1', // EU (Frankfurt)
'eu-west-1', // EU (Irland)
'eu-west-2', // EU (London)
'eu-west-3', // EU (Paris)
'eu-north-1', // EU (Stockholm)
'sa-east-1', // Südamerika (Sao Paulo)
'us-gov-east-1', // AWS GovCloud (USA Ost)
'us-gov-west-1' // AWS GovCloud (USA)
];
if ($scope.selected_type === 'aws_s3' && aws_regions.indexOf($scope.storage_config['aws_s3_region']) === -1) {
$scope.errors.push('REGION_IS_INVALID');
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_access_key_id']) {
$scope.errors.push('ACCESS_KEY_ID_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_secret_access_key']) {
$scope.errors.push('SECRET_ACCESS_KEY_IS_REQUIRED');
return;
}
if ($scope.modalCreateFileRepositoryForm.$invalid) {
return;
......@@ -84,8 +133,16 @@
$uibModalInstance.close();
};
return managerFileRepository.create_file_repository($scope.title, $scope.selected_type,
$scope.storage_config['gcp_cloud_storage_bucket'], $scope.storage_config['gcp_cloud_storage_json_key'])
return managerFileRepository.create_file_repository(
$scope.title,
$scope.selected_type,
$scope.storage_config['gcp_cloud_storage_bucket'],
$scope.storage_config['gcp_cloud_storage_json_key'],
$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']
)
.then(onSuccess, onError);
}
......
......@@ -62,7 +62,13 @@
$scope.grant = file_repository.grant;
if (file_repository.type === 'gcp_cloud_storage') {
$scope.storage_config['gcp_cloud_storage_bucket'] = file_repository.gcp_cloud_storage_bucket;
$scope.storage_config['gcp_cloud_storage_json_key'] = file_repository.gcp_cloud_storage_json_key
$scope.storage_config['gcp_cloud_storage_json_key'] = file_repository.gcp_cloud_storage_json_key;
}
if (file_repository.type === 'aws_s3') {
$scope.storage_config['aws_s3_bucket'] = file_repository.aws_s3_bucket;
$scope.storage_config['aws_s3_region'] = file_repository.aws_s3_region;
$scope.storage_config['aws_s3_access_key_id'] = file_repository.aws_s3_access_key_id;
$scope.storage_config['aws_s3_secret_access_key'] = file_repository.aws_s3_secret_access_key;
}
}
......@@ -103,6 +109,26 @@
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_bucket']) {
$scope.errors.push('BUCKET_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_region']) {
$scope.errors.push('REGION_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_access_key_id']) {
$scope.errors.push('ACCESS_KEY_ID_IS_REQUIRED');
return;
}
if ($scope.selected_type === 'aws_s3' && !$scope.storage_config['aws_s3_secret_access_key']) {
$scope.errors.push('SECRET_ACCESS_KEY_IS_REQUIRED');
return;
}
if ($scope.modalEditFileRepositoryForm.$invalid) {
return;
}
......@@ -115,8 +141,18 @@
$uibModalInstance.close();
};
return managerFileRepository.update_file_repository(file_repository.id, $scope.title, $scope.selected_type,
$scope.storage_config['gcp_cloud_storage_bucket'], $scope.storage_config['gcp_cloud_storage_json_key'], $scope.active)
return managerFileRepository.update_file_repository(
file_repository.id,
$scope.title,
$scope.selected_type,
$scope.storage_config['gcp_cloud_storage_bucket'],
$scope.storage_config['gcp_cloud_storage_json_key'],
$scope.active,
$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']
)
.then(onSuccess, onError);
}
......
(function(angular) {
'use strict';
/**
* @ngdoc service
* @name psonocli.apiAWS
* @requires $http
* @requires $q
* @requires psonocli.converter
*
* @description
* Service to talk to the psono REST api
*/
var apiAWS = 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.apiAWS#upload
* @methodOf psonocli.apiAWS
*
* @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.apiAWS#download
* @methodOf psonocli.apiAWS
*
* @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("apiAWS", ['$http', '$q', 'converter', apiAWS]);
}(angular));
......@@ -2256,10 +2256,14 @@
* @param {string} type The type of the new file repository
* @param {string} [gcp_cloud_storage_bucket] (optional) The gcp cloud storage bucket
* @param {string} [gcp_cloud_storage_json_key] (optional) The gcp cloud storage json key
* @param {string} [aws_s3_bucket] (optional) The s3 bucket
* @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
*
* @returns {promise} promise
*/
var create_file_repository = function (token, session_secret_key, title, type, gcp_cloud_storage_bucket, gcp_cloud_storage_json_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) {
var endpoint = '/file-repository/';
var connection_type = "PUT";
......@@ -2267,7 +2271,11 @@
title: title,
type: type,
gcp_cloud_storage_bucket: gcp_cloud_storage_bucket,
gcp_cloud_storage_json_key: gcp_cloud_storage_json_key
gcp_cloud_storage_json_key: gcp_cloud_storage_json_key,
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
};
var headers = {
......@@ -2292,11 +2300,15 @@
* @param {string} type The type of the new file repository
* @param {string} [gcp_cloud_storage_bucket] (optional) The gcp cloud storage bucket
* @param {string} [gcp_cloud_storage_json_key] (optional) The gcp cloud storage json key
* @param {string} [aws_s3_bucket] (optional) The s3 bucket
* @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 {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) {
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 endpoint = '/file-repository/';
var connection_type = "POST";
var data = {
......@@ -2305,7 +2317,11 @@
type: type,
gcp_cloud_storage_bucket: gcp_cloud_storage_bucket,
gcp_cloud_storage_json_key: gcp_cloud_storage_json_key,
active: active
active: active,
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
};
var headers = {
......
......@@ -203,22 +203,15 @@
return
}
if (shard_count > 0 && file_repository_count === 0) {
if (shard_count > 0) {
// only shards are available, so lets pick the first shard as default shard
_blueprint_file.field_index['file_destinations'].value = _shards[0];
}
if (shard_count === 0 && file_repository_count > 0) {
} else if (file_repository_count > 0) {
// only repositories are available, so lets pick the first repository as default repository
_blueprint_file.field_index['file_destinations'].value = _filesrepositories[0];
}
if (all_possibilities_count === 1) {
// only 1 possiblity, we dont have to confuse the user by showing the dropdown menus
return
}
if (shard_count > 0) {
if (all_possibilities_count > 1) {
_blueprint_file.field_index['file_destinations'].hidden = false;
}
});
......
......@@ -167,6 +167,7 @@
*/
var get_possible_types = function() {
return [
{value: 'aws_s3', title: 'AWS S3'},
{value: 'gcp_cloud_storage', title: 'GCP Cloud Storage'}
];
};
......@@ -237,10 +238,14 @@
* @param {string} type The type of the new file repository
* @param {string} [gcp_cloud_storage_bucket] (optional) The gcp cloud storage bucket
* @param {string} [gcp_cloud_storage_json_key] (optional) The gcp cloud storage json key
* @param {string} [aws_s3_bucket] (optional) The s3 bucket
* @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
*
* @returns {promise} Promise with the new id
*/
var create_file_repository = function(title, type, gcp_cloud_storage_bucket, gcp_cloud_storage_json_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) {
var onSuccess = function (result) {
var file_repository_id = result.data['file_repository_id'];
......@@ -258,7 +263,11 @@
title,
type,
gcp_cloud_storage_bucket,
gcp_cloud_storage_json_key
gcp_cloud_storage_json_key,
aws_s3_bucket,
aws_s3_region,
aws_s3_access_key_id,
aws_s3_secret_access_key
)
.then(onSuccess, onError);
};
......@@ -276,11 +285,16 @@
* @param {string} type The type of the new file repository
* @param {string} [gcp_cloud_storage_bucket] (optional) The gcp cloud storage bucket
* @param {string} [gcp_cloud_storage_json_key] (optional) The gcp cloud storage json key
* @param {string} [aws_s3_bucket] (optional) The s3 bucket
* @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 {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) {
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) {
return apiClient.update_file_repository(
managerBase.get_token(),
......@@ -290,7 +304,11 @@
type,
gcp_cloud_storage_bucket,
gcp_cloud_storage_json_key,
active
active,
aws_s3_bucket,
aws_s3_region,
aws_s3_access_key_id,
aws_s3_secret_access_key
)
};
......
......@@ -10,14 +10,17 @@
* @requires psonocli.managerBase
* @requires psonocli.browserClient
* @requires psonocli.cryptoLibrary
* @requires psonocli.converter
* @requires psonocli.apiClient
* @requires psonocli.apiFileserver
* @requires psonocli.apiGCP
* @requires psonocli.apiAWS
*
* @description
* Service to manage everything around file transfer
*/
var managerFileTransfer = function($q, helper, storage, managerBase, browserClient, cryptoLibrary , converter, apiClient, apiFileserver, apiGCP) {
var managerFileTransfer = function($q, helper, storage, managerBase, browserClient, cryptoLibrary , converter, apiClient, apiFileserver, apiGCP, apiAWS) {
var registrations = {};
......@@ -136,11 +139,11 @@
/**
* @ngdoc
* @name psonocli.managerFileTransfer#upload
* @name psonocli.managerFileTransfer#upload_file_repository_gcp_cloud_storage
* @methodOf psonocli.managerFileTransfer
*
* @description
* Triggered once someone wants to actually upload the file
* Triggered once someone wants to actually upload the file to GCP Cloud Storage
*
* @param {Blob} chunk The content of the chunk to upload
* @param {uuid} file_transfer_id The id of the file transfer
......@@ -173,36 +176,48 @@
return apiClient.file_repository_upload(managerBase.get_token(),
managerBase.get_session_secret_key(), file_transfer_id, chunk_size, chunk_position, hash_checksum)
.then(onSuccess, onError);
};
/**
* @ngdoc
* @name psonocli.managerFileTransfer#upload_file_repository_aws_s3
* @methodOf psonocli.managerFileTransfer
*
* @description
* Triggered once someone wants to actually upload the file to AWS S3
*
* @param {Blob} chunk The content of the chunk to upload
* @param {uuid} file_transfer_id The id of the file transfer
* @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_aws_s3 = function(chunk, file_transfer_id, chunk_size, chunk_position, hash_checksum) {
var onError = function(result) {
return $q.reject(result.data)
};
var onSuccess = function(result) {
//
// var ticket = {
// 'file_transfer_id': file_transfer_id,
// 'chunk_position': chunk_position,
// 'hash_checksum': hash_checksum
// };
//
// var ticket_enc = cryptoLibrary.encrypt_data(JSON.stringify(ticket), managerBase.get_session_secret_key());
//
// var fileserver;
// if (shard['fileserver'].length > 1) {
// // math random should be good enough here, don't use for crypto!
// var pos = Math.floor(Math.random() * shard['fileserver'].length);
// fileserver = shard['fileserver'][pos];
// } else {
// fileserver = shard['fileserver'][0];
// }
//
// var onError = function(result) {
// return $q.reject(result.data)
// };
//
// var onSuccess = function(result) {
// return result.data;
// };
//
// return apiFileserver.upload(fileserver['fileserver_url'], managerBase.get_token(), chunk, ticket_enc.text, ticket_enc.nonce)
// .then(onSuccess, onError);
var onError = function(result) {
return $q.reject(result.data)
};
var onSuccess = function(result) {
return result;
};
return apiAWS.upload(result.data.url, result.data.fields, chunk)
.then(onSuccess, onError);
};
return apiClient.file_repository_upload(managerBase.get_token(),
managerBase.get_session_secret_key(), file_transfer_id, chunk_size, chunk_position, hash_checksum)
.then(onSuccess, onError);
};
......@@ -230,6 +245,8 @@
return upload_shard(chunk, file_transfer_id, 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, 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, chunk_size, chunk_position, hash_checksum);
}
};
......@@ -648,6 +665,6 @@
};
var app = angular.module('psonocli');
app.factory("managerFileTransfer", ['$q', 'helper', 'storage', 'managerBase', 'browserClient', 'cryptoLibrary', 'converter', 'apiClient', 'apiFileserver', 'apiGCP', managerFileTransfer]);
app.factory("managerFileTransfer", ['$q', 'helper', 'storage', 'managerBase', 'browserClient', 'cryptoLibrary', 'converter', 'apiClient', 'apiFileserver', 'apiGCP', 'apiAWS', managerFileTransfer]);
}(angular, saveAs));
\ No newline at end of file
......@@ -291,6 +291,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -199,6 +199,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -415,6 +415,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -192,6 +192,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -251,6 +251,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-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>
<script src="js/service/helper.js" type="application/javascript"></script>
......
......@@ -259,6 +259,7 @@ self.addEventListener('install', function(event) {
'./js/service/api-client.js',
'./js/service/api-gcp.js',
'./js/service/api-aws.js',
'./js/service/api-fileserver.js',
'./js/service/api-pwnedpasswords.js',
'./js/service/helper.js',
......
......@@ -19,7 +19,11 @@
"JSON_KEY_IS_INVALID": "JSON Key ist nicht korrekt",
"TYPE_IS_REQUIRED": "Typ ist erforderlich",
"BUCKET_IS_REQUIRED": "Bucket ist erforderlich",
"REGION_IS_REQUIRED": "Region ist erforderlich",
"REGION_IS_INVALID": "Region ist ungültig",
"JSON_KEY_IS_REQUIRED": "JSON Key ist erforderlich",
"ACCESS_KEY_ID_IS_REQUIRED": "Access Key ID ist erforderlich",
"SECRET_ACCESS_KEY_IS_REQUIRED": "Secret Access Key ist erforderlich",
"JSON_KEY": "JSON Key",
"BUCKET": "Bucket",
"TARGET_STORAGE": "Ziel Speicher",
......@@ -207,7 +211,10 @@
"ONE_OF_YOUR_YUBIKEY_OTPS": "Einer deiner YubiKey Codes",
"EXISTING_DUOS": "Existierende Duos",
"TITLE_OF_YOUR_DUO": "Titel deines Duo",
"REGION": "Region",
"SECRET_KEY": "Secret Key",
"ACCESS_KEY_ID": "Access Key ID",
"SECRET_ACCESS_KEY": "Secret Access Key",
"INTEGRATION_KEY": "Integration Key",
"NEW_DUO": "Neuer Duo",
"TITLE_OF_YOUR_YUBIKEY": "Titel deines YubiKeys",
......
......@@ -19,7 +19,11 @@
"JSON_KEY_IS_INVALID": "JSON key is invalid",
"TYPE_IS_REQUIRED": "Type is required",
"BUCKET_IS_REQUIRED": "Bucket is required",
"REGION_IS_REQUIRED": "Region is required",
"REGION_IS_INVALID": "Region is invalid",</