Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -29,6 +29,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// response already authorized (or denied) on its way in.
.dispatcherTypeMatchers(DispatcherType.ERROR).permitAll()
.requestMatchers("/", "/privacy", "/auth/**", "/css/**", "/js/**", "/fonts/**").permitAll()
// Root-level icons: browsers fetch these outside any page
// context (tab icon, home-screen bookmark), often anonymously.
.requestMatchers("/favicon.svg", "/favicon.ico", "/apple-touch-icon.png").permitAll()
.requestMatchers("/instructor/**").hasRole("INSTRUCTOR")
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/courses/**").authenticated()
Expand Down
Binary file added src/main/resources/static/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/main/resources/static/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,22 @@ main:focus {
}

.site-header__brand {
display: inline-flex;
align-items: center;
font-family: var(--font-display);
font-weight: 700;
font-size: var(--font-size-lg);
color: var(--color-text);
text-decoration: none;
}

.site-header__logo {
width: 1.35em;
height: 1.35em;
margin-right: var(--space-2);
color: var(--color-primary);
}

.site-header__brand-mark {
color: var(--color-primary);
}
Expand Down
Binary file added src/main/resources/static/favicon.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions src/main/resources/static/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 16 additions & 1 deletion src/main/resources/templates/fragments/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title th:text="${title}">learn-dev</title>
<!-- ico first with a fixed size so SVG-capable browsers prefer the
scalable icon; the SVG adapts to dark tabs by itself. -->
<link rel="icon" th:href="@{/favicon.ico}" sizes="32x32">
<link rel="icon" th:href="@{/favicon.svg}" type="image/svg+xml">
<link rel="apple-touch-icon" th:href="@{/apple-touch-icon.png}">
<link rel="stylesheet" th:href="@{/css/fonts.css}">
<link rel="stylesheet" th:href="@{/css/theme-catppuccin.css}">
<link rel="stylesheet" th:href="@{/css/base.css}">
Expand All @@ -27,7 +32,17 @@
<!-- lang="en": the chrome stays English even on French pages (RGAA 8.7) -->
<header class="site-header" lang="en">
<div class="site-header__inner">
<a class="site-header__brand" th:href="@{/}">learn<span class="site-header__brand-mark">-dev</span></a>
<!-- The logo is inline SVG (not an img) so stroke="currentColor"
follows the theme tokens; aria-hidden keeps the visible text
"learn-dev" as the accessible name of the link (RGAA 1.1). -->
<a class="site-header__brand" th:href="@{/}"><svg class="site-header__logo"
viewBox="0 0 24 24" aria-hidden="true" focusable="false"
fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M8.5 5.5 2.5 12l6 6.5"/>
<path d="M15.5 5.5 21.5 12l-6 6.5"/>
<path d="M12 6v12"/>
</svg>learn<span class="site-header__brand-mark">-dev</span></a>
<nav class="site-header__nav" aria-label="Main">
<ul class="nav__list" sec:authorize="!isAuthenticated()">
<li><a class="nav__link" th:href="@{/}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ void anonymous_is_redirected_to_login_on_gated_prefixes() throws Exception {
}
}

@Test
void anonymous_can_fetch_the_root_level_icons() throws Exception {
// Browsers request tab and bookmark icons outside any page context,
// often before login; a redirect here breaks the tab icon.
for (String path : new String[] {"/favicon.svg", "/favicon.ico", "/apple-touch-icon.png"}) {
mvc.perform(get(path)).andExpect(status().isOk());
}
}

// Student: may pass the /courses gate, denied on instructor and admin.

@Test
Expand Down