mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Added max upload storage limits for user accounts
This commit is contained in:
parent
4207a2811f
commit
8954102306
@ -15,6 +15,10 @@ namespace Teknik.Configuration
|
||||
public long MaxUploadSizePremium { get; set; }
|
||||
// Gets the maximum download size before they are forced to the download page
|
||||
public long MaxDownloadSize { get; set; }
|
||||
// Maximum total size for basic users
|
||||
public long MaxTotalSizeBasic { get; set; }
|
||||
// Maximum total size for basic users
|
||||
public long MaxTotalSizePremium { get; set; }
|
||||
// Location of the upload directory
|
||||
public string UploadDirectory { get; set; }
|
||||
// File Extension for saved files
|
||||
@ -47,6 +51,8 @@ namespace Teknik.Configuration
|
||||
MaxUploadSizeBasic = 100000000;
|
||||
MaxUploadSizePremium = 100000000;
|
||||
MaxDownloadSize = 100000000;
|
||||
MaxTotalSizeBasic = 1000000000;
|
||||
MaxTotalSizePremium = 5000000000;
|
||||
UploadDirectory = Directory.GetCurrentDirectory();
|
||||
FileExtension = "enc";
|
||||
UrlLength = 5;
|
||||
|
@ -43,10 +43,22 @@ namespace Teknik.Areas.API.V1.Controllers
|
||||
if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
maxUploadSize = _config.UploadConfig.MaxUploadSizeBasic;
|
||||
long maxTotalSize = _config.UploadConfig.MaxTotalSizeBasic;
|
||||
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
|
||||
if (userInfo.AccountType == AccountType.Premium)
|
||||
{
|
||||
maxUploadSize = _config.UploadConfig.MaxUploadSizePremium;
|
||||
maxTotalSize = _config.UploadConfig.MaxTotalSizePremium;
|
||||
}
|
||||
|
||||
// Check account total limits
|
||||
var user = UserHelper.GetUser(_dbContext, User.Identity.Name);
|
||||
if (user.UploadSettings.MaxUploadStorage != null)
|
||||
maxTotalSize = user.UploadSettings.MaxUploadStorage.Value;
|
||||
var userUploadSize = user.Uploads.Sum(u => u.ContentLength);
|
||||
if (userUploadSize + model.file.Length > maxTotalSize)
|
||||
{
|
||||
return Json(new { error = new { message = string.Format("Account storage limit exceeded: {0} / {1}", StringHelper.GetBytesReadable(userUploadSize + model.file.Length), StringHelper.GetBytesReadable(maxTotalSize)) } });
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -176,7 +188,7 @@ namespace Teknik.Areas.API.V1.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(new { error = new { message = "File Too Large" } });
|
||||
return Json(new { error = new { message = "File Too Large. Max file size is " + StringHelper.GetBytesReadable(maxUploadSize) } });
|
||||
}
|
||||
}
|
||||
return Json(new { error = new { message = "Invalid Upload Request" } });
|
||||
|
@ -109,6 +109,12 @@
|
||||
<td class="text-center">@StringHelper.GetBytesReadable(Config.UploadConfig.MaxDownloadSize)</td>
|
||||
<td class="text-center">@StringHelper.GetBytesReadable(Config.UploadConfig.MaxDownloadSize)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-left">Upload Storage</td>
|
||||
<td class="text-center">@StringHelper.GetBytesReadable(Config.UploadConfig.MaxTotalSizePremium)</td>
|
||||
<td class="text-center">@StringHelper.GetBytesReadable(Config.UploadConfig.MaxTotalSizeBasic)</td>
|
||||
<td class="text-center">No Limit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-left">Upload Expiration</td>
|
||||
<td class="text-center">Never</td>
|
||||
|
@ -10,12 +10,15 @@
|
||||
<h3>User Accounts</h3>
|
||||
<ul>
|
||||
<li>You will not display or host links to Malware in your user profile</li>
|
||||
<li>Inactive Basic Accounts with no data will be deleted after 365 days (1 Year)
|
||||
<li>
|
||||
Inactive Basic Accounts with no data may be deleted after 365 days (1 Year)
|
||||
<ul>
|
||||
<li>Activity is defined as logging into the Teknik Website, into the Git website, into the mail service (Either through webmail or via another client), or Modifying/Adding a Git Repository</li>
|
||||
<li>Data is defined as Blog Posts/Comments, Podcast Comments, Emails, and Git Repositories</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Creating multiple accounts to get around account limits will result in the account(s) being banned without notice</li>
|
||||
<li>If your account has been banned, and you create a new account to get around said ban, the new account will be banned without notice</li>
|
||||
</ul>
|
||||
<h3>Premium Accounts</h3>
|
||||
<ul>
|
||||
@ -34,23 +37,18 @@
|
||||
</ul>
|
||||
<h3>Email</h3>
|
||||
<ul>
|
||||
<li>Email is limited to a maximum of 100 outbound email messages per day. This is to prevent spam accounts. If your account is flagged as spamming, it will be deleted without notice.</li>
|
||||
<li>Premium Accounts are allowed unlimited outbound email messages, but need to follow the same policy of no spam.</li>
|
||||
<li>Email is limited to a maximum of 100 outbound email messages per day. This is to prevent spam accounts. If your account is flagged as spamming, it will be banned without notice</li>
|
||||
<li>Premium Accounts are allowed unlimited outbound email messages, but need to follow the same policy of no spam</li>
|
||||
</ul>
|
||||
<h3>Uploads</h3>
|
||||
<h3>
|
||||
Services<br />
|
||||
<small>This includes but does not limit to: Uploads, Pastes, Vaults, Blogging, and Shortened URLs</small>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>This site may contain material your region may consider illegal. If you are viewing content, be mindful of the laws in your region</li>
|
||||
<li>Any Malware uploads will be removed without notice</li>
|
||||
<li>Any content containing or linking to malware/phishing sites will be removed without notice</li>
|
||||
<li>Copyrighted or Personal content will only be removed if it is deemed necessary for a person(s) safety</li>
|
||||
</ul>
|
||||
<h3>Pastebin</h3>
|
||||
<ul>
|
||||
<li>Copyrighted or Personal content will only be removed if it is demed necessary for a person(s) safety</li>
|
||||
</ul>
|
||||
<h3>Shortened URLs</h3>
|
||||
<ul>
|
||||
<li>No linking to Phishing Sites or Malware</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -65,7 +63,7 @@
|
||||
gitFullUrl = gitUrl.ToString();
|
||||
}
|
||||
}
|
||||
<p><i>Last Modified July 11, 2017 - <a href="@gitFullUrl">View History</a></i></p>
|
||||
<p><i>Last Modified January 20, 2020 - <a href="@gitFullUrl">View History</a></i></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -53,11 +53,23 @@ namespace Teknik.Areas.Upload.Controllers
|
||||
model.ExpirationUnit = user.UploadSettings.ExpirationUnit;
|
||||
model.Vaults = user.Vaults.ToList();
|
||||
|
||||
model.CurrentTotalSize = user.Uploads.Sum(u => u.ContentLength);
|
||||
|
||||
model.MaxUploadSize = _config.UploadConfig.MaxUploadSizeBasic;
|
||||
model.MaxTotalSize = _config.UploadConfig.MaxTotalSizeBasic;
|
||||
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
|
||||
if (userInfo.AccountType == AccountType.Premium)
|
||||
{
|
||||
model.MaxUploadSize = _config.UploadConfig.MaxUploadSizePremium;
|
||||
model.MaxTotalSize = _config.UploadConfig.MaxTotalSizePremium;
|
||||
}
|
||||
if (user.UploadSettings.MaxUploadStorage != null)
|
||||
model.MaxTotalSize = user.UploadSettings.MaxUploadStorage.Value;
|
||||
|
||||
if (model.CurrentTotalSize >= model.MaxTotalSize)
|
||||
{
|
||||
model.Error = true;
|
||||
model.ErrorMessage = string.Format("Account storage limit exceeded: {0} / {1}", StringHelper.GetBytesReadable(model.CurrentTotalSize), StringHelper.GetBytesReadable(model.MaxTotalSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,10 +89,22 @@ namespace Teknik.Areas.Upload.Controllers
|
||||
if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
maxUploadSize = _config.UploadConfig.MaxUploadSizeBasic;
|
||||
long maxTotalSize = _config.UploadConfig.MaxTotalSizeBasic;
|
||||
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
|
||||
if (userInfo.AccountType == AccountType.Premium)
|
||||
{
|
||||
maxUploadSize = _config.UploadConfig.MaxUploadSizePremium;
|
||||
maxTotalSize = _config.UploadConfig.MaxTotalSizePremium;
|
||||
}
|
||||
|
||||
// Check account total limits
|
||||
var user = UserHelper.GetUser(_dbContext, User.Identity.Name);
|
||||
if (user.UploadSettings.MaxUploadStorage != null)
|
||||
maxTotalSize = user.UploadSettings.MaxUploadStorage.Value;
|
||||
var userUploadSize = user.Uploads.Sum(u => u.ContentLength);
|
||||
if (userUploadSize + uploadFile.file.Length > maxTotalSize)
|
||||
{
|
||||
return Json(new { error = new { message = string.Format("Account storage limit exceeded. {0} / {1}", StringHelper.GetBytesReadable(userUploadSize + uploadFile.file.Length), StringHelper.GetBytesReadable(maxTotalSize)) } });
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -158,6 +182,7 @@ namespace Teknik.Areas.Upload.Controllers
|
||||
url = Url.SubRouteUrl("u", "Upload.Download", new { file = upload.Url }),
|
||||
contentType = upload.ContentType,
|
||||
contentLength = StringHelper.GetBytesReadable(upload.ContentLength),
|
||||
contentLengthRaw = upload.ContentLength,
|
||||
deleteUrl = Url.SubRouteUrl("u", "Upload.DeleteByKey", new { file = upload.Url, key = upload.DeleteKey }),
|
||||
expirationUnit = uploadFile.options.ExpirationUnit.ToString(),
|
||||
expirationLength = uploadFile.options.ExpirationLength
|
||||
@ -168,7 +193,7 @@ namespace Teknik.Areas.Upload.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(new { error = new { message = "File Too Large" } });
|
||||
return Json(new { error = new { message = "File Too Large. Max file size is " + StringHelper.GetBytesReadable(maxUploadSize) } });
|
||||
}
|
||||
}
|
||||
return Json(new { error = new { message = "Uploads are disabled" } });
|
||||
|
@ -21,6 +21,10 @@ namespace Teknik.Areas.Upload.ViewModels
|
||||
|
||||
public long MaxUploadSize { get; set; }
|
||||
|
||||
public long MaxTotalSize { get; set; }
|
||||
|
||||
public long CurrentTotalSize { get; set; }
|
||||
|
||||
public UploadViewModel()
|
||||
{
|
||||
CurrentSub = string.Empty;
|
||||
@ -29,6 +33,8 @@ namespace Teknik.Areas.Upload.ViewModels
|
||||
ExpirationUnit = ExpirationUnit.Never;
|
||||
Vaults = new List<Vault.Models.Vault>();
|
||||
MaxUploadSize = 0;
|
||||
MaxTotalSize = -1;
|
||||
CurrentTotalSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
var aesScriptSrc = '@Url.FullURL("~/js/crypto.min.js")';
|
||||
var uploadFileURL = '@Url.SubRouteUrl(Model.CurrentSub, "Upload.Action", new { action = "Upload" })';
|
||||
var maxUploadSize = @Model.MaxUploadSize;
|
||||
var maxTotalSize = @Model.MaxTotalSize;
|
||||
var curTotalSize = @Model.CurrentTotalSize;
|
||||
var chunkSize = @Config.UploadConfig.ChunkSize;
|
||||
var keySize = @Config.UploadConfig.KeySize;
|
||||
var blockSize = @Config.UploadConfig.BlockSize;
|
||||
@ -16,157 +18,186 @@
|
||||
|
||||
<bundle src="css/upload.min.css" append-version="true" />
|
||||
|
||||
<div class="container">
|
||||
<div class="row text-center">
|
||||
<div class="col-sm-10 col-sm-offset-1">
|
||||
<div class="row text-center">
|
||||
<div class="text-center upload__drop-container" id="uploadButton" style="cursor: pointer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h3 class="upload__drop-text"><span class="fa fa-cloud-upload fa-5x"></span></h3>
|
||||
@if (!Model.Error)
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row text-center">
|
||||
<div class="col-sm-10 col-sm-offset-1">
|
||||
<div class="row text-center">
|
||||
<div class="text-center upload__drop-container" id="uploadButton" style="cursor: pointer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h3 class="upload__drop-text"><span class="fa fa-cloud-upload fa-5x"></span></h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h2 class="upload__drop-text">DRAG & DROP</h2>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h2 class="upload__drop-text">DRAG & DROP</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<span class="upload__drop-text">Or select files from your system</span>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<span class="upload__drop-text">Or select files from your system</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<small class="upload__drop-text text-muted">(Individual file size limit @StringHelper.GetBytesReadable(Model.MaxUploadSize))</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-1 hidden-xs upload__help-icon">
|
||||
<a href="@Url.SubRouteUrl("help", "Help.Upload")" target="_blank"><i class="fa fa-question-circle-o"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-horizontal">
|
||||
<div class="col-sm-5 col-sm-offset-1">
|
||||
<div class="form-group form-group-sm" data-toggle="tooltip" data-placement="top" title="When enabled, each file is encrypted before upload using an AES-256-CTR cipher. A key is generated and required to download the file later.">
|
||||
<label for="encrypt" class="col-sm-6 col-xs-3 control-label">Encrypt in Browser</label>
|
||||
<div class="col-sm-6 col-xs-9">
|
||||
<input type="checkbox" class="center-block" name="encrypt" id="encrypt" @(Model.Encrypt ? "checked" : string.Empty) />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-group form-group-sm">
|
||||
@if (!User.Identity.IsAuthenticated)
|
||||
{
|
||||
@:<label class="col-xs-3 control-label" data-toggle="tooltip" data-placement="top" title="Uploads expire after 1 day for unregistered users">Expiration*</label>
|
||||
}
|
||||
else
|
||||
{
|
||||
@:<label class="col-xs-3 control-label">Expiration</label>
|
||||
}
|
||||
<fieldset @if (!User.Identity.IsAuthenticated) { @: disabled
|
||||
}>
|
||||
<div class="col-xs-4 hidden" id="length-div">
|
||||
<input type="number" min="1" step="1" class="form-control" name="expirelength" id="expirelength" value="@Model.ExpirationLength">
|
||||
</div>
|
||||
<div class="col-xs-9" id="unit-div">
|
||||
<select class="form-control" name="expireunit" id="expireunit">
|
||||
@foreach (ExpirationUnit unit in Enum.GetValues(typeof(ExpirationUnit)))
|
||||
{
|
||||
<!option value="@unit" @(Model.ExpirationUnit == unit ? "selected" : string.Empty)>@unit.ToString()</!option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row upload__action-buttons" id="upload-action-buttons" style="display: none">
|
||||
<div class="col-sm-12">
|
||||
<div class="btn-group pull-right" role="group">
|
||||
<button type="button" class="btn btn-default btn-sm" id="copy-all" data-toggle="popover" data-trigger="manual" data-placement="top" data-content="Copied to Clipboard" data-container="body"><i class="fa fa-clipboard"></i> Copy All Links</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="create-vault"><i class="fa fa-folder"></i> Create Vault</button>
|
||||
@if (User.Identity.IsAuthenticated && Model.Vaults != null && Model.Vaults.Any())
|
||||
{
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus"></i> Add to Vault <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu" id="add-to-vault-menu">
|
||||
@foreach (Vault item in Model.Vaults)
|
||||
{
|
||||
<li><a href="#" class="add-to-vault" data-add-to-vault-url="@Url.SubRouteUrl("vault", "Vault.EditVault", new { url = item.Url, type = "Upload" })">@item.Title</a></li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container" id="upload-links">
|
||||
</div>
|
||||
<br />
|
||||
<div class="text-center">
|
||||
Useful Tools: <a href="@Url.SubRouteUrl("help", "Help.Tools")">Upload Scripts and Utilities</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<input type="hidden" id="upload-url" />
|
||||
<div class="col-sm-8">
|
||||
<dl class="dl-horizontal" style="margin-bottom: 0;">
|
||||
<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>
|
||||
<dt>Expiration</dt>
|
||||
<dd id="upload-expiration"></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="delete-link"><i class="fa fa-trash"></i> Deletion Link</button>
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<small class="upload__drop-text text-muted">(Individual file size limit @StringHelper.GetBytesReadable(Model.MaxUploadSize))</small>
|
||||
</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 class="col-sm-1 hidden-xs upload__help-icon">
|
||||
<a href="@Url.SubRouteUrl("help", "Help.Upload")" target="_blank"><i class="fa fa-question-circle-o"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-horizontal">
|
||||
<div class="col-sm-5 col-sm-offset-1">
|
||||
<div class="form-group form-group-sm" data-toggle="tooltip" data-placement="top" title="When enabled, each file is encrypted before upload using an AES-256-CTR cipher. A key is generated and required to download the file later.">
|
||||
<label for="encrypt" class="col-sm-6 col-xs-3 control-label">Encrypt in Browser</label>
|
||||
<div class="col-sm-6 col-xs-9">
|
||||
<input type="checkbox" class="center-block" name="encrypt" id="encrypt" @(Model.Encrypt ? "checked" : string.Empty) />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-group form-group-sm">
|
||||
@if (!User.Identity.IsAuthenticated)
|
||||
{
|
||||
@:<label class="col-xs-3 control-label" data-toggle="tooltip" data-placement="top" title="Uploads expire after 1 day for unregistered users">Expiration*</label>
|
||||
}
|
||||
else
|
||||
{
|
||||
@:<label class="col-xs-3 control-label">Expiration</label>
|
||||
}
|
||||
<fieldset @if (!User.Identity.IsAuthenticated) { @: disabled
|
||||
}>
|
||||
<div class="col-xs-4 hidden" id="length-div">
|
||||
<input type="number" min="1" step="1" class="form-control" name="expirelength" id="expirelength" value="@Model.ExpirationLength">
|
||||
</div>
|
||||
<div class="col-xs-9" id="unit-div">
|
||||
<select class="form-control" name="expireunit" id="expireunit">
|
||||
@foreach (ExpirationUnit unit in Enum.GetValues(typeof(ExpirationUnit)))
|
||||
{
|
||||
<!option value="@unit" @(Model.ExpirationUnit == unit ? "selected" : string.Empty)>@unit.ToString()</!option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row upload__action-buttons" id="upload-action-buttons" style="display: none">
|
||||
<div class="col-sm-12">
|
||||
<div class="btn-group pull-right" role="group">
|
||||
<button type="button" class="btn btn-default btn-sm" id="copy-all" data-toggle="popover" data-trigger="manual" data-placement="top" data-content="Copied to Clipboard" data-container="body"><i class="fa fa-clipboard"></i> Copy All Links</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="create-vault"><i class="fa fa-folder"></i> Create Vault</button>
|
||||
@if (User.Identity.IsAuthenticated && Model.Vaults != null && Model.Vaults.Any())
|
||||
{
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus"></i> Add to Vault <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu" id="add-to-vault-menu">
|
||||
@foreach (Vault item in Model.Vaults)
|
||||
{
|
||||
<li><a href="#" class="add-to-vault" data-add-to-vault-url="@Url.SubRouteUrl("vault", "Vault.EditVault", new { url = item.Url, type = "Upload" })">@item.Title</a></li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container" id="upload-links">
|
||||
</div>
|
||||
<br />
|
||||
<div class="text-center">
|
||||
Useful Tools: <a href="@Url.SubRouteUrl("help", "Help.Tools")">Upload Scripts and Utilities</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<input type="hidden" id="upload-url" />
|
||||
<div class="col-sm-8">
|
||||
<dl class="dl-horizontal" style="margin-bottom: 0;">
|
||||
<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>
|
||||
<dt>Expiration</dt>
|
||||
<dd id="upload-expiration"></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="delete-link"><i class="fa fa-trash"></i> Deletion Link</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 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>
|
||||
|
||||
<bundle src="js/upload.min.js" append-version="true" />
|
||||
<bundle src="js/upload.min.js" append-version="true" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row text-center">
|
||||
<div class="col-sm-10 col-sm-offset-1">
|
||||
<div class="row text-center">
|
||||
<div class="text-center upload__drop-container-error" id="uploadButton" style="cursor: not-allowed">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h3 class="upload__drop-text"><span class="fa fa-cloud-upload fa-5x"></span></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h2 class="upload__drop-text">@Model.ErrorMessage</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-1 hidden-xs upload__help-icon">
|
||||
<a href="@Url.SubRouteUrl("help", "Help.Upload")" target="_blank"><i class="fa fa-question-circle-o"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -20,11 +20,15 @@ namespace Teknik.Areas.Users.Models
|
||||
[Column("ExpirationUnit")]
|
||||
public ExpirationUnit ExpirationUnit { get; set; }
|
||||
|
||||
[Column("MaxUploadStorage")]
|
||||
public long? MaxUploadStorage { get; set; }
|
||||
|
||||
public UploadSettings()
|
||||
{
|
||||
Encrypt = false;
|
||||
ExpirationLength = 1;
|
||||
ExpirationUnit = ExpirationUnit.Never;
|
||||
MaxUploadStorage = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,11 @@
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="uploads">
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col col-sm-12"><p>Total Upload Size: @StringHelper.GetBytesReadable(Model.Uploads.Sum(u => u.ContentLength))</p></div>
|
||||
</div>
|
||||
<br />
|
||||
@foreach (Teknik.Areas.Upload.Models.Upload upload in Model.Uploads)
|
||||
{
|
||||
<div class="panel panel-default" id="@upload.Url">
|
||||
|
@ -19,6 +19,19 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.upload__drop-container-error {
|
||||
border: 2px dashed #dc3545;
|
||||
background-color: #f5f5f5;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.upload__drop-container .upload__drop-text {
|
||||
opacity: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.upload__help-icon {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
772
Teknik/Data/Migrations/20200121080120_MaxUploadStorage.Designer.cs
generated
Normal file
772
Teknik/Data/Migrations/20200121080120_MaxUploadStorage.Designer.cs
generated
Normal file
@ -0,0 +1,772 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Teknik.Data;
|
||||
|
||||
namespace Teknik.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(TeknikEntities))]
|
||||
[Migration("20200121080120_MaxUploadStorage")]
|
||||
partial class MaxUploadStorage
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.Blog", b =>
|
||||
{
|
||||
b.Property<int>("BlogId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("UserId");
|
||||
|
||||
b.HasKey("BlogId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Blogs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPost", b =>
|
||||
{
|
||||
b.Property<int>("BlogPostId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("Article");
|
||||
|
||||
b.Property<int>("BlogId");
|
||||
|
||||
b.Property<DateTime>("DateEdited");
|
||||
|
||||
b.Property<DateTime>("DatePosted");
|
||||
|
||||
b.Property<DateTime>("DatePublished");
|
||||
|
||||
b.Property<bool>("Published");
|
||||
|
||||
b.Property<bool>("System");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("BlogPostId");
|
||||
|
||||
b.HasIndex("BlogId");
|
||||
|
||||
b.ToTable("BlogPosts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostComment", b =>
|
||||
{
|
||||
b.Property<int>("BlogPostCommentId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("Article");
|
||||
|
||||
b.Property<int>("BlogPostId");
|
||||
|
||||
b.Property<DateTime>("DateEdited");
|
||||
|
||||
b.Property<DateTime>("DatePosted");
|
||||
|
||||
b.Property<int?>("UserId");
|
||||
|
||||
b.HasKey("BlogPostCommentId");
|
||||
|
||||
b.HasIndex("BlogPostId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("BlogPostComments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostTag", b =>
|
||||
{
|
||||
b.Property<int>("BlogPostTagId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("BlogPostId");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("BlogPostTagId");
|
||||
|
||||
b.HasIndex("BlogPostId");
|
||||
|
||||
b.ToTable("BlogPostTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Contact.Models.Contact", b =>
|
||||
{
|
||||
b.Property<int>("ContactId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("DateAdded");
|
||||
|
||||
b.Property<string>("Email");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("Subject");
|
||||
|
||||
b.HasKey("ContactId");
|
||||
|
||||
b.ToTable("Contact");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Paste.Models.Paste", b =>
|
||||
{
|
||||
b.Property<int>("PasteId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("BlockSize");
|
||||
|
||||
b.Property<string>("Content");
|
||||
|
||||
b.Property<DateTime>("DateEdited");
|
||||
|
||||
b.Property<DateTime>("DatePosted");
|
||||
|
||||
b.Property<string>("DeleteKey")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<DateTime?>("ExpireDate");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<string>("HashedPassword")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<string>("IV")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<string>("Key")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int>("KeySize");
|
||||
|
||||
b.Property<int>("MaxViews");
|
||||
|
||||
b.Property<string>("Syntax");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int?>("UserId");
|
||||
|
||||
b.Property<int>("Views");
|
||||
|
||||
b.HasKey("PasteId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Pastes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.Podcast", b =>
|
||||
{
|
||||
b.Property<int>("PodcastId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("DateEdited");
|
||||
|
||||
b.Property<DateTime>("DatePosted");
|
||||
|
||||
b.Property<DateTime>("DatePublished");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<int>("Episode");
|
||||
|
||||
b.Property<bool>("Published");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("PodcastId");
|
||||
|
||||
b.ToTable("Podcasts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastComment", b =>
|
||||
{
|
||||
b.Property<int>("PodcastCommentId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("Article");
|
||||
|
||||
b.Property<DateTime>("DateEdited");
|
||||
|
||||
b.Property<DateTime>("DatePosted");
|
||||
|
||||
b.Property<int>("PodcastId");
|
||||
|
||||
b.Property<int>("UserId");
|
||||
|
||||
b.HasKey("PodcastCommentId");
|
||||
|
||||
b.HasIndex("PodcastId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PodcastComments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastFile", b =>
|
||||
{
|
||||
b.Property<int>("PodcastFileId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<long>("ContentLength");
|
||||
|
||||
b.Property<string>("ContentType");
|
||||
|
||||
b.Property<string>("FileName");
|
||||
|
||||
b.Property<string>("Path");
|
||||
|
||||
b.Property<int>("PodcastId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.HasKey("PodcastFileId");
|
||||
|
||||
b.HasIndex("PodcastId");
|
||||
|
||||
b.ToTable("PodcastFiles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastTag", b =>
|
||||
{
|
||||
b.Property<int>("PodcastTagId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<int>("PodcastId");
|
||||
|
||||
b.HasKey("PodcastTagId");
|
||||
|
||||
b.HasIndex("PodcastId");
|
||||
|
||||
b.ToTable("PodcastTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Shortener.Models.ShortenedUrl", b =>
|
||||
{
|
||||
b.Property<int>("ShortenedUrlId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("DateAdded");
|
||||
|
||||
b.Property<string>("OriginalUrl");
|
||||
|
||||
b.Property<string>("ShortUrl")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int?>("UserId");
|
||||
|
||||
b.Property<int>("Views");
|
||||
|
||||
b.HasKey("ShortenedUrlId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ShortenedUrls");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Stats.Models.Takedown", b =>
|
||||
{
|
||||
b.Property<int>("TakedownId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ActionTaken");
|
||||
|
||||
b.Property<DateTime>("DateActionTaken");
|
||||
|
||||
b.Property<DateTime>("DateRequested");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<string>("Requester");
|
||||
|
||||
b.Property<string>("RequesterContact");
|
||||
|
||||
b.HasKey("TakedownId");
|
||||
|
||||
b.ToTable("Takedowns");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Stats.Models.Transaction", b =>
|
||||
{
|
||||
b.Property<int>("TransactionId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("decimal(19, 5)");
|
||||
|
||||
b.Property<int>("Currency");
|
||||
|
||||
b.Property<DateTime>("DateSent");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.HasKey("TransactionId");
|
||||
|
||||
b.ToTable("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Upload.Models.Upload", b =>
|
||||
{
|
||||
b.Property<int>("UploadId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("BlockSize");
|
||||
|
||||
b.Property<long>("ContentLength");
|
||||
|
||||
b.Property<string>("ContentType");
|
||||
|
||||
b.Property<DateTime>("DateUploaded");
|
||||
|
||||
b.Property<string>("DeleteKey")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int>("Downloads");
|
||||
|
||||
b.Property<DateTime?>("ExpireDate");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<string>("IV")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<string>("Key")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int>("KeySize");
|
||||
|
||||
b.Property<int>("MaxDownloads");
|
||||
|
||||
b.Property<int?>("Takedown_TakedownId");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int?>("UserId");
|
||||
|
||||
b.HasKey("UploadId");
|
||||
|
||||
b.HasIndex("Takedown_TakedownId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Uploads");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.Feature", b =>
|
||||
{
|
||||
b.Property<string>("FeatureId")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<bool>("Enabled");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("FeatureId");
|
||||
|
||||
b.ToTable("Features");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
|
||||
{
|
||||
b.Property<int>("InviteCodeId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<int?>("ClaimedUserId");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
b.Property<int?>("OwnerId");
|
||||
|
||||
b.HasKey("InviteCodeId");
|
||||
|
||||
b.HasIndex("ClaimedUserId")
|
||||
.IsUnique()
|
||||
.HasFilter("[ClaimedUserId] IS NOT NULL");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("InviteCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.UserFeature", b =>
|
||||
{
|
||||
b.Property<int>("UserFeatureId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("FeatureId");
|
||||
|
||||
b.Property<int>("UserId");
|
||||
|
||||
b.HasKey("UserFeatureId");
|
||||
|
||||
b.HasIndex("FeatureId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserFeatures");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
|
||||
{
|
||||
b.Property<int>("VaultId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("DateCreated");
|
||||
|
||||
b.Property<DateTime>("DateEdited");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Url");
|
||||
|
||||
b.Property<int?>("UserId");
|
||||
|
||||
b.Property<int>("Views");
|
||||
|
||||
b.HasKey("VaultId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Vaults");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.VaultItem", b =>
|
||||
{
|
||||
b.Property<int>("VaultItemId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("DateAdded");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("Index");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<int>("VaultId");
|
||||
|
||||
b.HasKey("VaultItemId");
|
||||
|
||||
b.HasIndex("VaultId");
|
||||
|
||||
b.ToTable("VaultItems");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("VaultItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.PasteVaultItem", b =>
|
||||
{
|
||||
b.HasBaseType("Teknik.Areas.Vault.Models.VaultItem");
|
||||
|
||||
b.Property<int>("PasteId");
|
||||
|
||||
b.HasIndex("PasteId");
|
||||
|
||||
b.HasDiscriminator().HasValue("PasteVaultItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.UploadVaultItem", b =>
|
||||
{
|
||||
b.HasBaseType("Teknik.Areas.Vault.Models.VaultItem");
|
||||
|
||||
b.Property<int>("UploadId");
|
||||
|
||||
b.HasIndex("UploadId");
|
||||
|
||||
b.HasDiscriminator().HasValue("UploadVaultItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.Blog", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPost", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Blog.Models.Blog", "Blog")
|
||||
.WithMany("BlogPosts")
|
||||
.HasForeignKey("BlogId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostComment", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Blog.Models.BlogPost", "BlogPost")
|
||||
.WithMany("Comments")
|
||||
.HasForeignKey("BlogPostId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostTag", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Blog.Models.BlogPost", "BlogPost")
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("BlogPostId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Paste.Models.Paste", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany("Pastes")
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastComment", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
|
||||
.WithMany("Comments")
|
||||
.HasForeignKey("PodcastId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastFile", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
|
||||
.WithMany("Files")
|
||||
.HasForeignKey("PodcastId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastTag", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("PodcastId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Shortener.Models.ShortenedUrl", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany("ShortenedUrls")
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Upload.Models.Upload", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Stats.Models.Takedown")
|
||||
.WithMany("Attachments")
|
||||
.HasForeignKey("Takedown_TakedownId");
|
||||
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany("Uploads")
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "ClaimedUser")
|
||||
.WithOne("ClaimedInviteCode")
|
||||
.HasForeignKey("Teknik.Areas.Users.Models.InviteCode", "ClaimedUserId");
|
||||
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "Owner")
|
||||
.WithMany("OwnedInviteCodes")
|
||||
.HasForeignKey("OwnerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
|
||||
{
|
||||
b.OwnsOne("Teknik.Areas.Users.Models.BlogSettings", "BlogSettings", b1 =>
|
||||
{
|
||||
b1.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b1.Property<string>("Description")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b1.Property<string>("Title")
|
||||
.HasColumnName("Title");
|
||||
|
||||
b1.HasKey("UserId");
|
||||
|
||||
b1.ToTable("Users");
|
||||
|
||||
b1.HasOne("Teknik.Areas.Users.Models.User")
|
||||
.WithOne("BlogSettings")
|
||||
.HasForeignKey("Teknik.Areas.Users.Models.BlogSettings", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
b.OwnsOne("Teknik.Areas.Users.Models.UploadSettings", "UploadSettings", b1 =>
|
||||
{
|
||||
b1.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b1.Property<bool>("Encrypt")
|
||||
.HasColumnName("Encrypt");
|
||||
|
||||
b1.Property<int>("ExpirationLength")
|
||||
.HasColumnName("ExpirationLength");
|
||||
|
||||
b1.Property<int>("ExpirationUnit")
|
||||
.HasColumnName("ExpirationUnit");
|
||||
|
||||
b1.Property<long?>("MaxUploadStorage")
|
||||
.HasColumnName("MaxUploadStorage");
|
||||
|
||||
b1.HasKey("UserId");
|
||||
|
||||
b1.ToTable("Users");
|
||||
|
||||
b1.HasOne("Teknik.Areas.Users.Models.User")
|
||||
.WithOne("UploadSettings")
|
||||
.HasForeignKey("Teknik.Areas.Users.Models.UploadSettings", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
b.OwnsOne("Teknik.Areas.Users.Models.UserSettings", "UserSettings", b1 =>
|
||||
{
|
||||
b1.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b1.Property<string>("About")
|
||||
.HasColumnName("About");
|
||||
|
||||
b1.Property<string>("Quote")
|
||||
.HasColumnName("Quote");
|
||||
|
||||
b1.Property<string>("Website")
|
||||
.HasColumnName("Website");
|
||||
|
||||
b1.HasKey("UserId");
|
||||
|
||||
b1.ToTable("Users");
|
||||
|
||||
b1.HasOne("Teknik.Areas.Users.Models.User")
|
||||
.WithOne("UserSettings")
|
||||
.HasForeignKey("Teknik.Areas.Users.Models.UserSettings", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Users.Models.UserFeature", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Users.Models.Feature", "Feature")
|
||||
.WithMany()
|
||||
.HasForeignKey("FeatureId");
|
||||
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany("Features")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Users.Models.User", "User")
|
||||
.WithMany("Vaults")
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.VaultItem", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Vault.Models.Vault", "Vault")
|
||||
.WithMany("VaultItems")
|
||||
.HasForeignKey("VaultId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.PasteVaultItem", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Paste.Models.Paste", "Paste")
|
||||
.WithMany("PasteVaultItems")
|
||||
.HasForeignKey("PasteId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Teknik.Areas.Vault.Models.UploadVaultItem", b =>
|
||||
{
|
||||
b.HasOne("Teknik.Areas.Upload.Models.Upload", "Upload")
|
||||
.WithMany("UploadVaultItems")
|
||||
.HasForeignKey("UploadId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
22
Teknik/Data/Migrations/20200121080120_MaxUploadStorage.cs
Normal file
22
Teknik/Data/Migrations/20200121080120_MaxUploadStorage.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Teknik.Data.Migrations
|
||||
{
|
||||
public partial class MaxUploadStorage : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "MaxUploadStorage",
|
||||
table: "Users",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MaxUploadStorage",
|
||||
table: "Users");
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace Teknik.Data.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.2.0-preview3-35497")
|
||||
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
@ -683,6 +683,9 @@ namespace Teknik.Data.Migrations
|
||||
b1.Property<int>("ExpirationUnit")
|
||||
.HasColumnName("ExpirationUnit");
|
||||
|
||||
b1.Property<long?>("MaxUploadStorage")
|
||||
.HasColumnName("MaxUploadStorage");
|
||||
|
||||
b1.HasKey("UserId");
|
||||
|
||||
b1.ToTable("Users");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* globals shortenURL, createVaultURL, uploadFileURL, maxUploadSize, keySize, blockSize, encScriptSrc, aesScriptSrc, chunkSize */
|
||||
/* globals shortenURL, createVaultURL, uploadFileURL, maxUploadSize, maxTotalSize, curTotalSize:true, keySize, blockSize, encScriptSrc, aesScriptSrc, chunkSize */
|
||||
$(document).ready(function () {
|
||||
$("#upload-links").css('display', 'none', 'important');
|
||||
$("#upload-links").html('');
|
||||
@ -42,6 +42,22 @@ $(document).ready(function () {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(document.body).dropzone({
|
||||
url: uploadFileURL,
|
||||
maxFilesize: maxUploadSize, // MB
|
||||
addRemoveLinks: true,
|
||||
autoProcessQueue: false,
|
||||
clickable: "#uploadButton",
|
||||
previewTemplate: function () { },
|
||||
addedfile: function (file) {
|
||||
// Upload the file to the server
|
||||
upload(file);
|
||||
|
||||
// Remove this file from the dropzone set
|
||||
this.removeFile(file);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function linkExpireSelect(element) {
|
||||
@ -183,22 +199,6 @@ function setExpireWidth(unit) {
|
||||
}
|
||||
}
|
||||
|
||||
$(document.body).dropzone({
|
||||
url: uploadFileURL,
|
||||
maxFilesize: maxUploadSize, // MB
|
||||
addRemoveLinks: true,
|
||||
autoProcessQueue: false,
|
||||
clickable: "#uploadButton",
|
||||
previewTemplate: function () { },
|
||||
addedfile: function (file) {
|
||||
// Upload the file to the server
|
||||
upload(file);
|
||||
|
||||
// Remove this file from the dropzone set
|
||||
this.removeFile(file);
|
||||
}
|
||||
});
|
||||
|
||||
function upload(file) {
|
||||
// Convert file to blob
|
||||
var blob = file.slice(0, file.size);
|
||||
@ -249,6 +249,20 @@ function createUpload(fileName, token) {
|
||||
}
|
||||
|
||||
function processFile(fileBlob, fileName, contentType, contentSize, fileID, token) {
|
||||
// Check to see if they have reached their max upload size
|
||||
if (maxTotalSize >= 0 && contentSize + curTotalSize > maxTotalSize) {
|
||||
setProgress(
|
||||
fileID,
|
||||
100,
|
||||
'progress-bar-danger',
|
||||
'',
|
||||
'Account storage limit exceeded: ' +
|
||||
getReadableFileSizeString(contentSize + curTotalSize) +
|
||||
' / ' +
|
||||
getReadableFileSizeString(maxTotalSize));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the file size
|
||||
if (contentSize <= maxUploadSize) {
|
||||
|
||||
@ -440,6 +454,7 @@ function uploadComplete(fileID, key, options, token, evt) {
|
||||
}
|
||||
var contentType = obj.result.contentType;
|
||||
var contentLength = obj.result.contentLength;
|
||||
var contentLengthRaw = obj.result.contentLengthRaw;
|
||||
var deleteUrl = obj.result.deleteUrl;
|
||||
var expirationUnit = obj.result.expirationUnit;
|
||||
var expirationLength = obj.result.expirationLength;
|
||||
@ -475,6 +490,9 @@ function uploadComplete(fileID, key, options, token, evt) {
|
||||
|
||||
// Allow actions for all uploads
|
||||
$('#upload-action-buttons').show();
|
||||
|
||||
// Update the current content size
|
||||
curTotalSize += contentLengthRaw;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -29,7 +29,7 @@
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-sm-5 col-sm-offset-1 text-left text-muted">
|
||||
© Teknik 2013-2019 | <a href="@Url.SubRouteUrl("faq", "FAQ.Index")">FAQ</a> | <a href="@Url.SubRouteUrl("privacy", "Privacy.Index")">Privacy</a> | <a href="@Url.SubRouteUrl("tos", "TOS.Index")">TOS</a> | <a href="@Url.SubRouteUrl("abuse", "Abuse.Index")">Abuse</a> | <a href="@Url.SubRouteUrl("stats", "Stats.Index")">Statistics</a>
|
||||
© Teknik 2013-2020 | <a href="@Url.SubRouteUrl("faq", "FAQ.Index")">FAQ</a> | <a href="@Url.SubRouteUrl("privacy", "Privacy.Index")">Privacy</a> | <a href="@Url.SubRouteUrl("tos", "TOS.Index")">TOS</a> | <a href="@Url.SubRouteUrl("abuse", "Abuse.Index")">Abuse</a> | <a href="@Url.SubRouteUrl("stats", "Stats.Index")">Statistics</a>
|
||||
</div>
|
||||
<div class="col-sm-5 text-right text-muted">
|
||||
<div id="pagetime" style="display:none;">
|
||||
|
Loading…
Reference in New Issue
Block a user