using System.Text; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.Rendering; using Newtonsoft.Json; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.WebAssets; using Umbraco.Cms.Infrastructure.WebAssets; using Umbraco.Cms.Web.BackOffice.Controllers; using Umbraco.Cms.Web.BackOffice.Security; namespace Umbraco.Extensions; public static class HtmlHelperBackOfficeExtensions { /// /// Outputs a script tag containing the bare minimum (non secure) server vars for use with the angular app /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// These are the bare minimal server variables that are required for the application to start without being /// authenticated, /// we will load the rest of the server vars after the user is authenticated. /// public static async Task BareMinimumServerVariablesScriptAsync(this IHtmlHelper html, BackOfficeServerVariables backOfficeServerVariables) { Dictionary minVars = await backOfficeServerVariables.BareMinimumServerVariablesAsync(); var str = @""; return html.Raw(str); } /// /// Used to render the script that will pass in the angular "externalLoginInfo" service/value on page load /// /// /// /// public static async Task AngularValueExternalLoginInfoScriptAsync(this IHtmlHelper html, IBackOfficeExternalLoginProviders externalLogins, BackOfficeExternalLoginProviderErrors externalLoginErrors) { IEnumerable providers = await externalLogins.GetBackOfficeProvidersAsync(); var loginProviders = providers .Select(p => new { authType = p.ExternalLoginProvider.AuthenticationType, caption = p.AuthenticationScheme.DisplayName, properties = p.ExternalLoginProvider.Options }) .ToArray(); var sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine(@"var errors = [];"); if (externalLoginErrors != null) { if (externalLoginErrors.Errors is not null) { foreach (var error in externalLoginErrors.Errors) { sb.AppendFormat(@"errors.push(""{0}"");", error.ToSingleLine()).AppendLine(); } } } sb.AppendLine(@"app.value(""externalLoginInfo"", {"); if (externalLoginErrors?.AuthenticationType != null) { sb.AppendLine($@"errorProvider: '{externalLoginErrors.AuthenticationType}',"); } sb.AppendLine(@"errors: errors,"); sb.Append(@"providers: "); sb.AppendLine(JsonConvert.SerializeObject(loginProviders)); sb.AppendLine(@"});"); return html.Raw(sb.ToString()); } /// /// Used to render the script that will pass in the angular "resetPasswordCodeInfo" service/value on page load /// /// /// /// public static IHtmlContent AngularValueResetPasswordCodeInfoScript(this IHtmlHelper html, object? val) { var sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine(@"var errors = [];"); if (val is IEnumerable errors) { foreach (var error in errors) { sb.AppendFormat(@"errors.push(""{0}"");", error).AppendLine(); } val = null; } sb.AppendLine(@"app.value(""resetPasswordCodeInfo"", {"); sb.AppendLine(@"errors: errors,"); sb.Append(@"resetCodeModel: "); sb.AppendLine(val?.ToString() ?? "null"); sb.AppendLine(@"});"); return html.Raw(sb.ToString()); } public static async Task AngularValueTinyMceAssetsAsync(this IHtmlHelper html, IRuntimeMinifier runtimeMinifier) { IEnumerable files = await runtimeMinifier.GetJsAssetPathsAsync(BackOfficeWebAssets.UmbracoTinyMceJsBundleName); var sb = new StringBuilder(); sb.AppendLine(@"app.value(""tinyMceAssets"","); sb.AppendLine(JsonConvert.SerializeObject(files)); sb.AppendLine(@");"); return html.Raw(sb.ToString()); } }