| { | { | ||||
| CreateMap<Message, MessageDto>().ReverseMap(); | CreateMap<Message, MessageDto>().ReverseMap(); | ||||
| } | } | ||||
| } | } |
| using System.Reflection.Metadata; | |||||
| using AutoMapper; | |||||
| using AutoMapper; | |||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||
| using SecureSharing.Business.Dtos; | using SecureSharing.Business.Dtos; | ||||
| using SecureSharing.Business.Infrastructure; | using SecureSharing.Business.Infrastructure; | ||||
| var toReturn = result.Select(x => x.Code).ToList(); | var toReturn = result.Select(x => x.Code).ToList(); | ||||
| _dbContext.RemoveRange(result); | _dbContext.RemoveRange(result); | ||||
| await _dbContext.SaveChangesAsync(); | await _dbContext.SaveChangesAsync(); | ||||
| return toReturn; | return toReturn; | ||||
| } | } | ||||
| await _dbContext.SaveChangesAsync(); | await _dbContext.SaveChangesAsync(); | ||||
| } | } | ||||
| private void DeleteFiles(Guid basePathGuid) | |||||
| { | |||||
| // TODO: this path needs to be extracted somehow. | |||||
| var basePath = Path.Combine(@"D:\secure-sharing\SecureSharing\wwwroot\files", basePathGuid.ToString()); | |||||
| Directory.Delete(basePath, true); | |||||
| } | |||||
| public async Task<bool> Delete(int id) | public async Task<bool> Delete(int id) | ||||
| { | { | ||||
| var messageDto = await GetById(id); | var messageDto = await GetById(id); | ||||
| if (messageDto is null) | |||||
| if (messageDto is null) | |||||
| return false; | return false; | ||||
| DeleteFiles(messageDto.Code); | DeleteFiles(messageDto.Code); | ||||
| _dbContext.Messages.Remove(_mapper.Map<Message>(messageDto)); | _dbContext.Messages.Remove(_mapper.Map<Message>(messageDto)); | ||||
| try | try | ||||
| { | { | ||||
| public async Task<MessageDto> GetById(int messageId) | public async Task<MessageDto> GetById(int messageId) | ||||
| { | { | ||||
| var result = await _dbContext.Messages.Include(x=>x.FileNames).AsNoTracking().FirstOrDefaultAsync(x => x.Id == messageId); | |||||
| var result = await _dbContext.Messages.Include(x => x.FileNames).AsNoTracking() | |||||
| .FirstOrDefaultAsync(x => x.Id == messageId); | |||||
| var mappedResult = _mapper.Map<MessageDto>(result); | var mappedResult = _mapper.Map<MessageDto>(result); | ||||
| return mappedResult; | return mappedResult; | ||||
| } | } | ||||
| public async Task<MessageDto> GetByCode(Guid code) | public async Task<MessageDto> GetByCode(Guid code) | ||||
| { | { | ||||
| var result = await _dbContext.Messages.Include(x=>x.FileNames).AsNoTracking().FirstOrDefaultAsync(x => x.Code == code.ToString()); | |||||
| var result = await _dbContext.Messages.Include(x => x.FileNames).AsNoTracking() | |||||
| .FirstOrDefaultAsync(x => x.Code == code.ToString()); | |||||
| var mappedResult = _mapper.Map<MessageDto>(result); | var mappedResult = _mapper.Map<MessageDto>(result); | ||||
| return mappedResult; | return mappedResult; | ||||
| } | } | ||||
| public async Task Update(MessageDto messageDto) | public async Task Update(MessageDto messageDto) | ||||
| { | { | ||||
| var a = _dbContext.Messages.Update(_mapper.Map<Message>(messageDto)); | var a = _dbContext.Messages.Update(_mapper.Map<Message>(messageDto)); | ||||
| await _dbContext.SaveChangesAsync(); | await _dbContext.SaveChangesAsync(); | ||||
| } | } | ||||
| private void DeleteFiles(Guid basePathGuid) | |||||
| { | |||||
| // TODO: this path needs to be extracted somehow. | |||||
| var basePath = Path.Combine(@"D:\secure-sharing\SecureSharing\wwwroot\files", basePathGuid.ToString()); | |||||
| Directory.Delete(basePath, true); | |||||
| } | |||||
| } | } |
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" /> | |||||
| <PackageReference Include="AutoMapper" Version="11.0.1"/> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | ||||
| <PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
| </PackageReference> | </PackageReference> | ||||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" /> | |||||
| <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> | |||||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1"/> | |||||
| <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0"/> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Folder Include="Migrations" /> | |||||
| <Folder Include="Migrations"/> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> |
| using Microsoft.AspNetCore.Authorization; | using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.StaticFiles; | using Microsoft.AspNetCore.StaticFiles; | ||||
| using Org.BouncyCastle.Ocsp; | |||||
| using SecureSharing.Business.Dtos; | using SecureSharing.Business.Dtos; | ||||
| using SecureSharing.Business.Interfaces; | using SecureSharing.Business.Interfaces; | ||||
| using SecureSharing.Data.Data; | using SecureSharing.Data.Data; | ||||
| [Authorize] | [Authorize] | ||||
| public sealed class HomeController : Controller | public sealed class HomeController : Controller | ||||
| { | { | ||||
| private const string DefaultPath = "files"; | |||||
| private const string DefaultPathTmp = "filestmp"; | |||||
| private readonly ILogger<HomeController> _logger; | private readonly ILogger<HomeController> _logger; | ||||
| private readonly IMessageService _messageService; | private readonly IMessageService _messageService; | ||||
| private readonly IModelFactory _modelFactory; | private readonly IModelFactory _modelFactory; | ||||
| private readonly IWebHostEnvironment _webHostEnvironment; | private readonly IWebHostEnvironment _webHostEnvironment; | ||||
| private const string DefaultPath = "files"; | |||||
| private const string DefaultPathTmp = "filestmp"; | |||||
| public HomeController(ILogger<HomeController> logger, IMessageService messageService, IModelFactory modelFactory, IWebHostEnvironment webHostEnvironment) | |||||
| public HomeController(ILogger<HomeController> logger, IMessageService messageService, IModelFactory modelFactory, | |||||
| IWebHostEnvironment webHostEnvironment) | |||||
| { | { | ||||
| _logger = logger; | _logger = logger; | ||||
| _messageService = messageService; | _messageService = messageService; | ||||
| var files = Request.Form.Files.ToList(); | var files = Request.Form.Files.ToList(); | ||||
| var basePath = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPathTmp, code); | var basePath = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPathTmp, code); | ||||
| Directory.CreateDirectory(basePath); | Directory.CreateDirectory(basePath); | ||||
| foreach (var formFile in files) | foreach (var formFile in files) | ||||
| { | { | ||||
| if (formFile.Length <= 0) | |||||
| if (formFile.Length <= 0) | |||||
| continue; | continue; | ||||
| var filePath = Path.Combine(basePath, formFile.FileName); | var filePath = Path.Combine(basePath, formFile.FileName); | ||||
| await using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); | await using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); | ||||
| await formFile.CopyToAsync(stream); | await formFile.CopyToAsync(stream); | ||||
| public async Task<IActionResult> CreateMessage(MessageModel model) | public async Task<IActionResult> CreateMessage(MessageModel model) | ||||
| { | { | ||||
| if (string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 && string.IsNullOrEmpty(model.FilesAsText)) | if (string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 && string.IsNullOrEmpty(model.FilesAsText)) | ||||
| { | |||||
| return Redirect("/"); | return Redirect("/"); | ||||
| } | |||||
| var message = new MessageDto { Text = model.Text }; | var message = new MessageDto { Text = model.Text }; | ||||
| await UploadFiles(model, message); | await UploadFiles(model, message); | ||||
| var code = await _messageService.Create(message, model.ChosenPeriod); | var code = await _messageService.Create(message, model.ChosenPeriod); | ||||
| return RedirectToAction("Link", "Home", new { code = code, share = true }); | |||||
| return RedirectToAction("Link", "Home", new { code, share = true }); | |||||
| } | } | ||||
| private async Task UploadFiles(MessageModel model, MessageDto message) | private async Task UploadFiles(MessageModel model, MessageDto message) | ||||
| { | { | ||||
| var basePath = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPath, message.Code.ToString()); | |||||
| var basePath = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPath, | |||||
| message.Code.ToString()); | |||||
| var basePathTemporary = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPathTmp); | var basePathTemporary = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPathTmp); | ||||
| Directory.CreateDirectory(basePath); | Directory.CreateDirectory(basePath); | ||||
| .ToList(); | .ToList(); | ||||
| var fileNames = fileNamesTmp.Select(x => x.Split(':')[1]).ToList(); | var fileNames = fileNamesTmp.Select(x => x.Split(':')[1]).ToList(); | ||||
| foreach (var file in fileNames) | |||||
| { | |||||
| message.FileNames.Add(new FileModel { Name = file }); | |||||
| } | |||||
| foreach (var file in fileNames) message.FileNames.Add(new FileModel { Name = file }); | |||||
| for (var ind = 0; ind < directoryNames.Count; ind++) | for (var ind = 0; ind < directoryNames.Count; ind++) | ||||
| { | { | ||||
| var directoryName = directoryNames[ind]; | var directoryName = directoryNames[ind]; | ||||
| var directoryPath = Path.Combine(basePathTemporary, directoryName); | var directoryPath = Path.Combine(basePathTemporary, directoryName); | ||||
| var files = Directory.GetFiles(directoryPath); | var files = Directory.GetFiles(directoryPath); | ||||
| for (var i = 0; i < files.Length; i++) | for (var i = 0; i < files.Length; i++) | ||||
| { | { | ||||
| // var file = files[i]; | // var file = files[i]; | ||||
| } | } | ||||
| } | } | ||||
| foreach (var directory in directoryNames) | |||||
| { | |||||
| Directory.Delete(Path.Combine(basePathTemporary, directory), true); | |||||
| } | |||||
| foreach (var directory in directoryNames) Directory.Delete(Path.Combine(basePathTemporary, directory), true); | |||||
| foreach (var formFile in model.Files) | foreach (var formFile in model.Files) | ||||
| { | { | ||||
| await stream.CopyToAsync(memory); | await stream.CopyToAsync(memory); | ||||
| memory.Position = 0; | memory.Position = 0; | ||||
| new FileExtensionContentTypeProvider().TryGetContentType(filename, out var contentType); | new FileExtensionContentTypeProvider().TryGetContentType(filename, out var contentType); | ||||
| return contentType is null ? null : File(memory, contentType,Path.GetFileName(path)); | |||||
| return contentType is null ? null : File(memory, contentType, Path.GetFileName(path)); | |||||
| } | } | ||||
| [HttpGet] | [HttpGet] |
| using SecureSharing.Business.Interfaces; | using SecureSharing.Business.Interfaces; | ||||
| using SecureSharing.Data.Data; | |||||
| using SecureSharing.Models; | using SecureSharing.Models; | ||||
| namespace SecureSharing.Infrastructure; | namespace SecureSharing.Infrastructure; | ||||
| { | { | ||||
| MessageModel = new MessageModel | MessageModel = new MessageModel | ||||
| { | { | ||||
| Code = code, | |||||
| Code = code, | |||||
| Text = message.Text, | Text = message.Text, | ||||
| FileNames = message.FileNames.Select(x => x.Name).ToList() | FileNames = message.FileNames.Select(x => x.Name).ToList() | ||||
| }, | |||||
| }, | |||||
| Share = share, | Share = share, | ||||
| IsValid = message.IsValid | IsValid = message.IsValid | ||||
| }; | }; |
| public PeriodOfValidity ChosenPeriod { get; set; } | public PeriodOfValidity ChosenPeriod { get; set; } | ||||
| public List<IFormFile> Files { get; init; } = new(); | public List<IFormFile> Files { get; init; } = new(); | ||||
| public List<string> FileNames { get; init; } = new(); | public List<string> FileNames { get; init; } = new(); | ||||
| public string FilesAsText { get; set; } = default!; | public string FilesAsText { get; set; } = default!; | ||||
| // public Dictionary<int, string> AvailablePeriods { get; set; } | // public Dictionary<int, string> AvailablePeriods { get; set; } | ||||
| } | } |
| services.AddControllersWithViews(); | services.AddControllersWithViews(); | ||||
| services.AddRazorPages(); | services.AddRazorPages(); | ||||
| StartupExtensions.ConfigureServices(services); | StartupExtensions.ConfigureServices(services); | ||||
| services.AddDefaultIdentity<IdentityUser>(options => | |||||
| { | |||||
| options.SignIn.RequireConfirmedAccount = false; | |||||
| }) | |||||
| services.AddDefaultIdentity<IdentityUser>(options => { options.SignIn.RequireConfirmedAccount = false; }) | |||||
| .AddDefaultUI() | .AddDefaultUI() | ||||
| .AddRoles<IdentityRole>() | .AddRoles<IdentityRole>() | ||||
| .AddEntityFrameworkStores<AppDbContext>(); | .AddEntityFrameworkStores<AppDbContext>(); | ||||
| services.AddScoped<IMessageService, MessageService>(); | services.AddScoped<IMessageService, MessageService>(); | ||||
| services.AddScoped<IModelFactory, ModelFactory>(); | services.AddScoped<IModelFactory, ModelFactory>(); | ||||
| services.AddAuthentication(o => | |||||
| { | |||||
| o.DefaultScheme = GoogleDefaults.AuthenticationScheme; | |||||
| }) | |||||
| services.AddAuthentication(o => { o.DefaultScheme = GoogleDefaults.AuthenticationScheme; }) | |||||
| .AddGoogle(options => | .AddGoogle(options => | ||||
| { | { | ||||
| options.ClientId = configuration["EmailSettings:ClientId"]; | options.ClientId = configuration["EmailSettings:ClientId"]; | ||||
| options.ClientSecret =configuration["EmailSettings:ClientSecret"]; | |||||
| options.ClientSecret = configuration["EmailSettings:ClientSecret"]; | |||||
| }); | }); | ||||
| // Add Quartz services | // Add Quartz services | ||||
| services.AddSingleton<IJobFactory, JobFactory>(); | services.AddSingleton<IJobFactory, JobFactory>(); | ||||
| services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); | services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); |
| public void ReturnJob(IJob job) | public void ReturnJob(IJob job) | ||||
| { | { | ||||
| if (_scopes.TryRemove(job, out var scope)) | if (_scopes.TryRemove(job, out var scope)) | ||||
| { | |||||
| // The Dispose() method ends the scope lifetime. | // The Dispose() method ends the scope lifetime. | ||||
| // Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed. | // Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed. | ||||
| scope.Dispose(); | scope.Dispose(); | ||||
| } | |||||
| } | } | ||||
| } | } |
| public sealed class MessageDeletionJob : IJob | public sealed class MessageDeletionJob : IJob | ||||
| { | { | ||||
| private readonly IMessageService _messageService; | |||||
| private readonly string _basePath; | private readonly string _basePath; | ||||
| private readonly string _basePathTmp; | private readonly string _basePathTmp; | ||||
| private readonly IMessageService _messageService; | |||||
| public MessageDeletionJob(IMessageService messageService, IWebHostEnvironment webHostEnvironment) | public MessageDeletionJob(IMessageService messageService, IWebHostEnvironment webHostEnvironment) | ||||
| { | { | ||||
| var foldersToRemove = await _messageService.DeleteExpiredMessages(); | var foldersToRemove = await _messageService.DeleteExpiredMessages(); | ||||
| foreach (var path in foldersToRemove.Select(folder => Path.Combine(_basePath, folder))) | foreach (var path in foldersToRemove.Select(folder => Path.Combine(_basePath, folder))) | ||||
| { | |||||
| Directory.Delete(path, true); | Directory.Delete(path, true); | ||||
| } | |||||
| Directory.Delete(_basePathTmp, true); | Directory.Delete(_basePathTmp, true); | ||||
| } | } |
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||||
| <PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.9" /> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" /> | |||||
| <PackageReference Include="AutoMapper" Version="11.0.1"/> | |||||
| <PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3"/> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | ||||
| <PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
| </PackageReference> | </PackageReference> | ||||
| <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" /> | |||||
| <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9" /> | |||||
| <PackageReference Include="Quartz" Version="3.5.0" /> | |||||
| <PackageReference Include="Serilog" Version="2.12.0" /> | |||||
| <PackageReference Include="Serilog.AspNetCore" Version="6.0.1" /> | |||||
| <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1"/> | |||||
| <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9"/> | |||||
| <PackageReference Include="Quartz" Version="3.5.0"/> | |||||
| <PackageReference Include="Serilog" Version="2.12.0"/> | |||||
| <PackageReference Include="Serilog.AspNetCore" Version="6.0.1"/> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <ProjectReference Include="..\SecureSharing.Business\SecureSharing.Business.csproj" /> | |||||
| <ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj" /> | |||||
| <ProjectReference Include="..\SecureSharing.Business\SecureSharing.Business.csproj"/> | |||||
| <ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj"/> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Folder Include="AppData\Errors\" /> | |||||
| <Folder Include="wwwroot\files" /> | |||||
| <Folder Include="AppData\Errors\"/> | |||||
| <Folder Include="wwwroot\files"/> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\Login.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\LoginTestbe.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\Register.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\ResetPassword.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\_ViewImports.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\_ValidationScriptsPartial.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\_ViewImports.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\_ViewStart.cshtml" /> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\Login.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\LoginTestbe.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\Register.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\ResetPassword.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\Account\_ViewImports.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\_ValidationScriptsPartial.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\_ViewImports.cshtml"/> | |||||
| <_ContentIncludedByDefault Remove="Areas\Identity\Pages\_ViewStart.cshtml"/> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> |
| <input asp-for="FilesAsText" id="fileInputAsText" type="text" style="display:none"/> | <input asp-for="FilesAsText" id="fileInputAsText" type="text" style="display:none"/> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="label-text"> | <div class="label-text"> | ||||
| Your files | Your files | ||||
| </div> | </div> | ||||
| <div id="filesUploaded"> | <div id="filesUploaded"> | ||||
| </div> | </div> | ||||
| <button class=" btn btn-light share-button" type="submit">Share</button> | <button class=" btn btn-light share-button" type="submit">Share</button> | ||||
| </form> | </form> | ||||
| <div class="label-text link-show"> | <div class="label-text link-show"> | ||||
| @foreach (var file in Model.MessageModel.FileNames) | @foreach (var file in Model.MessageModel.FileNames) | ||||
| { | { | ||||
| <a asp-action="Download" asp-route-filename="@file" asp-route-code="@Model.MessageModel.Code">@file</a><br/> | |||||
| <a asp-action="Download" asp-route-filename="@file" asp-route-code="@Model.MessageModel.Code">@file</a> | |||||
| <br/> | |||||
| } | } | ||||
| </div> | </div> | ||||
| } | } | ||||
| <div class="label-text link-show"> | <div class="label-text link-show"> | ||||
| @foreach (var file in Model.MessageModel.FileNames) | @foreach (var file in Model.MessageModel.FileNames) | ||||
| { | { | ||||
| <a asp-action="Download" asp-route-filename="@file" asp-route-code="@Model.MessageModel.Code">@file</a><br/> | |||||
| <a asp-action="Download" asp-route-filename="@file" asp-route-code="@Model.MessageModel.Code">@file</a> | |||||
| <br/> | |||||
| } | } | ||||
| </div> | </div> | ||||
| } | } |
| <link rel="stylesheet" href="~/plugins/daterangepicker/daterangepicker.css"> | <link rel="stylesheet" href="~/plugins/daterangepicker/daterangepicker.css"> | ||||
| <!-- summernote --> | <!-- summernote --> | ||||
| <link rel="stylesheet" href="~/plugins/summernote/summernote-bs4.min.css"> | <link rel="stylesheet" href="~/plugins/summernote/summernote-bs4.min.css"> | ||||
| <link href="~/lib/jquery-confirm/jquery-confirm.min.css" rel="stylesheet"/> | <link href="~/lib/jquery-confirm/jquery-confirm.min.css" rel="stylesheet"/> | ||||
| <link rel="stylesheet" href="~/css/site.css"> | <link rel="stylesheet" href="~/css/site.css"> |