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:
parent
679c148029
commit
a509291022
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
1
Teknik/Areas/Upload/Content/Upload.css
Normal file
1
Teknik/Areas/Upload/Content/Upload.css
Normal file
@ -0,0 +1 @@
|
||||
|
@ -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" } });
|
||||
}
|
||||
|
@ -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">×</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">×</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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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> 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> Shorten</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="generate-delete-link"><i class="fa fa-trash"></i> 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")
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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" />
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user