Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3e7d549
Created explicit endpoints returning the login image instead of leaki…
bergmania Dec 2, 2024
09403d2
Remove magic concatenation for action lookup
Migaroez Dec 3, 2024
ca1df39
Merge remote-tracking branch 'origin/v15/dev' into v15/bugfix/allow-c…
iOvergaard Dec 4, 2024
b708001
remove unused backoffice asset (login.jpg)
iOvergaard Dec 4, 2024
b99c408
remove unused umbraco logo assets
iOvergaard Dec 4, 2024
73dfada
add manifest handlers
iOvergaard Dec 4, 2024
ac34243
add mock handlers for the `security/back-office/graphics` endpoints t…
iOvergaard Dec 4, 2024
03f270f
add mock handlers for the `security/back-office/graphics` endpoints t…
iOvergaard Dec 4, 2024
25c525f
chore: update msw service worker
iOvergaard Dec 4, 2024
f00f395
feat: make static assets available for consumption without copying th…
iOvergaard Dec 4, 2024
c64cfb2
update consts with new location for static assets
iOvergaard Dec 4, 2024
c092dc1
feat: prefix login assets with `login-`
iOvergaard Dec 4, 2024
7bb32c0
remove unused asset `logo.png`
iOvergaard Dec 4, 2024
c840431
feat: introduce a `/back-office/graphics/logo` endpoint to serve the …
iOvergaard Dec 4, 2024
fd9109e
feat: use the alternative logo for disabled javascript warning
iOvergaard Dec 4, 2024
23891e1
feat: use the umbraco logo on the NoNodes.cshtml page
iOvergaard Dec 4, 2024
7dc45d2
Do not expose the new readme in the package
bergmania Dec 5, 2024
6dc8cf4
feat: add logo.svg
iOvergaard Dec 5, 2024
73fe41e
feat: add `umb-app-logo` element to display the backoffice logo inclu…
iOvergaard Dec 5, 2024
802cd3f
feat: use the new `umb-app-logo` element relevant places and make sur…
iOvergaard Dec 5, 2024
cd2a74e
feat: move logic to connectedCallback to prevent error from non-exist…
iOvergaard Dec 5, 2024
aba86dc
Merge remote-tracking branch 'origin/v15/dev' into v15/bugfix/allow-c…
iOvergaard Dec 5, 2024
dfec147
Merge branch 'v15/dev' into v15/bugfix/allow-changing-background-on-l…
iOvergaard Dec 5, 2024
9ed85a0
revert usage of HideBackOfficeLogo
iOvergaard Dec 5, 2024
d4dea13
feat: add alt text to logos
iOvergaard Dec 5, 2024
9a80df0
feat: add obsolete message and a hint to use BackOfficeLogo insted
iOvergaard Dec 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;

namespace Umbraco.Cms.Api.Management.Controllers.Security;

[ApiVersion("1.0")]
[VersionedApiBackOfficeRoute(Common.Security.Paths.BackOfficeApi.EndpointTemplate + "/graphics")]
[ApiExplorerSettings(IgnoreApi = true)]
public class BackOfficeGraphicsController : Controller
{
public const string LogoRouteName = nameof(BackOfficeGraphicsController) + "." + nameof(Logo);
public const string LoginBackGroundRouteName = nameof(BackOfficeGraphicsController) + "." + nameof(LoginBackground);
public const string LoginLogoRouteName = nameof(BackOfficeGraphicsController) + "." + nameof(LoginLogo);
public const string LoginLogoAlternativeRouteName = nameof(BackOfficeGraphicsController) + "." + nameof(LoginLogoAlternative);

private readonly IOptions<ContentSettings> _contentSettings;
private readonly IContentTypeProvider _contentTypeProvider;
private readonly IWebHostEnvironment _webHostEnvironment;

public BackOfficeGraphicsController(IOptions<ContentSettings> contentSettings, IOptions<StaticFileOptions> staticFileOptions, IWebHostEnvironment webHostEnvironment)
{
_contentSettings = contentSettings;
_webHostEnvironment = webHostEnvironment;
_contentTypeProvider = staticFileOptions.Value.ContentTypeProvider ?? new FileExtensionContentTypeProvider();
}

[HttpGet("login-background", Name = LoginBackGroundRouteName)]
[AllowAnonymous]
[MapToApiVersion("1.0")]
public IActionResult LoginBackground() => HandleFileRequest(_contentSettings.Value.LoginBackgroundImage);

[HttpGet("logo", Name = LogoRouteName)]
[AllowAnonymous]
[MapToApiVersion("1.0")]
public IActionResult Logo() => HandleFileRequest(_contentSettings.Value.BackOfficeLogo);

[HttpGet("login-logo", Name = LoginLogoRouteName)]
[AllowAnonymous]
[MapToApiVersion("1.0")]
public IActionResult LoginLogo() => HandleFileRequest(_contentSettings.Value.LoginLogoImage);

[HttpGet("login-logo-alternative", Name = LoginLogoAlternativeRouteName)]
[AllowAnonymous]
[MapToApiVersion("1.0")]
public IActionResult LoginLogoAlternative() => HandleFileRequest(_contentSettings.Value.LoginLogoImageAlternative);

private IActionResult HandleFileRequest(string virtualPath)
{
var filePath = Path.Combine(Constants.SystemDirectories.Umbraco, virtualPath).TrimStart(Constants.CharArrays.Tilde);
var fileInfo = _webHostEnvironment.WebRootFileProvider.GetFileInfo(filePath);

if (fileInfo.PhysicalPath is null)
{
return NotFound();
}

if (_contentTypeProvider.TryGetContentType(fileInfo.PhysicalPath, out var contentType))
{
Stream fileStream = fileInfo.CreateReadStream();
return File(fileStream, contentType);
}

return StatusCode(StatusCodes.Status412PreconditionFailed);
}
}
4 changes: 4 additions & 0 deletions src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
<Content Remove="$(LoginAssetsPath)\**" />
</ItemGroup>

<ItemGroup>
<Content Remove="wwwroot\umbraco\assets\README.md" />
</ItemGroup>

<Target Name="RestoreLogin" Inputs="$(LoginProjectDirectory)package-lock.json" Outputs="$(LoginProjectDirectory)node_modules/.package-lock.json">
<Message Importance="high" Text="Restoring Login NPM packages..." />
<Exec Command="npm ci --no-fund --no-audit --prefer-offline" WorkingDirectory="$(LoginProjectDirectory)" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@using Microsoft.Extensions.Options
@using Umbraco.Cms.Api.Management.Controllers.Security
@using Umbraco.Cms.Api.Management.Extensions
@using Umbraco.Cms.Core.Configuration.Models
@using Umbraco.Cms.Core.Logging
Expand All @@ -11,13 +12,12 @@
@inject IJsonSerializer JsonSerializer
@inject IProfilerHtml ProfilerHtml
@inject IOptions<GlobalSettings> GlobalSettings
@inject IOptions<ContentSettings> ContentSettings

@{
bool.TryParse(Context.Request.Query["umbDebug"], out var isDebug);
var backOfficePath = BackOfficePathGenerator.BackOfficePath;
var backOfficeAssetsPath = BackOfficePathGenerator.BackOfficeAssetsPath;
var loginLogoImage = ContentSettings.Value.LoginLogoImage;
var loginLogoImageAlternative = Url.RouteUrl(BackOfficeGraphicsController.LoginLogoAlternativeRouteName, new {Version= "1"});
}

<!DOCTYPE html>
Expand Down Expand Up @@ -54,8 +54,8 @@
}
</style>
<div id="noscript-container">
<h1 class="uui-h3" style="display: inline-flex; align-items: center; gap: 10px">
<img aria-hidden="true" alt="logo" src="@loginLogoImage" style="width: 100%" />
<h1 aria-hidden="true" class="uui-h3" style="display: inline-flex; align-items: center; gap: 10px">
<img alt="logo" src="@loginLogoImageAlternative" style="width: 100%" />
</h1>
<p>For full functionality of Umbraco CMS it is necessary to enable JavaScript.</p>
<p>Here are the <a href="https://www.enable-javascript.com/" target="_blank" rel="noopener" style="text-decoration: underline;">instructions how to enable JavaScript in your web browser</a>.</p>
Expand Down
12 changes: 6 additions & 6 deletions src/Umbraco.Cms.StaticAssets/umbraco/UmbracoLogin/Index.cshtml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Options;
@using Umbraco.Cms.Api.Management.Controllers.Security
@using Umbraco.Cms.Api.Management.Extensions
@using Umbraco.Cms.Api.Management.Security
@using Umbraco.Cms.Core.Configuration.Models
Expand All @@ -10,7 +11,6 @@
@using Umbraco.Cms.Core.Serialization
@using Umbraco.Cms.Web.Common.Hosting
@using Umbraco.Extensions
@inject IOptions<ContentSettings> ContentSettings
@inject IOptions<SecuritySettings> SecuritySettings
@inject IEmailSender EmailSender
@inject IHostingEnvironment HostingEnvironment
Expand All @@ -23,9 +23,9 @@
@{
bool.TryParse(Context.Request.Query["umbDebug"], out var isDebug);
var backOfficePath = GlobalSettings.Value.GetBackOfficePath(HostingEnvironment);
var loginLogoImage = ContentSettings.Value.LoginLogoImage;
var loginLogoImageAlternative = ContentSettings.Value.LoginLogoImageAlternative;
var loginBackgroundImage = ContentSettings.Value.LoginBackgroundImage;
var loginLogoImage = Url.RouteUrl(BackOfficeGraphicsController.LoginLogoRouteName, new {Version= "1"});
var loginLogoImageAlternative = Url.RouteUrl(BackOfficeGraphicsController.LoginLogoAlternativeRouteName, new {Version= "1"});
var loginBackgroundImage = Url.RouteUrl(BackOfficeGraphicsController.LoginBackGroundRouteName, new {Version= "1"});
var usernameIsEmail = SecuritySettings.Value.UsernameIsEmail;
var allowUserInvite = EmailSender.CanSendRequiredEmail();
var allowPasswordReset = SecuritySettings.Value.AllowPasswordReset && EmailSender.CanSendRequiredEmail();
Expand Down Expand Up @@ -73,8 +73,8 @@
}
</style>
<div id="noscript-container">
<h1 class="uui-h3" style="display: inline-flex; align-items: center; gap: 10px">
<img aria-hidden="true" alt="logo" src="@loginLogoImage" style="width: 100%" />
<h1 aria-hidden="true" class="uui-h3" style="display: inline-flex; align-items: center; gap: 10px">
<img alt="logo" src="@loginLogoImageAlternative" style="width: 100%" />
</h1>
<p>For full functionality of Umbraco CMS it is necessary to enable JavaScript.</p>
<p>Here are the <a href="https://www.enable-javascript.com/" target="_blank" rel="noopener" style="text-decoration: underline;">instructions how to enable JavaScript in your web browser</a>.</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@using Microsoft.Extensions.Options
@using Umbraco.Cms.Api.Management.Controllers.Security
@using Umbraco.Cms.Core.Configuration.Models
@using Umbraco.Cms.Core.Hosting
@using Umbraco.Cms.Core.Routing
Expand All @@ -8,6 +9,7 @@
@inject IOptions<GlobalSettings> globalSettings
@{
var backOfficePath = globalSettings.Value.GetBackOfficePath(hostingEnvironment);
var logoImage = Url.RouteUrl(BackOfficeGraphicsController.LogoRouteName, new {Version= "1"});
}
<!doctype html>
<html class="no-js" lang="en">
Expand All @@ -26,7 +28,7 @@
<article>
<div>
<div class="logo" aria-hidden="true">
<img alt="Umbraco" src="umbraco/backoffice/assets/umbraco_logomark_white.svg" width="91" height="91" />
<img alt="logo" src="@logoImage" height="91"/>
</div>

<h1>Welcome to your Umbraco installation</h1>
Expand Down
16 changes: 16 additions & 0 deletions src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Umbraco static assets

The files in this directory are static assets that are used by the Umbraco backoffice, installer, public-facing sites, and login screen. These files are served by the Umbraco backend and are not intended to be used by the front-end of your website.

## Structure

The assets are structured in the following way:

| Name | Description | Usage |
| ---- |--------------------------------------------------------------------|---------------------------------------------------------------------------------|
| `login.jpg` | The background image for the login screen. | /umbraco/management/api/v1/security/back-office/graphics/login-background |
| `logo.svg` | The Umbraco logo for the Backoffice and other public facing sites. | /umbraco/management/api/v1/security/back-office/graphics/logo |
| `logo_dark.svg` | The Umbraco logo in dark mode for the login screen. | /umbraco/management/api/v1/security/back-office/graphics/login-logo-alternative |
| `logo_light.svg` | The Umbraco logo in light mode for the login screen. | /umbraco/management/api/v1/security/back-office/graphics/login-logo |

All assets are linked up through the BackOfficeGraphicsController which uses the constants defined in [ContentSettings](../../../../Umbraco.Core/Configuration/Models/ContentSettings.cs).
Binary file not shown.
14 changes: 11 additions & 3 deletions src/Umbraco.Core/Configuration/Models/ContentSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ public class ContentSettings

internal const string StaticDisallowedUploadFiles = "ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,xamlx";
internal const bool StaticShowDeprecatedPropertyEditors = false;
internal const string StaticLoginBackgroundImage = "login/login.jpg";
internal const string StaticLoginLogoImage = "login/logo_light.svg";
internal const string StaticLoginLogoImageAlternative = "login/logo_dark.svg";
internal const string StaticLoginBackgroundImage = "assets/login.jpg";
internal const string StaticLoginLogoImage = "assets/logo_light.svg";
internal const string StaticLoginLogoImageAlternative = "assets/logo_dark.svg";
internal const string StaticBackOfficeLogo = "assets/logo.svg";
internal const bool StaticHideBackOfficeLogo = false;
internal const bool StaticDisableDeleteWhenReferenced = false;
internal const bool StaticDisableUnpublishWhenReferenced = false;
Expand Down Expand Up @@ -83,10 +84,17 @@ public class ContentSettings
[DefaultValue(StaticLoginLogoImageAlternative)]
public string LoginLogoImageAlternative { get; set; } = StaticLoginLogoImageAlternative;

/// <summary>
/// Gets or sets a value for the path to the backoffice logo.
/// </summary>
[DefaultValue(StaticBackOfficeLogo)]
public string BackOfficeLogo { get; set; } = StaticBackOfficeLogo;

/// <summary>
/// Gets or sets a value indicating whether to hide the backoffice umbraco logo or not.
/// </summary>
[DefaultValue(StaticHideBackOfficeLogo)]
[Obsolete("This setting is no longer used and will be removed in future versions. An alternative BackOffice logo can be set using the BackOfficeLogo setting.")]
public bool HideBackOfficeLogo { get; set; } = StaticHideBackOfficeLogo;

/// <summary>
Expand Down
8 changes: 2 additions & 6 deletions src/Umbraco.Web.UI.Client/src/apps/app/app-error.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ export class UmbAppErrorElement extends UmbLitElement {
return html`
<div id="background"></div>

<div id="logo" aria-hidden="true">
<img src="/umbraco/backoffice/assets/umbraco_logomark_white.svg" alt="Umbraco" />
<div id="logo">
<umb-app-logo></umb-app-logo>
</div>

<div id="container" class="uui-text">
Expand Down Expand Up @@ -222,10 +222,6 @@ export class UmbAppErrorElement extends UmbLitElement {
height: 30px;
}

#logo img {
height: 100%;
}

#container {
position: relative;
display: flex;
Expand Down
46 changes: 46 additions & 0 deletions src/Umbraco.Web.UI.Client/src/apps/app/app-logo.element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit';

@customElement('umb-app-logo')
export class UmbAppLogoElement extends UmbLitElement {
@state()
private _logoUrl?: string;

constructor() {
super();

this.consumeContext(UMB_APP_CONTEXT, (instance) => {
this._logoUrl = `${instance.getServerUrl()}/umbraco/management/api/v1/security/back-office/graphics/logo`;
});
}

/**
* Do not use shadow DOM for this element.
* @returns {this} The element instance.
*/
override createRenderRoot(): this {
return this;
}

override render() {
if (!this._logoUrl) {
return nothing;
}

return html`
<img
aria-hidden="true"
loading="eager"
src="/umbraco/management/api/v1/security/back-office/graphics/logo"
alt="logo"
style="height: 100%" />
`;
}
}

declare global {
interface HTMLElementTagNameMap {
'umb-app-logo': UmbAppLogoElement;
}
}
1 change: 1 addition & 0 deletions src/Umbraco.Web.UI.Client/src/apps/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export type * from './app-context-config.interface.js';
export * from './app-logo.element.js';
export * from './app.element.js';
export * from './app.context.js';
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_NEWVERSION_MODAL, UMB_SYSINFO_MODAL } from '@umbraco-cms/backoffice/sysinfo';
import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app';

@customElement('umb-backoffice-header-logo')
export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
Expand All @@ -17,6 +18,9 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
@state()
private _serverUpgradeCheck = false;

@state()
private _serverUrl = '';

#backofficeContext?: typeof UMB_BACKOFFICE_CONTEXT.TYPE;

constructor() {
Expand All @@ -34,6 +38,10 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {

this.#backofficeContext = context;
});

this.consumeContext(UMB_APP_CONTEXT, (context) => {
this._serverUrl = context.getServerUrl();
});
}

protected override async firstUpdated() {
Expand All @@ -50,15 +58,16 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {

override render() {
return html`
<uui-button id="logo" look="primary" label="Umbraco" compact popovertarget="logo-popover">
<img src="/umbraco/backoffice/assets/umbraco_logomark_white.svg" alt="Umbraco" />
<uui-button id="logo" look="primary" label="Logo" compact popovertarget="logo-popover">
<umb-app-logo id="logo-img"></umb-app-logo>
</uui-button>
<uui-popover-container id="logo-popover" placement="bottom-start">
<umb-popover-layout>
<div id="modal">
<img
src="/umbraco/backoffice/assets/umbraco_logo_blue.svg"
alt="Umbraco"
aria-hidden="true"
src="${this._serverUrl}/umbraco/management/api/v1/security/back-office/graphics/login-logo-alternative"
alt="logo"
width="300"
height="82"
loading="lazy" />
Expand Down Expand Up @@ -107,9 +116,9 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
--uui-button-background-color: transparent;
}

#logo > img {
#logo-img {
display: block;
height: var(--uui-size-10);
width: var(--uui-size-10);
}

#modal {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import { css, html, LitElement, customElement } from '@umbraco-cms/backoffice/ex
export class UmbInstallerLayoutElement extends LitElement {
override render() {
return html`
<!-- <div id="background" aria-hidden="true"></div> -->

<div id="logo" aria-hidden="true">
<img src="/umbraco/backoffice/assets/umbraco_logomark_white.svg" alt="Umbraco" />
<div id="logo">
<umb-app-logo></umb-app-logo>
</div>

<main id="container">
Expand All @@ -32,7 +30,6 @@ export class UmbInstallerLayoutElement extends LitElement {
position: relative;
height: 100%;

background-color: var(--uui-color-default);
background-color: hsla(240, 68%, 11%, 1);
background-image: radial-gradient(at 99% 2%, hsla(212, 40%, 12%, 1) 0px, transparent 50%),
radial-gradient(at 98% 95%, hsla(255, 40%, 12%, 1) 0px, transparent 50%),
Expand All @@ -52,10 +49,6 @@ export class UmbInstallerLayoutElement extends LitElement {
z-index: 10;
}

#logo img {
height: 100%;
}

#container {
container: container / inline-size;
width: 100%;
Expand Down
Loading