Skip to content

Commit a4a9a27

Browse files
ZeegaanAndyButlandkjacJasonElkinMigaroez
authored
V14: Merge 13 to 14 (#16340)
* Updates JSON schema for Umbraco 10 with latest references for Forms and Deploy (#15918) * Ported over #15928 changes for 13.3 RC (#16023) * Ported over #15928 changes for 13.3 RC * Use GetOrAdd() * Lock dictionary initialization --------- Co-authored-by: Jason Elkin <[email protected]> * Make the API content response builder extendable (#16056) * Make the API content response builder extendable * DeliveryApiJsonTypeResolver needs to be extendable too * bump rc to regular * Bump to next minor * Add blocks in RTE telemetry (#16104) * Add blocks telemetry * Use constants and update tests * V13: Add property type information to telemetry (#16109) * Add property type counts to telemetry * Use constants and fix tests * Update description * V10: Fix for fallback file upload (#14892) (#15868) * Fix for fallback file upload (#14892) * Added check for file type * Removed unneeded null checks and fixed tabs * Cleaning * Cleanups, cleanups, and removal of unneeded null checks * Reverted removal of relationshipservice * Revert null check removals (too risky) --------- Co-authored-by: Ambert van Unen <[email protected]> Co-authored-by: Laura Neto <[email protected]> (cherry picked from commit 0b5d1f8) * Fix up formatting --------- Co-authored-by: Ambert van Unen <[email protected]> * Implementors using Umbraco.Tests.Integration won't have to override GetLocalizedTextService (cherry picked from commit b001668) (cherry picked from commit 2bb56f1) * Fix logic for retrieving lastKnownElement (cherry picked from commit cae106b) * bump version * Bump version * Bump version * Since v13 properties can sometimes be of type IRichTextEditorIntermediateValue - this was unexpected in the XPath navigator code (#16121) * Webhook log improvements (#16200) * fix: include all headers in webhook log * feat: return webhook log status from server * feat: make webhook logs deep linkable * feat: add webhook log pagination * feat: improve webhook request/response body preview * V13: Optimize custom MVC routing (#16218) * Introduce EagerMatcherPolicy to conditionally bypass content routing * Ensure that the candidate we disable dynamic routing for is valid * Skip Umbraco endpoints * Simplify logic a bit * Move install logic to matcher * Ensure that dynamic routing is still skipped when in upgrade state * Fixup comments * Reduce nesting a bit * Don't show maintenance page when statically routed controllers are hít * Remove excess check, since installer requests are statically routed * V13: Optimize custom MVC routing (#16218) * Introduce EagerMatcherPolicy to conditionally bypass content routing * Ensure that the candidate we disable dynamic routing for is valid * Skip Umbraco endpoints * Simplify logic a bit * Move install logic to matcher * Ensure that dynamic routing is still skipped when in upgrade state * Fixup comments * Reduce nesting a bit * Don't show maintenance page when statically routed controllers are hít * Remove excess check, since installer requests are statically routed (cherry picked from commit ba9ddd1) * Property source level variation should only be applied when configured (#16270) * Property source level variation should only be applied when configured (#16270) (cherry picked from commit ab32bac) * Merge pull request from GHSA-j74q-mv2c-rxmp * Merge pull request from GHSA-j74q-mv2c-rxmp * Merge pull request from GHSA-j74q-mv2c-rxmp * Fix up after merge * Remove obselete test --------- Co-authored-by: Andy Butland <[email protected]> Co-authored-by: Kenn Jacobsen <[email protected]> Co-authored-by: Jason Elkin <[email protected]> Co-authored-by: Sven Geusens <[email protected]> Co-authored-by: Mole <[email protected]> Co-authored-by: Ambert van Unen <[email protected]> Co-authored-by: Lars-Erik <[email protected]> Co-authored-by: Joshua Daniel Pratt Nielsen <[email protected]> Co-authored-by: Bjarke Berg <[email protected]> Co-authored-by: Sebastiaan Janssen <[email protected]> Co-authored-by: Rasmus John Pedersen <[email protected]>
1 parent 8ddb911 commit a4a9a27

File tree

23 files changed

+548
-145
lines changed

23 files changed

+548
-145
lines changed

src/Umbraco.Cms.Api.Delivery/Json/DeliveryApiJsonTypeResolver.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,36 @@ public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions option
1212
{
1313
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);
1414

15+
Type[] derivedTypes = GetDerivedTypes(jsonTypeInfo);
16+
if (derivedTypes.Length > 0)
17+
{
18+
ConfigureJsonPolymorphismOptions(jsonTypeInfo, derivedTypes);
19+
}
20+
21+
return jsonTypeInfo;
22+
}
23+
24+
protected virtual Type[] GetDerivedTypes(JsonTypeInfo jsonTypeInfo)
25+
{
1526
if (jsonTypeInfo.Type == typeof(IApiContent))
1627
{
17-
ConfigureJsonPolymorphismOptions(jsonTypeInfo, typeof(ApiContent));
28+
return new[] { typeof(ApiContent) };
1829
}
19-
else if (jsonTypeInfo.Type == typeof(IApiContentResponse))
30+
31+
if (jsonTypeInfo.Type == typeof(IApiContentResponse))
2032
{
21-
ConfigureJsonPolymorphismOptions(jsonTypeInfo, typeof(ApiContentResponse));
33+
return new[] { typeof(ApiContentResponse) };
2234
}
23-
else if (jsonTypeInfo.Type == typeof(IRichTextElement))
35+
36+
if (jsonTypeInfo.Type == typeof(IRichTextElement))
2437
{
25-
ConfigureJsonPolymorphismOptions(jsonTypeInfo, typeof(RichTextRootElement), typeof(RichTextGenericElement), typeof(RichTextTextElement));
38+
return new[] { typeof(RichTextRootElement), typeof(RichTextGenericElement), typeof(RichTextTextElement) };
2639
}
2740

28-
return jsonTypeInfo;
41+
return Array.Empty<Type>();
2942
}
3043

31-
private void ConfigureJsonPolymorphismOptions(JsonTypeInfo jsonTypeInfo, params Type[] derivedTypes)
44+
protected void ConfigureJsonPolymorphismOptions(JsonTypeInfo jsonTypeInfo, params Type[] derivedTypes)
3245
{
3346
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
3447
{

src/Umbraco.Core/Constants-Telemetry.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,10 @@ public static class Telemetry
3535
public static string WebhookTotal = $"{WebhookPrefix}Total";
3636
public static string WebhookCustomHeaders = $"{WebhookPrefix}CustomHeaders";
3737
public static string WebhookCustomEvent = $"{WebhookPrefix}CustomEvent";
38+
public static string RichTextEditorCount = "RichTextEditorCount";
39+
public static string RichTextBlockCount = "RichTextBlockCount";
40+
public static string TotalPropertyCount = "TotalPropertyCount";
41+
public static string HighestPropertyCount = "HighestPropertyCount";
42+
public static string TotalCompositions = "TotalCompositions";
3843
}
3944
}

src/Umbraco.Core/Constants-Web.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public static class Routing
6262
public const string ControllerToken = "controller";
6363
public const string ActionToken = "action";
6464
public const string AreaToken = "area";
65+
public const string DynamicRoutePattern = "/{**umbracoSlug}";
6566
}
6667

6768
public static class RoutePath

src/Umbraco.Core/DeliveryApi/ApiContentResponseBuilder.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
using Umbraco.Cms.Core.Models.DeliveryApi;
22
using Umbraco.Cms.Core.Models.PublishedContent;
3-
using Umbraco.Cms.Core.Routing;
43
using Umbraco.Extensions;
54

65
namespace Umbraco.Cms.Core.DeliveryApi;
76

8-
public sealed class ApiContentResponseBuilder : ApiContentBuilderBase<IApiContentResponse>, IApiContentResponseBuilder
7+
public class ApiContentResponseBuilder : ApiContentBuilderBase<IApiContentResponse>, IApiContentResponseBuilder
98
{
109
private readonly IApiContentRouteBuilder _apiContentRouteBuilder;
1110

@@ -14,6 +13,12 @@ public ApiContentResponseBuilder(IApiContentNameProvider apiContentNameProvider,
1413
=> _apiContentRouteBuilder = apiContentRouteBuilder;
1514

1615
protected override IApiContentResponse Create(IPublishedContent content, string name, IApiContentRoute route, IDictionary<string, object?> properties)
16+
{
17+
IDictionary<string, IApiContentRoute> cultures = GetCultures(content);
18+
return new ApiContentResponse(content.Key, name, content.ContentType.Alias, content.CreateDate, content.UpdateDate, route, properties, cultures);
19+
}
20+
21+
protected virtual IDictionary<string, IApiContentRoute> GetCultures(IPublishedContent content)
1722
{
1823
var routesByCulture = new Dictionary<string, IApiContentRoute>();
1924

@@ -35,6 +40,6 @@ protected override IApiContentResponse Create(IPublishedContent content, string
3540
routesByCulture[publishedCultureInfo.Culture] = cultureRoute;
3641
}
3742

38-
return new ApiContentResponse(content.Key, name, content.ContentType.Alias, content.CreateDate, content.UpdateDate, route, properties, routesByCulture);
43+
return routesByCulture;
3944
}
4045
}

src/Umbraco.Core/EmbeddedResources/Lang/en.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@
476476
<key alias="detailedLevelDescription"><![CDATA[We will send:
477477
<ul>
478478
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
479-
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, and Property Editors in use.</li>
479+
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Property Types, Compositions, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, rich text datatypes, blocks used in rich text datatypes, and Property Editors in use.</li>
480480
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
481481
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>
482482
</ul>

src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@
470470
We will send:
471471
<ul>
472472
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
473-
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.</li>
473+
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Property Types, Compositions, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, rich text datatypes, blocks used in rich text datatypes, and Property Editors in use.</li>
474474
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
475475
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>
476476
</ul>

src/Umbraco.Core/Models/WebhookLog.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ public class WebhookLog
2727
public string ResponseBody { get; set; } = string.Empty;
2828

2929
public bool ExceptionOccured { get; set; }
30+
31+
public bool IsSuccessStatusCode { get; set; }
3032
}

src/Umbraco.Core/Routing/UmbracoRequestPaths.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ private static bool IsPluginControllerRoute(string path)
143143
/// <summary>
144144
/// Checks if the current uri is an install request
145145
/// </summary>
146-
public bool IsInstallerRequest(string absPath) => absPath.InvariantStartsWith(_installPath);
146+
public bool IsInstallerRequest(string absPath) => absPath.InvariantStartsWith(_managementApiPath);
147147

148148
/// <summary>
149149
/// Rudimentary check to see if it's not a server side request

src/Umbraco.Core/Routing/WebPath.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,28 @@ public static string Combine(params string[]? paths)
5050

5151
return sb.ToString();
5252
}
53+
54+
55+
/// <summary>
56+
/// Determines whether the provided web path is well-formed according to the specified UriKind.
57+
/// </summary>
58+
/// <param name="webPath">The web path to check. This can be null.</param>
59+
/// <param name="uriKind">The kind of Uri (Absolute, Relative, or RelativeOrAbsolute).</param>
60+
/// <returns>
61+
/// true if <paramref name="webPath"/> is well-formed; otherwise, false.
62+
/// </returns>
63+
public static bool IsWellFormedWebPath(string? webPath, UriKind uriKind)
64+
{
65+
if (string.IsNullOrWhiteSpace(webPath))
66+
{
67+
return false;
68+
}
69+
70+
if (webPath.StartsWith("//"))
71+
{
72+
return uriKind is not UriKind.Relative;
73+
}
74+
75+
return Uri.IsWellFormedUriString(webPath, uriKind);
76+
}
5377
}

src/Umbraco.Core/Services/WebhookLogFactory.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ public async Task<WebhookLog> CreateAsync(string eventAlias, HttpRequestMessage
1616
Url = webhook.Url,
1717
WebhookKey = webhook.Key,
1818
RetryCount = retryCount,
19-
RequestHeaders = requestMessage.Headers.ToString(),
19+
RequestHeaders = $"{requestMessage.Content?.Headers}{requestMessage.Headers}",
2020
RequestBody = await requestMessage.Content?.ReadAsStringAsync(cancellationToken)!,
2121
ExceptionOccured = exception is not null,
2222
};
2323

2424
if (httpResponseMessage is not null)
2525
{
2626
log.StatusCode = MapStatusCodeToMessage(httpResponseMessage.StatusCode);
27-
log.ResponseHeaders = httpResponseMessage.Headers.ToString();
27+
log.IsSuccessStatusCode = httpResponseMessage.IsSuccessStatusCode;
28+
log.ResponseHeaders = $"{httpResponseMessage.Content.Headers}{httpResponseMessage.Headers}";
2829
log.ResponseBody = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken);
2930
}
3031
else if (exception is HttpRequestException httpRequestException)

0 commit comments

Comments
 (0)