diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8840d0872c3a1706f63582dcb7a97a8f2ee6918b..50eb362cd2e9c0e79882d923b3386fd680b5338c 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -44,7 +44,6 @@ Changed
   * Introduce PBKDF2-SHA1 password hashing
 * Persistent database connections are now health-checked as to not fail
   requests
-* Incorporate SPDX license list for app licenses on About page
 * [Dev] The undocumented field `check` on `DataCheckResult` was renamed to `data_check`
 * Frontend bundling migrated from Webpack to Vite
 * Get dashboard widgets and data checks from apps with new registration mechanism.
@@ -57,14 +56,10 @@ Fixed
 ~~~~~
 
 * The error page displayed when an ObjectOverview component is not able to get the required data was incomplete.
-* The permission check for the dashboard edit page failed when the user had no person assigned.
 * In some cases, the IFrame for legacy pages was not properly sized for its content.
 * When accessing the person overview page without a person ID, the avatar image was not displayed properly.
 * The system tried to send notifications for done background tasks
   in addition to tasks started in the foreground.
-* Invitations for existing short name did not work.
-* Invitations for persons without pre-defined e-mail address did not behave correctly
-* OIDC scope "phone" had no claims.
 * 2FA via messages or phone calls didn't work.
 * [Dev] Site reference on extensible models can no longer cause name clashes
   because of its related name.
@@ -78,6 +73,27 @@ Removed
   * It caused major performance issues and is not useful with the new
     frontend anymore
 
+`2.12.3` - 2023-03-07
+---------------------
+
+Fixed
+~~~~~
+
+* The permission check for the dashboard edit page failed when the user had no person assigned.
+* OIDC scope "phone" had no claims.
+* AlekSIS groups were not synced to Django groups on registration of existing persons
+* Invitations for existing short name did not work.
+* Invitations for persons without pre-defined e-mail address did not behave correctly
+
+`2.12.2`_ - 2022-12-18
+----------------------
+
+Fixed
+~~~~~
+
+* Incorporate SPDX license list for app licenses on About page because
+  spdx-license-list dependency vanished.
+
 `2.12.1`_ - 2022-11-06
 ----------------------
 
@@ -1030,3 +1046,5 @@ Fixed
 .. _2.11.1: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.11.1
 .. _2.12: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.12
 .. _2.12.1: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.12.1
+.. _2.12.2: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.12.2
+.. _2.12.3: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.12.3
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index d2c02ed4a5815bfb113fa0aff19700b153b20eb4..f5e5899063678abc338ac971d1df3f55db3d0430 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -1,3 +1,5 @@
+from importlib import import_module
+
 from django.apps import apps
 from django.conf import settings
 from django.contrib import admin
@@ -410,12 +412,18 @@ for app_config in apps.app_configs.values():
         continue
 
     try:
-        urlpatterns.append(
-            path(f"django/app/{app_config.label}/", include(f"{app_config.name}.urls"))
-        )
+        urls_module = import_module(f"{app_config.name}.urls")
     except ModuleNotFoundError:
         # Ignore exception as app just has no URLs
-        pass  # noqa
+        urls_module = None
+
+    if hasattr(urls_module, "urlpatterns"):
+        urlpatterns.append(
+            path(f"django/app/{app_config.label}/", include(urls_module.urlpatterns))
+        )
+
+    if hasattr(urls_module, "api_urlpatterns"):
+        urlpatterns.append(path(f"app/{app_config.label}/", include(urls_module.api_urlpatterns)))
 
 urlpatterns.append(
     re_path(
diff --git a/pyproject.toml b/pyproject.toml
index 92ff925ecd444a8a5414d63a853d2c6132780c20..6c6616fda401bcf8dfe63a91f81fd16f1416434c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -66,7 +66,7 @@ colour = "^0.1.5"
 dynaconf = {version = "^3.1", extras = ["yaml", "toml", "ini"]}
 django-auth-ldap = { version = "^4.0", optional = true }
 django-maintenance-mode = "^0.18.0"
-django-ipware = "^4.0"
+django-ipware = "^5.0"
 django-impersonate = "^1.4"
 psycopg2 = "^2.8"
 django_select2 = "^8.0"