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
43 changes: 4 additions & 39 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ jobs:
name: Build
runs-on: windows-latest
steps:
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: 11
distribution: 'temurin'

- name: Checkout repository with submodules
uses: actions/checkout@v4
with:
Expand All @@ -32,38 +26,9 @@ jobs:
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Cache SonarCloud packages
uses: actions/cache@v4
with:
path: ~\sonar\cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar

- name: Cache SonarCloud scanner
id: cache-sonar-scanner
uses: actions/cache@v4
with:
path: .\.sonar\scanner
key: ${{ runner.os }}-sonar-scanner
restore-keys: ${{ runner.os }}-sonar-scanner

- name: Install SonarCloud scanner
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
shell: powershell
run: |
New-Item -Path .\.sonar\scanner -ItemType Directory
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
- name: Restore dependencies
run: dotnet restore

- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
shell: powershell
run: |
.\.sonar\scanner\dotnet-sonarscanner begin /k:"Geta_${{ github.event.repository.name }}" /o:"geta" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths=**/**/coverage.opencover.xml
dotnet build
dotnet test --filter Category!=Integration /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=coverage
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --configuration Release --no-build
7 changes: 6 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release with Auto-Generated Notes
run: |
gh release create ${{ github.ref_name }} --generate-notes
$notes = @"
## Release notes

- Removed the explicit ``System.Text.Json`` package reference. It now comes as a transitive dependency from Optimizely, so it no longer needs to be declared in the package.
"@
gh release create ${{ github.ref_name }} --notes "$notes" --generate-notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Loop through all .nupkg files in the current directory and upload them to the release
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,5 @@ FakesAssemblies/

# Rider
*/.idea/*
.idea/*
.idea/*
/.claude
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

All notable changes to this project will be documented in this file.

## [7.0.0] - 2026-06-01

### Changed

- Upgraded target framework to .NET 10.
- Upgraded to Optimizely CMS 13 (`EPiServer.CMS.UI.Core` 13) and Optimizely Commerce 15.
- Bumped `Microsoft.Data.SqlClient` to 6.1.5.
- Replaced `Newtonsoft.Json` with `System.Text.Json` for content URL history serialization in `SqlContentUrlHistoryRepository`. `System.Text.Json` is provided transitively by Optimizely, so no explicit package reference is added.

### Fixed

- `Geta.NotFoundHandler.Optimizely` now registers its Optimizely Shell module when the package is referenced transitively (for example when only `Geta.NotFoundHandler.Optimizely.Commerce` is installed). The `module.config` copy target is now shipped under `buildTransitive`, fixing the "Unable to find a module by assembly 'Geta.NotFoundHandler.Optimizely'" error in the admin UI.

## [1.1.0]

- Refctoring
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
# NotFound Handler for ASP.NET Core and Optimizely

[![Build](https://github.com/Geta/geta-notfoundhandler/actions/workflows/build.yml/badge.svg)](https://github.com/Geta/geta-notfoundhandler/actions/workflows/build.yml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Geta_geta-notfoundhandler&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Geta_geta-notfoundhandler)
[![Platform](https://img.shields.io/badge/Platform-.NET%205-blue.svg?style=flat)](https://docs.microsoft.com/en-us/dotnet/)
[![Platform](https://img.shields.io/badge/Optimizely-%2012-orange.svg?style=flat)](http://world.episerver.com/cms/)
[![Platform](https://img.shields.io/badge/Platform-.NET%2010-blue.svg?style=flat)](https://docs.microsoft.com/en-us/dotnet/)
[![Platform](https://img.shields.io/badge/Optimizely-%2013-orange.svg?style=flat)](http://world.episerver.com/cms/)

## Description

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<PackageId>Geta.NotFoundHandler.Admin</PackageId>
<Title>Admin UI for NotFound Handler for ASP.NET Core and EPiServer</Title>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<PackageId>Geta.NotFoundHandler.Optimizely.Commerce</PackageId>
<Title>NotFound handler Admin UI integration Optimizely Commerce</Title>
<Authors>Geta Digital</Authors>
Expand Down Expand Up @@ -30,7 +30,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="EPiServer.Commerce.Core" Version="14.3.1" />
<PackageReference Include="EPiServer.Commerce.Core" Version="15.0.0" />
<PackageReference Include="MailKit" Version="4.16.0" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.7" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.Applications;
using EPiServer.Core;
using EPiServer.Web;

namespace Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects
{
public class CmsContentLinkProvider : IContentLinkProvider
{
private readonly ISiteDefinitionRepository _siteDefinitionRepository;
private readonly IApplicationRepository _applicationRepository;
private readonly IContentLoader _contentLoader;

public CmsContentLinkProvider(ISiteDefinitionRepository siteDefinitionRepository, IContentLoader contentLoader)
public CmsContentLinkProvider(IApplicationRepository applicationRepository, IContentLoader contentLoader)
{
_siteDefinitionRepository = siteDefinitionRepository;
_applicationRepository = applicationRepository;
_contentLoader = contentLoader;
}

public IEnumerable<ContentReference> GetAllLinks()
{
var allSites = _siteDefinitionRepository.List();
return allSites.SelectMany(site => _contentLoader.GetDescendents(site.StartPage));
return _applicationRepository.List()
.OfType<IRoutableApplication>()
.SelectMany(app => _contentLoader.GetDescendents(app.EntryPoint));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@

using System;
using System.Linq;
using EPiServer.PlugIn;
using EPiServer.Scheduler;
using Geta.NotFoundHandler.Optimizely.Infrastructure;

namespace Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects
{
[ScheduledPlugIn(DisplayName = "[Geta NotFoundHandler] Index content URLs",
GUID = "53C743AE-E152-497A-A7E5-7E30F4B5B321",
SortIndex = 5555)]
[ScheduledJob(DisplayName = "[Geta NotFoundHandler] Index content URLs",
GUID = "53C743AE-E152-497A-A7E5-7E30F4B5B321")]
public class IndexContentUrlsJob : ScheduledJobBase
{
private bool _stopped;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@

using System;
using System.Linq;
using EPiServer.PlugIn;
using EPiServer.Scheduler;
using Geta.NotFoundHandler.Optimizely.Infrastructure;

namespace Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects
{
[ScheduledPlugIn(DisplayName = "[Geta NotFoundHandler] Register content move redirects",
GUID = "EC96ABEE-5DA4-404F-A0C8-451C77CA4983",
SortIndex = 5555)]
[ScheduledJob(DisplayName = "[Geta NotFoundHandler] Register content move redirects",
GUID = "EC96ABEE-5DA4-404F-A0C8-451C77CA4983")]
public class RegisterMovedContentRedirectsJob : ScheduledJobBase
{
private readonly IContentUrlHistoryLoader _contentUrlHistoryLoader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
// Copyright (c) Geta Digital. All rights reserved.
// Licensed under Apache-2.0. See the LICENSE file in the project root for more information

using EPiServer.PlugIn;
using EPiServer.Scheduler;
using Geta.NotFoundHandler.Core.Suggestions;

namespace Geta.NotFoundHandler.Optimizely.Core.Suggestions.Jobs;

[ScheduledPlugIn(DisplayName = "[Geta NotFoundHandler] Suggestions cleanup job",
Description = "As suggestions table grow fast we should add a possibility to clean up old suggestions",
GUID = "6AE19CEC-1052-4482-97DF-981076DDD6F2",
SortIndex = 5555)]
[ScheduledJob(DisplayName = "[Geta NotFoundHandler] Suggestions cleanup job",
Description = "As suggestions table grow fast we should add a possibility to clean up old suggestions",
GUID = "6AE19CEC-1052-4482-97DF-981076DDD6F2")]
public class SuggestionsCleanupJob : ScheduledJobBase
{
private readonly ISuggestionsCleanupService _suggestionsCleanupService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
using System.Linq;
using Geta.NotFoundHandler.Data;
using Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
Comment thread
valdisiljuconoks marked this conversation as resolved.
using System.Text.Json.Serialization;

namespace Geta.NotFoundHandler.Optimizely.Data
{
Expand All @@ -25,18 +25,10 @@ public SqlContentUrlHistoryRepository(IDataExecutor dataExecutor)
_dataExecutor = dataExecutor;
}

private static JsonSerializerSettings JsonSettings
private static readonly JsonSerializerOptions JsonSettings = new()
{
get
{
var settings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc, Formatting = Formatting.None
};
settings.Converters.Add(new StringEnumConverter());
return settings;
}
}
Converters = { new JsonStringEnumConverter() }
};

private static byte[] CalculateMd5Hash(string input)
{
Expand Down Expand Up @@ -173,14 +165,14 @@ private void Update(ContentUrlHistory entity)

private static string ToJson(ICollection<TypedUrl> urls)
{
return JsonConvert.SerializeObject(urls, JsonSettings);
return JsonSerializer.Serialize(urls, JsonSettings);
}

private static ICollection<TypedUrl> FromJson(string value)
{
return string.IsNullOrEmpty(value)
? new List<TypedUrl>()
: JsonConvert.DeserializeObject<List<TypedUrl>>(value, JsonSettings);
: JsonSerializer.Deserialize<List<TypedUrl>>(value, JsonSettings);
}

private static IEnumerable<ContentUrlHistory> ToContentUrlHistory(DataTable table)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@using EPiServer.Framework.Web.Resources
@using EPiServer.Shell.Navigation
<!DOCTYPE html>
<html lang="en">
<head>
Expand Down Expand Up @@ -31,8 +30,8 @@
</head>
<body>
@Html.AntiForgeryToken()
@Html.CreatePlatformNavigationMenu()
<div @Html.ApplyPlatformNavigation()>
<platform-navigation />
<div>
@RenderBody()
</div>
</body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<PackageId>Geta.NotFoundHandler.Optimizely</PackageId>
<Title>NotFound handler Admin UI integration Optimizely</Title>
Expand All @@ -23,7 +23,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="EPiServer.CMS.UI.Core" Version="12.7.0" />
<PackageReference Include="EPiServer.CMS.UI.Core" Version="13.1.0" />
<PackageReference Include="MailKit" Version="4.16.0" />
</ItemGroup>

<ItemGroup>
Expand All @@ -49,7 +50,7 @@
<Pack>true</Pack>
<PackageCopyToOutput>true</PackageCopyToOutput>
<BuildAction>None</BuildAction>
<PackagePath>build\net6.0\$(MSBuildProjectName).targets</PackagePath>
<PackagePath>build\net6.0\$(MSBuildProjectName).targets;buildTransitive\net6.0\$(MSBuildProjectName).targets</PackagePath>
</Content>
</ItemGroup>

Expand Down
3 changes: 2 additions & 1 deletion src/Geta.NotFoundHandler.Web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,5 @@ FakesAssemblies/
.idea/*

wwwroot
modules
modules/*
!modules/ModulesInclude.proj
12 changes: 6 additions & 6 deletions src/Geta.NotFoundHandler.Web/Geta.NotFoundHandler.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\sub\geta-foundation-core\src\Foundation\Foundation.csproj" />
<ProjectReference Include="..\Geta.NotFoundHandler.Admin\Geta.NotFoundHandler.Admin.csproj"/>
<ProjectReference Include="..\Geta.NotFoundHandler.Optimizely.Commerce\Geta.NotFoundHandler.Optimizely.Commerce.csproj"/>
<ProjectReference Include="..\Geta.NotFoundHandler.Optimizely\Geta.NotFoundHandler.Optimizely.csproj"/>
<ProjectReference Include="..\Geta.NotFoundHandler\Geta.NotFoundHandler.csproj"/>
<ProjectReference Include="..\Geta.NotFoundHandler.Admin\Geta.NotFoundHandler.Admin.csproj" />
<ProjectReference Include="..\Geta.NotFoundHandler.Optimizely.Commerce\Geta.NotFoundHandler.Optimizely.Commerce.csproj" />
<ProjectReference Include="..\Geta.NotFoundHandler.Optimizely\Geta.NotFoundHandler.Optimizely.csproj" />
<ProjectReference Include="..\Geta.NotFoundHandler\Geta.NotFoundHandler.csproj" />
</ItemGroup>

<Import Project="..\..\sub\geta-foundation-core\src\Foundation\modules\ModulesInclude.proj"/>
<Import Project="modules\ModulesInclude.proj" Condition="Exists('modules\ModulesInclude.proj')" />
</Project>
8 changes: 7 additions & 1 deletion src/Geta.NotFoundHandler.Web/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using EPiServer.Authorization;
using EPiServer.Cms.Shell.UI;
using EPiServer.DependencyInjection;
using EPiServer.Framework.Hosting;
using EPiServer.Web.Hosting;
using Geta.NotFoundHandler.Infrastructure.Configuration;
Expand All @@ -25,6 +27,10 @@ public void ConfigureServices(IServiceCollection services)
services.AddNotFoundHandler(o => o.UseSqlServer(_configuration.GetConnectionString("EPiServerDB")),
policy => policy.RequireRole(Roles.CmsAdmins));
services.AddOptimizelyNotFoundHandler();
services.AddAdminUserRegistration(options =>
{
options.Behavior = RegisterAdminUserBehaviors.Enabled;
});
_foundationStartup.ConfigureServices(services);

var moduleName = typeof(ContainerController).Assembly.GetName().Name;
Expand All @@ -33,7 +39,7 @@ public void ConfigureServices(IServiceCollection services)
services.Configure<CompositeFileProviderOptions>(options =>
{
options.BasePathFileProviders.Add(new MappingPhysicalFileProvider(
$"/EPiServer/{moduleName}",
$"/Optimizely/{moduleName}",
string.Empty,
fullPath));
});
Expand Down
Loading
Loading