- Added session cacheing of paste password.tags/3.0.0^2
@@ -1,4 +1,6 @@ | |||
namespace Teknik.Areas.API.V1.Models | |||
using Teknik.Utilities; | |||
namespace Teknik.Areas.API.V1.Models | |||
{ | |||
public class PasteAPIv1Model : BaseAPIv1Model | |||
{ | |||
@@ -8,7 +10,7 @@ | |||
public string syntax { get; set; } | |||
public string expireUnit { get; set; } | |||
public ExpirationUnit expireUnit { get; set; } | |||
public int expireLength { get; set; } | |||
@@ -19,7 +21,7 @@ | |||
code = null; | |||
title = string.Empty; | |||
syntax = "text"; | |||
expireUnit = "never"; | |||
expireUnit = ExpirationUnit.Never; | |||
expireLength = 1; | |||
password = string.Empty; | |||
} |
@@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Http; | |||
using Teknik.Logging; | |||
using System.IO; | |||
using System.Threading.Tasks; | |||
using Microsoft.AspNetCore.Diagnostics; | |||
namespace Teknik.Areas.Paste.Controllers | |||
{ | |||
@@ -64,6 +65,7 @@ namespace Teknik.Areas.Paste.Controllers | |||
model.Title = paste.Title; | |||
model.Syntax = paste.Syntax; | |||
model.DatePosted = paste.DatePosted; | |||
model.Username = paste.User?.Username; | |||
if (User.Identity.IsAuthenticated && type.ToLower() == "full") | |||
{ | |||
@@ -80,6 +82,11 @@ namespace Teknik.Areas.Paste.Controllers | |||
// The paste has a password set | |||
if (!string.IsNullOrEmpty(paste.HashedPassword)) | |||
{ | |||
if (string.IsNullOrEmpty(password)) | |||
{ | |||
// Try to get the password from the session | |||
password = GetCachedPassword(url); | |||
} | |||
string hash = string.Empty; | |||
if (!string.IsNullOrEmpty(password)) | |||
{ | |||
@@ -89,6 +96,7 @@ namespace Teknik.Areas.Paste.Controllers | |||
if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword) | |||
{ | |||
PasswordViewModel passModel = new PasswordViewModel(); | |||
passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.View"); | |||
passModel.Url = url; | |||
passModel.Type = type; | |||
@@ -103,6 +111,9 @@ namespace Teknik.Areas.Paste.Controllers | |||
} | |||
} | |||
// Save the password to the cache | |||
CachePassword(url, password); | |||
// Read in the file | |||
string subDir = paste.FileName[0].ToString(); | |||
string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.FileName); | |||
@@ -158,7 +169,7 @@ namespace Teknik.Areas.Paste.Controllers | |||
{ | |||
Models.Paste paste = PasteHelper.CreatePaste(_config, _dbContext, model.Content, model.Title, model.Syntax, model.ExpireUnit, model.ExpireLength ?? 1, model.Password); | |||
if (model.ExpireUnit == "view") | |||
if (model.ExpireUnit == ExpirationUnit.Views) | |||
{ | |||
paste.Views = -1; | |||
} | |||
@@ -175,6 +186,9 @@ namespace Teknik.Areas.Paste.Controllers | |||
_dbContext.Pastes.Add(paste); | |||
_dbContext.SaveChanges(); | |||
// Cache the password | |||
CachePassword(paste.Url, model.Password); | |||
return Redirect(Url.SubRouteUrl("p", "Paste.View", new { type = "Full", url = paste.Url })); | |||
} | |||
catch (Exception ex) | |||
@@ -186,6 +200,171 @@ namespace Teknik.Areas.Paste.Controllers | |||
} | |||
return View("~/Areas/Paste/Views/Paste/Index.cshtml", model); | |||
} | |||
public async Task<IActionResult> Edit(string url, string password) | |||
{ | |||
Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault(); | |||
if (paste != null) | |||
{ | |||
if (paste.User?.Username != User.Identity.Name) | |||
return new StatusCodeResult(StatusCodes.Status403Forbidden); | |||
ViewBag.Title = "Edit Paste"; | |||
ViewBag.Description = "Edit your paste's content."; | |||
// Check Expiration | |||
if (PasteHelper.CheckExpiration(paste)) | |||
{ | |||
_dbContext.Pastes.Remove(paste); | |||
_dbContext.SaveChanges(); | |||
return new StatusCodeResult(StatusCodes.Status404NotFound); | |||
} | |||
PasteViewModel model = new PasteViewModel(); | |||
model.Url = url; | |||
model.Title = paste.Title; | |||
model.Syntax = paste.Syntax; | |||
model.DatePosted = paste.DatePosted; | |||
model.Username = paste.User?.Username; | |||
byte[] ivBytes = Encoding.Unicode.GetBytes(paste.IV); | |||
byte[] keyBytes = AesCounterManaged.CreateKey(paste.Key, ivBytes, paste.KeySize); | |||
// The paste has a password set | |||
if (!string.IsNullOrEmpty(paste.HashedPassword)) | |||
{ | |||
if (string.IsNullOrEmpty(password)) | |||
{ | |||
// Try to get the password from the session | |||
password = GetCachedPassword(url); | |||
} | |||
string hash = string.Empty; | |||
if (!string.IsNullOrEmpty(password)) | |||
{ | |||
hash = PasteHelper.HashPassword(paste.Key, password); | |||
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, paste.KeySize); | |||
} | |||
if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword) | |||
{ | |||
PasswordViewModel passModel = new PasswordViewModel(); | |||
passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.Edit"); | |||
passModel.Url = url; | |||
if (!string.IsNullOrEmpty(password) && hash != paste.HashedPassword) | |||
{ | |||
passModel.Error = true; | |||
passModel.ErrorMessage = "Invalid Password"; | |||
} | |||
// Redirect them to the password request page | |||
return View("~/Areas/Paste/Views/Paste/PasswordNeeded.cshtml", passModel); | |||
} | |||
} | |||
// Cache the password | |||
CachePassword(url, password); | |||
// Read in the file | |||
string subDir = paste.FileName[0].ToString(); | |||
string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.FileName); | |||
if (!System.IO.File.Exists(filePath)) | |||
{ | |||
return new StatusCodeResult(StatusCodes.Status404NotFound); | |||
} | |||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) | |||
using (AesCounterStream cs = new AesCounterStream(fs, false, keyBytes, ivBytes)) | |||
using (StreamReader sr = new StreamReader(cs, Encoding.Unicode)) | |||
{ | |||
model.Content = await sr.ReadToEndAsync(); | |||
} | |||
return View("~/Areas/Paste/Views/Paste/Edit.cshtml", model); | |||
} | |||
return new StatusCodeResult(StatusCodes.Status404NotFound); | |||
} | |||
[HttpPost] | |||
[DisableRequestSizeLimit] | |||
public IActionResult EditSubmit([Bind("Content, Title, Syntax, Url")]PasteEditViewModel model) | |||
{ | |||
if (_config.PasteConfig.Enabled) | |||
{ | |||
try | |||
{ | |||
Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == model.Url).FirstOrDefault(); | |||
if (paste != null) | |||
{ | |||
if (paste.User?.Username != User.Identity.Name) | |||
return new StatusCodeResult(StatusCodes.Status403Forbidden); | |||
string password = null; | |||
// The paste has a password set | |||
if (!string.IsNullOrEmpty(paste.HashedPassword)) | |||
{ | |||
// Try to get the password from the session | |||
password = GetCachedPassword(model.Url); | |||
string hash = string.Empty; | |||
if (!string.IsNullOrEmpty(password)) | |||
{ | |||
hash = PasteHelper.HashPassword(paste.Key, password); | |||
} | |||
if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword) | |||
{ | |||
PasswordViewModel passModel = new PasswordViewModel(); | |||
passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.Edit"); | |||
passModel.Url = model.Url; | |||
if (!string.IsNullOrEmpty(password) && hash != paste.HashedPassword) | |||
{ | |||
passModel.Error = true; | |||
passModel.ErrorMessage = "Invalid Password"; | |||
} | |||
// Redirect them to the password request page | |||
return View("~/Areas/Paste/Views/Paste/PasswordNeeded.cshtml", passModel); | |||
} | |||
} | |||
// Delete the old file | |||
string subDir = paste.FileName[0].ToString(); | |||
string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.FileName); | |||
if (System.IO.File.Exists(filePath)) | |||
System.IO.File.Delete(filePath); | |||
// Generate a unique file name that does not currently exist | |||
string newFilePath = FileHelper.GenerateRandomFileName(_config.PasteConfig.PasteDirectory, _config.PasteConfig.FileExtension, 10); | |||
string fileName = Path.GetFileName(newFilePath); | |||
string key = PasteHelper.GenerateKey(_config.PasteConfig.KeySize); | |||
string iv = PasteHelper.GenerateIV(_config.PasteConfig.BlockSize); | |||
PasteHelper.EncryptContents(model.Content, newFilePath, password, key, iv, _config.PasteConfig.KeySize, _config.PasteConfig.ChunkSize); | |||
paste.Key = key; | |||
paste.KeySize = _config.PasteConfig.KeySize; | |||
paste.IV = iv; | |||
paste.BlockSize = _config.PasteConfig.BlockSize; | |||
paste.HashedPassword = PasteHelper.HashPassword(paste.Key, password); | |||
paste.FileName = fileName; | |||
paste.Title = model.Title; | |||
paste.Syntax = model.Syntax; | |||
paste.DateEdited = DateTime.Now; | |||
_dbContext.Entry(paste).State = EntityState.Modified; | |||
_dbContext.SaveChanges(); | |||
return Redirect(Url.SubRouteUrl("p", "Paste.View", new { type = "Full", url = paste.Url })); | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
return Redirect(Url.SubRouteUrl("error", "Error.500", new { exception = ex })); | |||
} | |||
} | |||
return new StatusCodeResult(StatusCodes.Status403Forbidden); | |||
} | |||
[HttpPost] | |||
public IActionResult Delete(string id) | |||
@@ -206,11 +385,36 @@ namespace Teknik.Areas.Paste.Controllers | |||
System.IO.File.Delete(filePath); | |||
} | |||
return Json(new { result = true }); | |||
return Json(new { result = true, redirect = Url.SubRouteUrl("p", "Paste.Index") }); | |||
} | |||
return Json(new { error = new { message = "You do not have permission to edit this Paste" } }); | |||
} | |||
return Json(new { error = new { message = "This Paste does not exist" } }); | |||
} | |||
private void CachePassword(string url, string password) | |||
{ | |||
if (HttpContext != null) | |||
{ | |||
HttpContext.Session.Set("PastePassword_" + url, password); | |||
} | |||
} | |||
private string GetCachedPassword(string url) | |||
{ | |||
if (HttpContext != null) | |||
{ | |||
return HttpContext.Session.Get<string>("PastePassword_" + url); | |||
} | |||
return null; | |||
} | |||
private void ClearCachedPassword(string url) | |||
{ | |||
if (HttpContext != null) | |||
{ | |||
HttpContext.Session.Remove("PastePassword_" + url); | |||
} | |||
} | |||
} | |||
} |
@@ -21,6 +21,8 @@ namespace Teknik.Areas.Paste.Models | |||
public DateTime DatePosted { get; set; } | |||
public DateTime DateEdited { get; set; } | |||
[CaseSensitive] | |||
public string Url { get; set; } | |||
@@ -14,7 +14,7 @@ namespace Teknik.Areas.Paste | |||
{ | |||
public static class PasteHelper | |||
{ | |||
public static Models.Paste CreatePaste(Config config, TeknikEntities db, string content, string title = "", string syntax = "text", string expireUnit = "never", int expireLength = 1, string password = "") | |||
public static Models.Paste CreatePaste(Config config, TeknikEntities db, string content, string title = "", string syntax = "text", ExpirationUnit expireUnit = ExpirationUnit.Never, int expireLength = 1, string password = "") | |||
{ | |||
Models.Paste paste = new Models.Paste(); | |||
paste.DatePosted = DateTime.Now; | |||
@@ -30,26 +30,26 @@ namespace Teknik.Areas.Paste | |||
paste.Url = url; | |||
// Figure out the expire date (null if 'never' or 'visit') | |||
switch (expireUnit.ToLower()) | |||
switch (expireUnit) | |||
{ | |||
case "never": | |||
case ExpirationUnit.Never: | |||
break; | |||
case "view": | |||
case ExpirationUnit.Views: | |||
paste.MaxViews = expireLength; | |||
break; | |||
case "minute": | |||
case ExpirationUnit.Minutes: | |||
paste.ExpireDate = paste.DatePosted.AddMinutes(expireLength); | |||
break; | |||
case "hour": | |||
case ExpirationUnit.Hours: | |||
paste.ExpireDate = paste.DatePosted.AddHours(expireLength); | |||
break; | |||
case "day": | |||
case ExpirationUnit.Days: | |||
paste.ExpireDate = paste.DatePosted.AddDays(expireLength); | |||
break; | |||
case "month": | |||
case ExpirationUnit.Months: | |||
paste.ExpireDate = paste.DatePosted.AddMonths(expireLength); | |||
break; | |||
case "year": | |||
case ExpirationUnit.Years: | |||
paste.ExpireDate = paste.DatePosted.AddYears(expireLength); | |||
break; | |||
default: |
@@ -9,6 +9,8 @@ namespace Teknik.Areas.Paste.ViewModels | |||
{ | |||
public class PasswordViewModel : ViewModelBase | |||
{ | |||
public string ActionUrl { get; set; } | |||
public string Url { get; set; } | |||
public string Type { get; set; } |
@@ -1,4 +1,5 @@ | |||
using System.ComponentModel.DataAnnotations; | |||
using Teknik.Utilities; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Paste.ViewModels | |||
@@ -15,7 +16,7 @@ namespace Teknik.Areas.Paste.ViewModels | |||
[Range(1, int.MaxValue)] | |||
public int? ExpireLength { get; set; } | |||
public string ExpireUnit { get; set; } | |||
public ExpirationUnit ExpireUnit { get; set; } | |||
public string Password { get; set; } | |||
@@ -0,0 +1,16 @@ | |||
using System.ComponentModel.DataAnnotations; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Paste.ViewModels | |||
{ | |||
public class PasteEditViewModel : ViewModelBase | |||
{ | |||
public string Url { get; set; } | |||
public string Content { get; set; } | |||
public string Title { get; set; } | |||
public string Syntax { get; set; } | |||
} | |||
} |
@@ -13,6 +13,7 @@ namespace Teknik.Areas.Paste.ViewModels | |||
public string Password { get; set; } | |||
public bool Hide { get; set; } | |||
public DateTime DatePosted { get; set; } | |||
public string Username { get; set; } | |||
public List<Vault.Models.Vault> Vaults { get; set; } | |||
} |
@@ -0,0 +1,48 @@ | |||
@model Teknik.Areas.Paste.ViewModels.PasteViewModel | |||
<bundle src="css/paste.edit.min.css" append-version="true"></bundle> | |||
<div class="container"> | |||
<div class="row"> | |||
<div class="col-sm-10 col-sm-offset-1 text-center"> | |||
<b>@Html.ValidationSummary(true, "The input is not valid")</b> | |||
</div> | |||
</div> | |||
<div class="row"> | |||
<div class="col-sm-12"> | |||
<!form class="form-horizontal" name="editor" method="post" action="@Url.SubRouteUrl("p", "Paste.Action", new { action = "EditSubmit", url = Model.Url })"> | |||
<input type="hidden" class="form-control" name="Url" id="url" value="@Model.Url"> | |||
<div class="form-group"> | |||
<div class="col-sm-10 col-sm-offset-1"> | |||
<textarea class="form-control" name="Content" id="content" rows="20">@Model.Content</textarea> | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<label for="title" class="col-sm-2 col-sm-offset-1 control-label">Title</label> | |||
<div class="col-sm-4"> | |||
<input type="text" class="form-control" name="Title" id="title" value="@Model.Title"> | |||
</div> | |||
<div class="col-sm-1 col-sm-offset-2"> | |||
<button type="submit" class="btn btn-primary pull-right" id="pasteSubmit">Save</button> | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<label for="syntax" class="col-sm-2 col-sm-offset-1 control-label">Syntax</label> | |||
<div class="col-sm-4"> | |||
<select class="form-control" name="Syntax" id="syntax"> | |||
<!option value=""@((string.IsNullOrEmpty(Model.Syntax)) ? " selected" : string.Empty)>Text</!option> | |||
@foreach (var format in HighlightHelper.Languages.GroupBy(l => l.Value).ToList()) | |||
{ | |||
<!option value="@(format?.FirstOrDefault().Key)"@((Model.Syntax == format?.FirstOrDefault().Key) ? " selected" : string.Empty)>@(format?.Key)</!option> | |||
} | |||
</select> | |||
</div> | |||
</div> | |||
</!form> | |||
</div> | |||
</div> | |||
</div> | |||
<bundle src="js/paste.edit.min.js" append-version="true"></bundle> |
@@ -16,6 +16,7 @@ | |||
<script> | |||
var createVaultURL = '@Url.SubRouteUrl("vault", "Vault.NewVaultFromService", new { type = "Paste" })'; | |||
var deletePasteURL = '@Url.SubRouteUrl("p", "Paste.Delete")'; | |||
</script> | |||
<div class="container"> | |||
@@ -27,21 +28,35 @@ | |||
<hr /> | |||
<div class="row"> | |||
<div class="col-sm-12 pull-left"> | |||
<div class="btn-group" role="group"> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Simple", new { url = Model.Url })">Simple</a> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Raw", new { url = Model.Url })">Raw</a> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Download", new { url = Model.Url })">Download</a> | |||
<button type="button" class="btn btn-default" id="create-vault" data-paste-url="@Model.Url" data-paste-title="@((string.IsNullOrEmpty(Model.Title)) ? "Untitled" : Model.Title)">Create Vault</button> | |||
@if (User.Identity.IsAuthenticated && Model.Vaults != null && Model.Vaults.Any()) | |||
<div class="btn-toolbar" role="toolbar"> | |||
<div class="btn-group" role="group"> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Simple", new { url = Model.Url })">Simple</a> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Raw", new { url = Model.Url })">Raw</a> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Download", new { url = Model.Url })">Download</a> | |||
</div> | |||
@if (User.Identity.IsAuthenticated && User.Identity.Name == Model.Username) | |||
{ | |||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Add to Vault <span class="caret"></span></button> | |||
<ul class="dropdown-menu pull-right" id="add-to-vault-menu"> | |||
@foreach (Vault item in Model.Vaults) | |||
<div class="btn-group pull-right" role="group"> | |||
<a role="button" class="btn btn-default" href="@Url.SubRouteUrl("p", "Paste.Edit", new { url = Model.Url })"><span class="text-primary">Edit</span></a> | |||
<button type="button" class="btn btn-default" id="delete-paste" data-paste-url="@Model.Url"><span class="text-danger">Delete</span></button> | |||
</div> | |||
} | |||
<div class="btn-group pull-right" role="group"> | |||
<button type="button" class="btn btn-default" id="create-vault" data-paste-url="@Model.Url" data-paste-title="@((string.IsNullOrEmpty(Model.Title)) ? "Untitled" : Model.Title)">Create Vault</button> | |||
@if (User.Identity.IsAuthenticated) | |||
{ | |||
@if (Model.Vaults != null && Model.Vaults.Any()) | |||
{ | |||
<li><a href="#" class="add-to-vault" data-add-to-vault-url="@Url.SubRouteUrl("vault", "Vault.EditVault", new { url = item.Url, type = "Paste" })" data-paste-url="@Model.Url" data-paste-title="@((string.IsNullOrEmpty(Model.Title)) ? "Untitled" : Model.Title)">@item.Title</a></li> | |||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Add to Vault <span class="caret"></span></button> | |||
<ul class="dropdown-menu pull-right" 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 = "Paste" })" data-paste-url="@Model.Url" data-paste-title="@((string.IsNullOrEmpty(Model.Title)) ? "Untitled" : Model.Title)">@item.Title</a></li> | |||
} | |||
</ul> | |||
} | |||
</ul> | |||
} | |||
} | |||
</div> | |||
</div> | |||
</div> | |||
</div> |
@@ -46,13 +46,10 @@ | |||
</div> | |||
<div class="col-sm-4" id="unit-div"> | |||
<select class="form-control" name="ExpireUnit" id="expireunit"> | |||
<!option value="never">Never</!option> | |||
<!option value="view">Views</!option> | |||
<!option value="minute">Minutes</!option> | |||
<!option value="hour">Hours</!option> | |||
<!option value="day">Days</!option> | |||
<!option value="month">Months</!option> | |||
<!option value="year">Years</!option> | |||
@foreach (ExpirationUnit unit in Enum.GetValues(typeof(ExpirationUnit))) | |||
{ | |||
<!option value="@unit">@unit.ToString()</!option> | |||
} | |||
</select> | |||
</div> | |||
</div> |
@@ -13,7 +13,7 @@ | |||
} | |||
<div class="row text-center"> | |||
<div class="col-sm-6 col-sm-offset-3"> | |||
<!form class="form-inline" method="post" action="@Url.SubRouteUrl("paste", "Paste.View")"> | |||
<!form class="form-inline" method="post" action="@Model.ActionUrl"> | |||
<h3>This paste is password protected</h3> | |||
<input type="hidden" name="type" value="@Model.Type"> | |||
<input type="hidden" name="url" value="@Model.Url"> |
@@ -0,0 +1,29 @@ | |||
pre { | |||
background-color: #ffffff; | |||
} | |||
pre code, | |||
pre .line-number { | |||
/* Ukuran line-height antara teks di dalam tag <code> dan <span class="line-number"> harus sama! */ | |||
font:normal normal 12px/14px "Courier New",Courier,Monospace; | |||
color:black; | |||
display:block; | |||
} | |||
pre .line-number { | |||
float:left; | |||
margin:0 1em 0 -1em; | |||
padding-top: 5px; | |||
border-right:1px solid; | |||
text-align:right; | |||
} | |||
pre .line-number span { | |||
display:block; | |||
padding:0 .5em 0 1em; | |||
} | |||
pre .cl { | |||
display:block; | |||
clear:both; | |||
} |
@@ -0,0 +1,749 @@ | |||
// <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("20190124080711_PasteEditDate")] | |||
partial class PasteEditDate | |||
{ | |||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||
{ | |||
#pragma warning disable 612, 618 | |||
modelBuilder | |||
.HasAnnotation("ProductVersion", "2.2.0-preview3-35497") | |||
.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.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.LoginInfo", b => | |||
{ | |||
b.Property<int>("LoginInfoId") | |||
.ValueGeneratedOnAdd() | |||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||
b.Property<string>("LoginProvider"); | |||
b.Property<string>("ProviderDisplayName"); | |||
b.Property<string>("ProviderKey"); | |||
b.Property<int>("UserId"); | |||
b.HasKey("LoginInfoId"); | |||
b.HasIndex("UserId"); | |||
b.ToTable("UserLogins"); | |||
}); | |||
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.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<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.LoginInfo", b => | |||
{ | |||
b.HasOne("Teknik.Areas.Users.Models.User", "User") | |||
.WithMany("Logins") | |||
.HasForeignKey("UserId") | |||
.OnDelete(DeleteBehavior.Cascade); | |||
}); | |||
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.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.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 | |||
} | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
using System; | |||
using Microsoft.EntityFrameworkCore.Migrations; | |||
namespace Teknik.Data.Migrations | |||
{ | |||
public partial class PasteEditDate : Migration | |||
{ | |||
protected override void Up(MigrationBuilder migrationBuilder) | |||
{ | |||
migrationBuilder.AddColumn<DateTime>( | |||
name: "DateEdited", | |||
table: "Pastes", | |||
nullable: false, | |||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); | |||
} | |||
protected override void Down(MigrationBuilder migrationBuilder) | |||
{ | |||
migrationBuilder.DropColumn( | |||
name: "DateEdited", | |||
table: "Pastes"); | |||
} | |||
} | |||
} |
@@ -138,6 +138,8 @@ namespace Teknik.Data.Migrations | |||
b.Property<string>("Content"); | |||
b.Property<DateTime>("DateEdited"); | |||
b.Property<DateTime>("DatePosted"); | |||
b.Property<string>("DeleteKey") |
@@ -417,6 +417,13 @@ namespace Teknik | |||
template: "Download/{url}/{password?}", | |||
defaults: new { area = "Paste", controller = "Paste", action = "ViewPaste", type = "Download" } | |||
); | |||
routes.MapSubdomainRoute( | |||
name: "Paste.Edit", | |||
domains: new List<string>() { config.Host }, | |||
subDomains: new List<string>() { "paste", "p" }, | |||
template: "Edit/{url}/{password?}", | |||
defaults: new { area = "Paste", controller = "Paste", action = "Edit" } | |||
); | |||
routes.MapSubdomainRoute( | |||
name: "Paste.Delete", | |||
domains: new List<string>() { config.Host }, |
@@ -0,0 +1,3 @@ | |||
$(document).ready(function () { | |||
$('#content').focus(); | |||
}); |
@@ -1,10 +1,41 @@ | |||
/* globals createVaultURL */ | |||
/* globals createVaultURL, deletePasteURL */ | |||
$(document).ready(function () { | |||
linkCreateVault($('#create-vault')); | |||
$('#add-to-vault-menu').find('.add-to-vault').each(function () { | |||
linkAddToVault($(this)); | |||
}); | |||
$('#delete-paste').click(function () { | |||
var id = $(this).data('paste-url'); | |||
bootbox.confirm("Are you sure you want to delete this paste?", function (result) { | |||
if (result) { | |||
$.ajax({ | |||
type: "POST", | |||
url: deletePasteURL, | |||
data: { id: id }, | |||
headers: { 'X-Requested-With': 'XMLHttpRequest' }, | |||
xhrFields: { | |||
withCredentials: true | |||
}, | |||
success: function (response) { | |||
if (response.result) { | |||
window.location = response.redirect; | |||
} | |||
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>' + parseErrorMessage(response) + '</div>'); | |||
} | |||
}, | |||
error: function (response) { | |||
$("#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>' + parseErrorMessage(response.responseText) + '</div>'); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
}); | |||
function linkCreateVault(element) { |
@@ -96,6 +96,9 @@ | |||
<CopyToPublishDirectory>Never</CopyToPublishDirectory> | |||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
</Content> | |||
<Content Update="Areas\Paste\Views\Paste\Edit.cshtml"> | |||
<Pack>$(IncludeRazorContentInPack)</Pack> | |||
</Content> | |||
<Content Update="Areas\User\Views\User\Settings\ClientView.cshtml"> | |||
<Pack>$(IncludeRazorContentInPack)</Pack> | |||
</Content> |
@@ -99,6 +99,7 @@ | |||
{ | |||
"outputFileName": "./wwwroot/js/paste.view.min.js", | |||
"inputFiles": [ | |||
"./wwwroot/lib/bootbox/js/bootbox.js", | |||
"./wwwroot/js/app/lib/Prism/prism.js", | |||
"./wwwroot/js/app/lib/Prism/prism-line-numbers.js", | |||
"./wwwroot/js/app/lib/Prism/prism-line-highlight.js", | |||
@@ -113,6 +114,24 @@ | |||
"./wwwroot/css/app/lib/Prism/prism-vs.css" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/paste.edit.min.js", | |||
"inputFiles": [ | |||
"./wwwroot/js/app/lib/Prism/prism.js", | |||
"./wwwroot/js/app/lib/Prism/prism-line-numbers.js", | |||
"./wwwroot/js/app/lib/Prism/prism-line-highlight.js", | |||
"./wwwroot/js/app/Paste/EditPaste.js" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/css/paste.edit.min.css", | |||
"inputFiles": [ | |||
"./wwwroot/css/app/lib/Prism/prism-line-numbers.css", | |||
"./wwwroot/css/app/lib/Prism/prism-line-highlight.css", | |||
"./wwwroot/css/app/lib/Prism/prism-vs.css", | |||
"./wwwroot/css/app/Paste/EditPaste.css" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/podcast.min.js", | |||
"inputFiles": [ |