From 5fd53dd697438246db8d3ec561f400ebc25a460b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 07:41:47 +0000 Subject: [PATCH 01/14] Initial plan for issue From 6c2de757c3ffa13b1b56592722c1b76ae64fa2e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 07:49:45 +0000 Subject: [PATCH 02/14] Update DeserializedAuthenticationStateProvider to use SupplyParameterFromPersistentComponentState Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../DeserializedAuthenticationStateProvider.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs index bff25cd51fbe..d47f4ef28efa 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs @@ -17,7 +17,10 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt private static readonly Task _defaultUnauthenticatedTask = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()))); - private readonly Task _authenticationStateTask = _defaultUnauthenticatedTask; + private Task _authenticationStateTask = _defaultUnauthenticatedTask; + + [SupplyParameterFromPersistentComponentState] + private AuthenticationStateData? AuthStateData { get; set; } [UnconditionalSuppressMessage( "Trimming", @@ -28,12 +31,18 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt [DynamicDependency(JsonSerialized, typeof(ClaimData))] public DeserializedAuthenticationStateProvider(PersistentComponentState state, IOptions options) { - if (!state.TryTakeFromJson(PersistenceKey, out var authenticationStateData) || authenticationStateData is null) + // For backwards compatibility, try to read from the direct state first + if (AuthStateData is null && + state.TryTakeFromJson(PersistenceKey, out var authenticationStateData) && + authenticationStateData is not null) { - return; + AuthStateData = authenticationStateData; } - _authenticationStateTask = options.Value.DeserializationCallback(authenticationStateData); + if (AuthStateData is not null) + { + _authenticationStateTask = options.Value.DeserializationCallback(AuthStateData); + } } public override Task GetAuthenticationStateAsync() => _authenticationStateTask; From 0a88fce3a3443fce2b1d3fb2ab11cdd975fd2cc1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 08:08:34 +0000 Subject: [PATCH 03/14] Update DeserializedAuthenticationStateProvider to use declarative persistent state Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- ...DeserializedAuthenticationStateProvider.cs | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs index d47f4ef28efa..6bfc5ebf0ea6 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs @@ -11,13 +11,10 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication; internal sealed class DeserializedAuthenticationStateProvider : AuthenticationStateProvider { - // Do not change. This must match all versions of the server-side AuthenticationStateSerializer.PersistenceKey. - private const string PersistenceKey = $"__internal__{nameof(AuthenticationState)}"; - private static readonly Task _defaultUnauthenticatedTask = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()))); - private Task _authenticationStateTask = _defaultUnauthenticatedTask; + private readonly Task _authenticationStateTask; [SupplyParameterFromPersistentComponentState] private AuthenticationStateData? AuthStateData { get; set; } @@ -29,20 +26,11 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt [DynamicDependency(JsonSerialized, typeof(AuthenticationStateData))] [DynamicDependency(JsonSerialized, typeof(IList))] [DynamicDependency(JsonSerialized, typeof(ClaimData))] - public DeserializedAuthenticationStateProvider(PersistentComponentState state, IOptions options) + public DeserializedAuthenticationStateProvider(IOptions options) { - // For backwards compatibility, try to read from the direct state first - if (AuthStateData is null && - state.TryTakeFromJson(PersistenceKey, out var authenticationStateData) && - authenticationStateData is not null) - { - AuthStateData = authenticationStateData; - } - - if (AuthStateData is not null) - { - _authenticationStateTask = options.Value.DeserializationCallback(AuthStateData); - } + _authenticationStateTask = AuthStateData is not null + ? options.Value.DeserializationCallback(AuthStateData) + : _defaultUnauthenticatedTask; } public override Task GetAuthenticationStateAsync() => _authenticationStateTask; From 37de7d3df09e2c651ddddd3598f06e5bd8ce0089 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 09:19:22 +0000 Subject: [PATCH 04/14] Update DeserializedAuthenticationStateProvider to use persistent component state properly Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- package-lock.json | 4 +- ...DeserializedAuthenticationStateProvider.cs | 8 +-- ...thenticationServiceCollectionExtensions.cs | 2 + .../Microsoft.JSInterop.JS/src/package.json | 2 +- .../src/package.json.bak | 47 ++++++++++++++++ .../ts/signalr-protocol-msgpack/package.json | 6 +-- .../signalr-protocol-msgpack/package.json.bak | 51 ++++++++++++++++++ src/SignalR/clients/ts/signalr/package.json | 2 +- .../clients/ts/signalr/package.json.bak | 54 +++++++++++++++++++ 9 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak create mode 100644 src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak create mode 100644 src/SignalR/clients/ts/signalr/package.json.bak diff --git a/package-lock.json b/package-lock.json index c9f11b07ccbc..a20b21f4d6d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18895,7 +18895,7 @@ }, "src/SignalR/clients/ts/signalr": { "name": "@microsoft/signalr", - "version": "5.0.0-dev", + "version": "10.0.0-dev", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -18907,7 +18907,7 @@ }, "src/SignalR/clients/ts/signalr-protocol-msgpack": { "name": "@microsoft/signalr-protocol-msgpack", - "version": "5.0.0-dev", + "version": "10.0.0-dev", "license": "MIT", "dependencies": { "@microsoft/signalr": "*", diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs index 6bfc5ebf0ea6..bab39175030b 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs @@ -19,13 +19,7 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt [SupplyParameterFromPersistentComponentState] private AuthenticationStateData? AuthStateData { get; set; } - [UnconditionalSuppressMessage( - "Trimming", - "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", - Justification = $"{nameof(DeserializedAuthenticationStateProvider)} uses the {nameof(DynamicDependencyAttribute)} to preserve the necessary members.")] - [DynamicDependency(JsonSerialized, typeof(AuthenticationStateData))] - [DynamicDependency(JsonSerialized, typeof(IList))] - [DynamicDependency(JsonSerialized, typeof(ClaimData))] + public DeserializedAuthenticationStateProvider(IOptions options) { _authenticationStateTask = AuthStateData is not null diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs index 20cf1e0867f7..75e71ac8e74e 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs @@ -5,6 +5,7 @@ using System.Reflection; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Infrastructure; using Microsoft.AspNetCore.Components.WebAssembly.Authentication; using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -30,6 +31,7 @@ public static IServiceCollection AddAuthenticationStateDeserialization(this ISer { services.AddOptions(); services.TryAddScoped(); + RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(services, RenderMode.InteractiveWebAssembly); if (configure != null) { services.Configure(configure); diff --git a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json index 4a91339cf24f..8f480f3052c6 100644 --- a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json +++ b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json @@ -44,4 +44,4 @@ "rimraf": "^5.0.5", "typescript": "^5.3.3" } -} \ No newline at end of file +} diff --git a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak new file mode 100644 index 000000000000..4a91339cf24f --- /dev/null +++ b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak @@ -0,0 +1,47 @@ +{ + "name": "@microsoft/dotnet-js-interop", + "version": "10.0.0-dev", + "description": "Provides abstractions and features for interop between .NET and JavaScript code.", + "main": "dist/src/Microsoft.JSInterop.js", + "types": "dist/src/Microsoft.JSInterop.d.ts", + "type": "module", + "scripts": { + "clean": "rimraf ./dist", + "test": "jest", + "test:watch": "jest --watch", + "test:debug": "node --nolazy --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --colors --verbose", + "build": "npm run clean && npm run build:esm", + "build:lint": "eslint -c .eslintrc.json --ext .ts ./src", + "build:esm": "tsc --project ./tsconfig.json", + "get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/dotnet/extensions.git" + }, + "author": "Microsoft", + "license": "MIT", + "bugs": { + "url": "https://github.com/dotnet/aspnetcore/issues" + }, + "homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/JSInterop", + "files": [ + "dist/**" + ], + "devDependencies": { + "@babel/core": "^7.23.6", + "@babel/preset-env": "^7.23.6", + "@babel/preset-typescript": "^7.26.0", + "@typescript-eslint/eslint-plugin": "^6.15.0", + "@typescript-eslint/parser": "^6.15.0", + "babel-jest": "^29.7.0", + "eslint": "^8.56.0", + "eslint-plugin-jsdoc": "^46.9.1", + "eslint-plugin-prefer-arrow": "^1.2.3", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-junit": "^16.0.0", + "rimraf": "^5.0.5", + "typescript": "^5.3.3" + } +} \ No newline at end of file diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json index c9cc83805bbc..3f9769cdc736 100644 --- a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json +++ b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/signalr-protocol-msgpack", - "version": "5.0.0-dev", + "version": "10.0.0-dev", "description": "MsgPack Protocol support for ASP.NET Core SignalR", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", @@ -41,11 +41,11 @@ "src/**/*" ], "dependencies": { - "@microsoft/signalr": "*", + "@microsoft/signalr": ">=10.0.0-dev", "@msgpack/msgpack": "^2.7.0" }, "overrides": { "ws": ">=7.4.6", "tough-cookie": ">=4.1.3" } -} +} \ No newline at end of file diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak new file mode 100644 index 000000000000..c9cc83805bbc --- /dev/null +++ b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak @@ -0,0 +1,51 @@ +{ + "name": "@microsoft/signalr-protocol-msgpack", + "version": "5.0.0-dev", + "description": "MsgPack Protocol support for ASP.NET Core SignalR", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "typings": "./dist/esm/index.d.ts", + "umd": "./dist/browser/signalr-protocol-msgpack.js", + "umd_name": "signalR.protocols.msgpack", + "unpkg": "./dist/browser/signalr-protocol-msgpack.js", + "directories": { + "test": "spec" + }, + "sideEffects": false, + "scripts": { + "clean": "rimraf ./dist", + "prebuild": "rimraf ./src/pkg-version.ts && node -e \"const fs = require('fs'); const packageJson = require('./package.json'); fs.writeFileSync('./src/pkg-version.ts', 'export const VERSION = \\'' + packageJson.version + '\\';');\"", + "build": "npm run build:esm && npm run build:cjs && npm run build:browser && npm run build:uglify", + "build:esm": "tsc --project ./tsconfig.json --module es2015 --outDir ./dist/esm -d", + "build:cjs": "tsc --project ./tsconfig.json --module commonjs --outDir ./dist/cjs", + "build:browser": "webpack-cli", + "build:uglify": "terser -m -c --ecma 2019 --module --source-map \"url='signalr-protocol-msgpack.min.js.map',content='./dist/browser/signalr-protocol-msgpack.js.map'\" --comments -o ./dist/browser/signalr-protocol-msgpack.min.js ./dist/browser/signalr-protocol-msgpack.js", + "get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\"" + }, + "keywords": [ + "signalr", + "aspnetcore" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/dotnet/aspnetcore.git" + }, + "author": "Microsoft", + "license": "MIT", + "bugs": { + "url": "https://github.com/dotnet/aspnetcore/issues" + }, + "homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/SignalR#readme", + "files": [ + "dist/**/*", + "src/**/*" + ], + "dependencies": { + "@microsoft/signalr": "*", + "@msgpack/msgpack": "^2.7.0" + }, + "overrides": { + "ws": ">=7.4.6", + "tough-cookie": ">=4.1.3" + } +} diff --git a/src/SignalR/clients/ts/signalr/package.json b/src/SignalR/clients/ts/signalr/package.json index 805aed5a9bb2..a13e0ba8ee8b 100644 --- a/src/SignalR/clients/ts/signalr/package.json +++ b/src/SignalR/clients/ts/signalr/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/signalr", - "version": "5.0.0-dev", + "version": "10.0.0-dev", "description": "ASP.NET Core SignalR Client", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", diff --git a/src/SignalR/clients/ts/signalr/package.json.bak b/src/SignalR/clients/ts/signalr/package.json.bak new file mode 100644 index 000000000000..805aed5a9bb2 --- /dev/null +++ b/src/SignalR/clients/ts/signalr/package.json.bak @@ -0,0 +1,54 @@ +{ + "name": "@microsoft/signalr", + "version": "5.0.0-dev", + "description": "ASP.NET Core SignalR Client", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "typings": "./dist/esm/index.d.ts", + "umd": "./dist/browser/signalr.js", + "umd_name": "signalR", + "unpkg": "./dist/browser/signalr.js", + "directories": { + "test": "spec" + }, + "sideEffects": false, + "scripts": { + "clean": "rimraf ./dist", + "prebuild": "rimraf ./src/pkg-version.ts && node -e \"const fs = require('fs'); const packageJson = require('./package.json'); fs.writeFileSync('./src/pkg-version.ts', 'export const VERSION = \\'' + packageJson.version + '\\';');\"", + "build": "npm run build:esm && npm run build:cjs && npm run build:browser && npm run build:webworker", + "build:esm": "tsc --project ./tsconfig.json --module es2015 --outDir ./dist/esm -d", + "build:cjs": "tsc --project ./tsconfig.json --module commonjs --outDir ./dist/cjs", + "build:browser": "webpack-cli", + "build:webworker": "webpack-cli --env platform=webworker", + "get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\"" + }, + "keywords": [ + "signalr", + "aspnetcore" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/dotnet/aspnetcore.git" + }, + "author": "Microsoft", + "license": "MIT", + "bugs": { + "url": "https://github.com/dotnet/aspnetcore/issues" + }, + "homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/SignalR#readme", + "files": [ + "dist/**/*", + "src/**/*" + ], + "dependencies": { + "abort-controller": "^3.0.0", + "eventsource": "^2.0.2", + "fetch-cookie": "^2.0.3", + "node-fetch": "^2.6.7", + "ws": "^7.5.10" + }, + "overrides": { + "ansi-regex": "5.0.1", + "tough-cookie": ">=4.1.3" + } +} From 75fc6a156dbd6f26fe5a0ac70876ecde1296924b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 09:35:10 +0000 Subject: [PATCH 05/14] Refactor AuthenticationStateSerializer to use declarative persistent component state Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- package-lock.json | 4 +- .../src/AuthenticationStateSerializer.cs | 14 +++-- ...ssemblyRazorComponentsBuilderExtensions.cs | 2 + .../Microsoft.JSInterop.JS/src/package.json | 2 +- .../src/package.json.bak | 47 ---------------- .../ts/signalr-protocol-msgpack/package.json | 6 +-- .../signalr-protocol-msgpack/package.json.bak | 51 ------------------ src/SignalR/clients/ts/signalr/package.json | 2 +- .../clients/ts/signalr/package.json.bak | 54 ------------------- 9 files changed, 18 insertions(+), 164 deletions(-) delete mode 100644 src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak delete mode 100644 src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak delete mode 100644 src/SignalR/clients/ts/signalr/package.json.bak diff --git a/package-lock.json b/package-lock.json index a20b21f4d6d0..c9f11b07ccbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18895,7 +18895,7 @@ }, "src/SignalR/clients/ts/signalr": { "name": "@microsoft/signalr", - "version": "10.0.0-dev", + "version": "5.0.0-dev", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -18907,7 +18907,7 @@ }, "src/SignalR/clients/ts/signalr-protocol-msgpack": { "name": "@microsoft/signalr-protocol-msgpack", - "version": "10.0.0-dev", + "version": "5.0.0-dev", "license": "MIT", "dependencies": { "@microsoft/signalr": "*", diff --git a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs index 4c4a83e23196..ca43b4f2741b 100644 --- a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs +++ b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs @@ -17,6 +17,14 @@ internal sealed class AuthenticationStateSerializer : IHostEnvironmentAuthentica private readonly PersistingComponentStateSubscription _subscription; private Task? _authenticationStateTask; + private AuthenticationStateData? _authenticationStateData; + + [PersistentComponentStateStore] + public AuthenticationStateData? AuthStateData + { + get => _authenticationStateData; + set => _authenticationStateData = value; + } public AuthenticationStateSerializer(PersistentComponentState persistentComponentState, IOptions options) { @@ -32,11 +40,7 @@ private async Task OnPersistingAsync() throw new InvalidOperationException($"{nameof(SetAuthenticationState)} must be called before the {nameof(PersistentComponentState)}.{nameof(PersistentComponentState.RegisterOnPersisting)} callback."); } - var authenticationStateData = await _serializeCallback(await _authenticationStateTask); - if (authenticationStateData is not null) - { - _state.PersistAsJson(PersistenceKey, authenticationStateData); - } + AuthStateData = await _serializeCallback(await _authenticationStateTask); } /// diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs index d783bede44f5..dbfa966115ce 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Endpoints.Infrastructure; +using Microsoft.AspNetCore.Components.Infrastructure; using Microsoft.AspNetCore.Components.WebAssembly.Server; using Microsoft.AspNetCore.Components.WebAssembly.Services; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -41,6 +42,7 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I public static IRazorComponentsBuilder AddAuthenticationStateSerialization(this IRazorComponentsBuilder builder, Action? configure = null) { builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped()); + RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveWebAssembly); if (configure is not null) { builder.Services.Configure(configure); diff --git a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json index 8f480f3052c6..4a91339cf24f 100644 --- a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json +++ b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json @@ -44,4 +44,4 @@ "rimraf": "^5.0.5", "typescript": "^5.3.3" } -} +} \ No newline at end of file diff --git a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak b/src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak deleted file mode 100644 index 4a91339cf24f..000000000000 --- a/src/JSInterop/Microsoft.JSInterop.JS/src/package.json.bak +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@microsoft/dotnet-js-interop", - "version": "10.0.0-dev", - "description": "Provides abstractions and features for interop between .NET and JavaScript code.", - "main": "dist/src/Microsoft.JSInterop.js", - "types": "dist/src/Microsoft.JSInterop.d.ts", - "type": "module", - "scripts": { - "clean": "rimraf ./dist", - "test": "jest", - "test:watch": "jest --watch", - "test:debug": "node --nolazy --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --colors --verbose", - "build": "npm run clean && npm run build:esm", - "build:lint": "eslint -c .eslintrc.json --ext .ts ./src", - "build:esm": "tsc --project ./tsconfig.json", - "get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\"" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/dotnet/extensions.git" - }, - "author": "Microsoft", - "license": "MIT", - "bugs": { - "url": "https://github.com/dotnet/aspnetcore/issues" - }, - "homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/JSInterop", - "files": [ - "dist/**" - ], - "devDependencies": { - "@babel/core": "^7.23.6", - "@babel/preset-env": "^7.23.6", - "@babel/preset-typescript": "^7.26.0", - "@typescript-eslint/eslint-plugin": "^6.15.0", - "@typescript-eslint/parser": "^6.15.0", - "babel-jest": "^29.7.0", - "eslint": "^8.56.0", - "eslint-plugin-jsdoc": "^46.9.1", - "eslint-plugin-prefer-arrow": "^1.2.3", - "jest": "^29.7.0", - "jest-environment-jsdom": "^29.7.0", - "jest-junit": "^16.0.0", - "rimraf": "^5.0.5", - "typescript": "^5.3.3" - } -} \ No newline at end of file diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json index 3f9769cdc736..c9cc83805bbc 100644 --- a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json +++ b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/signalr-protocol-msgpack", - "version": "10.0.0-dev", + "version": "5.0.0-dev", "description": "MsgPack Protocol support for ASP.NET Core SignalR", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", @@ -41,11 +41,11 @@ "src/**/*" ], "dependencies": { - "@microsoft/signalr": ">=10.0.0-dev", + "@microsoft/signalr": "*", "@msgpack/msgpack": "^2.7.0" }, "overrides": { "ws": ">=7.4.6", "tough-cookie": ">=4.1.3" } -} \ No newline at end of file +} diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak deleted file mode 100644 index c9cc83805bbc..000000000000 --- a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json.bak +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@microsoft/signalr-protocol-msgpack", - "version": "5.0.0-dev", - "description": "MsgPack Protocol support for ASP.NET Core SignalR", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "typings": "./dist/esm/index.d.ts", - "umd": "./dist/browser/signalr-protocol-msgpack.js", - "umd_name": "signalR.protocols.msgpack", - "unpkg": "./dist/browser/signalr-protocol-msgpack.js", - "directories": { - "test": "spec" - }, - "sideEffects": false, - "scripts": { - "clean": "rimraf ./dist", - "prebuild": "rimraf ./src/pkg-version.ts && node -e \"const fs = require('fs'); const packageJson = require('./package.json'); fs.writeFileSync('./src/pkg-version.ts', 'export const VERSION = \\'' + packageJson.version + '\\';');\"", - "build": "npm run build:esm && npm run build:cjs && npm run build:browser && npm run build:uglify", - "build:esm": "tsc --project ./tsconfig.json --module es2015 --outDir ./dist/esm -d", - "build:cjs": "tsc --project ./tsconfig.json --module commonjs --outDir ./dist/cjs", - "build:browser": "webpack-cli", - "build:uglify": "terser -m -c --ecma 2019 --module --source-map \"url='signalr-protocol-msgpack.min.js.map',content='./dist/browser/signalr-protocol-msgpack.js.map'\" --comments -o ./dist/browser/signalr-protocol-msgpack.min.js ./dist/browser/signalr-protocol-msgpack.js", - "get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\"" - }, - "keywords": [ - "signalr", - "aspnetcore" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/dotnet/aspnetcore.git" - }, - "author": "Microsoft", - "license": "MIT", - "bugs": { - "url": "https://github.com/dotnet/aspnetcore/issues" - }, - "homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/SignalR#readme", - "files": [ - "dist/**/*", - "src/**/*" - ], - "dependencies": { - "@microsoft/signalr": "*", - "@msgpack/msgpack": "^2.7.0" - }, - "overrides": { - "ws": ">=7.4.6", - "tough-cookie": ">=4.1.3" - } -} diff --git a/src/SignalR/clients/ts/signalr/package.json b/src/SignalR/clients/ts/signalr/package.json index a13e0ba8ee8b..805aed5a9bb2 100644 --- a/src/SignalR/clients/ts/signalr/package.json +++ b/src/SignalR/clients/ts/signalr/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/signalr", - "version": "10.0.0-dev", + "version": "5.0.0-dev", "description": "ASP.NET Core SignalR Client", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", diff --git a/src/SignalR/clients/ts/signalr/package.json.bak b/src/SignalR/clients/ts/signalr/package.json.bak deleted file mode 100644 index 805aed5a9bb2..000000000000 --- a/src/SignalR/clients/ts/signalr/package.json.bak +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@microsoft/signalr", - "version": "5.0.0-dev", - "description": "ASP.NET Core SignalR Client", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "typings": "./dist/esm/index.d.ts", - "umd": "./dist/browser/signalr.js", - "umd_name": "signalR", - "unpkg": "./dist/browser/signalr.js", - "directories": { - "test": "spec" - }, - "sideEffects": false, - "scripts": { - "clean": "rimraf ./dist", - "prebuild": "rimraf ./src/pkg-version.ts && node -e \"const fs = require('fs'); const packageJson = require('./package.json'); fs.writeFileSync('./src/pkg-version.ts', 'export const VERSION = \\'' + packageJson.version + '\\';');\"", - "build": "npm run build:esm && npm run build:cjs && npm run build:browser && npm run build:webworker", - "build:esm": "tsc --project ./tsconfig.json --module es2015 --outDir ./dist/esm -d", - "build:cjs": "tsc --project ./tsconfig.json --module commonjs --outDir ./dist/cjs", - "build:browser": "webpack-cli", - "build:webworker": "webpack-cli --env platform=webworker", - "get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\"" - }, - "keywords": [ - "signalr", - "aspnetcore" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/dotnet/aspnetcore.git" - }, - "author": "Microsoft", - "license": "MIT", - "bugs": { - "url": "https://github.com/dotnet/aspnetcore/issues" - }, - "homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/SignalR#readme", - "files": [ - "dist/**/*", - "src/**/*" - ], - "dependencies": { - "abort-controller": "^3.0.0", - "eventsource": "^2.0.2", - "fetch-cookie": "^2.0.3", - "node-fetch": "^2.6.7", - "ws": "^7.5.10" - }, - "overrides": { - "ansi-regex": "5.0.1", - "tough-cookie": ">=4.1.3" - } -} From f76329477dadeb3e814339479027c2fe2ff8d2d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 09:54:28 +0000 Subject: [PATCH 06/14] Fix AuthenticationStateSerializer to use declarative persistent component state Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../src/AuthenticationStateSerializer.cs | 33 +++++-------------- ...ssemblyRazorComponentsBuilderExtensions.cs | 1 + ...DeserializedAuthenticationStateProvider.cs | 3 -- ...thenticationServiceCollectionExtensions.cs | 1 + 4 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs index ca43b4f2741b..0dc79871e032 100644 --- a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs +++ b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs @@ -2,55 +2,40 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Components.Authorization; -using Microsoft.AspNetCore.Components.Web; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Components.WebAssembly.Server; -internal sealed class AuthenticationStateSerializer : IHostEnvironmentAuthenticationStateProvider, IDisposable +internal sealed class AuthenticationStateSerializer : IHostEnvironmentAuthenticationStateProvider { // Do not change. This must match all versions of the server-side DeserializedAuthenticationStateProvider.PersistenceKey. internal const string PersistenceKey = $"__internal__{nameof(AuthenticationState)}"; - private readonly PersistentComponentState _state; private readonly Func> _serializeCallback; - private readonly PersistingComponentStateSubscription _subscription; private Task? _authenticationStateTask; private AuthenticationStateData? _authenticationStateData; - [PersistentComponentStateStore] + [SupplyParameterFromPersistentComponentState] public AuthenticationStateData? AuthStateData { get => _authenticationStateData; set => _authenticationStateData = value; } - public AuthenticationStateSerializer(PersistentComponentState persistentComponentState, IOptions options) + public AuthenticationStateSerializer(IOptions options) { - _state = persistentComponentState; _serializeCallback = options.Value.SerializationCallback; - _subscription = persistentComponentState.RegisterOnPersisting(OnPersistingAsync, RenderMode.InteractiveWebAssembly); - } - - private async Task OnPersistingAsync() - { - if (_authenticationStateTask is null) - { - throw new InvalidOperationException($"{nameof(SetAuthenticationState)} must be called before the {nameof(PersistentComponentState)}.{nameof(PersistentComponentState.RegisterOnPersisting)} callback."); - } - - AuthStateData = await _serializeCallback(await _authenticationStateTask); } /// - public void SetAuthenticationState(Task authenticationStateTask) + public async void SetAuthenticationState(Task authenticationStateTask) { _authenticationStateTask = authenticationStateTask ?? throw new ArgumentNullException(nameof(authenticationStateTask)); - } - - public void Dispose() - { - _subscription.Dispose(); + + if (_authenticationStateTask is not null) + { + AuthStateData = await _serializeCallback(await _authenticationStateTask); + } } } diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs index dbfa966115ce..5bfabf460651 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Endpoints.Infrastructure; using Microsoft.AspNetCore.Components.Infrastructure; +using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Server; using Microsoft.AspNetCore.Components.WebAssembly.Services; using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs index bab39175030b..07ba89c00719 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Security.Claims; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.Extensions.Options; -using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication; @@ -19,7 +17,6 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt [SupplyParameterFromPersistentComponentState] private AuthenticationStateData? AuthStateData { get; set; } - public DeserializedAuthenticationStateProvider(IOptions options) { _authenticationStateTask = AuthStateData is not null diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs index 75e71ac8e74e..d659246417c1 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Infrastructure; +using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Authentication; using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal; using Microsoft.Extensions.DependencyInjection.Extensions; From 56573f197c12aaa2f085561ab7eff4b076c259d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 10:19:34 +0000 Subject: [PATCH 07/14] Update AuthenticationState registration to use AuthenticationStateProvider interface Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs | 2 +- .../src/WebAssemblyAuthenticationServiceCollectionExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs index 5bfabf460651..af11a6a13785 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs @@ -43,7 +43,7 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I public static IRazorComponentsBuilder AddAuthenticationStateSerialization(this IRazorComponentsBuilder builder, Action? configure = null) { builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped()); - RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveWebAssembly); + RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveWebAssembly); if (configure is not null) { builder.Services.Configure(configure); diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs index d659246417c1..cd73c15cf11c 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs @@ -32,7 +32,7 @@ public static IServiceCollection AddAuthenticationStateDeserialization(this ISer { services.AddOptions(); services.TryAddScoped(); - RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(services, RenderMode.InteractiveWebAssembly); + RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(services, RenderMode.InteractiveWebAssembly); if (configure != null) { services.Configure(configure); From df67bb9d50abf0dfbd94221d952e284cbdae88e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 11:38:25 +0000 Subject: [PATCH 08/14] Updated AuthenticationStateProvider registration to use correct DI pattern Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs index af11a6a13785..fd605331b752 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs @@ -43,7 +43,8 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I public static IRazorComponentsBuilder AddAuthenticationStateSerialization(this IRazorComponentsBuilder builder, Action? configure = null) { builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped()); - RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveWebAssembly); + builder.Services.TryAddScoped(sp => (AuthenticationStateProvider)sp.GetRequiredService()); + RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveAuto); if (configure is not null) { builder.Services.Configure(configure); From 5558fc130deccdd5d978cadccb37ecf7b2a342dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 11:50:13 +0000 Subject: [PATCH 09/14] Update AuthenticationStateSerializer to inherit from AuthenticationStateProvider Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Server/src/AuthenticationStateSerializer.cs | 14 +++++++------- .../WebAssemblyRazorComponentsBuilderExtensions.cs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs index 0dc79871e032..8abb4da7219f 100644 --- a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs +++ b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Server; -internal sealed class AuthenticationStateSerializer : IHostEnvironmentAuthenticationStateProvider +internal sealed class AuthenticationStateSerializer : AuthenticationStateProvider, IHostEnvironmentAuthenticationStateProvider { // Do not change. This must match all versions of the server-side DeserializedAuthenticationStateProvider.PersistenceKey. internal const string PersistenceKey = $"__internal__{nameof(AuthenticationState)}"; @@ -14,14 +14,9 @@ internal sealed class AuthenticationStateSerializer : IHostEnvironmentAuthentica private readonly Func> _serializeCallback; private Task? _authenticationStateTask; - private AuthenticationStateData? _authenticationStateData; [SupplyParameterFromPersistentComponentState] - public AuthenticationStateData? AuthStateData - { - get => _authenticationStateData; - set => _authenticationStateData = value; - } + private AuthenticationStateData? AuthStateData { get; set; } public AuthenticationStateSerializer(IOptions options) { @@ -36,6 +31,11 @@ public async void SetAuthenticationState(Task authenticatio if (_authenticationStateTask is not null) { AuthStateData = await _serializeCallback(await _authenticationStateTask); + NotifyAuthenticationStateChanged(_authenticationStateTask); } } + + /// + public override Task GetAuthenticationStateAsync() => + _authenticationStateTask ?? Task.FromResult(new AuthenticationState(new System.Security.Claims.ClaimsPrincipal())); } diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs index fd605331b752..2a0e08389c4c 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs @@ -43,7 +43,7 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I public static IRazorComponentsBuilder AddAuthenticationStateSerialization(this IRazorComponentsBuilder builder, Action? configure = null) { builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped()); - builder.Services.TryAddScoped(sp => (AuthenticationStateProvider)sp.GetRequiredService()); + builder.Services.TryAddScoped(sp => (AuthenticationStateSerializer)sp.GetRequiredService()); RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveAuto); if (configure is not null) { From 8edba16b02cb37bea861dac61185375844f2778c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 12:05:56 +0000 Subject: [PATCH 10/14] Fix AuthenticationStateSerializer property visibility and remove redundant null check Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Server/src/AuthenticationStateSerializer.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs index 8abb4da7219f..78ab013ecbfa 100644 --- a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs +++ b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs @@ -16,7 +16,7 @@ internal sealed class AuthenticationStateSerializer : AuthenticationStateProvide private Task? _authenticationStateTask; [SupplyParameterFromPersistentComponentState] - private AuthenticationStateData? AuthStateData { get; set; } + public AuthenticationStateData? AuthStateData { get; set; } public AuthenticationStateSerializer(IOptions options) { @@ -28,11 +28,8 @@ public async void SetAuthenticationState(Task authenticatio { _authenticationStateTask = authenticationStateTask ?? throw new ArgumentNullException(nameof(authenticationStateTask)); - if (_authenticationStateTask is not null) - { - AuthStateData = await _serializeCallback(await _authenticationStateTask); - NotifyAuthenticationStateChanged(_authenticationStateTask); - } + AuthStateData = await _serializeCallback(await _authenticationStateTask); + NotifyAuthenticationStateChanged(_authenticationStateTask); } /// From f35c3dacdabbc9e610e54d27aa40d9b2cc4c6c3f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 14:05:55 +0000 Subject: [PATCH 11/14] Make AuthStateData property public in DeserializedAuthenticationStateProvider Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../src/Services/DeserializedAuthenticationStateProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs index 07ba89c00719..adb2234516b7 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs @@ -15,7 +15,7 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt private readonly Task _authenticationStateTask; [SupplyParameterFromPersistentComponentState] - private AuthenticationStateData? AuthStateData { get; set; } + public AuthenticationStateData? AuthStateData { get; set; } public DeserializedAuthenticationStateProvider(IOptions options) { From cb3a8fc00b89859ed685c072e99b1674420a500a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 May 2025 09:29:35 +0000 Subject: [PATCH 12/14] Change DeserializedAuthenticationStateProvider registration to singleton in WASM Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../src/WebAssemblyAuthenticationServiceCollectionExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs index cd73c15cf11c..6d3c95e34145 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs @@ -31,7 +31,7 @@ public static class WebAssemblyAuthenticationServiceCollectionExtensions public static IServiceCollection AddAuthenticationStateDeserialization(this IServiceCollection services, Action? configure = null) { services.AddOptions(); - services.TryAddScoped(); + services.TryAddSingleton(); RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(services, RenderMode.InteractiveWebAssembly); if (configure != null) { From 9f1fb88e09537a3c67d876ae1356492a340947fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 May 2025 11:26:07 +0000 Subject: [PATCH 13/14] Add AuthenticationStateProvider registration to TryAddEnumerable Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs index 2a0e08389c4c..d93981f4f531 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs @@ -43,6 +43,7 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I public static IRazorComponentsBuilder AddAuthenticationStateSerialization(this IRazorComponentsBuilder builder, Action? configure = null) { builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped()); + builder.Services.TryAddEnumerable(ServiceDescriptor.Scoped()); builder.Services.TryAddScoped(sp => (AuthenticationStateSerializer)sp.GetRequiredService()); RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(builder.Services, RenderMode.InteractiveAuto); if (configure is not null) From b5092e8e4011634ffa063262ef88dc5428f803ec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 May 2025 12:14:19 +0000 Subject: [PATCH 14/14] Rename AuthStateData to CurrentAuthenticationState to match expected naming pattern Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../WebAssembly/Server/src/AuthenticationStateSerializer.cs | 4 ++-- .../src/Services/DeserializedAuthenticationStateProvider.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs index 78ab013ecbfa..7793601885dc 100644 --- a/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs +++ b/src/Components/WebAssembly/Server/src/AuthenticationStateSerializer.cs @@ -16,7 +16,7 @@ internal sealed class AuthenticationStateSerializer : AuthenticationStateProvide private Task? _authenticationStateTask; [SupplyParameterFromPersistentComponentState] - public AuthenticationStateData? AuthStateData { get; set; } + public AuthenticationStateData? CurrentAuthenticationState { get; set; } public AuthenticationStateSerializer(IOptions options) { @@ -28,7 +28,7 @@ public async void SetAuthenticationState(Task authenticatio { _authenticationStateTask = authenticationStateTask ?? throw new ArgumentNullException(nameof(authenticationStateTask)); - AuthStateData = await _serializeCallback(await _authenticationStateTask); + CurrentAuthenticationState = await _serializeCallback(await _authenticationStateTask); NotifyAuthenticationStateChanged(_authenticationStateTask); } diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs index adb2234516b7..da37acc5a4cc 100644 --- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs +++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Services/DeserializedAuthenticationStateProvider.cs @@ -15,12 +15,12 @@ internal sealed class DeserializedAuthenticationStateProvider : AuthenticationSt private readonly Task _authenticationStateTask; [SupplyParameterFromPersistentComponentState] - public AuthenticationStateData? AuthStateData { get; set; } + public AuthenticationStateData? CurrentAuthenticationState { get; set; } public DeserializedAuthenticationStateProvider(IOptions options) { - _authenticationStateTask = AuthStateData is not null - ? options.Value.DeserializationCallback(AuthStateData) + _authenticationStateTask = CurrentAuthenticationState is not null + ? options.Value.DeserializationCallback(CurrentAuthenticationState) : _defaultUnauthenticatedTask; }