diff --git a/global.json b/global.json index 391ba3c2a3..da113e4cbd 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,7 @@ { "sdk": { - "version": "8.0.100", - "rollForward": "latestFeature" + "version": "8.0.0", + "rollForward": "latestFeature", + "allowPrerelease": false } -} +} \ No newline at end of file diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props new file mode 100644 index 0000000000..bfa71d3932 --- /dev/null +++ b/src/Directory.Packages.props @@ -0,0 +1,70 @@ + + + + true + NU1507 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj b/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj index b6f8e44c5d..82439efec6 100644 --- a/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj +++ b/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj b/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj index db7ac432bc..bb9b44cf51 100644 --- a/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj +++ b/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj @@ -2,11 +2,12 @@ Umbraco CMS - Imaging - ImageSharp Adds imaging support using ImageSharp/ImageSharp.Web to Umbraco CMS. + false - - + + diff --git a/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj b/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj index 84370a54c2..d55479d8ec 100644 --- a/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj +++ b/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj @@ -2,6 +2,7 @@ Umbraco CMS - Imaging - ImageSharp 2 Adds imaging support using ImageSharp/ImageSharp.Web version 2 to Umbraco CMS. + false diff --git a/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj b/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj index baab56e96e..5229f513a2 100644 --- a/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj +++ b/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj b/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj index e17f16b8bb..36751bb869 100644 --- a/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj +++ b/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj b/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj index 538a4d9f25..39f035407b 100644 --- a/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj +++ b/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj @@ -5,10 +5,9 @@ - - - - + + + diff --git a/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj b/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj index 37cd0da0f7..0de13a39b6 100644 --- a/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj +++ b/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj index b49b4eebee..f9755aad61 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj +++ b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj index 37653bc9a8..b930ff1bc0 100644 --- a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj +++ b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj @@ -4,6 +4,9 @@ Installs Umbraco CMS with minimal dependencies in your ASP.NET Core project. false false + + false + false diff --git a/src/Umbraco.Cms/Umbraco.Cms.csproj b/src/Umbraco.Cms/Umbraco.Cms.csproj index 39a3b03c56..8b0dcb8a87 100644 --- a/src/Umbraco.Cms/Umbraco.Cms.csproj +++ b/src/Umbraco.Cms/Umbraco.Cms.csproj @@ -4,6 +4,7 @@ Installs Umbraco CMS with all default dependencies in your ASP.NET Core project. false false + false diff --git a/src/Umbraco.Core/Constants-WebhookEvents.cs b/src/Umbraco.Core/Constants-WebhookEvents.cs index afd57b5188..41b9849f08 100644 --- a/src/Umbraco.Core/Constants-WebhookEvents.cs +++ b/src/Umbraco.Core/Constants-WebhookEvents.cs @@ -6,6 +6,57 @@ public static partial class Constants { public static class Aliases { + + /// + /// Webhook event alias for content versions deleted + /// + public const string ContentDeletedVersions = "Umbraco.ContentDeletedVersions"; + + /// + /// Webhook event alias for content blueprint saved + /// + public const string ContentSavedBlueprint = "Umbraco.ContentSavedBlueprint"; + + /// + /// Webhook event alias for content blueprint deleted + /// + public const string ContentDeletedBlueprint = "Umbraco.ContentDeletedBlueprint"; + + /// + /// Webhook event alias for content moved into the recycle bin. + /// + public const string ContentMovedToRecycleBin = "Umbraco.ContentMovedToRecycleBin"; + + /// + /// Webhook event alias for content sorted. + /// + public const string ContentSorted = "Umbraco.ContentSorted"; + + /// + /// Webhook event alias for content moved. + /// + public const string ContentMoved = "Umbraco.ContentMoved"; + + /// + /// Webhook event alias for content copied. + /// + public const string ContentCopied = "Umbraco.ContentCopied"; + + /// + /// Webhook event alias for content emptied recycle bin. + /// + public const string ContentEmptiedRecycleBin = "Umbraco.ContentEmptiedRecycleBin"; + + /// + /// Webhook event alias for content rolled back. + /// + public const string ContentRolledBack = "Umbraco.ContentRolledBack"; + + /// + /// Webhook event alias for content saved. + /// + public const string ContentSaved = "Umbraco.ContentSaved"; + /// /// Webhook event alias for content publish. /// diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml index 572fe05dd4..00cb113ddf 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml @@ -1941,6 +1941,14 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Create header Logs No webhook headers have been added + No events were found. + Enabled + Events + Event + Url + Types + Webhook key + Retry count Add language diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml index 33901735ee..c6c0280997 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml @@ -2023,6 +2023,14 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Create header Logs No webhook headers have been added + No events were found. + Enabled + Events + Event + Url + Types + Webhook key + Retry count Add language diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/fr.xml b/src/Umbraco.Core/EmbeddedResources/Lang/fr.xml index b30dba4a69..24da7d0066 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/fr.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/fr.xml @@ -1585,6 +1585,13 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Ceci n'est pas d'application pour un Type d'Elément Vous avez apporté des modifications à cette propriété. Etes-vous certain.e de vouloir les annuler? + + Créer un webhook + Ajouter un header au webhook + Logs + Ajouter un Type de Document + Ajouter un Type de Media + Ajouter une langue Langue obligatoire @@ -1715,6 +1722,7 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Configuration Modélisation Parties Tierces + Webhooks Nouvelle mise à jour disponible diff --git a/src/Umbraco.Core/HealthChecks/HealthCheckResults.cs b/src/Umbraco.Core/HealthChecks/HealthCheckResults.cs index afeb8ba9fa..f88b96c9d6 100644 --- a/src/Umbraco.Core/HealthChecks/HealthCheckResults.cs +++ b/src/Umbraco.Core/HealthChecks/HealthCheckResults.cs @@ -53,6 +53,8 @@ public class HealthCheckResults return new HealthCheckResults(results, allChecksSuccessful); } + public static async Task Create(HealthCheck check) => await Create(new List() { check }); + public void LogResults() { Logger.LogInformation("Scheduled health check results:"); diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs index 4cf5bdd6af..9bced05ff5 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs @@ -71,6 +71,14 @@ public interface IPublishedPropertyType /// Type ModelClrType { get; } + /// + /// Gets the property model Delivery Api CLR type. + /// + /// + /// The model CLR type may be a type, or may contain types. + /// + Type DeliveryApiModelClrType => ModelClrType; + /// /// Gets the property CLR type. /// diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs index 52e3371767..ed2d19cd6f 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs @@ -24,6 +24,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent private PropertyCacheLevel _deliveryApiCacheLevelForExpansion; private Type? _modelClrType; + private Type? _deliveryApiModelClrType; private Type? _clrType; #region Constructors @@ -192,17 +193,13 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } } + var deliveryApiPropertyValueConverter = _converter as IDeliveryApiPropertyValueConverter; + _cacheLevel = _converter?.GetPropertyCacheLevel(this) ?? PropertyCacheLevel.Snapshot; - if (_converter is IDeliveryApiPropertyValueConverter deliveryApiPropertyValueConverter) - { - _deliveryApiCacheLevel = deliveryApiPropertyValueConverter.GetDeliveryApiPropertyCacheLevel(this); - _deliveryApiCacheLevelForExpansion = deliveryApiPropertyValueConverter.GetDeliveryApiPropertyCacheLevelForExpansion(this); - } - else - { - _deliveryApiCacheLevel = _deliveryApiCacheLevelForExpansion = _cacheLevel; - } + _deliveryApiCacheLevel = deliveryApiPropertyValueConverter?.GetDeliveryApiPropertyCacheLevel(this) ?? _cacheLevel; + _deliveryApiCacheLevelForExpansion = deliveryApiPropertyValueConverter?.GetDeliveryApiPropertyCacheLevelForExpansion(this) ?? _cacheLevel; _modelClrType = _converter?.GetPropertyValueType(this) ?? typeof(object); + _deliveryApiModelClrType = deliveryApiPropertyValueConverter?.GetDeliveryApiPropertyValueType(this) ?? _modelClrType; } /// @@ -352,6 +349,20 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } } + /// + public Type DeliveryApiModelClrType + { + get + { + if (!_initialized) + { + Initialize(); + } + + return _deliveryApiModelClrType!; + } + } + /// public Type? ClrType { diff --git a/src/Umbraco.Core/Notifications/HealthCheckCompletedNotification.cs b/src/Umbraco.Core/Notifications/HealthCheckCompletedNotification.cs new file mode 100644 index 0000000000..67df86deb1 --- /dev/null +++ b/src/Umbraco.Core/Notifications/HealthCheckCompletedNotification.cs @@ -0,0 +1,13 @@ +using Umbraco.Cms.Core.HealthChecks; + +namespace Umbraco.Cms.Core.Notifications; + +public class HealthCheckCompletedNotification : INotification +{ + public HealthCheckCompletedNotification(HealthCheckResults healthCheckResults) + { + HealthCheckResults = healthCheckResults; + } + + public HealthCheckResults HealthCheckResults { get; } +} diff --git a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs index 0f9cc8fca9..8abc0906ce 100644 --- a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs +++ b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Umbraco.Cms.Core.PublishedCache; /// @@ -6,5 +8,5 @@ namespace Umbraco.Cms.Core.PublishedCache; /// public interface IPublishedSnapshotAccessor { - bool TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot); + bool TryGetPublishedSnapshot([NotNullWhen(true)] out IPublishedSnapshot? publishedSnapshot); } diff --git a/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs b/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs index 8f3e4fe827..91e32e6db4 100644 --- a/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs +++ b/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Umbraco.Cms.Core.Web; namespace Umbraco.Cms.Core.PublishedCache; @@ -29,7 +30,7 @@ public class UmbracoContextPublishedSnapshotAccessor : IPublishedSnapshotAccesso set => throw new NotSupportedException(); // not ok to set } - public bool TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) + public bool TryGetPublishedSnapshot([NotNullWhen(true)] out IPublishedSnapshot? publishedSnapshot) { if (!_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext)) { diff --git a/src/Umbraco.Core/Services/UserServiceExtensions.cs b/src/Umbraco.Core/Services/UserServiceExtensions.cs index f17a266616..7399f37fe8 100644 --- a/src/Umbraco.Core/Services/UserServiceExtensions.cs +++ b/src/Umbraco.Core/Services/UserServiceExtensions.cs @@ -8,6 +8,11 @@ namespace Umbraco.Extensions; public static class UserServiceExtensions { public static EntityPermission? GetPermissions(this IUserService userService, IUser? user, string path) + { + return userService.GetAllPermissions(user, path).FirstOrDefault(); + } + + public static EntityPermissionCollection GetAllPermissions(this IUserService userService, IUser? user, string path) { var ids = path.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries) .Select(x => @@ -23,7 +28,7 @@ public static class UserServiceExtensions " could not be parsed into an array of integers or the path was empty"); } - return userService.GetPermissions(user, ids[^1]).FirstOrDefault(); + return userService.GetPermissions(user, ids[^1]); } /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7e56ff8f76..8aebb53f60 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -7,16 +7,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentCopiedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentCopiedWebhookEvent.cs new file mode 100644 index 0000000000..3d6f0163d7 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentCopiedWebhookEvent.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Copied", Constants.WebhookEvents.Types.Content)] +public class ContentCopiedWebhookEvent : WebhookEventBase +{ + public ContentCopiedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentCopied; + + public override object? ConvertNotificationToRequestPayload(ContentCopiedNotification notification) + { + return new + { + notification.Copy, + notification.Original, + notification.ParentId, + notification.RelateToOriginal + }; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedBlueprintWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedBlueprintWebhookEvent.cs new file mode 100644 index 0000000000..996b8abd15 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedBlueprintWebhookEvent.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Template [Blueprint] Deleted", Constants.WebhookEvents.Types.Content)] +public class ContentDeletedBlueprintWebhookEvent : WebhookEventContentBase +{ + public ContentDeletedBlueprintWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentDeletedBlueprint; + + protected override IEnumerable GetEntitiesFromNotification(ContentDeletedBlueprintNotification notification) => + notification.DeletedBlueprints; + + protected override object ConvertEntityToRequestPayload(IContent entity) => entity; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedVersionsWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedVersionsWebhookEvent.cs new file mode 100644 index 0000000000..c543bfe3ca --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedVersionsWebhookEvent.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Versions Deleted", Constants.WebhookEvents.Types.Content)] +public class ContentDeletedVersionsWebhookEvent : WebhookEventBase +{ + public ContentDeletedVersionsWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentDeletedVersions; + + public override object? ConvertNotificationToRequestPayload(ContentDeletedVersionsNotification notification) + { + return new + { + notification.Id, + notification.DeletePriorVersions, + notification.SpecificVersion, + notification.DateToRetain + }; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedWebhookEvent.cs similarity index 77% rename from src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs rename to src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedWebhookEvent.cs index 85a1f39ba9..1282822995 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentDeletedWebhookEvent.cs @@ -5,12 +5,12 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; -namespace Umbraco.Cms.Core.Webhooks.Events; +namespace Umbraco.Cms.Core.Webhooks.Events.Content; -[WebhookEvent("Content was deleted", Constants.WebhookEvents.Types.Content)] -public class ContentDeleteWebhookEvent : WebhookEventContentBase +[WebhookEvent("Content Deleted", Constants.WebhookEvents.Types.Content)] +public class ContentDeletedWebhookEvent : WebhookEventContentBase { - public ContentDeleteWebhookEvent( + public ContentDeletedWebhookEvent( IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor webhookSettings, diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentEmptiedRecycleBinWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentEmptiedRecycleBinWebhookEvent.cs new file mode 100644 index 0000000000..8670d23c49 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentEmptiedRecycleBinWebhookEvent.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DeliveryApi; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Recycle Bin Emptied", Constants.WebhookEvents.Types.Content)] +public class ContentEmptiedRecycleBinWebhookEvent : WebhookEventContentBase +{ + private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IApiContentBuilder _apiContentBuilder; + + public ContentEmptiedRecycleBinWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IApiContentBuilder apiContentBuilder) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + _publishedSnapshotAccessor = publishedSnapshotAccessor; + _apiContentBuilder = apiContentBuilder; + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentEmptiedRecycleBin; + + protected override IEnumerable GetEntitiesFromNotification(ContentEmptiedRecycleBinNotification notification) => + notification.DeletedEntities; + + protected override object? ConvertEntityToRequestPayload(IContent entity) => entity; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentMovedToRecycleBinWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentMovedToRecycleBinWebhookEvent.cs new file mode 100644 index 0000000000..6ed74d8c66 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentMovedToRecycleBinWebhookEvent.cs @@ -0,0 +1,29 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Moved to Recycle Bin", Constants.WebhookEvents.Types.Content)] +public class ContentMovedToRecycleBinWebhookEvent : WebhookEventBase +{ + public ContentMovedToRecycleBinWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentMovedToRecycleBin; + + public override object? ConvertNotificationToRequestPayload(ContentMovedToRecycleBinNotification notification) + => notification.MoveInfoCollection; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentMovedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentMovedWebhookEvent.cs new file mode 100644 index 0000000000..46d487c499 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentMovedWebhookEvent.cs @@ -0,0 +1,29 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Moved", Constants.WebhookEvents.Types.Content)] +public class ContentMovedWebhookEvent : WebhookEventBase +{ + public ContentMovedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentMoved; + + public override object? ConvertNotificationToRequestPayload(ContentMovedNotification notification) + => notification.MoveInfoCollection; +} diff --git a/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentPublishedWebhookEvent.cs similarity index 86% rename from src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs rename to src/Umbraco.Core/Webhooks/Events/Content/ContentPublishedWebhookEvent.cs index e1ba7125ec..5847fb450e 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentPublishedWebhookEvent.cs @@ -8,15 +8,15 @@ using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; -namespace Umbraco.Cms.Core.Webhooks.Events; +namespace Umbraco.Cms.Core.Webhooks.Events.Content; -[WebhookEvent("Content was published", Constants.WebhookEvents.Types.Content)] -public class ContentPublishWebhookEvent : WebhookEventContentBase +[WebhookEvent("Content Published", Constants.WebhookEvents.Types.Content)] +public class ContentPublishedWebhookEvent : WebhookEventContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly IApiContentBuilder _apiContentBuilder; - public ContentPublishWebhookEvent( + public ContentPublishedWebhookEvent( IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor webhookSettings, diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentRolledBack.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentRolledBack.cs new file mode 100644 index 0000000000..f38ff571f9 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentRolledBack.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DeliveryApi; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Rolled Back", Constants.WebhookEvents.Types.Content)] +public class ContentRolledBackWebhookEvent : WebhookEventContentBase +{ + private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IApiContentBuilder _apiContentBuilder; + + public ContentRolledBackWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IApiContentBuilder apiContentBuilder) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + _publishedSnapshotAccessor = publishedSnapshotAccessor; + _apiContentBuilder = apiContentBuilder; + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentRolledBack; + + protected override IEnumerable GetEntitiesFromNotification(ContentRolledBackNotification notification) => + new List { notification.Entity }; + + protected override object? ConvertEntityToRequestPayload(IContent entity) + { + if (_publishedSnapshotAccessor.TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) is false || publishedSnapshot!.Content is null) + { + return null; + } + + // Get preview/saved version of content for a rollback + IPublishedContent? publishedContent = publishedSnapshot.Content.GetById(true, entity.Key); + return publishedContent is null ? null : _apiContentBuilder.Build(publishedContent); + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentSavedBlueprintWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentSavedBlueprintWebhookEvent.cs new file mode 100644 index 0000000000..40630b453f --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentSavedBlueprintWebhookEvent.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Template [Blueprint] Saved", Constants.WebhookEvents.Types.Content)] +public class ContentSavedBlueprintWebhookEvent : WebhookEventContentBase +{ + public ContentSavedBlueprintWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentSavedBlueprint; + + protected override IEnumerable + GetEntitiesFromNotification(ContentSavedBlueprintNotification notification) + => new List { notification.SavedBlueprint }; + + protected override object ConvertEntityToRequestPayload(IContent entity) => entity; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentSavedWebhookEvent.cs new file mode 100644 index 0000000000..fac16de822 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentSavedWebhookEvent.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DeliveryApi; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Saved", Constants.WebhookEvents.Types.Content)] +public class ContentSavedWebhookEvent : WebhookEventContentBase +{ + private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IApiContentBuilder _apiContentBuilder; + + public ContentSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IApiContentBuilder apiContentBuilder) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + _publishedSnapshotAccessor = publishedSnapshotAccessor; + _apiContentBuilder = apiContentBuilder; + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentSaved; + + protected override IEnumerable GetEntitiesFromNotification(ContentSavedNotification notification) => + notification.SavedEntities; + + protected override object? ConvertEntityToRequestPayload(IContent entity) + { + if (_publishedSnapshotAccessor.TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) is false || publishedSnapshot!.Content is null) + { + return null; + } + + // Get preview/saved version of content + IPublishedContent? publishedContent = publishedSnapshot.Content.GetById(true, entity.Key); + return publishedContent is null ? null : _apiContentBuilder.Build(publishedContent); + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/Content/ContentSortedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentSortedWebhookEvent.cs new file mode 100644 index 0000000000..d2a95028e2 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentSortedWebhookEvent.cs @@ -0,0 +1,53 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DeliveryApi; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Content; + +[WebhookEvent("Content Sorted", Constants.WebhookEvents.Types.Content)] +public class ContentSortedWebhookEvent : WebhookEventBase +{ + private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IApiContentBuilder _apiContentBuilder; + + public ContentSortedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webhookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IApiContentBuilder apiContentBuilder) + : base( + webhookFiringService, + webhookService, + webhookSettings, + serverRoleAccessor) + { + _publishedSnapshotAccessor = publishedSnapshotAccessor; + _apiContentBuilder = apiContentBuilder; + } + + public override string Alias => Constants.WebhookEvents.Aliases.ContentSorted; + + public override object? ConvertNotificationToRequestPayload(ContentSortedNotification notification) + { + if (_publishedSnapshotAccessor.TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) is false || publishedSnapshot!.Content is null) + { + return null; + } + var sortedEntities = new List(); + foreach (var entity in notification.SortedEntities) + { + IPublishedContent? publishedContent = publishedSnapshot.Content.GetById(entity.Key); + object? payload = publishedContent is null ? null : _apiContentBuilder.Build(publishedContent); + sortedEntities.Add(payload); + } + return sortedEntities; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Content/ContentUnpublishedWebhookEvent.cs similarity index 76% rename from src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs rename to src/Umbraco.Core/Webhooks/Events/Content/ContentUnpublishedWebhookEvent.cs index 76499eb277..81245f9b75 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/Content/ContentUnpublishedWebhookEvent.cs @@ -5,12 +5,12 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; -namespace Umbraco.Cms.Core.Webhooks.Events; +namespace Umbraco.Cms.Core.Webhooks.Events.Content; -[WebhookEvent("Content was unpublished", Constants.WebhookEvents.Types.Content)] -public class ContentUnpublishWebhookEvent : WebhookEventContentBase +[WebhookEvent("Content Unpublished", Constants.WebhookEvents.Types.Content)] +public class ContentUnpublishedWebhookEvent : WebhookEventContentBase { - public ContentUnpublishWebhookEvent( + public ContentUnpublishedWebhookEvent( IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor webhookSettings, diff --git a/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeDeletedWebhookEvent.cs new file mode 100644 index 0000000000..b121c6f394 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.DataType; + +[WebhookEvent("Data Type Deleted")] +public class DataTypeDeletedWebhookEvent : WebhookEventBase +{ + public DataTypeDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "dataTypeDeleted"; + + public override object? ConvertNotificationToRequestPayload(DataTypeSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeMovedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeMovedWebhookEvent.cs new file mode 100644 index 0000000000..03c0954305 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeMovedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.DataType; + +[WebhookEvent("Data Type Moved")] +public class DataTypeMovedWebhookEvent : WebhookEventBase +{ + public DataTypeMovedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "dataTypeMoved"; + + public override object? ConvertNotificationToRequestPayload(DataTypeMovedNotification notification) + => notification.MoveInfoCollection; +} diff --git a/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeSavedWebhookEvent.cs new file mode 100644 index 0000000000..a6e5afe189 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/DataType/DataTypeSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.DataType; + +[WebhookEvent("Data Type Saved")] +public class DataTypeSavedWebhookEvent : WebhookEventBase +{ + public DataTypeSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "dataTypeSaved"; + + public override object? ConvertNotificationToRequestPayload(DataTypeSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Dictionary/DictionaryItemDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Dictionary/DictionaryItemDeletedWebhookEvent.cs new file mode 100644 index 0000000000..fa3c95cea5 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Dictionary/DictionaryItemDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Dictionary; + +[WebhookEvent("Dictionary Item Deleted")] +public class DictionaryItemDeletedWebhookEvent : WebhookEventBase +{ + public DictionaryItemDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "dictionaryItemDeleted"; + + public override object? ConvertNotificationToRequestPayload(DictionaryItemDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Dictionary/DictionaryItemSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Dictionary/DictionaryItemSavedWebhookEvent.cs new file mode 100644 index 0000000000..7edd4e7849 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Dictionary/DictionaryItemSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Dictionary; + +[WebhookEvent("Dictionary Item Saved")] +public class DictionaryItemSavedWebhookEvent : WebhookEventBase +{ + public DictionaryItemSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "dictionaryItemSaved"; + + public override object? ConvertNotificationToRequestPayload(DictionaryItemSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Domain/DomainDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Domain/DomainDeletedWebhookEvent.cs new file mode 100644 index 0000000000..30605a28de --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Domain/DomainDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Domain; + +[WebhookEvent("Domain Deleted")] +public class DomainDeletedWebhookEvent : WebhookEventBase +{ + public DomainDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "domainDeleted"; + + public override object? ConvertNotificationToRequestPayload(DomainDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Domain/DomainSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Domain/DomainSavedWebhookEvent.cs new file mode 100644 index 0000000000..5cd80f743b --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Domain/DomainSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Domain; + +[WebhookEvent("Domain Saved")] +public class DomainSavedWebhookEvent : WebhookEventBase +{ + public DomainSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "domainSaved"; + + public override object? ConvertNotificationToRequestPayload(DomainSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Language/LanguageDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Language/LanguageDeletedWebhookEvent.cs new file mode 100644 index 0000000000..98ebd4d5c8 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Language/LanguageDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Language; + +[WebhookEvent("Language Deleted")] +public class LanguageDeletedWebhookEvent : WebhookEventBase +{ + public LanguageDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "languageDeleted"; + + public override object? ConvertNotificationToRequestPayload(LanguageDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Language/LanguageSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Language/LanguageSavedWebhookEvent.cs new file mode 100644 index 0000000000..ccc52f4245 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Language/LanguageSavedWebhookEvent.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Language; + +[WebhookEvent("Language Saved")] +public class LanguageSavedWebhookEvent : WebhookEventBase +{ + public LanguageSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "languageSaved"; + + public override object? ConvertNotificationToRequestPayload(LanguageSavedNotification notification) + => notification.SavedEntities; +} + diff --git a/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Media/MediaDeletedWebhookEvent.cs similarity index 78% rename from src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs rename to src/Umbraco.Core/Webhooks/Events/Media/MediaDeletedWebhookEvent.cs index ba9fb2333a..659917652d 100644 --- a/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/Media/MediaDeletedWebhookEvent.cs @@ -5,12 +5,12 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; -namespace Umbraco.Cms.Core.Webhooks.Events; +namespace Umbraco.Cms.Core.Webhooks.Events.Media; -[WebhookEvent("Media was deleted", Constants.WebhookEvents.Types.Media)] -public class MediaDeleteWebhookEvent : WebhookEventContentBase +[WebhookEvent("Media Deleted", Constants.WebhookEvents.Types.Media)] +public class MediaDeletedWebhookEvent : WebhookEventContentBase { - public MediaDeleteWebhookEvent( + public MediaDeletedWebhookEvent( IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor webhookSettings, diff --git a/src/Umbraco.Core/Webhooks/Events/Media/MediaEmptiedRecycleBinWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Media/MediaEmptiedRecycleBinWebhookEvent.cs new file mode 100644 index 0000000000..29d0e44e46 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Media/MediaEmptiedRecycleBinWebhookEvent.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Media; + +[WebhookEvent("Media Recycle Bin Emptied", Constants.WebhookEvents.Types.Media)] +public class MediaEmptiedRecycleBinWebhookEvent : WebhookEventContentBase +{ + public MediaEmptiedRecycleBinWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webHookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => "mediaEmptiedRecycleBin"; + + protected override IEnumerable GetEntitiesFromNotification(MediaEmptiedRecycleBinNotification notification) => notification.DeletedEntities; + + protected override object ConvertEntityToRequestPayload(IMedia entity) => new DefaultPayloadModel { Id = entity.Key }; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Media/MediaMovedToRecycleBinWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Media/MediaMovedToRecycleBinWebhookEvent.cs new file mode 100644 index 0000000000..1bd05c6d7b --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Media/MediaMovedToRecycleBinWebhookEvent.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Media; + +[WebhookEvent("Media Moved to Recycle Bin", Constants.WebhookEvents.Types.Media)] +public class MediaMovedToRecycleBinWebhookEvent : WebhookEventContentBase +{ + public MediaMovedToRecycleBinWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webHookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => "mediaMovedToRecycleBin"; + + protected override IEnumerable GetEntitiesFromNotification(MediaMovedToRecycleBinNotification notification) => notification.MoveInfoCollection.Select(x => x.Entity); + + protected override object ConvertEntityToRequestPayload(IMedia entity) => new DefaultPayloadModel { Id = entity.Key }; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Media/MediaMovedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Media/MediaMovedWebhookEvent.cs new file mode 100644 index 0000000000..60b235f4cc --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Media/MediaMovedWebhookEvent.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Media; + +[WebhookEvent("Media Moved", Constants.WebhookEvents.Types.Media)] +public class MediaMovedWebhookEvent : WebhookEventContentBase +{ + public MediaMovedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base( + webhookFiringService, + webHookService, + webhookSettings, + serverRoleAccessor) + { + } + + public override string Alias => "mediaMoved"; + + protected override IEnumerable GetEntitiesFromNotification(MediaMovedNotification notification) => notification.MoveInfoCollection.Select(x => x.Entity); + + protected override object ConvertEntityToRequestPayload(IMedia entity) => new DefaultPayloadModel { Id = entity.Key }; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Media/MediaSavedWebhookEvent.cs similarity index 68% rename from src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs rename to src/Umbraco.Core/Webhooks/Events/Media/MediaSavedWebhookEvent.cs index cea7181d51..6c68e8edb1 100644 --- a/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/Media/MediaSavedWebhookEvent.cs @@ -8,15 +8,15 @@ using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; -namespace Umbraco.Cms.Core.Webhooks.Events; +namespace Umbraco.Cms.Core.Webhooks.Events.Media; -[WebhookEvent("Media was saved", Constants.WebhookEvents.Types.Media)] -public class MediaSaveWebhookEvent : WebhookEventContentBase +[WebhookEvent("Media Saved", Constants.WebhookEvents.Types.Media)] +public class MediaSavedWebhookEvent : WebhookEventContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly IApiMediaBuilder _apiMediaBuilder; - public MediaSaveWebhookEvent( + public MediaSavedWebhookEvent( IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor webhookSettings, @@ -29,8 +29,8 @@ public class MediaSaveWebhookEvent : WebhookEventContentBase Constants.WebhookEvents.Aliases.MediaSave; @@ -39,12 +39,12 @@ public class MediaSaveWebhookEvent : WebhookEventContentBase +{ + public MediaTypeChangedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "mediaTypeChanged"; + + public override object? ConvertNotificationToRequestPayload(MediaTypeChangedNotification notification) + => notification.Changes; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeDeletedWebhookEvent.cs new file mode 100644 index 0000000000..7b46967d06 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MediaType; + +[WebhookEvent("Media Type Deleted")] +public class MediaTypeDeletedWebhookEvent : WebhookEventBase +{ + public MediaTypeDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "mediaTypeDeleted"; + + public override object? ConvertNotificationToRequestPayload(MediaTypeDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeMovedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeMovedWebhookEvent.cs new file mode 100644 index 0000000000..ae2a35995e --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeMovedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MediaType; + +[WebhookEvent("Media Type Moved")] +public class MediaTypeMovedWebhookEvent : WebhookEventBase +{ + public MediaTypeMovedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "mediaTypeMoved"; + + public override object? ConvertNotificationToRequestPayload(MediaTypeMovedNotification notification) + => notification.MoveInfoCollection; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeSavedWebhookEvent.cs new file mode 100644 index 0000000000..818b38f71b --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MediaType/MediaTypeSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MediaType; + +[WebhookEvent("Media Type Saved")] +public class MediaTypeSavedWebhookEvent : WebhookEventBase +{ + public MediaTypeSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "mediaTypeSaved"; + + public override object? ConvertNotificationToRequestPayload(MediaTypeSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/AssignedMemberRolesWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/AssignedMemberRolesWebhookEvent.cs new file mode 100644 index 0000000000..4812bdcc73 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/AssignedMemberRolesWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Roles Assigned")] +public class AssignedMemberRolesWebhookEvent : WebhookEventBase +{ + public AssignedMemberRolesWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "assignedMemberRoles"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/ExportedMemberWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/ExportedMemberWebhookEvent.cs new file mode 100644 index 0000000000..3f72587c8f --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/ExportedMemberWebhookEvent.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Exported")] +public class ExportedMemberWebhookEvent : WebhookEventBase +{ + public ExportedMemberWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "exportedMember"; + + public override object? ConvertNotificationToRequestPayload(ExportedMemberNotification notification) + { + // No need to return the original member in the notification as well + return new + { + exportedMember = notification.Exported + }; + + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/MemberDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/MemberDeletedWebhookEvent.cs new file mode 100644 index 0000000000..c29e22003f --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/MemberDeletedWebhookEvent.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Deleted")] +public class MemberDeletedWebhookEvent : WebhookEventBase +{ + public MemberDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberDeleted"; + + public override object? ConvertNotificationToRequestPayload(MemberDeletedNotification notification) + { + // TODO: Map more stuff here + var result = notification.DeletedEntities.Select(entity => new + { + entity.Id, + entity.Key, + entity.Name, + entity.ContentTypeAlias, + entity.Email, + entity.Username, + entity.FailedPasswordAttempts + }); + + return result; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/MemberGroupDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/MemberGroupDeletedWebhookEvent.cs new file mode 100644 index 0000000000..ab41dfed07 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/MemberGroupDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Group Deleted")] +public class MemberGroupDeletedWebhookEvent : WebhookEventBase +{ + public MemberGroupDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberGroupDeleted"; + + public override object? ConvertNotificationToRequestPayload(MemberGroupDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/MemberGroupSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/MemberGroupSavedWebhookEvent.cs new file mode 100644 index 0000000000..19d3e7d4b2 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/MemberGroupSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Group Saved")] +public class MemberGroupSavedWebhookEvent : WebhookEventBase +{ + public MemberGroupSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberGroupSaved"; + + public override object? ConvertNotificationToRequestPayload(MemberGroupSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/MemberSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/MemberSavedWebhookEvent.cs new file mode 100644 index 0000000000..edb82cb518 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/MemberSavedWebhookEvent.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Saved")] +public class MemberSavedWebhookEvent : WebhookEventBase +{ + public MemberSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberSaved"; + + public override object? ConvertNotificationToRequestPayload(MemberSavedNotification notification) + { + // TODO: Map more stuff here + var result = notification.SavedEntities.Select(entity => new + { + entity.Id, + entity.Key, + entity.Name, + entity.ContentTypeAlias, + entity.Email, + entity.Username, + entity.FailedPasswordAttempts + }); + + return result; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/Member/RemovedMemberRolesWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Member/RemovedMemberRolesWebhookEvent.cs new file mode 100644 index 0000000000..8925b24059 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Member/RemovedMemberRolesWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Member; + +[WebhookEvent("Member Roles Removed")] +public class RemovedMemberRolesWebhookEvent : WebhookEventBase +{ + public RemovedMemberRolesWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "removedMemberRoles"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeChangedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeChangedWebhookEvent.cs new file mode 100644 index 0000000000..68c4424e48 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeChangedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MemberType; + +[WebhookEvent("Member Type Changed")] +public class MemberTypeChangedWebhookEvent : WebhookEventBase +{ + public MemberTypeChangedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberTypeChanged"; + + public override object? ConvertNotificationToRequestPayload(MemberTypeChangedNotification notification) + => notification.Changes; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeDeletedWebhookEvent.cs new file mode 100644 index 0000000000..005143826c --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MemberType; + +[WebhookEvent("Member Type Deleted")] +public class MemberTypeDeletedWebhookEvent : WebhookEventBase +{ + public MemberTypeDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberTypeDeleted"; + + public override object? ConvertNotificationToRequestPayload(MemberTypeDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeMovedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeMovedWebhookEvent.cs new file mode 100644 index 0000000000..ddef29a0c2 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeMovedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MemberType; + +[WebhookEvent("Member Type Moved")] +public class MemberTypeMovedWebhookEvent : WebhookEventBase +{ + public MemberTypeMovedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberTypeMoved"; + + public override object? ConvertNotificationToRequestPayload(MemberTypeMovedNotification notification) + => notification.MoveInfoCollection; +} diff --git a/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeSavedWebhookEvent.cs new file mode 100644 index 0000000000..db4bcf8ad4 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/MemberType/MemberTypeSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.MemberType; + +[WebhookEvent("Member Type Saved")] +public class MemberTypeSavedWebhookEvent : WebhookEventBase +{ + public MemberTypeSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "memberTypeSaved"; + + public override object? ConvertNotificationToRequestPayload(MemberTypeSavedNotification notification) => + notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Package/ImportedPackageWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Package/ImportedPackageWebhookEvent.cs new file mode 100644 index 0000000000..8495dde4c2 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Package/ImportedPackageWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Package; + +[WebhookEvent("Package Imported")] +public class ImportedPackageWebhookEvent : WebhookEventBase +{ + public ImportedPackageWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "packageImported"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/PublicAccess/PublicAccessEntryDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/PublicAccess/PublicAccessEntryDeletedWebhookEvent.cs new file mode 100644 index 0000000000..00f5a2ca86 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/PublicAccess/PublicAccessEntryDeletedWebhookEvent.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.PublicAccess; + +[WebhookEvent("Public Access Entry Deleted")] +public class PublicAccessEntryDeletedWebhookEvent : WebhookEventBase +{ + public PublicAccessEntryDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "publicAccessEntryDeleted"; + + public override object? ConvertNotificationToRequestPayload(PublicAccessEntryDeletedNotification notification) => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/PublicAccess/PublicAccessEntrySavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/PublicAccess/PublicAccessEntrySavedWebhookEvent.cs new file mode 100644 index 0000000000..3977db2832 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/PublicAccess/PublicAccessEntrySavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.PublicAccess; + +[WebhookEvent("Public Access Entry Saved")] +public class PublicAccessEntrySavedWebhookEvent : WebhookEventBase +{ + public PublicAccessEntrySavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "publicAccessEntrySaved"; + + public override object? ConvertNotificationToRequestPayload(PublicAccessEntrySavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Relation/RelationDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Relation/RelationDeletedWebhookEvent.cs new file mode 100644 index 0000000000..2ade4bd08e --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Relation/RelationDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Relation; + +[WebhookEvent("Relation Deleted")] +public class RelationDeletedWebhookEvent : WebhookEventBase +{ + public RelationDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "relationDeleted"; + + public override object? ConvertNotificationToRequestPayload(RelationDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Relation/RelationSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Relation/RelationSavedWebhookEvent.cs new file mode 100644 index 0000000000..4cc775aa21 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Relation/RelationSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Relation; + +[WebhookEvent("Relation Saved")] +public class RelationSavedWebhookEvent : WebhookEventBase +{ + public RelationSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "relationSaved"; + + public override object? ConvertNotificationToRequestPayload(RelationSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/RelationType/RelationTypeDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/RelationType/RelationTypeDeletedWebhookEvent.cs new file mode 100644 index 0000000000..41f9619a41 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/RelationType/RelationTypeDeletedWebhookEvent.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.RelationType; + +[WebhookEvent("Relation Type Deleted")] +public class RelationTypeDeletedWebhookEvent : WebhookEventBase +{ + public RelationTypeDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + + public override string Alias => "relationTypeDeleted"; + + public override object? ConvertNotificationToRequestPayload(RelationTypeDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/RelationType/RelationTypeSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/RelationType/RelationTypeSavedWebhookEvent.cs new file mode 100644 index 0000000000..915e95c6cb --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/RelationType/RelationTypeSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.RelationType; + +[WebhookEvent("Relation Type Saved")] +public class RelationTypeSavedWebhookEvent : WebhookEventBase +{ + public RelationTypeSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "relationTypeSaved"; + + public override object? ConvertNotificationToRequestPayload(RelationTypeSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Script/ScriptDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Script/ScriptDeletedWebhookEvent.cs new file mode 100644 index 0000000000..1dad592cb1 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Script/ScriptDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Script; + +[WebhookEvent("Script Deleted")] +public class ScriptDeletedWebhookEvent : WebhookEventBase +{ + public ScriptDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "scriptDeleted"; + + public override object? ConvertNotificationToRequestPayload(ScriptDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Script/ScriptSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Script/ScriptSavedWebhookEvent.cs new file mode 100644 index 0000000000..4d026b9f6c --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Script/ScriptSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Script; + +[WebhookEvent("Script Saved")] +public class ScriptSavedWebhookEvent : WebhookEventBase +{ + public ScriptSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "scriptSaved"; + + public override object? ConvertNotificationToRequestPayload(ScriptDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Stylesheet/StylesheetDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Stylesheet/StylesheetDeletedWebhookEvent.cs new file mode 100644 index 0000000000..5214dc39cb --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Stylesheet/StylesheetDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Stylesheet; + +[WebhookEvent("Stylesheet Deleted")] +public class StylesheetDeletedWebhookEvent : WebhookEventBase +{ + public StylesheetDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "stylesheetDeleted"; + + public override object? ConvertNotificationToRequestPayload(StylesheetDeletedNotification notification) => + notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Stylesheet/StylesheetSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Stylesheet/StylesheetSavedWebhookEvent.cs new file mode 100644 index 0000000000..a135f70131 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Stylesheet/StylesheetSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Stylesheet; + +[WebhookEvent("Stylesheet Saved")] +public class StylesheetSavedWebhookEvent : WebhookEventBase +{ + public StylesheetSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "stylesheetSaved"; + + public override object? ConvertNotificationToRequestPayload(StylesheetSavedNotification notification) + => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Template/PartialViewDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Template/PartialViewDeletedWebhookEvent.cs new file mode 100644 index 0000000000..1f3fc756fb --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Template/PartialViewDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Template; + +[WebhookEvent("Partial View Deleted")] +public class PartialViewDeletedWebhookEvent : WebhookEventBase +{ + public PartialViewDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "partialViewDeleted"; + + public override object? ConvertNotificationToRequestPayload(PartialViewDeletedNotification notification) + => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Template/PartialViewSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Template/PartialViewSavedWebhookEvent.cs new file mode 100644 index 0000000000..224d71c837 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Template/PartialViewSavedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Template; + +[WebhookEvent("Partial View Saved")] +public class PartialViewSavedWebhookEvent : WebhookEventBase +{ + public PartialViewSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "partialViewSaved"; + + public override object? ConvertNotificationToRequestPayload(PartialViewSavedNotification notification) => + notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Template/TemplateDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Template/TemplateDeletedWebhookEvent.cs new file mode 100644 index 0000000000..2e18dd9932 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Template/TemplateDeletedWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Template; + +[WebhookEvent("Template Deleted")] +public class TemplateDeletedWebhookEvent : WebhookEventBase +{ + public TemplateDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "templateDeleted"; + + public override object? ConvertNotificationToRequestPayload(TemplateDeletedNotification notification) => + notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/Template/TemplateSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/Template/TemplateSavedWebhookEvent.cs new file mode 100644 index 0000000000..3950e7e370 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/Template/TemplateSavedWebhookEvent.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.Template; + +[WebhookEvent("Template Saved")] +public class TemplateSavedWebhookEvent : WebhookEventBase +{ + public TemplateSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "templateSaved"; + + public override object? ConvertNotificationToRequestPayload(TemplateSavedNotification notification) + { + // Create a new anonymous object with the properties we want + return new + { + notification.CreateTemplateForContentType, + notification.ContentTypeAlias, + notification.SavedEntities + }; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/AssignedUserGroupPermissionsWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/AssignedUserGroupPermissionsWebhookEvent.cs new file mode 100644 index 0000000000..1b8b1002bc --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/AssignedUserGroupPermissionsWebhookEvent.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Group Permissions Assigned")] +public class AssignedUserGroupPermissionsWebhookEvent : WebhookEventBase +{ + public AssignedUserGroupPermissionsWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "assignedUserGroupPermissions"; + + public override object? ConvertNotificationToRequestPayload(AssignedUserGroupPermissionsNotification notification) + => notification.EntityPermissions; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserDeletedWebhookEvent.cs new file mode 100644 index 0000000000..3d7a6b2afa --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserDeletedWebhookEvent.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Deleted")] +public class UserDeletedWebhookEvent : WebhookEventBase +{ + public UserDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userDeleted"; + + public override object? ConvertNotificationToRequestPayload(UserDeletedNotification notification) + { + // TODO: Map more stuff here + var result = notification.DeletedEntities.Select(entity => new + { + entity.Id, + entity.Key, + entity.Name, + entity.Language, + entity.Email, + entity.Username, + entity.FailedPasswordAttempts + }); + + return result; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserForgotPasswordRequestedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserForgotPasswordRequestedWebhookEvent.cs new file mode 100644 index 0000000000..0426d7a1e6 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserForgotPasswordRequestedWebhookEvent.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Forgot Password Requested")] +public class UserForgotPasswordRequestedWebhookEvent : WebhookEventBase +{ + public UserForgotPasswordRequestedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userForgotPasswordRequested"; + +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserForgottenPasswordRequestedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserForgottenPasswordRequestedWebhookEvent.cs new file mode 100644 index 0000000000..7bd15f5a51 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserForgottenPasswordRequestedWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Forgotten Password Requested")] +public class UserForgottenPasswordRequestedWebhookEvent : WebhookEventBase +{ + public UserForgottenPasswordRequestedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userForgottenPasswordRequested"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserGroupDeletedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserGroupDeletedWebhookEvent.cs new file mode 100644 index 0000000000..c05bacb377 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserGroupDeletedWebhookEvent.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Group Deleted")] +public class UserGroupDeletedWebhookEvent : WebhookEventBase +{ + public UserGroupDeletedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userGroupDeleted"; + + public override object? ConvertNotificationToRequestPayload(UserGroupDeletedNotification notification) => notification.DeletedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserGroupSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserGroupSavedWebhookEvent.cs new file mode 100644 index 0000000000..0bfe438a7b --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserGroupSavedWebhookEvent.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Group Saved")] +public class UserGroupSavedWebhookEvent : WebhookEventBase +{ + public UserGroupSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userGroupSaved"; + + public override object? ConvertNotificationToRequestPayload(UserGroupSavedNotification notification) => notification.SavedEntities; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserLockedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserLockedWebhookEvent.cs new file mode 100644 index 0000000000..eb3106687f --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserLockedWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Locked")] +public class UserLockedWebhookEvent : WebhookEventBase +{ + public UserLockedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userLocked"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserLoginFailedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserLoginFailedWebhookEvent.cs new file mode 100644 index 0000000000..e6957d39dc --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserLoginFailedWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Login Failed")] +public class UserLoginFailedWebhookEvent : WebhookEventBase +{ + public UserLoginFailedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userLoginFailed"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserLoginRequiresVerificationWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserLoginRequiresVerificationWebhookEvent.cs new file mode 100644 index 0000000000..a642827150 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserLoginRequiresVerificationWebhookEvent.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Login Requires Verification")] +public class UserLoginRequiresVerificationWebhookEvent : WebhookEventBase +{ + public UserLoginRequiresVerificationWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userLoginRequiresVerification"; + +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserLoginSuccessWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserLoginSuccessWebhookEvent.cs new file mode 100644 index 0000000000..58b98d8e07 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserLoginSuccessWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Login Success")] +public class UserLoginSuccessWebhookEvent : WebhookEventBase +{ + public UserLoginSuccessWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userLoginSuccess"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserLogoutSuccessWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserLogoutSuccessWebhookEvent.cs new file mode 100644 index 0000000000..dc0f8d7bb2 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserLogoutSuccessWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Logout Success")] +public class UserLogoutSuccessWebhookEvent : WebhookEventBase +{ + public UserLogoutSuccessWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userLogoutSuccess"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserPasswordChangedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserPasswordChangedWebhookEvent.cs new file mode 100644 index 0000000000..99c654aba3 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserPasswordChangedWebhookEvent.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Password Changed")] +public class UserPasswordChangedWebhookEvent : WebhookEventBase +{ + public UserPasswordChangedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userPasswordChanged"; + +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserPasswordResetWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserPasswordResetWebhookEvent.cs new file mode 100644 index 0000000000..368116df0b --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserPasswordResetWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Password Reset")] +public class UserPasswordResetWebhookEvent : WebhookEventBase +{ + public UserPasswordResetWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userPasswordReset"; +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserSavedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserSavedWebhookEvent.cs new file mode 100644 index 0000000000..ee65e9b2eb --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserSavedWebhookEvent.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Saved")] +public class UserSavedWebhookEvent : WebhookEventBase +{ + public UserSavedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userSaved"; + + public override object? ConvertNotificationToRequestPayload(UserSavedNotification notification) + { + // TODO: Map more stuff here + var result = notification.SavedEntities.Select(entity => new + { + entity.Id, + entity.Key, + entity.Name, + entity.Language, + entity.Email, + entity.Username, + entity.FailedPasswordAttempts + }); + + return result; + } +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserTwoFactorRequestedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserTwoFactorRequestedWebhookEvent.cs new file mode 100644 index 0000000000..afcac294ca --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserTwoFactorRequestedWebhookEvent.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Two Factor Requested")] +public class UserTwoFactorRequestedWebhookEvent : WebhookEventBase +{ + public UserTwoFactorRequestedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userTwoFactorRequested"; + +} diff --git a/src/Umbraco.Core/Webhooks/Events/User/UserUnlockedWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/User/UserUnlockedWebhookEvent.cs new file mode 100644 index 0000000000..a6aea62196 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/Events/User/UserUnlockedWebhookEvent.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks.Events.User; + +[WebhookEvent("User Unlocked")] +public class UserUnlockedWebhookEvent : WebhookEventBase +{ + public UserUnlockedWebhookEvent( + IWebhookFiringService webhookFiringService, + IWebhookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) + { + } + + public override string Alias => "userUnlocked"; +} diff --git a/src/Umbraco.Core/Webhooks/WebhookEventBase.cs b/src/Umbraco.Core/Webhooks/WebhookEventBase.cs index 5d4ee69d3b..138ebc56fd 100644 --- a/src/Umbraco.Core/Webhooks/WebhookEventBase.cs +++ b/src/Umbraco.Core/Webhooks/WebhookEventBase.cs @@ -62,7 +62,7 @@ public abstract class WebhookEventBase : IWebhookEvent, INotifica continue; } - await WebhookFiringService.FireAsync(webhook, Alias, notification, cancellationToken); + await WebhookFiringService.FireAsync(webhook, Alias, ConvertNotificationToRequestPayload(notification), cancellationToken); } } @@ -95,4 +95,14 @@ public abstract class WebhookEventBase : IWebhookEvent, INotifica await ProcessWebhooks(notification, webhooks, cancellationToken); } + + /// + /// Use this method if you wish to change the shape of the object to be serialised + /// for the JSON webhook payload. + /// For example excluding sensitive data + /// + /// + /// + public virtual object? ConvertNotificationToRequestPayload(TNotification notification) + => notification; } diff --git a/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs b/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs index e0eeb186e8..9ebc7ee13f 100644 --- a/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs +++ b/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs @@ -2,35 +2,43 @@ using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Notifications; -using Umbraco.Cms.Core.Webhooks.Events; +using Umbraco.Cms.Core.Webhooks.Events.Content; +using Umbraco.Cms.Core.Webhooks.Events.DataType; +using Umbraco.Cms.Core.Webhooks.Events.Dictionary; +using Umbraco.Cms.Core.Webhooks.Events.Domain; +using Umbraco.Cms.Core.Webhooks.Events.Language; +using Umbraco.Cms.Core.Webhooks.Events.Media; +using Umbraco.Cms.Core.Webhooks.Events.MediaType; +using Umbraco.Cms.Core.Webhooks.Events.Member; +using Umbraco.Cms.Core.Webhooks.Events.MemberType; +using Umbraco.Cms.Core.Webhooks.Events.Package; +using Umbraco.Cms.Core.Webhooks.Events.PublicAccess; +using Umbraco.Cms.Core.Webhooks.Events.Relation; +using Umbraco.Cms.Core.Webhooks.Events.RelationType; +using Umbraco.Cms.Core.Webhooks.Events.Script; +using Umbraco.Cms.Core.Webhooks.Events.Stylesheet; +using Umbraco.Cms.Core.Webhooks.Events.Template; +using Umbraco.Cms.Core.Webhooks.Events.User; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Webhooks; -public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase +public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase { protected override WebhookEventCollectionBuilder This => this; public override void RegisterWith(IServiceCollection services) { // register the collection - services.Add(new ServiceDescriptor(typeof(WebhookEventCollection), CreateCollection, ServiceLifetime.Singleton)); + services.Add(new ServiceDescriptor(typeof(WebhookEventCollection), CreateCollection, + ServiceLifetime.Singleton)); // register the types RegisterTypes(services); base.RegisterWith(services); } - public WebhookEventCollectionBuilder AddCoreWebhooks() - { - Append(); - Append(); - Append(); - Append(); - Append(); - return this; - } - private void RegisterTypes(IServiceCollection services) { Type[] types = GetRegisteringTypes(GetTypes()).ToArray(); @@ -68,7 +76,8 @@ public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase typeof(INotification).IsAssignableFrom(arg)); + Type? notificationType = + genericArguments.FirstOrDefault(arg => typeof(INotification).IsAssignableFrom(arg)); if (notificationType is not null) { @@ -78,4 +87,187 @@ public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase + this.AddContentWebhooks() + .AddDataTypeWebhooks() + .AddDictionaryWebhooks() + .AddDomainWebhooks() + .AddLanguageWebhooks() + .AddMediaWebhooks() + .AddMemberWebhooks() + .AddMemberTypeWebhooks() + .AddPackageWebhooks() + .AddPublicAccessWebhooks() + .AddRelationWebhooks() + .AddScriptWebhooks() + .AddStylesheetWebhooks() + .AddTemplateWebhooks() + .AddUserWebhooks(); + + public WebhookEventCollectionBuilder AddContentWebhooks() + { + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddCoreWebhooks() + { + Append(); + Append(); + Append(); + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddDataTypeWebhooks() + { + Append(); + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddDictionaryWebhooks() + { + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddDomainWebhooks() + { + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddLanguageWebhooks() + { + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddMediaWebhooks() + { + // Even though these two are in the AddCoreWebhooks() + // The job of the CollectionBuilder should be removing duplicates + // Would allow someone to use .AddCoreWebhooks().AddMediaWebhooks() + // Or if they explicitly they could skip over CoreWebHooks and just add this perhaps + Append(); + Append(); + + Append(); + Append(); + Append(); + + Append(); + Append(); + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddMemberWebhooks() + { + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddMemberTypeWebhooks() + { + Append(); + Append(); + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddPackageWebhooks() + { + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddPublicAccessWebhooks() + { + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddRelationWebhooks() + { + Append(); + Append(); + + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddScriptWebhooks() + { + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddStylesheetWebhooks() + { + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddTemplateWebhooks() + { + Append(); + Append(); + + Append(); + Append(); + return this; + } + + public WebhookEventCollectionBuilder AddUserWebhooks() + { + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + Append(); + return this; + } } diff --git a/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj b/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj index c96686f41c..76349f9671 100644 --- a/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj +++ b/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs index ba78af33b4..a3dc6ec779 100644 --- a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs +++ b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs @@ -1,14 +1,18 @@ // Copyright (c) Umbraco. // See LICENSE for more details. +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.HealthChecks; using Umbraco.Cms.Core.HealthChecks.NotificationMethods; using Umbraco.Cms.Core.Logging; +using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Runtime; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Services; @@ -38,9 +42,30 @@ public class HealthCheckNotifierJob : IRecurringBackgroundJob private readonly ILogger _logger; private readonly HealthCheckNotificationMethodCollection _notifications; private readonly IProfilingLogger _profilingLogger; + private readonly IEventAggregator _eventAggregator; private readonly ICoreScopeProvider _scopeProvider; private HealthChecksSettings _healthChecksSettings; + [Obsolete("Use constructor that accepts IEventAggregator as a parameter, scheduled for removal in V14")] + public HealthCheckNotifierJob( + IOptionsMonitor healthChecksSettings, + HealthCheckCollection healthChecks, + HealthCheckNotificationMethodCollection notifications, + ICoreScopeProvider scopeProvider, + ILogger logger, + IProfilingLogger profilingLogger, + ICronTabParser cronTabParser) + : this( + healthChecksSettings, + healthChecks, + notifications, + scopeProvider, + logger, + profilingLogger, + cronTabParser, + StaticServiceProvider.Instance.GetRequiredService()) + { } + /// /// Initializes a new instance of the class. /// @@ -58,7 +83,8 @@ public class HealthCheckNotifierJob : IRecurringBackgroundJob ICoreScopeProvider scopeProvider, ILogger logger, IProfilingLogger profilingLogger, - ICronTabParser cronTabParser) + ICronTabParser cronTabParser, + IEventAggregator eventAggregator) { _healthChecksSettings = healthChecksSettings.CurrentValue; _healthChecks = healthChecks; @@ -66,6 +92,7 @@ public class HealthCheckNotifierJob : IRecurringBackgroundJob _scopeProvider = scopeProvider; _logger = logger; _profilingLogger = profilingLogger; + _eventAggregator = eventAggregator; Period = healthChecksSettings.CurrentValue.Notification.Period; Delay = DelayCalculator.GetDelay(healthChecksSettings.CurrentValue.Notification.FirstRunTime, cronTabParser, logger, TimeSpan.FromMinutes(3)); @@ -106,6 +133,8 @@ public class HealthCheckNotifierJob : IRecurringBackgroundJob HealthCheckResults results = await HealthCheckResults.Create(checks); results.LogResults(); + _eventAggregator.Publish(new HealthCheckCompletedNotification(results)); + // Send using registered notification methods that are enabled. foreach (IHealthCheckNotificationMethod notificationMethod in _notifications.Where(x => x.Enabled)) { diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs index ca8a4e0353..d727c8c130 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs @@ -3,7 +3,9 @@ using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Infrastructure.Scoping; +using Umbraco.Cms.Web.Common.DependencyInjection; using IScope = Umbraco.Cms.Infrastructure.Scoping.IScope; +using StaticServiceProvider = Umbraco.Cms.Core.DependencyInjection.StaticServiceProvider; namespace Umbraco.Cms.Core.Logging.Viewer; @@ -57,14 +59,15 @@ public class LogViewerConfig : ILogViewerConfig { using IScope scope = _scopeProvider.CreateScope(); ILogViewerQuery? item = _logViewerQueryRepository.GetByName(name); - if (item is not null) { _logViewerQueryRepository.Delete(item); } // Return the updated object - so we can instantly reset the entire array from the API response - IReadOnlyList result = GetSavedSearches(); + IReadOnlyList result = GetSavedSearches()!; + scope.Complete(); + return result; scope.Complete(); return result; } diff --git a/src/Umbraco.Infrastructure/Models/Blocks/BlockListEditorDataConverter.cs b/src/Umbraco.Infrastructure/Models/Blocks/BlockListEditorDataConverter.cs index 9d89b41643..6644ee7fb5 100644 --- a/src/Umbraco.Infrastructure/Models/Blocks/BlockListEditorDataConverter.cs +++ b/src/Umbraco.Infrastructure/Models/Blocks/BlockListEditorDataConverter.cs @@ -6,15 +6,32 @@ using Newtonsoft.Json.Linq; namespace Umbraco.Cms.Core.Models.Blocks; /// -/// Data converter for the block list property editor +/// Handles the conversion of data for the block list property editor. /// public class BlockListEditorDataConverter : BlockEditorDataConverter { + /// + /// Initializes a new instance of the class with a default alias. + /// public BlockListEditorDataConverter() : base(Constants.PropertyEditors.Aliases.BlockList) { } + /// + /// Initializes a new instance of the class with a provided alias. + /// + /// The alias of the property editor. + public BlockListEditorDataConverter(string propertyEditorAlias) + : base(propertyEditorAlias) + { + } + + /// + /// Extracts block references from the provided JSON layout. + /// + /// The JSON layout containing the block references. + /// A collection of objects extracted from the JSON layout. protected override IEnumerable? GetBlockReferences(JToken jsonLayout) { IEnumerable? blockListLayout = jsonLayout.ToObject>(); diff --git a/src/Umbraco.Infrastructure/PropertyEditors/BlockListPropertyEditorBase.cs b/src/Umbraco.Infrastructure/PropertyEditors/BlockListPropertyEditorBase.cs index 194383560e..a2f5616518 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/BlockListPropertyEditorBase.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/BlockListPropertyEditorBase.cs @@ -35,16 +35,22 @@ public abstract class BlockListPropertyEditorBase : DataEditor public override IPropertyIndexValueFactory PropertyIndexValueFactory => _blockValuePropertyIndexValueFactory; - #region Value Editor + /// + /// Instantiates a new for use with the block list editor property value editor. + /// + /// A new instance of . + protected virtual BlockEditorDataConverter CreateBlockEditorDataConverter() => new BlockListEditorDataConverter(); + protected override IDataValueEditor CreateValueEditor() => - DataValueEditorFactory.Create(Attribute!); + DataValueEditorFactory.Create(Attribute!, CreateBlockEditorDataConverter()); internal class BlockListEditorPropertyValueEditor : BlockEditorPropertyValueEditor { public BlockListEditorPropertyValueEditor( DataEditorAttribute attribute, + BlockEditorDataConverter blockEditorDataConverter, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, IContentTypeService contentTypeService, @@ -56,7 +62,7 @@ public abstract class BlockListPropertyEditorBase : DataEditor IPropertyValidationService propertyValidationService) : base(attribute, propertyEditors, dataTypeService, textService, logger, shortStringHelper, jsonSerializer, ioHelper) { - BlockEditorValues = new BlockEditorValues(new BlockListEditorDataConverter(), contentTypeService, logger); + BlockEditorValues = new BlockEditorValues(blockEditorDataConverter, contentTypeService, logger); Validators.Add(new BlockEditorValidator(propertyValidationService, BlockEditorValues, contentTypeService)); Validators.Add(new MinMaxValidator(BlockEditorValues, textService)); } diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 67afb4baa3..a9fef3d046 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -11,36 +11,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj index a61eba6c79..75dfa13ec6 100644 --- a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj +++ b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj @@ -7,10 +7,10 @@ - - - - + + + + diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index 134a89372f..65d7c442f2 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -11,13 +11,13 @@ using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Primitives; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Configuration.Grid; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.Manifest; -using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; @@ -145,7 +145,6 @@ public class BackOfficeController : UmbracoController return await RenderDefaultOrProcessExternalLoginAsync( result, - () => defaultView, () => defaultView); } @@ -172,7 +171,6 @@ public class BackOfficeController : UmbracoController return await RenderDefaultOrProcessExternalLoginAsync( result, - () => View(viewPath), () => View(viewPath)); } @@ -460,11 +458,9 @@ public class BackOfficeController : UmbracoController /// private async Task RenderDefaultOrProcessExternalLoginAsync( AuthenticateResult authenticateResult, - Func defaultResponse, - Func externalSignInResponse) + Func defaultResponse) { ArgumentNullException.ThrowIfNull(defaultResponse); - ArgumentNullException.ThrowIfNull(externalSignInResponse); ViewData.SetUmbracoPath(_globalSettings.GetUmbracoMvcArea(_hostingEnvironment)); @@ -481,23 +477,35 @@ public class BackOfficeController : UmbracoController // First check if there's external login info, if there's not proceed as normal ExternalLoginInfo? loginInfo = await _signInManager.GetExternalLoginInfoAsync(); - if (loginInfo == null || loginInfo.Principal == null) + if (loginInfo != null) { - // if the user is not logged in, check if there's any auto login redirects specified - if (!authenticateResult.Succeeded) - { - var oauthRedirectAuthProvider = _externalLogins.GetAutoLoginProvider(); - if (!oauthRedirectAuthProvider.IsNullOrWhiteSpace()) - { - return ExternalLogin(oauthRedirectAuthProvider!); - } - } + // we're just logging in with an external source, not linking accounts + return await ExternalSignInAsync(loginInfo, defaultResponse); + } + // If we are authenticated then we can just render the default view + if (authenticateResult.Succeeded) + { return defaultResponse(); } - // we're just logging in with an external source, not linking accounts - return await ExternalSignInAsync(loginInfo, externalSignInResponse); + // If the user is not logged in, check if there's any auto login redirects specified + var oauthRedirectAuthProvider = _externalLogins.GetAutoLoginProvider(); + + // If there's no auto login provider specified, then we'll render the default view + if (oauthRedirectAuthProvider.IsNullOrWhiteSpace()) + { + return defaultResponse(); + } + + // If the ?logout=true query string is not specified, then we'll redirect to the external login provider + // which will then redirect back to the ExternalLoginCallback action + if (Request.Query.TryGetValue("logout", out StringValues logout) == false || logout != "true") + { + return ExternalLogin(oauthRedirectAuthProvider); + } + + return defaultResponse(); } private async Task ExternalSignInAsync(ExternalLoginInfo loginInfo, Func response) diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs index 83063f156f..d06062498a 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs @@ -2401,8 +2401,10 @@ public class ContentController : ContentControllerBase } // Validate permissions on node - EntityPermission? permission = _userService.GetPermissions(_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, node.Path); - if (permission?.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) == false) + var permissions = _userService.GetAllPermissions(_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, node.Path); + + if (permissions.Any(x => + x.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) && x.EntityId == node.Id) == false) { HttpContext.SetReasonPhrase("Permission Denied."); return BadRequest("You do not have permission to assign domains on that node."); diff --git a/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs b/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs index a5e5e3b447..11e8099a57 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs @@ -20,7 +20,7 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Web.BackOffice.Controllers; -[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)] [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] public class RedirectUrlManagementController : UmbracoAuthorizedApiController { diff --git a/src/Umbraco.Web.BackOffice/HealthChecks/HealthCheckController.cs b/src/Umbraco.Web.BackOffice/HealthChecks/HealthCheckController.cs index 9744ed8c5f..1880b26ced 100644 --- a/src/Umbraco.Web.BackOffice/HealthChecks/HealthCheckController.cs +++ b/src/Umbraco.Web.BackOffice/HealthChecks/HealthCheckController.cs @@ -3,11 +3,15 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.HealthChecks; +using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Web.BackOffice.Controllers; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Authorization; @@ -24,14 +28,27 @@ public class HealthCheckController : UmbracoAuthorizedJsonController private readonly HealthCheckCollection _checks; private readonly IList _disabledCheckIds; private readonly ILogger _logger; + private readonly IEventAggregator _eventAggregator; + private readonly HealthChecksSettings _healthChecksSettings; /// /// Initializes a new instance of the class. /// + [Obsolete("Use constructor that accepts IEventAggregator as a parameter, scheduled for removal in V14")] public HealthCheckController(HealthCheckCollection checks, ILogger logger, IOptions healthChecksSettings) + : this(checks, logger, healthChecksSettings, StaticServiceProvider.Instance.GetRequiredService()) + { } + + /// + /// Initializes a new instance of the class. + /// + [ActivatorUtilitiesConstructor] + public HealthCheckController(HealthCheckCollection checks, ILogger logger, IOptions healthChecksSettings, IEventAggregator eventAggregator) { _checks = checks ?? throw new ArgumentNullException(nameof(checks)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _eventAggregator = eventAggregator ?? throw new ArgumentException(nameof(eventAggregator)); + _healthChecksSettings = healthChecksSettings?.Value ?? throw new ArgumentException(nameof(healthChecksSettings)); HealthChecksSettings healthCheckConfig = healthChecksSettings.Value ?? throw new ArgumentNullException(nameof(healthChecksSettings)); @@ -80,6 +97,16 @@ public class HealthCheckController : UmbracoAuthorizedJsonController { _logger.LogDebug("Running health check: " + check.Name); } + + if (!_healthChecksSettings.Notification.Enabled) + { + return await check.GetStatus(); + } + + HealthCheckResults results = await HealthCheckResults.Create(check); + _eventAggregator.Publish(new HealthCheckCompletedNotification(results)); + + return await check.GetStatus(); } catch (Exception ex) diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeAntiforgery.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeAntiforgery.cs index a6e4e96d8b..cc1fc0c4bc 100644 --- a/src/Umbraco.Web.BackOffice/Security/BackOfficeAntiforgery.cs +++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeAntiforgery.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration.Models; @@ -20,25 +22,35 @@ namespace Umbraco.Cms.Web.BackOffice.Security; public class BackOfficeAntiforgery : IBackOfficeAntiforgery { private readonly IAntiforgery _internalAntiForgery; - private GlobalSettings _globalSettings; + private readonly CookieBuilder _angularCookieBuilder; + [Obsolete($"Please use the constructor that accepts {nameof(ILoggerFactory)}. Will be removed in V14.")] public BackOfficeAntiforgery(IOptionsMonitor globalSettings) + : this(globalSettings, NullLoggerFactory.Instance) + { } + + public BackOfficeAntiforgery(IOptionsMonitor globalSettings, ILoggerFactory loggerFactory) { + CookieSecurePolicy cookieSecurePolicy = globalSettings.CurrentValue.UseHttps ? CookieSecurePolicy.Always : CookieSecurePolicy.SameAsRequest; + // NOTE: This is the only way to create a separate IAntiForgery service :( // Everything in netcore is internal. I have logged an issue here https://github.com/dotnet/aspnetcore/issues/22217 // but it will not be handled so we have to revert to this. - var services = new ServiceCollection(); - services.AddLogging(); - services.AddAntiforgery(x => - { - x.HeaderName = Constants.Web.AngularHeadername; - x.Cookie.Name = Constants.Web.CsrfValidationCookieName; - x.Cookie.SecurePolicy = globalSettings.CurrentValue.UseHttps ? CookieSecurePolicy.Always : CookieSecurePolicy.SameAsRequest; - }); - ServiceProvider container = services.BuildServiceProvider(); - _internalAntiForgery = container.GetRequiredService(); - _globalSettings = globalSettings.CurrentValue; - globalSettings.OnChange(x => _globalSettings = x); + _internalAntiForgery = new ServiceCollection() + .AddSingleton(loggerFactory) + .AddAntiforgery(x => + { + x.HeaderName = Constants.Web.AngularHeadername; + x.Cookie.Name = Constants.Web.CsrfValidationCookieName; + x.Cookie.SecurePolicy = cookieSecurePolicy; + }) + .BuildServiceProvider() + .GetRequiredService(); + + // Configure cookie builder using defaults from antiforgery options + _angularCookieBuilder = new AntiforgeryOptions().Cookie; + _angularCookieBuilder.HttpOnly = false; // Needs to be accessed from JavaScript + _angularCookieBuilder.SecurePolicy = cookieSecurePolicy; } /// @@ -68,15 +80,6 @@ public class BackOfficeAntiforgery : IBackOfficeAntiforgery // We need to set 2 cookies: // The cookie value that angular will use to set a header value on each request - we need to manually set this here // The validation cookie value generated by the anti-forgery helper that we validate the header token against - set above in GetAndStoreTokens - httpContext.Response.Cookies.Append( - Constants.Web.AngularCookieName, - set.RequestToken, - new CookieOptions - { - Path = "/", - //must be js readable - HttpOnly = false, - Secure = _globalSettings.UseHttps - }); + httpContext.Response.Cookies.Append(Constants.Web.AngularCookieName, set.RequestToken, _angularCookieBuilder.Build(httpContext)); } } diff --git a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj index c8b09bcad5..8a9f3f8033 100644 --- a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj +++ b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs index 1813c75932..ad5f480a72 100644 --- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs +++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs @@ -27,7 +27,7 @@ internal class AspNetCoreSessionManager : ISessionIdResolver, ISessionManager /// /// If session isn't enabled this will throw an exception so we check /// - private bool IsSessionsAvailable => !(_httpContextAccessor.HttpContext?.Features.Get() is null); + private bool IsSessionsAvailable => !(_httpContextAccessor.HttpContext?.Features.Get()?.Session is null); public string? GetSessionValue(string key) { diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index e5cb683865..c7e259d283 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -7,15 +7,19 @@ - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 310afe560f..ad30a030a1 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -9,7 +9,7 @@ "@microsoft/signalr": "7.0.12", "@umbraco-ui/uui": "1.5.0", "@umbraco-ui/uui-css": "1.5.0", - "ace-builds": "1.31.0", + "ace-builds": "1.31.1", "angular": "1.8.3", "angular-animate": "1.8.3", "angular-aria": "1.8.3", @@ -3116,9 +3116,9 @@ } }, "node_modules/ace-builds": { - "version": "1.31.0", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.31.0.tgz", - "integrity": "sha512-nitIhcUYA6wyO3lo2WZBPX5fcjllW6XFt4EFyHwcN2Fp70/IZwz8tdw6a0+8udDEwDj/ebt3aWEClIyCs/6qYA==" + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.31.1.tgz", + "integrity": "sha512-3DnE5bZF6Ji+l4F5acoLk+rV7mxrUt1C4r61Xy9owp5rVM4lj5NL8GJfoX6Jnnbhx6kKV7Vdpb+Tco+0ORTvhg==" }, "node_modules/acorn": { "version": "8.9.0", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 315425bc77..3d3dc9da15 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -21,7 +21,7 @@ "@microsoft/signalr": "7.0.12", "@umbraco-ui/uui": "1.5.0", "@umbraco-ui/uui-css": "1.5.0", - "ace-builds": "1.31.0", + "ace-builds": "1.31.1", "angular": "1.8.3", "angular-animate": "1.8.3", "angular-aria": "1.8.3", diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html index e65a5f767f..e87674791c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html @@ -2,29 +2,55 @@ - + - - - - - + -
    -
  • -
    - -
    -
  • -
+ +
+ + +
+ + + +
+
    +
  • +
    + +
    +
  • +
+
+ + + No events were found. +
diff --git a/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html b/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html index 9b1a59a0db..3a92c04a56 100644 --- a/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html +++ b/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html @@ -3,11 +3,11 @@ - Webhook key - Date - Url - Event - Retry count + Webhook key + Date + Url + Event + Retry count diff --git a/src/Umbraco.Web.UI.Client/src/views/webhooks/webhooks.html b/src/Umbraco.Web.UI.Client/src/views/webhooks/webhooks.html index 70d2a0be05..44e69cd499 100644 --- a/src/Umbraco.Web.UI.Client/src/views/webhooks/webhooks.html +++ b/src/Umbraco.Web.UI.Client/src/views/webhooks/webhooks.html @@ -17,10 +17,10 @@ - - - - + + + + diff --git a/src/Umbraco.Web.UI.Login/src/components/layouts/auth-layout.element.ts b/src/Umbraco.Web.UI.Login/src/components/layouts/auth-layout.element.ts index 44ebab1b3c..4d9f972743 100644 --- a/src/Umbraco.Web.UI.Login/src/components/layouts/auth-layout.element.ts +++ b/src/Umbraco.Web.UI.Login/src/components/layouts/auth-layout.element.ts @@ -8,15 +8,23 @@ import { when } from 'lit/directives/when.js'; * @element umb-auth-layout * @slot - The content of the layout * @cssprop --umb-login-background - The background of the layout (default: #f4f4f4) + * @cssprop --umb-login-primary-color - The color of the headline (default: #283a97) + * @cssprop --umb-login-text-color - The color of the text (default: #000) + * @cssprop --umb-login-header-font-size - The font-size of the headline (default: 3rem) + * @cssprop --umb-login-header-font-size-large - The font-size of the headline on large screens (default: 4rem) + * @cssprop --umb-login-header-secondary-font-size - The font-size of the secondary headline (default: 2.4rem) * @cssprop --umb-login-image - The background of the image wrapper (default: the value of the backgroundImage property) * @cssprop --umb-login-image-display - The display of the image wrapper (default: flex) + * @cssprop --umb-login-image-border-radius - The border-radius of the image wrapper (default: 38px) * @cssprop --umb-login-content-background - The background of the content wrapper (default: none) * @cssprop --umb-login-content-display - The display of the content wrapper (default: flex) * @cssprop --umb-login-content-width - The width of the content wrapper (default: 100%) * @cssprop --umb-login-content-height - The height of the content wrapper (default: 100%) + * @cssprop --umb-login-content-border-radius - The border-radius of the content wrapper (default: 0) * @cssprop --umb-login-align-items - The align-items of the main wrapper (default: unset) - * @cssprop --umb-curves-color - The color of the curves (default: #f5c1bc) - * @cssprop --umb-curves-display - The display of the curves (default: inline) + * @cssprop --umb-login-button-border-radius - The border-radius of the buttons (default: 45px) + * @cssprop --umb-login-curves-color - The color of the curves (default: #f5c1bc) + * @cssprop --umb-login-curves-display - The display of the curves (default: inline) */ @customElement('umb-auth-layout') export class UmbAuthLayoutElement extends LitElement { @@ -97,20 +105,21 @@ export class UmbAuthLayoutElement extends LitElement { static styles: CSSResultGroup = [ css` :host { - --uui-color-interactive: #283a97; - --uui-button-border-radius: 45px; + --uui-color-interactive: var(--umb-login-primary-color, #283a97); + --uui-button-border-radius: var(--umb-login-button-border-radius, 45px); --uui-color-default: var(--uui-color-interactive); --uui-button-height: 42px; --uui-select-height: 38px; --input-height: 40px; - --header-font-size: 3rem; - --header-secondary-font-size: 2.4rem; - --curves-color: var(--umb-curves-color, #f5c1bc); - --curves-display: var(--umb-curves-display, inline); + --header-font-size: var(--umb-login-header-font-size, 3rem); + --header-secondary-font-size: var(--umb-login-header-secondary-font-size, 2.4rem); + --curves-color: var(--umb-login-curves-color, #f5c1bc); + --curves-display: var(--umb-login-curves-display, inline); display: block; background: var(--umb-login-background, #f4f4f4); + color: var(--umb-login-text-color, #000); } #main-no-image, @@ -136,6 +145,7 @@ export class UmbAuthLayoutElement extends LitElement { height: var(--umb-login-content-height, 100%); box-sizing: border-box; overflow: auto; + border-radius: var(--umb-login-content-border-radius, 0); } #content { @@ -148,7 +158,7 @@ export class UmbAuthLayoutElement extends LitElement { background: var(--umb-login-image, var(--image)); width: 100%; height: 100%; - border-radius: 38px; + border-radius: var(--umb-login-image-border-radius, 38px); position: relative; overflow: hidden; color: var(--curves-color); @@ -181,7 +191,7 @@ export class UmbAuthLayoutElement extends LitElement { @media only screen and (min-width: 900px) { :host { - --header-font-size: 4rem; + --header-font-size: var(--umb-login-header-font-size-large, 4rem); } #main { diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 76f2f57e3b..0609c216eb 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -3,6 +3,7 @@ Umbraco.Cms.Web.UIfalsefalse + false diff --git a/templates/Umbraco.Templates.csproj b/templates/Umbraco.Templates.csproj index 165e767bec..6a4d0460d1 100644 --- a/templates/Umbraco.Templates.csproj +++ b/templates/Umbraco.Templates.csproj @@ -9,6 +9,7 @@ true . NU5128 + false diff --git a/templates/UmbracoPackage/UmbracoPackage.csproj b/templates/UmbracoPackage/UmbracoPackage.csproj index 268611b9ae..98f5bac3ad 100644 --- a/templates/UmbracoPackage/UmbracoPackage.csproj +++ b/templates/UmbracoPackage/UmbracoPackage.csproj @@ -8,6 +8,7 @@ ... umbraco plugin package UmbracoPackage + false diff --git a/templates/UmbracoProject/UmbracoProject.csproj b/templates/UmbracoProject/UmbracoProject.csproj index ee8dd5e56e..1c530223ad 100644 --- a/templates/UmbracoProject/UmbracoProject.csproj +++ b/templates/UmbracoProject/UmbracoProject.csproj @@ -4,6 +4,7 @@ enable enable Umbraco.Cms.Web.UI + false diff --git a/tests/Directory.Packages.props b/tests/Directory.Packages.props new file mode 100644 index 0000000000..41398eed6e --- /dev/null +++ b/tests/Directory.Packages.props @@ -0,0 +1,24 @@ + + + + true + NU1507 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Umbraco.TestData/Umbraco.TestData.csproj b/tests/Umbraco.TestData/Umbraco.TestData.csproj index c118664df2..7e19740a31 100644 --- a/tests/Umbraco.TestData/Umbraco.TestData.csproj +++ b/tests/Umbraco.TestData/Umbraco.TestData.csproj @@ -1,6 +1,6 @@ - + diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index 45b0ebbe91..28bcb052fc 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json @@ -121,12 +121,6 @@ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", "dev": true }, - "node_modules/@types/node": { - "version": "14.17.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.33.tgz", - "integrity": "sha512-noEeJ06zbn3lOh4gqe2v7NMGS33jrulfNqYFDjjEbhpDEHR5VTxgYNQSBqBlJIsBJW3uEYDgD6kvMnrrhGzq8g==", - "dev": true - }, "node_modules/@umbraco/json-models-builders": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-1.0.6.tgz", @@ -999,718 +993,5 @@ "node": ">= 6" } } - }, - "dependencies": { - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true - }, - "@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "dev": true - }, - "@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@playwright/test": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.0.tgz", - "integrity": "sha512-xis/RXXsLxwThKnlIXouxmIvvT3zvQj1JE39GsNieMUrMpb3/GySHDh2j8itCG22qKVD4MYLBp7xB73cUW/UUw==", - "dev": true, - "requires": { - "playwright": "1.38.0" - } - }, - "@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "dev": true - }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true - }, - "@types/node": { - "version": "14.17.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.33.tgz", - "integrity": "sha512-noEeJ06zbn3lOh4gqe2v7NMGS33jrulfNqYFDjjEbhpDEHR5VTxgYNQSBqBlJIsBJW3uEYDgD6kvMnrrhGzq8g==", - "dev": true - }, - "@umbraco/json-models-builders": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-1.0.6.tgz", - "integrity": "sha512-bXwfXcpuqG1Ye714L9KJEGXuSzJfckysE/6CuPjdG8FqHWTE1brv28teR2oMw+ih8ca2u2zUboRgdzLEU/1D3Q==", - "requires": { - "camelize": "^1.0.0", - "faker": "^4.1.0" - } - }, - "@umbraco/playwright-testhelpers": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-1.0.25.tgz", - "integrity": "sha512-6H452J6LhP0EHjF4jR7V7i0U8WPTiAbSyhN1J459BbbYEJ4QX1A2ZlCdA6VSBAsK1xYdMXD+yxsVJq7AAwiy9A==", - "requires": { - "@umbraco/json-models-builders": "^1.0.6", - "camelize": "^1.0.0", - "faker": "^4.1.0", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "xhr2": "^0.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "axios": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", - "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.7" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "cycle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==", - "dev": true - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dotenv": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz", - "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==" - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", - "dev": true - }, - "faker": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", - "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "joi": { - "version": "17.6.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.3.tgz", - "integrity": "sha512-YlQsIaS9MHYekzf1Qe11LjTkNzx9qhYluK3172z38RxYoAUf82XMX1p1DG1H4Wtk2ED/vPdSn9OggqtDu+aTow==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.0", - "@sideway/pinpoint": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "requires": { - "mime-db": "1.51.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", - "dev": true - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "playwright": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.0.tgz", - "integrity": "sha512-fJGw+HO0YY+fU/F1N57DMO+TmXHTrmr905J05zwAQE9xkuwP/QLDk63rVhmyxh03dYnEhnRbsdbH9B0UVVRB3A==", - "dev": true, - "requires": { - "fsevents": "2.3.2", - "playwright-core": "1.38.0" - } - }, - "playwright-core": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.0.tgz", - "integrity": "sha512-f8z1y8J9zvmHoEhKgspmCvOExF2XdcxMW8jNRuX4vkQFrzV4MlZ55iwb5QeyiFQgOFCUolXiRHgpjSEnqvO48g==", - "dev": true - }, - "prompt": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.3.0.tgz", - "integrity": "sha512-ZkaRWtaLBZl7KKAKndKYUL8WqNT+cQHKRZnT4RYYms48jQkFw3rrBL+/N5K/KtdEveHkxs982MX2BkDKub2ZMg==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "async": "3.2.3", - "read": "1.0.x", - "revalidator": "0.1.x", - "winston": "2.x" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", - "dev": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "revalidator": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", - "integrity": "sha512-xcBILK2pA9oh4SiinPEZfhP8HfrB/ha+a2fTMyl7Om2WjlDVrOQy99N2MXXlUHqGJz4qEu2duXxHJjDWuK/0xg==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", - "dev": true - }, - "wait-on": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", - "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", - "dev": true, - "requires": { - "axios": "^0.25.0", - "joi": "^17.6.0", - "lodash": "^4.17.21", - "minimist": "^1.2.5", - "rxjs": "^7.5.4" - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "winston": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.6.tgz", - "integrity": "sha512-J5Zu4p0tojLde8mIOyDSsmLmcP8I3Z6wtwpTDHx1+hGcdhxcJaAmG4CFtagkb+NiN1M9Ek4b42pzMWqfc9jm8w==", - "dev": true, - "requires": { - "async": "^3.2.3", - "colors": "1.0.x", - "cycle": "1.0.x", - "eyes": "0.1.x", - "isstream": "0.1.x", - "stack-trace": "0.0.x" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xhr2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", - "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==" - } } } diff --git a/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj index 885fc01b0e..09a4600005 100644 --- a/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj +++ b/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj @@ -1,12 +1,16 @@ Exe + false + false + false + false - - - + + + diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj index 8dd0bd4060..bf0dc9ddc1 100644 --- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj +++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj @@ -9,11 +9,10 @@ - - - - - + + + + diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 44801a1011..c4d3070472 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -10,11 +10,11 @@ - - - - - + + + + + diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueEditorReuseTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueEditorReuseTests.cs index d88a9689ab..67dd5162bf 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueEditorReuseTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueEditorReuseTests.cs @@ -1,8 +1,9 @@ -using System.Linq; +using System.Linq; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Umbraco.Cms.Core.IO; +using Umbraco.Cms.Core.Models.Blocks; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; @@ -34,9 +35,10 @@ public class DataValueEditorReuseTests _dataValueEditorFactoryMock .Setup(m => - m.Create(It.IsAny())) + m.Create(It.IsAny(), It.IsAny())) .Returns(() => new BlockListPropertyEditorBase.BlockListEditorPropertyValueEditor( new DataEditorAttribute("a", "b", "c"), + new BlockListEditorDataConverter(), _propertyEditorCollection, Mock.Of(), Mock.Of(), @@ -105,7 +107,7 @@ public class DataValueEditorReuseTests Assert.NotNull(dataValueEditor2); Assert.AreNotSame(dataValueEditor1, dataValueEditor2); _dataValueEditorFactoryMock.Verify( - m => m.Create(It.IsAny()), + m => m.Create(It.IsAny(), It.IsAny()), Times.Exactly(2)); } @@ -128,7 +130,7 @@ public class DataValueEditorReuseTests Assert.AreEqual("config", ((DataValueEditor)dataValueEditor2).Configuration); Assert.AreNotSame(dataValueEditor1, dataValueEditor2); _dataValueEditorFactoryMock.Verify( - m => m.Create(It.IsAny()), + m => m.Create(It.IsAny(), It.IsAny()), Times.Exactly(2)); } } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/DefaultContentVersionCleanupPolicyTest.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/DefaultContentVersionCleanupPolicyTest.cs index b0fc8cbb43..6233e22041 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/DefaultContentVersionCleanupPolicyTest.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/DefaultContentVersionCleanupPolicyTest.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Linq; using AutoFixture.NUnit3; using Microsoft.Extensions.Options; using Moq; diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJobTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJobTests.cs index cf9883603b..316605a04e 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJobTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJobTests.cs @@ -10,6 +10,7 @@ using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.HealthChecks; using Umbraco.Cms.Core.HealthChecks.NotificationMethods; using Umbraco.Cms.Core.Logging; @@ -105,7 +106,8 @@ public class HealthCheckNotifierJobTests mockScopeProvider.Object, mockLogger.Object, mockProfilingLogger.Object, - Mock.Of()); + Mock.Of(), + Mock.Of()); } private void VerifyNotificationsNotSent() => VerifyNotificationsSentTimes(Times.Never()); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index 8120ab343a..b766bea5f4 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -5,10 +5,10 @@ - - - - + + + + diff --git a/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj b/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj index c9275c6b94..8b66986898 100644 --- a/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj +++ b/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj @@ -3,6 +3,7 @@ Exe false false + false diff --git a/umbraco.sln b/umbraco.sln index 432c5d1afc..98a353a387 100644 --- a/umbraco.sln +++ b/umbraco.sln @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B5BD12C1 tests\.editorconfig = tests\.editorconfig tests\codeanalysis.ruleset = tests\codeanalysis.ruleset tests\Directory.Build.props = tests\Directory.Build.props + tests\Directory.Packages.props = tests\Directory.Packages.props EndProjectSection EndProject Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "http://localhost:3961", "{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}" @@ -133,6 +134,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution umbraco.sln.DotSettings = umbraco.sln.DotSettings version.json = version.json global.json = global.json + src\Directory.Packages.props = src\Directory.Packages.props EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{20CE9C97-9314-4A19-BCF1-D12CF49B7205}"
EnabledEventsUrlTypesEnabledEventsUrlTypes