1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

- Modified uploads to either encrypt in the browser, or encrypt server side.

- Reconfigured the upload screen.
This commit is contained in:
Uncled1023 2017-02-12 12:38:16 -08:00
parent 679c148029
commit a509291022
15 changed files with 277 additions and 276 deletions

View File

@ -16,7 +16,7 @@ namespace Teknik
// Set if we are using Cdn
bundles.UseCdn = config.UseCdn;
BundleTable.EnableOptimizations = false;
BundleTable.EnableOptimizations = true;
#if !DEBUG
BundleTable.EnableOptimizations = true;
#endif

View File

@ -50,16 +50,6 @@ namespace Teknik.Areas.API.Controllers
// Scan the file to detect a virus
if (Config.UploadConfig.VirusScanEnable)
{
// If it was encrypted client side, decrypt it
//if (!model.encrypt && model.key != null)
//{
// // If the IV is set, and Key is set, then decrypt it
// if (!string.IsNullOrEmpty(model.key) && !string.IsNullOrEmpty(model.iv))
// {
// // Decrypt the data
// scanData = AES.Decrypt(scanData, model.key, model.iv);
// }
//}
ClamClient clam = new ClamClient(Config.UploadConfig.ClamServer, Config.UploadConfig.ClamPort);
clam.MaxStreamSize = Config.UploadConfig.MaxUploadSize;
ClamScanResult scanResult = clam.SendAndScanFile(model.file.InputStream);
@ -90,7 +80,7 @@ namespace Teknik.Areas.API.Controllers
model.blockSize = Config.UploadConfig.BlockSize;
// Save the file data
Upload.Models.Upload upload = Uploader.SaveFile(db, Config, model.file.InputStream, model.contentType, contentLength, model.encrypt, fileExt, model.iv, model.key, model.saveKey, model.keySize, model.blockSize);
Upload.Models.Upload upload = Uploader.SaveFile(db, Config, model.file.InputStream, model.contentType, contentLength, model.encrypt, fileExt, model.iv, model.key, model.keySize, model.blockSize);
if (upload != null)
{

View File

@ -0,0 +1 @@


View File

@ -40,20 +40,18 @@ namespace Teknik.Areas.Upload.Controllers
Users.Models.User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
model.SaveKey = user.UploadSettings.SaveKey;
model.ServerSideEncrypt = user.UploadSettings.ServerSideEncrypt;
model.Encrypt = user.UploadSettings.Encrypt;
}
else
{
model.SaveKey = true;
model.ServerSideEncrypt = true;
model.Encrypt = false;
}
return View(model);
}
[HttpPost]
[AllowAnonymous]
public ActionResult Upload(string fileType, string fileExt, string iv, int keySize, int blockSize, bool encrypt, bool saveKey, HttpPostedFileWrapper data, string key = null)
public ActionResult Upload(string fileType, string fileExt, string iv, int keySize, int blockSize, bool encrypt, HttpPostedFileWrapper data)
{
try
{
@ -67,16 +65,6 @@ namespace Teknik.Areas.Upload.Controllers
// Scan the file to detect a virus
if (Config.UploadConfig.VirusScanEnable)
{
// If it was encrypted client side, decrypt it
//if (!encrypt && key != null)
//{
// // If the IV is set, and Key is set, then decrypt it
// if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(iv))
// {
// // Decrypt the data
// scanData = AES.Decrypt(scanData, key, iv);
// }
//}
ClamClient clam = new ClamClient(Config.UploadConfig.ClamServer, Config.UploadConfig.ClamPort);
clam.MaxStreamSize = Config.UploadConfig.MaxUploadSize;
ClamScanResult scanResult = clam.SendAndScanFile(data.InputStream);
@ -94,7 +82,7 @@ namespace Teknik.Areas.Upload.Controllers
}
}
Models.Upload upload = Uploader.SaveFile(db, Config, data.InputStream, fileType, contentLength, encrypt, fileExt, iv, key, saveKey, keySize, blockSize);
Models.Upload upload = Uploader.SaveFile(db, Config, data.InputStream, fileType, contentLength, encrypt, fileExt, iv, null, keySize, blockSize);
if (upload != null)
{
if (User.Identity.IsAuthenticated)
@ -107,7 +95,7 @@ namespace Teknik.Areas.Upload.Controllers
db.SaveChanges();
}
}
return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("u", "Upload.Download", new { file = upload.Url }), key = key } }, "text/plain");
return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("u", "Upload.Download", new { file = upload.Url }), contentType = upload.ContentType, contentLength = StringHelper.GetBytesReadable(upload.ContentLength) } }, "text/plain");
}
return Json(new { error = new { message = "Unable to upload file" } });
}

View File

@ -2,58 +2,13 @@
$("#upload-links").css('display', 'none', 'important');
$("#upload-links").html('');
$("[name='saveKey']").bootstrapSwitch();
$("[name='serverSideEncrypt']").bootstrapSwitch();
$("[name='encrypt']").bootstrapSwitch();
linkCopyAll($('#copy-all-button'));
});
function linkSaveKey(selector, uploadID, key, fileID) {
$(selector).click(function () {
$.ajax({
type: "POST",
url: saveKeyToServerURL,
data: { file: uploadID, key: key },
success: function (html) {
if (html.result) {
$('#key-link-' + fileID).html('<button type="button" class="btn btn-default btn-sm" id="remove-key-link-' + fileID + '">Remove Key From Server</button>');
$('#upload-link-' + fileID).html('<p><a href="' + html.result + '" id="full-url-link-' + fileID + '" target="_blank" class="alert-link">' + html.result + '</a></p>');
linkRemoveKey('#remove-key-link-' + fileID + '', uploadID, key, fileID);
$('#shortenUrl-button-' + fileID).prop('disabled', false);
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
}
function linkRemoveKey(selector, uploadID, key, fileID) {
$(selector).click(function () {
$.ajax({
type: "POST",
url: removeKeyFromServerURL,
data: { file: uploadID, key: key },
success: function (html) {
if (html.result) {
$('#key-link-' + fileID).html('<button type="button" class="btn btn-default btn-sm" id="save-key-link-' + fileID + '">Save Key To Server</button>');
$('#upload-link-' + fileID).html('<p><a href="' + html.result + '#' + key + '" id="full-url-link-' + fileID + '" target="_blank" class="alert-link">' + html.result + '#' + key + '</a></p>');
linkSaveKey('#save-key-link-' + fileID + '', uploadID, key, fileID);
$('#shortenUrl-button-' + fileID).prop('disabled', false);
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
}
function linkUploadDelete(selector, uploadID) {
$(selector).click(function () {
function linkUploadDelete(element, uploadID) {
element.click(function () {
$.ajax({
type: "POST",
url: generateDeleteKeyURL,
@ -76,17 +31,18 @@ function linkUploadDelete(selector, uploadID) {
});
}
function linkShortenUrl(selector, fileID, url) {
$(selector).click(function () {
var url = $('#full-url-link-' + fileID).html();
function linkShortenUrl(element, fileID, url) {
element.click(function () {
var url = $('#upload-panel-' + fileID).find('#upload-link').text();
$.ajax({
type: "POST",
url: shortenURL,
data: { url: url },
success: function (html) {
if (html.result) {
$(selector).prop('disabled', true);
$('#upload-link-' + fileID).html('<p><a href="' + html.result.shortUrl + '" id="full-url-link-' + fileID + '" target="_blank" class="alert-link">' + html.result.shortUrl + '</a></p>');
element.prop('disabled', true);
$('#upload-panel-' + fileID).find('#upload-link').attr('href', html.result.shortUrl);
$('#upload-panel-' + fileID).find('#upload-link').text(html.result.shortUrl);
}
else {
$("#top_msg").css('display', 'inline', 'important');
@ -98,20 +54,40 @@ function linkShortenUrl(selector, fileID, url) {
});
}
function linkRemove(selector, fileID) {
$(selector).click(function () {
$('#link-' + fileID).remove();
function linkRemove(element, fileID) {
element.click(function () {
$('#upload-panel-' + fileID).remove();
if ($('#upload-links').children().length == 0) {
$("#upload-links").css('display', 'none', 'important');
$('#copy-all-button').hide();
}
return false;
});
}
function linkCancel(selector, fileID) {
$(selector).click(function () {
$('#link-' + fileID).remove();
function linkCancel(element, fileID) {
element.click(function () {
$('#upload-panel-' + fileID).remove();
return false;
});
}
function linkCopyAll(element) {
element.click(function () {
var allUploads = [];
$("div[id^='upload-panel-']").each(function () {
var url = $(this).find('#upload-link').text();
if (url !== '') {
allUploads.push(url);
}
});
if (allUploads.length > 0) {
var urlList = allUploads.join();
copyTextToClipboard(urlList);
}
});
}
var fileCount = 0;
var dropZone = new Dropzone(document.body, {
@ -125,35 +101,27 @@ var dropZone = new Dropzone(document.body, {
// Create the UI element for the new item
var fileID = fileCount;
fileCount++;
$("#upload-links").css('display', 'inline', 'important');
$('#copy-all-button').show();
var itemDiv = $('#upload-template').clone();
itemDiv.attr('id', 'upload-panel-' + fileID);
// Hide Upload Details
itemDiv.find('#upload-link-panel').hide();
// Assign buttons
linkRemove(itemDiv.find('#upload-close'), fileID);
// Set the info
itemDiv.find('#upload-title').html(file.name);
// Add the upload panel to the list
$("#upload-links").prepend(itemDiv);
// save ID to the file object
file.ID = fileID;
$("#upload-links").css('display', 'inline', 'important');
$("#upload-links").prepend(' \
<div class="panel panel-default" id="link-' + fileID + '"> \
<div class="panel-heading text-center" id="link-header-' + fileID + '">'+ file.name + '</div> \
<div class="panel-body" id="link-panel-' + fileID + '"> \
<div class="row"> \
<div class="col-sm-12 text-center" id="upload-link-' + fileID + '"></div> \
</div> \
<div class="row"> \
<div class="col-sm-12 text-center"> \
<div class="progress" id="progress-' + fileID + '"> \
<div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 0%">0%</div> \
</div> \
</div> \
</div> \
</div> \
<div class="panel-footer" id="link-footer-' + fileID + '"> \
<div class="row"> \
<div class="col-sm-12 text-center"> \
<button type="button" class="btn btn-default btn-sm" id="remove-link-' + fileID + '">Cancel Upload</button> \
</div> \
</div> \
</div> \
</div> \
');
linkRemove('#remove-link-' + fileID + '', fileID);
// Check the file size
if (file.size <= maxUploadSize) {
@ -163,12 +131,7 @@ var dropZone = new Dropzone(document.body, {
else
{
// An error occured
$("#progress-" + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-striped');
$("#progress-" + fileID).children('.progress-bar').removeClass('active');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-danger');
$("#progress-" + fileID).children('.progress-bar').html('File Too Large');
setProgress(fileID, 100, 'progress-bar-danger', '', 'File Too Large');
}
this.removeFile(file);
}
@ -181,8 +144,7 @@ function encryptFile(file, callback) {
var fileExt = getFileExtension(file.name);
// Get session settings
var saveKey = $('#saveKey').is(':checked');
var serverSideEncrypt = $('#serverSideEncrypt').is(':checked');
var encrypt = $('#encrypt').is(':checked');
// Start the file reader
var reader = new FileReader();
@ -190,28 +152,39 @@ function encryptFile(file, callback) {
// When the file has been loaded, encrypt it
reader.onload = (function (callback) {
return function (e) {
// Create random key and iv (divide size by 8 for character length)
var keyStr = randomString((keySize / 8), '#aA');
var ivStr = randomString((blockSize / 8), '#aA');
// Encrypt on the server side if they ask for it
if (serverSideEncrypt) {
callback(e.target.result, keyStr, ivStr, filetype, fileExt, fileID, saveKey, serverSideEncrypt);
// Just send straight to server if they don't want to encrypt it
if (!encrypt) {
callback(e.target.result, null, null, filetype, fileExt, fileID, encrypt);
}
else {
// Set variables for tracking
var lastTime = (new Date()).getTime();
var lastData = 0;
// Create random key and iv (divide size by 8 for character length)
var keyStr = randomString((keySize / 8), '#aA');
var ivStr = randomString((blockSize / 8), '#aA');
var worker = new Worker(GenerateBlobURL(encScriptSrc));
worker.addEventListener('message', function (e) {
switch (e.data.cmd) {
case 'progress':
var percentComplete = Math.round(e.data.processed * 100 / e.data.total);
$("#progress-" + fileID).children('.progress-bar').css('width', (percentComplete * (2 / 5)) + 20 + '%');
$("#progress-" + fileID).children('.progress-bar').html(percentComplete + '% Encrypted');
var curTime = (new Date()).getTime();
var elapsedTime = (curTime - lastTime) / 1000;
if (elapsedTime >= 0.1) {
var speed = ((e.data.processed - lastData) / elapsedTime);
lastTime = curTime;
lastData = e.data.processed;
var percentComplete = Math.round(e.data.processed * 100 / e.data.total);
setProgress(fileID, percentComplete, 'progress-bar-success progress-bar-striped active', percentComplete + '%', 'Encrypting [' + getReadableBandwidthString(speed) + ']');
}
break;
case 'finish':
if (callback != null) {
// Finish
callback(e.data.buffer, keyStr, ivStr, filetype, fileExt, fileID, saveKey, serverSideEncrypt);
callback(e.data.buffer, keyStr, ivStr, filetype, fileExt, fileID, encrypt);
}
break;
}
@ -219,12 +192,8 @@ function encryptFile(file, callback) {
worker.onerror = function (err) {
// An error occured
$("#progress-" + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-striped');
$("#progress-" + fileID).children('.progress-bar').removeClass('active');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-danger');
$("#progress-" + fileID).children('.progress-bar').html('Error Occured');
setProgress(fileID, 100, 'progress-bar-danger', '', 'Error Occured');
$('#upload-panel-' + fileID).find('.panel').addClass('panel-danger');
}
// Generate the script to include as a blob
@ -248,8 +217,7 @@ function encryptFile(file, callback) {
reader.onprogress = function (data) {
if (data.lengthComputable) {
var progress = parseInt(((data.loaded / data.total) * 100), 10);
$('#progress-' + fileID).children('.progress-bar').css('width', (progress / 5) + '%');
$('#progress-' + fileID).children('.progress-bar').html(progress + '% Loaded');
setProgress(fileID, progress, 'progress-bar-success progress-bar-striped active', progress + '%', 'Loading');
}
}
@ -258,124 +226,117 @@ function encryptFile(file, callback) {
reader.readAsArrayBuffer(blob);
}
function uploadFile(data, key, iv, filetype, fileExt, fileID, saveKey, serverSideEncrypt)
function uploadFile(data, key, iv, filetype, fileExt, fileID, encrypt)
{
$('#key-' + fileID).val(key);
// Set variables for tracking
var lastTime = (new Date()).getTime();
var lastData = 0;
var blob = new Blob([data]);
// Now we need to upload the file
var fd = new FormData();
fd.append('fileType', filetype);
fd.append('fileExt', fileExt);
if (saveKey)
{
fd.append('key', key);
}
fd.append('iv', iv);
fd.append('keySize', keySize);
fd.append('blockSize', blockSize);
fd.append('data', blob);
fd.append('saveKey', saveKey);
fd.append('encrypt', serverSideEncrypt);
fd.append('encrypt', !encrypt);
fd.append('__RequestVerificationToken', $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val());
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress.bind(null, fileID), false);
xhr.addEventListener("load", uploadComplete.bind(null, fileID, key, saveKey, serverSideEncrypt), false);
xhr.upload.addEventListener("progress", uploadProgress.bind(null, fileID, lastTime, lastData), false);
xhr.addEventListener("load", uploadComplete.bind(null, fileID, key, encrypt), false);
xhr.addEventListener("error", uploadFailed.bind(null, fileID), false);
xhr.addEventListener("abort", uploadCanceled.bind(null, fileID), false);
xhr.open("POST", uploadFileURL);
xhr.send(fd);
}
function uploadProgress(fileID, evt) {
function uploadProgress(fileID, lastTime, lastData, evt) {
var serverSideEncrypt = $('#serverSideEncrypt').is(':checked');
if (evt.lengthComputable) {
var curTime = (new Date()).getTime();
var elapsedTime = (curTime - lastTime) / 1000;
var speed = ((evt.loaded - lastData) / elapsedTime);
lastTime = curTime;
lastData = evt.loaded;
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
if (serverSideEncrypt && percentComplete == 100) {
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$('#progress-' + fileID).children('.progress-bar').html('Encrypting');
if (percentComplete == 100) {
setProgress(fileID, 100, 'progress-bar-success progress-bar-striped active', '', 'Processing Upload');
}
else {
$('#progress-' + fileID).children('.progress-bar').css('width', (percentComplete * (2 / 5)) + 60 + '%');
$('#progress-' + fileID).children('.progress-bar').html(percentComplete + '% Uploaded');
setProgress(fileID, percentComplete, 'progress-bar-success progress-bar-striped active', percentComplete + '%', 'Uploading to Server [' + getReadableBandwidthString(speed) + ']');
}
}
}
function uploadComplete(fileID, key, saveKey, serverSideEncrypt, evt) {
function uploadComplete(fileID, key, encrypt, evt) {
obj = JSON.parse(evt.target.responseText);
if (obj.result != null) {
var name = obj.result.name;
var fullName = obj.result.url;
if (obj.result.key != null)
key = obj.result.key;
if (!saveKey) {
fullName = fullName + '#' + key;
var itemDiv = $('#upload-panel-' + fileID);
if (itemDiv) {
var name = obj.result.name;
var fullName = obj.result.url;
if (encrypt) {
fullName = fullName + '#' + key;
}
var contentType = obj.result.contentType;
var contentLength = obj.result.contentLength;
// Set progress bar
setProgress(fileID, 100, 'progress-bar-success', '', 'Complete');
// Set the panel to success
itemDiv.find('.panel').addClass('panel-success');
// Add the upload details
itemDiv.find('#upload-link').attr('href', fullName);
itemDiv.find('#upload-link').text(fullName);
itemDiv.find('#upload-contentType').html(contentType);
itemDiv.find('#upload-contentLength').html(contentLength);
// Setup the buttons
linkUploadDelete(itemDiv.find('#generate-delete-link'), name);
linkShortenUrl(itemDiv.find('#shortenUrl'), fileID, fullName);
// Hide the progress bar
itemDiv.find('#upload-progress-panel').hide();
// Show the details
itemDiv.find('#upload-link-panel').show();
}
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-striped');
$("#progress-" + fileID).children('.progress-bar').removeClass('active');
$('#progress-' + fileID).children('.progress-bar').html('Complete');
$('#upload-link-' + fileID).html('<p><a href="' + fullName + '" id="full-url-link-' + fileID + '" target="_blank" class="alert-link">' + fullName + '</a></p>');
var keyBtn = '<div class="col-sm-4 text-center" id="key-link-' + fileID + '"> \
<button type="button" class="btn btn-default btn-sm" id="save-key-link-' + fileID + '">Save Key On Server</button> \
</div>';
if (saveKey) {
keyBtn = '<div class="col-sm-4 text-center" id="key-link-' + fileID + '"> \
<button type="button" class="btn btn-default btn-sm" id="remove-key-link-' + fileID + '">Remove Key From Server</button> \
</div>';
}
$('#link-footer-' + fileID).html(' \
<div class="row"> \
' + keyBtn + ' \
<div class="col-sm-4 text-center"> \
<button type="button" class="btn btn-default btn-sm" id="generate-delete-link-' + fileID + '">Generate Deletion URL</button> \
</div> \
<div class="col-sm-4 text-center"> \
<button type="button" class="btn btn-default btn-sm" id="shortenUrl-button-' + fileID + '">Shorten Url</button> \
</div> \
</div> \
');
if (saveKey) {
linkRemoveKey('#remove-key-link-' + fileID + '', name, key, fileID);
}
else {
linkSaveKey('#save-key-link-' + fileID + '', name, key, fileID);
}
linkUploadDelete('#generate-delete-link-' + fileID + '', name);
linkShortenUrl('#shortenUrl-button-' + fileID + '', fileID, fullName);
}
else
{
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-striped');
$("#progress-" + fileID).children('.progress-bar').removeClass('active');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-danger');
$('#remove-link-' + fileID).text('Clear Upload');
var errorMessage = 'Unable to Upload File';
if (obj.error != null) {
$('#progress-' + fileID).children('.progress-bar').html(obj.error.message);
}
else {
$('#progress-' + fileID).children('.progress-bar').html('Unable to Upload File');
errorMessage = obj.error.message;
}
setProgress(fileID, 100, 'progress-bar-danger', '', errorMessage);
}
}
function uploadFailed(fileID, evt) {
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-striped');
$("#progress-" + fileID).children('.progress-bar').removeClass('active');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-danger');
$('#progress-' + fileID).children('.progress-bar').html('Upload Failed');
setProgress(fileID, 100, 'progress-bar-danger', '', 'Upload Failed');
$('#upload-panel-' + fileID).find('.panel').addClass('panel-danger');
}
function uploadCanceled(fileID, evt) {
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-striped');
$("#progress-" + fileID).children('.progress-bar').removeClass('active');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-warning');
$('#progress-' + fileID).children('.progress-bar').html('Upload Canceled');
setProgress(fileID, 100, 'progress-bar-warning', '', 'Upload Canceled');
$('#upload-panel-' + fileID).find('.panel').addClass('panel-warning');
}
function setProgress(fileID, percentage, classes, barMessage, title) {
var progress = $('#upload-panel-' + fileID);
if (progress !== null) {
progress.find('#progress-bar').css('width', percentage + '%');
progress.find('#progress-bar').removeClass();
progress.find('#progress-bar').addClass('progress-bar');
progress.find('#progress-bar').addClass(classes);
progress.find('#progress-bar').html(barMessage);
progress.find('#progress-info').html(title);
}
}

View File

@ -7,6 +7,7 @@ using Teknik.Configuration;
using Teknik.Models;
using Teknik.Utilities;
using System.Text;
using Org.BouncyCastle.Utilities.Encoders;
namespace Teknik.Areas.Upload
{
@ -14,24 +15,24 @@ namespace Teknik.Areas.Upload
{
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, string.Empty, null, null, false, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, string.Empty, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt, string defaultExtension)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, defaultExtension, null, null, false, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, defaultExtension, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt, string defaultExtension, string iv)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, defaultExtension, iv, null, false, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, defaultExtension, iv, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt, string defaultExtension, string iv, string key, bool saveKey)
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt, string defaultExtension, string iv, string key)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, defaultExtension, iv, key, saveKey, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, defaultExtension, iv, key, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt, string defaultExtension, string iv, string key, bool saveKey, int keySize, int blockSize)
public static Models.Upload SaveFile(TeknikEntities db, Config config, System.IO.Stream file, string contentType, int contentLength, bool encrypt, string defaultExtension, string iv, string key, int keySize, int blockSize)
{
if (!Directory.Exists(config.UploadConfig.UploadDirectory))
{
@ -45,15 +46,9 @@ namespace Teknik.Areas.Upload
// once we have the filename, lets save the file
if (encrypt)
{
// Generate key and iv if empty
if (string.IsNullOrEmpty(key))
{
key = StringHelper.RandomString(keySize / 8);
}
if (string.IsNullOrEmpty(iv))
{
iv = StringHelper.RandomString(blockSize / 8);
}
// Generate a key and iv
key = StringHelper.RandomString(config.UploadConfig.KeySize / 8);
iv = StringHelper.RandomString(config.UploadConfig.BlockSize / 8);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
@ -86,7 +81,7 @@ namespace Teknik.Areas.Upload
upload.FileName = fileName;
upload.ContentType = (!string.IsNullOrEmpty(contentType)) ? contentType : "application/octet-stream";
upload.ContentLength = contentLength;
upload.Key = (saveKey) ? key : null;
upload.Key = key;
upload.IV = iv;
upload.KeySize = keySize;
upload.BlockSize = blockSize;

View File

@ -10,8 +10,6 @@ namespace Teknik.Areas.Upload.ViewModels
{
public string CurrentSub { get; set; }
public bool SaveKey { get; set; }
public bool ServerSideEncrypt { get; set; }
public bool Encrypt { get; set; }
}
}

View File

@ -44,19 +44,17 @@
<div class="col-sm-2">
<div class="row">
<div class="col-sm-12">
<label for="saveKey">Save Key</label>
<input type="checkbox" name="saveKey" id="saveKey" @(Model.SaveKey ? "checked" : string.Empty) />
</div>
</div>
<div class="row">
<div class="col-sm-12">
<label for="serverSideEncrypt">Encrypt Server Side</label>
<input type="checkbox" name="serverSideEncrypt" id="serverSideEncrypt" @(Model.ServerSideEncrypt ? "checked" : string.Empty) />
<label for="encrypt">Encrypt in Browser</label>
<input type="checkbox" name="encrypt" id="encrypt" @(Model.Encrypt ? "checked" : string.Empty) />
</div>
</div>
</div>
</div>
<br />
<div class="row" id="copy-all-button" style="display: none">
<div class="col-sm-12">
<button type="button" class="btn btn-default btn-sm pull-right" id="copy-all"><i class="fa fa-clipboard"></i>&nbsp;Copy All Uploads</button>
</div>
</div>
<div class="container" id="upload-links">
</div>
<br />
@ -65,7 +63,7 @@
Each file is encrypted on upload using an AES-256-CTR cipher.
</p>
<p>
To view the file decrypted, you must use the direct Teknik link in a javascript enabled browser or save the key to the server.
To view the file decrypted, you must use the direct Teknik link in a javascript enabled browser.
</p>
<p>
The maximum file size per upload is <b>@StringHelper.GetBytesReadable(Model.Config.UploadConfig.MaxUploadSize)</b>
@ -76,4 +74,57 @@
</div>
</div>
@Scripts.Render("~/bundles/upload")
<div id="templates" style="display: none">
<div class="row" id="upload-template">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading text-center" id="upload-header">
<div class="row">
<div class="col-sm-10 col-sm-offset-1" id="upload-title"></div>
<div class="col-sm-1">
<button type="button" class="close pull-right" id="upload-close"><i class="fa fa-times-circle"></i></button>
</div>
</div>
</div>
<div class="panel-body" id="upload-details">
<div class="row" id="upload-link-panel">
<div class="col-sm-8">
<dl class="dl-horizontal">
<dt>Url</dt>
<dd><a href="#" id="upload-link" target="_blank" class="alert-link"></a></dd>
<dt>Content-Type</dt>
<dd id="upload-contentType"></dd>
<dt>File Size</dt>
<dd id="upload-contentLength"></dd>
</dl>
</div>
<div class="col-sm-4">
<div class="btn-group pull-right" role="group">
<button type="button" class="btn btn-default btn-sm" id="shortenUrl"><i class="fa fa-link"></i>&nbsp;Shorten</button>
<button type="button" class="btn btn-default btn-sm" id="generate-delete-link"><i class="fa fa-trash"></i>&nbsp;Deletion URL</button>
</div>
</div>
</div>
<div class="row" id="upload-progress-panel">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12 text-center">
<div class="progress" id="progress">
<div id="progress-bar" class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-sm-offset-1 text-center">
<span id="progress-info"></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@Scripts.Render("~/bundles/upload")

View File

@ -350,7 +350,7 @@ namespace Teknik.Areas.Users.Controllers
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(string curPass, string newPass, string newPassConfirm, string pgpPublicKey, string recoveryEmail, bool allowTrustedDevices, bool twoFactorEnabled, string website, string quote, string about, string blogTitle, string blogDesc, bool saveKey, bool serverSideEncrypt)
public ActionResult Edit(string curPass, string newPass, string newPassConfirm, string pgpPublicKey, string recoveryEmail, bool allowTrustedDevices, bool twoFactorEnabled, string website, string quote, string about, string blogTitle, string blogDesc, bool encrypt)
{
if (ModelState.IsValid)
{
@ -440,8 +440,7 @@ namespace Teknik.Areas.Users.Controllers
user.BlogSettings.Description = blogDesc;
// Uploads
user.UploadSettings.SaveKey = saveKey;
user.UploadSettings.ServerSideEncrypt = serverSideEncrypt;
user.UploadSettings.Encrypt = encrypt;
UserHelper.EditAccount(db, Config, user, changePass, newPass);

View File

@ -21,14 +21,11 @@ namespace Teknik.Areas.Users.Models
public virtual UserSettings UserSettings { get; set; }
public bool SaveKey { get; set; }
public bool ServerSideEncrypt { get; set; }
public bool Encrypt { get; set; }
public UploadSettings()
{
SaveKey = true;
ServerSideEncrypt = true;
Encrypt = false;
}
}
}

View File

@ -1,6 +1,5 @@
$(document).ready(function () {
$("[name='update_upload_saveKey']").bootstrapSwitch();
$("[name='update_upload_serverSideEncrypt']").bootstrapSwitch();
$("[name='update_upload_encrypt']").bootstrapSwitch();
$("[name='update_security_two_factor']").bootstrapSwitch();
$("[name='update_security_allow_trusted']").bootstrapSwitch();
@ -208,8 +207,7 @@
about = $("#update_about").val();
blog_title = $("#update_blog_title").val();
blog_desc = $("#update_blog_description").val();
upload_saveKey = $("#update_upload_saveKey").is(":checked");
upload_serverSideEncrypt = $("#update_upload_serverSideEncrypt").is(":checked");
upload_encrypt = $("#update_upload_encrypt").is(":checked");
$.ajax({
type: "POST",
url: editUserURL,
@ -226,8 +224,7 @@
about: about,
blogTitle: blog_title,
blogDesc: blog_desc,
saveKey: upload_saveKey,
serverSideEncrypt: upload_serverSideEncrypt
encrypt: upload_encrypt
}),
success: function (html) {
$.unblockUI();

View File

@ -219,16 +219,8 @@
<div class="col-sm-6">
<div class="checkbox">
<label>
<label for="update_upload_saveKey"><h4>Save Key on Server</h4></label>
<input id="update_upload_saveKey" name="update_upload_saveKey" title="whether the key should be saved on the server or not" type="checkbox" value="true" @(Model.UploadSettings.SaveKey ? "checked" : string.Empty) />
</label>
</div>
</div>
<div class="col-sm-6">
<div class="checkbox">
<label>
<label for="update_upload_serverSideEncrypt"><h4>Encrypt on Server Side</h4></label>
<input id="update_upload_serverSideEncrypt" name="update_upload_serverSideEncrypt" title="whether the file should be encrypted server side or client side" type="checkbox" value="true" @(Model.UploadSettings.ServerSideEncrypt ? "checked" : string.Empty) />
<label for="update_upload_encrypt"><h4>Encrypt in Browser</h4></label>
<input id="update_upload_encrypt" name="update_upload_encrypt" title="whether the file should be encrypted in the browser before upload" type="checkbox" value="true" @(Model.UploadSettings.Encrypt ? "checked" : string.Empty) />
</label>
</div>
</div>

View File

@ -195,6 +195,27 @@ AddAntiForgeryToken = function (data) {
return data;
};
function copyTextToClipboard(text) {
var copyFrom = document.createElement("textarea");
copyFrom.textContent = text;
var body = document.getElementsByTagName('body')[0];
body.appendChild(copyFrom);
copyFrom.select();
document.execCommand('copy');
body.removeChild(copyFrom);
}
function getReadableBandwidthString(bandwidth) {
var i = -1;
var byteUnits = [' Kbps', ' Mbps', ' Gbps', ' Tbps', 'Pbps', 'Ebps', 'Zbps', 'Ybps'];
do {
bandwidth = bandwidth / 1024;
i++;
} while (bandwidth > 1024);
return Math.max(bandwidth, 0.1).toFixed(1) + byteUnits[i];
}
/***************************** TIMER Page Load *******************************/
var loopTime;
var startTime = new Date();

View File

@ -334,6 +334,7 @@
<Content Include="Areas\Podcast\Content\Podcast.css" />
<Content Include="Areas\Podcast\Scripts\Podcast.js" />
<Content Include="Areas\Transparency\Scripts\Transparency.js" />
<Content Include="Areas\Upload\Content\Upload.css" />
<Content Include="Areas\User\Scripts\CheckAuthCode.js" />
<Content Include="Areas\User\Scripts\User.js" />
<Content Include="Areas\Shortener\Scripts\Shortener.js" />

View File

@ -96,13 +96,23 @@ namespace Teknik.Utilities
public static string Hash(string value)
{
byte[] valueBytes = Encoding.Unicode.GetBytes(value);
HashAlgorithm hash = new SHA256CryptoServiceProvider();
return Hash(valueBytes);
}
byte[] hashBytes = hash.ComputeHash(valueBytes);
public static string Hash(byte[] value)
{
HashAlgorithm hash = new SHA256CryptoServiceProvider();
byte[] hashBytes = hash.ComputeHash(value);
return Convert.ToBase64String(hashBytes);
}
public static byte[] Hash(Stream value)
{
HashAlgorithm hash = new SHA256CryptoServiceProvider();
return hash.ComputeHash(value);
}
public static string Hash(string value, string salt1, string salt2)
{
SHA256Managed hash = new SHA256Managed();