From 4b423cfca91465238ba72a578c2f2df7f640ba0e Mon Sep 17 00:00:00 2001 From: George Whysall Date: Wed, 20 Apr 2022 18:37:09 +0100 Subject: [PATCH 1/3] Splitting out seeding functionality. --- projects/Hood.Core/Models/HoodDbContext.cs | 137 +++++++++++------- .../AccountRepository/AccountRepository.cs | 34 +---- .../Auth0AccountRepository.cs | 16 -- .../AccountRepository/IAccountRepository.cs | 2 - .../Services/EmailSender/EmailSender.cs | 2 - .../Startup/IServiceCollectionExtensions.cs | 34 +++-- .../Hood.UI/Controllers/AccountController.cs | 80 +++++++++- 7 files changed, 181 insertions(+), 124 deletions(-) diff --git a/projects/Hood.Core/Models/HoodDbContext.cs b/projects/Hood.Core/Models/HoodDbContext.cs index c1e13862..55c4be08 100644 --- a/projects/Hood.Core/Models/HoodDbContext.cs +++ b/projects/Hood.Core/Models/HoodDbContext.cs @@ -95,24 +95,53 @@ public DbSet Set() where TEntity : BaseEntity } public async virtual Task Seed() + { + await CheckDatabaseIsInitialisedAsync(); + + ApplicationUser siteAdmin = await GetOrUpdateSiteOwnerAsync(); + + await SetupRequiredRolesAsync(); + await SetupHoodMediaDirectoriesAsync(siteAdmin); + await InitialiseHoodSettingsAsync(); + await UpdateLegacyMediaDirectoryReferencesAsync(); + await SetDatabaseVersionAsync(); + } + + protected virtual async Task SetupRequiredRolesAsync() { try { - Option option = await Options.FirstOrDefaultAsync(); - } - catch (SqlException ex) - { - if (ex.Message.Contains("Login failed for user") || ex.Message.Contains("permission was denied")) - { - throw new StartupException("There was a problem connecting to the database.", ex, StartupError.DatabaseConnectionFailed); - } - else if (ex.Message.Contains("Invalid object name")) + var roleManager = Engine.Services.Resolve>(); + var userManager = Engine.Services.Resolve>(); + if (Engine.AccountManager.SupportsRoles()) { - - throw new StartupException("There are migrations missing.", ex, StartupError.MigrationMissing); + // Check all required roles exist locally + foreach (string role in Models.Roles.All) + { + if (!await roleManager.RoleExistsAsync(role)) + { + await Engine.AccountManager.CreateRoleAsync(role); + } + else + { + // If it does exist locally, ensure it has a remote id linked to it. + var localRole = await roleManager.FindByNameAsync(role); + if (!localRole.RemoteId.IsSet()) + { + await Engine.AccountManager.CreateRoleAsync(role); + } + } + } } } + catch (Exception ex) + { + throw new StartupException("An error occurred syncing local roles with Auth0.", ex, StartupError.Auth0Issue); + } + } + protected virtual async Task GetOrUpdateSiteOwnerAsync() + { try { string ownerEmail = Engine.SiteOwnerEmail; @@ -150,52 +179,52 @@ public async virtual Task Seed() } } + ApplicationUser siteAdmin = await Engine.AccountManager.GetUserByEmailAsync(Engine.SiteOwnerEmail); + var siteOwnerRef = await Options.SingleOrDefaultAsync(o => o.Id == "Hood.Settings.SiteOwner"); + if (siteOwnerRef == null) + { + Options.Add(new Option + { + Id = "Hood.Settings.SiteOwner", + Value = siteAdmin.Id + }); + } + else + { + siteOwnerRef.Value = siteAdmin.Id; + } + await SaveChangesAsync(); + + return siteAdmin; + } catch (Exception ex) { throw new StartupException("An error occurred while loading or creating the admin user.", ex, StartupError.AdminUserSetupError); } + } - ApplicationUser siteAdmin = await Engine.AccountManager.GetUserByEmailAsync(Engine.SiteOwnerEmail); + public virtual async Task CheckDatabaseIsInitialisedAsync() + { try { - var roleManager = Engine.Services.Resolve>(); - var userManager = Engine.Services.Resolve>(); - if (Engine.AccountManager.SupportsRoles()) - { - // Check all required roles exist locally - foreach (string role in Models.Roles.All) - { - if (!await roleManager.RoleExistsAsync(role)) - { - await Engine.AccountManager.CreateRoleAsync(role); - } - else - { - // If it does exist locally, ensure it has a remote id linked to it. - var localRole = await roleManager.FindByNameAsync(role); - if (!localRole.RemoteId.IsSet()) - { - await Engine.AccountManager.CreateRoleAsync(role); - } - } - } - } - } - catch (Exception ex) - { - throw new StartupException("An error occurred syncing local roles with Auth0.", ex, StartupError.Auth0Issue); + Option option = await Options.FirstOrDefaultAsync(); } - - if (!Options.Any(o => o.Id == "Hood.Settings.SiteOwner")) + catch (SqlException ex) { - Options.Add(new Option + if (ex.Message.Contains("Login failed for user") || ex.Message.Contains("permission was denied")) { - Id = "Hood.Settings.SiteOwner", - Value = siteAdmin.Id - }); + throw new StartupException("There was a problem connecting to the database.", ex, StartupError.DatabaseConnectionFailed); + } + else if (ex.Message.Contains("Invalid object name")) + { + throw new StartupException("There are migrations missing.", ex, StartupError.MigrationMissing); + } } + } + protected virtual async Task SetupHoodMediaDirectoriesAsync(ApplicationUser siteAdmin) + { if (!MediaDirectories.Any(o => o.Slug == MediaManager.SiteDirectorySlug && o.Type == DirectoryType.System)) { MediaDirectories.Add(new MediaDirectory { DisplayName = "Default", Slug = MediaManager.SiteDirectorySlug, OwnerId = siteAdmin.Id, Type = DirectoryType.System }); @@ -215,7 +244,11 @@ public async virtual Task Seed() { MediaDirectories.Add(new MediaDirectory { DisplayName = "Property", Slug = MediaManager.PropertyDirectorySlug, OwnerId = siteAdmin.Id, Type = DirectoryType.System }); } + await SaveChangesAsync(); + } + protected virtual async Task InitialiseHoodSettingsAsync() + { if (!Options.Any(o => o.Id == "Hood.Settings.Theme")) { Options.Add(new Option { Id = "Hood.Settings.Theme", Value = JsonConvert.SerializeObject("default") }); @@ -355,8 +388,11 @@ public async virtual Task Seed() Options.Add(new Option { Id = typeof(SeoSettings).ToString(), Value = JsonConvert.SerializeObject(new SeoSettings()) }); } } + await SaveChangesAsync(); + } - + protected virtual async Task UpdateLegacyMediaDirectoryReferencesAsync() + { if (Media.Any(o => o.DirectoryId == null)) { // Save any existing seeding, in case directories needed creating. @@ -405,14 +441,10 @@ public async virtual Task Seed() } } } + } - if (!Options.Any(o => o.Id == "Hood.Api.SystemPrivateKey")) - { - string guid = Guid.NewGuid().ToString(); - string key = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(guid)); - Options.Add(new Option { Id = "Hood.Api.SystemPrivateKey", Value = JsonConvert.SerializeObject(key) }); - } - + protected virtual async Task SetDatabaseVersionAsync() + { // Mark the database with the current version of Hood. if (!Options.Any(o => o.Id == "Hood.Version")) { @@ -426,6 +458,5 @@ public async virtual Task Seed() await SaveChangesAsync(); } - } } \ No newline at end of file diff --git a/projects/Hood.Core/Services/AccountRepository/AccountRepository.cs b/projects/Hood.Core/Services/AccountRepository/AccountRepository.cs index 6a1d948b..4bd78b7d 100644 --- a/projects/Hood.Core/Services/AccountRepository/AccountRepository.cs +++ b/projects/Hood.Core/Services/AccountRepository/AccountRepository.cs @@ -18,18 +18,10 @@ namespace Hood.Services public class AccountRepository : IAccountRepository { protected readonly HoodDbContext _db; - protected readonly IHttpContextAccessor _contextAccessor; - protected readonly LinkGenerator _linkGenerator; - protected readonly IMailService _mailService; - protected readonly IEmailSender _emailSender; public AccountRepository() { _db = Engine.Services.Resolve(); - _contextAccessor = Engine.Services.Resolve(); - _linkGenerator = Engine.Services.Resolve(); - _mailService = Engine.Services.Resolve(); - _emailSender = Engine.Services.Resolve(); } #region Helpers @@ -190,16 +182,7 @@ public virtual async Task SetPhoneNumberAsync(ApplicationUser modelToUpdate, str throw new Exception(setPhoneResult.Errors.FirstOrDefault().Description); } } - public virtual async Task SendVerificationEmail(ApplicationUser localUser, string userId, string returnUrl) - { - var code = await UserManager.GenerateEmailConfirmationTokenAsync(localUser); - var callbackUrl = _linkGenerator.GetUriByAction(_contextAccessor.HttpContext, "ConfirmEmail", "Account", new { userId = localUser.Id, code, returnUrl }); - var verifyModel = new VerifyEmailModel(localUser, callbackUrl) - { - SendToRecipient = true - }; - await _mailService.ProcessAndSend(verifyModel); - } + public virtual async Task ChangePassword(ApplicationUser user, string oldPassword, string newPassword) { return await UserManager.ChangePasswordAsync(user, oldPassword, newPassword); @@ -208,22 +191,7 @@ public virtual async Task ResetPasswordAsync(ApplicationUser use { return await UserManager.ResetPasswordAsync(user, code, password); } - public virtual async Task SendPasswordResetToken(ApplicationUser user) - { - string code = await UserManager.GeneratePasswordResetTokenAsync(user); - string callbackUrl = _linkGenerator.GetUriByAction(_contextAccessor.HttpContext, "ResetPassword", "Account", new { userId = user.Id, code }); - MailObject message = new MailObject() - { - To = new SendGrid.Helpers.Mail.EmailAddress(user.Email), - PreHeader = "Reset your password.", - Subject = "Reset your password." - }; - message.AddParagraph($"Please reset your password by clicking here:"); - message.AddCallToAction("Reset your password", callbackUrl); - message.Template = MailSettings.WarningTemplate; - await _emailSender.SendEmailAsync(message); - } public virtual async Task CreateAsync(ApplicationUser user, string password) { return await UserManager.CreateAsync(user, password); diff --git a/projects/Hood.Core/Services/AccountRepository/Auth0AccountRepository.cs b/projects/Hood.Core/Services/AccountRepository/Auth0AccountRepository.cs index 68526ebb..8ab283e1 100644 --- a/projects/Hood.Core/Services/AccountRepository/Auth0AccountRepository.cs +++ b/projects/Hood.Core/Services/AccountRepository/Auth0AccountRepository.cs @@ -50,18 +50,6 @@ public override async Task DeleteUserAsync(string localUserId, System.Security.C // now delete the user await base.DeleteUserAsync(localUserId, adminUser); } - public override async Task SendVerificationEmail(ApplicationUser localUser, string userId, string returnUrl) - { - // get the users' current connected account. - // send a verification email on the whattheolddowntheold. - var authService = new Auth0Service(); - var ticket = await authService.GetEmailVerificationTicket(userId, returnUrl); - var verifyModel = new VerifyEmailModel(localUser, ticket.Value) - { - SendToRecipient = true - }; - await _mailService.ProcessAndSend(verifyModel); - } public override Task ChangePassword(ApplicationUser user, string oldPassword, string newPassword) { throw new ApplicationException("This feature is disabled when using Auth0."); @@ -70,10 +58,6 @@ public override Task ResetPasswordAsync(ApplicationUser user, st { throw new ApplicationException("This feature is disabled when using Auth0."); } - public override Task SendPasswordResetToken(ApplicationUser user) - { - throw new ApplicationException("This feature is disabled when using Auth0."); - } public override async Task CreateAsync(ApplicationUser user, string password) { return await base.CreateAsync(user, password); diff --git a/projects/Hood.Core/Services/AccountRepository/IAccountRepository.cs b/projects/Hood.Core/Services/AccountRepository/IAccountRepository.cs index feef95fc..911af496 100644 --- a/projects/Hood.Core/Services/AccountRepository/IAccountRepository.cs +++ b/projects/Hood.Core/Services/AccountRepository/IAccountRepository.cs @@ -19,7 +19,6 @@ public interface IAccountRepository Task GetDirectoryAsync(string id); Task SetEmailAsync(ApplicationUser modelToUpdate, string email); Task SetPhoneNumberAsync(ApplicationUser modelToUpdate, string email); - Task SendVerificationEmail(ApplicationUser localUser, string userId, string returnUrl); Task ChangePassword(ApplicationUser user, string oldPassword, string newPassword); Task ConfirmEmailAsync(ApplicationUser user, string code); Task ResetPasswordAsync(ApplicationUser user, string code, string password); @@ -54,7 +53,6 @@ public interface IAccountRepository #region Statistics Task GetStatisticsAsync(); - Task SendPasswordResetToken(ApplicationUser user); #endregion } } \ No newline at end of file diff --git a/projects/Hood.Core/Services/EmailSender/EmailSender.cs b/projects/Hood.Core/Services/EmailSender/EmailSender.cs index fe678046..2161e98c 100644 --- a/projects/Hood.Core/Services/EmailSender/EmailSender.cs +++ b/projects/Hood.Core/Services/EmailSender/EmailSender.cs @@ -15,7 +15,6 @@ namespace Hood.Services { public class EmailSender : IEmailSender { - protected readonly IHttpContextAccessor _contextAccessor; protected Models.MailSettings _mail; protected Models.BasicSettings _info; protected readonly IRazorViewRenderer _renderer; @@ -24,7 +23,6 @@ public class EmailSender : IEmailSender public EmailSender() { - _contextAccessor = Engine.Services.Resolve(); _renderer = Engine.Services.Resolve(); } diff --git a/projects/Hood.Core/Startup/IServiceCollectionExtensions.cs b/projects/Hood.Core/Startup/IServiceCollectionExtensions.cs index f35e633c..1c3a24a9 100644 --- a/projects/Hood.Core/Startup/IServiceCollectionExtensions.cs +++ b/projects/Hood.Core/Startup/IServiceCollectionExtensions.cs @@ -286,6 +286,25 @@ public static IServiceCollection ConfigureAuth0(this IServiceCollection services options.Scope = auth0Options.Scope; }); + services.AddAuth0IdentityStores(); + + services.AddOptions(CookieAuthenticationDefaults.AuthenticationScheme) + .Configure(options => + { + SetAuthenticationCookieDefaults(config, options); + }); + + services.AddAuthorization(options => + { + options.AddPolicy(Policies.Active, policy => policy.RequireClaim(Identity.HoodClaimTypes.Active)); + options.AddPolicy(Policies.AccountNotConnected, policy => policy.RequireClaim(Identity.HoodClaimTypes.AccountNotConnected)); + }); + return services; + + } + + public static void AddAuth0IdentityStores(this IServiceCollection services) + { // Mock Aspnet Identity stores. services.TryAddScoped, UserValidator>(); services.TryAddScoped, PasswordValidator>(); @@ -300,22 +319,9 @@ public static IServiceCollection ConfigureAuth0(this IServiceCollection services identityBuilder.AddRoleStore>(); identityBuilder.AddUserStore>(); identityBuilder.AddUserManager>(); + identityBuilder.AddRoleManager>(); services.AddScoped(); - - services.AddOptions(CookieAuthenticationDefaults.AuthenticationScheme) - .Configure(options => - { - SetAuthenticationCookieDefaults(config, options); - }); - - services.AddAuthorization(options => - { - options.AddPolicy(Policies.Active, policy => policy.RequireClaim(Identity.HoodClaimTypes.Active)); - options.AddPolicy(Policies.AccountNotConnected, policy => policy.RequireClaim(Identity.HoodClaimTypes.AccountNotConnected)); - }); - return services; - } private static void SetAuthenticationCookieDefaults(IConfiguration config, CookieAuthenticationOptions options) diff --git a/projects/Hood.UI/Controllers/AccountController.cs b/projects/Hood.UI/Controllers/AccountController.cs index 7a21e435..98643f72 100644 --- a/projects/Hood.UI/Controllers/AccountController.cs +++ b/projects/Hood.UI/Controllers/AccountController.cs @@ -14,9 +14,11 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Routing; using System; using System.Collections.Generic; using System.Linq; @@ -86,7 +88,7 @@ public virtual async Task Login(LoginViewModel model, string retu ApplicationUser user = await _userManager.FindByNameAsync(model.Username); if (Engine.Settings.Account.RequireEmailConfirmation && !user.EmailConfirmed) { - await _account.SendVerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); + await SendVerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); return RedirectToAction(nameof(ConfirmRequired), new { user = user.Id }); } @@ -201,7 +203,7 @@ public virtual async Task Register(PasswordRegisterViewModel mode if (Engine.Settings.Account.RequireEmailConfirmation) { - await _account.SendVerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); + await SendVerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); return RedirectToAction(nameof(AccountController.ConfirmRequired), "Account"); } return RedirectToLocal(returnUrl); @@ -247,6 +249,7 @@ public virtual async Task Authorize(string returnUrl = "/", string mode = "login throw new ApplicationException("This endpoint is only available when using Auth0."); } + // TODO: #269 Insert colours and logos and parameters for standard login. var authenticationPropertiesBuilder = new LoginAuthenticationPropertiesBuilder() // .WithParameter("logo", "https://cdn.jsdelivr.net/npm/hoodcms@5.0.15/images/icons/file.png") // .WithParameter("color", "black") @@ -726,7 +729,14 @@ public virtual async Task ResendConfirm() try { ApplicationUser user = await GetCurrentUserOrThrow(); - await _account.SendVerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); + if (Engine.Auth0Enabled) + { + await SendAuth0VerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); + } + else + { + await SendVerificationEmail(user, User.GetUserId(), Url.AbsoluteAction("Login", "Account")); + } SaveMessage = $"Email verification has been resent."; MessageType = AlertType.Success; @@ -861,7 +871,7 @@ public virtual async Task ForgotPassword(ForgotPasswordViewModel return View("ForgotPasswordConfirmation"); } - await _account.SendPasswordResetToken(user); + await SendPasswordResetToken(user); return RedirectToAction(nameof(ForgotPasswordConfirmation)); } @@ -981,6 +991,68 @@ public virtual IActionResult Deleted() #endregion #region Helpers + protected virtual async Task SendVerificationEmail(ApplicationUser localUser, string userId, string returnUrl) + { + var code = await _userManager.GenerateEmailConfirmationTokenAsync(localUser); + var contextAccessor = Engine.Services.Resolve(); + if (contextAccessor == null) + { + return; + } + var linkGenerator = Engine.Services.Resolve(); + if (linkGenerator == null) + { + return; + } + var callbackUrl = linkGenerator.GetUriByAction(contextAccessor.HttpContext, "ConfirmEmail", "Account", new { userId = localUser.Id, code, returnUrl }); + var verifyModel = new VerifyEmailModel(localUser, callbackUrl) + { + SendToRecipient = true + }; + await _mailService.ProcessAndSend(verifyModel); + } + + protected virtual async Task SendAuth0VerificationEmail(ApplicationUser localUser, string userId, string returnUrl) + { + // get the users' current connected account. + // send a verification email on the whattheolddowntheold. + var authService = new Auth0Service(); + var ticket = await authService.GetEmailVerificationTicket(userId, returnUrl); + var verifyModel = new VerifyEmailModel(localUser, ticket.Value) + { + SendToRecipient = true + }; + await _mailService.ProcessAndSend(verifyModel); + } + + protected virtual async Task SendPasswordResetToken(ApplicationUser user) + { + string code = await _userManager.GeneratePasswordResetTokenAsync(user); + + var contextAccessor = Engine.Services.Resolve(); + if (contextAccessor == null) + { + return; + } + var linkGenerator = Engine.Services.Resolve(); + if (linkGenerator == null) + { + return; + } + + string callbackUrl = linkGenerator.GetUriByAction(contextAccessor.HttpContext, "ResetPassword", "Account", new { userId = user.Id, code }); + + MailObject message = new MailObject() + { + To = new SendGrid.Helpers.Mail.EmailAddress(user.Email), + PreHeader = "Reset your password.", + Subject = "Reset your password." + }; + message.AddParagraph($"Please reset your password by clicking here:"); + message.AddCallToAction("Reset your password", callbackUrl); + message.Template = MailSettings.WarningTemplate; + await _emailSender.SendEmailAsync(message); + } protected virtual async Task SendWelcomeEmail(ApplicationUser user) { From d2c30ef96414f203cc53f26230cf847e83c915b7 Mon Sep 17 00:00:00 2001 From: George Whysall Date: Wed, 4 May 2022 13:18:38 +0100 Subject: [PATCH 2/3] Fixed slug extensions to include params in type. --- .../Hood.Development/src/ts/extensions/jqueryExtensions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/Hood.Development/src/ts/extensions/jqueryExtensions.ts b/projects/Hood.Development/src/ts/extensions/jqueryExtensions.ts index 4abc8c46..22d7f65d 100644 --- a/projects/Hood.Development/src/ts/extensions/jqueryExtensions.ts +++ b/projects/Hood.Development/src/ts/extensions/jqueryExtensions.ts @@ -4,9 +4,9 @@ import { Alerts } from '../core/Alerts'; declare global { interface JQuery { exists(): number; - restrictToSlug(): void; - restrictToPageSlug(): void; - restrictToMetaSlug(): void; + restrictToSlug(restrictPattern?: RegExp): void; + restrictToPageSlug(restrictPattern?: RegExp): void; + restrictToMetaSlug(restrictPattern?: RegExp): void; characterCounter(): void; warningAlert(): void; } From ab8272f719fd44c61da5951153d430d44a02363f Mon Sep 17 00:00:00 2001 From: George Whysall Date: Fri, 20 May 2022 15:00:38 +0100 Subject: [PATCH 3/3] Bumped, and fixed media upload missing PDFs. --- projects/Hood.Admin/Hood.Admin.csproj | 2 +- projects/Hood.Core.Admin/Hood.Core.Admin.csproj | 2 +- projects/Hood.Core/Hood.Core.csproj | 2 +- projects/Hood.Development/package.json | 2 +- projects/Hood.Development/src/ts/core/Media.ts | 2 +- projects/Hood.UI.Admin/Hood.UI.Admin.csproj | 2 +- projects/Hood.UI.Bootstrap3/Hood.UI.Bootstrap3.csproj | 2 +- projects/Hood.UI.Bootstrap4/Hood.UI.Bootstrap4.csproj | 2 +- projects/Hood.UI.Core/Hood.UI.Core.csproj | 2 +- projects/Hood.UI/Hood.UI.csproj | 2 +- projects/Hood.Web/package.json | 4 ++-- projects/Hood/Hood.csproj | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/projects/Hood.Admin/Hood.Admin.csproj b/projects/Hood.Admin/Hood.Admin.csproj index b925c05f..2f97f6e7 100644 --- a/projects/Hood.Admin/Hood.Admin.csproj +++ b/projects/Hood.Admin/Hood.Admin.csproj @@ -5,7 +5,7 @@ Hood.Admin Hood.Admin - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.Core.Admin/Hood.Core.Admin.csproj b/projects/Hood.Core.Admin/Hood.Core.Admin.csproj index 8ebcfd26..a4e736f1 100644 --- a/projects/Hood.Core.Admin/Hood.Core.Admin.csproj +++ b/projects/Hood.Core.Admin/Hood.Core.Admin.csproj @@ -5,7 +5,7 @@ Hood.Core.Admin Hood.Core.Admin - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.Core/Hood.Core.csproj b/projects/Hood.Core/Hood.Core.csproj index d232ea9e..70844a95 100644 --- a/projects/Hood.Core/Hood.Core.csproj +++ b/projects/Hood.Core/Hood.Core.csproj @@ -5,7 +5,7 @@ Hood.Core Hood.Core - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.Development/package.json b/projects/Hood.Development/package.json index 9d546fea..500bbc17 100644 --- a/projects/Hood.Development/package.json +++ b/projects/Hood.Development/package.json @@ -1,6 +1,6 @@ { "name": "hoodcms", - "version": "6.0.8", + "version": "6.0.9", "description": "A fully customisable content management system built in ASP.NET Core 5 & Bootstrap 5.", "keywords": [ "hood", diff --git a/projects/Hood.Development/src/ts/core/Media.ts b/projects/Hood.Development/src/ts/core/Media.ts index cf38efe0..2c4c3d13 100644 --- a/projects/Hood.Development/src/ts/core/Media.ts +++ b/projects/Hood.Development/src/ts/core/Media.ts @@ -174,7 +174,7 @@ export class MediaService { thumbnailHeight: 80, parallelUploads: 5, paramName: 'files', - acceptedFiles: $("#media-upload").data('types') || ".png,.jpg,.jpeg,.gif", + acceptedFiles: $("#media-upload").data('types') || ".png,.jpg,.jpeg,.gif,.pdf", autoProcessQueue: true, // Make sure the files aren't queued until manually added previewsContainer: false, // Define the container to display the previews clickable: "#media-add", // Define the element that should be used as click trigger to select files. diff --git a/projects/Hood.UI.Admin/Hood.UI.Admin.csproj b/projects/Hood.UI.Admin/Hood.UI.Admin.csproj index 450ae6fa..68e2ca1e 100644 --- a/projects/Hood.UI.Admin/Hood.UI.Admin.csproj +++ b/projects/Hood.UI.Admin/Hood.UI.Admin.csproj @@ -5,7 +5,7 @@ Hood.UI.Admin Hood.UI.Admin - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.UI.Bootstrap3/Hood.UI.Bootstrap3.csproj b/projects/Hood.UI.Bootstrap3/Hood.UI.Bootstrap3.csproj index 75794149..2d58acad 100644 --- a/projects/Hood.UI.Bootstrap3/Hood.UI.Bootstrap3.csproj +++ b/projects/Hood.UI.Bootstrap3/Hood.UI.Bootstrap3.csproj @@ -5,7 +5,7 @@ Hood.UI.Bootstrap3 Hood.UI.Bootstrap3 - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.UI.Bootstrap4/Hood.UI.Bootstrap4.csproj b/projects/Hood.UI.Bootstrap4/Hood.UI.Bootstrap4.csproj index e8b710f3..7ff3b11c 100644 --- a/projects/Hood.UI.Bootstrap4/Hood.UI.Bootstrap4.csproj +++ b/projects/Hood.UI.Bootstrap4/Hood.UI.Bootstrap4.csproj @@ -5,7 +5,7 @@ Hood.UI.Bootstrap4 Hood.UI.Bootstrap4 - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.UI.Core/Hood.UI.Core.csproj b/projects/Hood.UI.Core/Hood.UI.Core.csproj index 9bd0ad12..dd9263e5 100644 --- a/projects/Hood.UI.Core/Hood.UI.Core.csproj +++ b/projects/Hood.UI.Core/Hood.UI.Core.csproj @@ -5,7 +5,7 @@ Hood.UI.Core Hood.UI.Core - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.UI/Hood.UI.csproj b/projects/Hood.UI/Hood.UI.csproj index 77dbcc61..8921b21a 100644 --- a/projects/Hood.UI/Hood.UI.csproj +++ b/projects/Hood.UI/Hood.UI.csproj @@ -5,7 +5,7 @@ Hood.UI Hood.UI - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library diff --git a/projects/Hood.Web/package.json b/projects/Hood.Web/package.json index deeb7407..0405b77b 100644 --- a/projects/Hood.Web/package.json +++ b/projects/Hood.Web/package.json @@ -1,6 +1,6 @@ { "name": "hood.blank", - "version": "6.0.8", + "version": "6.0.9", "description": "Demo project for Hood CMS. Uses Nuget packages.", "author": "George Whysall", "scripts": { @@ -22,7 +22,7 @@ "watch-tsc": "npm-watch tsc" }, "dependencies": { - "hoodcms": "6.0.8" + "hoodcms": "6.0.9" }, "devDependencies": { "@lopatnov/rollup-plugin-uglify": "^2.1.2", diff --git a/projects/Hood/Hood.csproj b/projects/Hood/Hood.csproj index f6388a23..331eae70 100644 --- a/projects/Hood/Hood.csproj +++ b/projects/Hood/Hood.csproj @@ -6,7 +6,7 @@ Hood Complete Hood CMS Package, includes all default controllers for basic setup, packaged with the Bootstrap 4 default theme. - 6.0.8 + 6.0.9 net5.0 Hood Digital;George Whysall; Library