From 7b29db20260744c5f9366064555b4fd1cf97bfd3 Mon Sep 17 00:00:00 2001 From: ahall Date: Mon, 6 Jul 2026 13:29:03 +0100 Subject: [PATCH 1/4] fix: resolve NU1903 for SQLitePCLRaw.lib.e_sqlite3 by pinning SQLitePCLRaw 3.x (#492) Microsoft.EntityFrameworkCore.Sqlite floats a transitive dependency on SQLitePCLRaw.bundle_e_sqlite3 2.1.11, which pulls in the deprecated SQLitePCLRaw.lib.e_sqlite3 2.1.11 and triggers NU1903 (GHSA-2m69-gcr7-jv3q / CVE-2025-6965 - SQLite versions before 3.50.2 have a memory corruption issue). The advisory says no patched version exists for lib.e_sqlite3, but the SQLitePCLRaw 3.x line (released after the advisory) drops lib.e_sqlite3 entirely and depends on SourceGear.sqlite3 3.50.4.5 instead (SQLite 3.50.4, above the fix line), with full runtime asset coverage for android, ios, maccatalyst, browser-wasm, linux (incl. musl), osx, and win RIDs. - Pin SQLitePCLRaw.bundle_e_sqlite3 to 3.0.3 in the root Directory.Packages.props. CentralPackageTransitivePinningEnabled propagates this into src/CommunityToolkit.Datasync.Client, tests/CommunityToolkit.Datasync.TestCommon, tests/CommunityToolkit.Datasync.TestService, and tests/CommunityToolkit.Datasync.Client.Test without needing an explicit PackageReference, mirroring the Microsoft.OpenApi NU1903 fix from #489. - This does not affect the main packages' own published dependency floor, so every sample that consumes CommunityToolkit.Datasync.Client via NuGet PackageReference still floats the vulnerable version on its own. Added the same explicit override to the 7 affected samples: TodoApp.Avalonia, TodoApp.MAUI, TodoApp.WPF, TodoApp.WinUI3, TodoApp.Uno (via its own local Directory.Packages.props), todoapp-tutorial/ClientApp, and todoapp-blazor-wasm/TodoApp.BlazorWasm.Client. - TodoApp.Avalonia.Desktop needs no change; it inherits the pin transitively via its ProjectReference to TodoApp.Avalonia (verified via restore). Verified: dotnet restore/build/test on Datasync.Toolkit.sln (2280 tests passing across all 12 suites, 0 warnings on build). Confirmed every restored project.assets.json in src/tests now resolves SQLitePCLRaw.bundle_e_sqlite3/3.0.3 with zero occurrences of sqlitepclraw.lib.e_sqlite3 anywhere in the graph. Also verified restore (and build where the target platform doesn't require a missing workload) for TodoApp.Avalonia, TodoApp.Avalonia.Desktop, TodoApp.BlazorWasm.Client, todoapp-tutorial/ClientApp, TodoApp.WPF, and TodoApp.WinUI3 -- all clean, no NU1903, SQLitePCLRaw resolves to 3.0.3. TodoApp.MAUI (net10.0-android) and TodoApp.Uno's mobile TFMs could not be restored in this environment due to missing Android/iOS workloads, the same limitation noted in #493; the package-version pin is applied identically and is expected to resolve cleanly once those workloads are available, same as every other affected project. Fixes #492 --- Directory.Packages.props | 11 +++++++++++ .../TodoApp.BlazorWasm.Client.csproj | 2 ++ samples/todoapp-tutorial/ClientApp/ClientApp.csproj | 2 ++ .../TodoApp.Avalonia/TodoApp.Avalonia.csproj | 2 ++ samples/todoapp/TodoApp.MAUI/TodoApp.MAUI.csproj | 2 ++ samples/todoapp/TodoApp.Uno/Directory.Packages.props | 2 ++ .../TodoApp.Uno/TodoApp.Uno/TodoApp.Uno.csproj | 2 ++ samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj | 2 ++ samples/todoapp/TodoApp.WinUI3/TodoApp.WinUI3.csproj | 2 ++ 9 files changed, 27 insertions(+) diff --git a/Directory.Packages.props b/Directory.Packages.props index 4d26d91e..98af520b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -46,6 +46,17 @@ + + diff --git a/samples/todoapp-blazor-wasm/TodoApp.BlazorWasm.Client/TodoApp.BlazorWasm.Client.csproj b/samples/todoapp-blazor-wasm/TodoApp.BlazorWasm.Client/TodoApp.BlazorWasm.Client.csproj index b5006326..16e6e879 100644 --- a/samples/todoapp-blazor-wasm/TodoApp.BlazorWasm.Client/TodoApp.BlazorWasm.Client.csproj +++ b/samples/todoapp-blazor-wasm/TodoApp.BlazorWasm.Client/TodoApp.BlazorWasm.Client.csproj @@ -11,6 +11,8 @@ + + diff --git a/samples/todoapp-tutorial/ClientApp/ClientApp.csproj b/samples/todoapp-tutorial/ClientApp/ClientApp.csproj index c3c6132f..d39763a7 100644 --- a/samples/todoapp-tutorial/ClientApp/ClientApp.csproj +++ b/samples/todoapp-tutorial/ClientApp/ClientApp.csproj @@ -11,6 +11,8 @@ + + diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj index e2c0899e..3824f904 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj @@ -19,5 +19,7 @@ + + diff --git a/samples/todoapp/TodoApp.MAUI/TodoApp.MAUI.csproj b/samples/todoapp/TodoApp.MAUI/TodoApp.MAUI.csproj index 424870a2..6235f7b9 100644 --- a/samples/todoapp/TodoApp.MAUI/TodoApp.MAUI.csproj +++ b/samples/todoapp/TodoApp.MAUI/TodoApp.MAUI.csproj @@ -54,6 +54,8 @@ + + diff --git a/samples/todoapp/TodoApp.Uno/Directory.Packages.props b/samples/todoapp/TodoApp.Uno/Directory.Packages.props index 73f9c81f..6ab74fca 100644 --- a/samples/todoapp/TodoApp.Uno/Directory.Packages.props +++ b/samples/todoapp/TodoApp.Uno/Directory.Packages.props @@ -11,6 +11,8 @@ + + diff --git a/samples/todoapp/TodoApp.Uno/TodoApp.Uno/TodoApp.Uno.csproj b/samples/todoapp/TodoApp.Uno/TodoApp.Uno/TodoApp.Uno.csproj index 741c2b8b..fe818551 100644 --- a/samples/todoapp/TodoApp.Uno/TodoApp.Uno/TodoApp.Uno.csproj +++ b/samples/todoapp/TodoApp.Uno/TodoApp.Uno/TodoApp.Uno.csproj @@ -61,6 +61,8 @@ + + diff --git a/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj b/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj index 1dcc8772..4da1bdf8 100644 --- a/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj +++ b/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj @@ -11,5 +11,7 @@ + + diff --git a/samples/todoapp/TodoApp.WinUI3/TodoApp.WinUI3.csproj b/samples/todoapp/TodoApp.WinUI3/TodoApp.WinUI3.csproj index c4863a84..890eaff5 100644 --- a/samples/todoapp/TodoApp.WinUI3/TodoApp.WinUI3.csproj +++ b/samples/todoapp/TodoApp.WinUI3/TodoApp.WinUI3.csproj @@ -36,6 +36,8 @@ + + From da0393394cf6a77ace3e66574cbd9c985af069d4 Mon Sep 17 00:00:00 2001 From: ahall Date: Mon, 6 Jul 2026 13:38:42 +0100 Subject: [PATCH 2/4] docs: document the SQLitePCLRaw NU1903 fix and fix a broken admonition title - Add a note under 'Creating an offline-capable DbContext' in docs/in-depth/client/index.md pointing consumers at the SQLitePCLRaw.bundle_e_sqlite3 3.0.3 override from #492/#498 if they hit the NU1903 audit warning in their own application. - Fix the 'Blazor WASM and Blazor Hybrid' admonition above that section: it used an unquoted, bold (**...**) title (!!! note **Blazor WASM and Blazor Hybrid**), which the admonition markdown extension's title regex does not accept -- the whole block silently failed to parse as an admonition and rendered as a plain paragraph with literal '!!! note' text. Quoting the title (!!! note "Blazor WASM and Blazor Hybrid") fixes it. Verified against python-markdown + pymdownx.superfences (the extensions configured in mkdocs.shared.yml) that both admonitions now render as proper admonition blocks, including the nested fenced xml code sample. --- docs/in-depth/client/index.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/in-depth/client/index.md b/docs/in-depth/client/index.md index 5a8a27f5..f75935ec 100644 --- a/docs/in-depth/client/index.md +++ b/docs/in-depth/client/index.md @@ -2,7 +2,7 @@ This guide shows you how to perform common scenarios using the Datasync Community Toolkit. Use the client library in any .NET 9 application, including AvaloniaUI, MAUI, Uno Platform, WinUI, and WPF applications. -!!! note **Blazor WASM and Blazor Hybrid** +!!! note "Blazor WASM and Blazor Hybrid" The offline capabilities are known to have issues with Blazor WASM and Blazor Hybrid (since EF Core and SQLite do not work in those environments when running in the browser). Use online-only operations in these environments. For more information, see [our guide on Blazor WASM](./advanced/blazor-wasm.md) This guide primary deals with offline operations. For online operations, see the [Online operations guide](./online.md). @@ -26,6 +26,15 @@ Use the `OfflineDbContext` as the base for your offline storage: } } +!!! note "Resolving the SQLitePCLRaw NuGet audit warning (NU1903)" + `OfflineDbContext` uses Entity Framework Core's SQLite provider for local storage, which transitively depends on an older version of `SQLitePCLRaw.bundle_e_sqlite3` that triggers a high-severity `NU1903` NuGet audit warning ([GHSA-2m69-gcr7-jv3q](https://github.com/advisories/GHSA-2m69-gcr7-jv3q)). If you see this warning in your own application, force the patched `SQLitePCLRaw` 3.x line by adding an explicit package reference to your client `.csproj` file: + + ```xml + + ``` + + See [issue #492](https://github.com/CommunityToolkit/Datasync/issues/492) for more details. + !!! warning Sqlite stores DateTimeOffset using a second accuracy by default. We strongly recommend using [a ValueConverter](https://learn.microsoft.com/ef/core/modeling/value-conversions?tabs=data-annotations) to store date/time values. From 9feb829c3087382841c8e92c5ed27a0cc3007e1c Mon Sep 17 00:00:00 2001 From: ahall Date: Mon, 6 Jul 2026 13:40:17 +0100 Subject: [PATCH 3/4] docs: fix a second broken admonition title in client index.md !!! warning DO NOT USE THE SAME ENTITY TYPE FOR BOTH SERVICE AND CLIENT used an unquoted, all-caps multi-word title. The admonition extension's title regex swallows unquoted words into the block's CSS class list instead of using them as the title, so this rendered with the generic 'Warning' title (its intended custom title was silently dropped) and polluted the div's class attribute with lowercased title words. Quoting the title fixes both problems. Verified against python-markdown + pymdownx.superfences (the extensions configured in mkdocs.shared.yml): now renders as
with the correct custom title. --- docs/in-depth/client/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/in-depth/client/index.md b/docs/in-depth/client/index.md index f75935ec..29d6b8e6 100644 --- a/docs/in-depth/client/index.md +++ b/docs/in-depth/client/index.md @@ -47,7 +47,7 @@ Each synchronizable entity in an offline context **MUST** have the following pro * `Version` - `string?` or `byte[]?` - the opaque version for the entity on the service - changes on each write. * `Deleted` - boolean (optional) - only needed if using soft-delete on the service; marks the entity as deleted. -!!! warning DO NOT USE THE SAME ENTITY TYPE FOR BOTH SERVICE AND CLIENT +!!! warning "Do not use the same entity type for both service and client" You may be tempted to use the same entity type for both service and client. This is a mistake: * The service side entity types have automatic updates configured on UpdatedAt and Version which are not appropriate for the client. From 23ee13619e247453ede53920d259745f8d93b694 Mon Sep 17 00:00:00 2001 From: ahall Date: Mon, 6 Jul 2026 13:45:22 +0100 Subject: [PATCH 4/4] docs: add 'Building the documentation site' section to README Documents how to build/serve the MkDocs site locally (python venv, mkdocs + mkdocs-mermaid2-plugin, mkdocs serve on localhost:7000, and mkdocs build for a static site). Also add .venv-*/ to .gitignore so a local docs venv isn't accidentally committed. --- .gitignore | 1 + README.md | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/.gitignore b/.gitignore index b78c59c6..84341d6d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ ### Mkdocs Site ### site/ +.venv-*/ # Ignore codespaces / C# Dev Kit files .mono diff --git a/README.md b/README.md index 75237819..3f7cddc3 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,26 @@ The majority of tests in the test suite provide [TestContainers](https://testcon > **NOTE**: The `.runsettings` file contains secrets. It should not be checked in. We have added this file to the `.gitignore` to ensure that it is > not checked into public GitHub repositories. +## 📖 Building the documentation site + +The documentation site is built with [MkDocs](https://www.mkdocs.org/). To build and serve it locally: + +```sh +python3 -m venv .venv-docs +source .venv-docs/bin/activate +pip install mkdocs mkdocs-mermaid2-plugin + +mkdocs serve +``` + +Browse to [http://localhost:7000](http://localhost:7000) to view the site. `mkdocs serve` watches the `docs` folder and live-reloads whenever you make changes. + +To produce a static build instead (the output is written to `./site`, which is git-ignored): + +```sh +mkdocs build +``` + ## 🌍 Roadmap Read what we [plan for next iterations](https://github.com/CommunityToolkit/Datasync/milestones), and feel free to ask questions.