SignInManager
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/Passkeys.razor b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/Passkeys.razor
index cd3893cd7f..121ef5ab49 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/Passkeys.razor
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/Passkeys.razor
@@ -1,6 +1,6 @@
@page "/Account/Manage/Passkeys"
-@using TemplateWithPasskey.Data
+@using BlazorWeb_CSharp.Data
@using Microsoft.AspNetCore.Identity
@using System.ComponentModel.DataAnnotations
@using System.Buffers.Text
@@ -60,16 +60,24 @@
{
No passkeys are registered.
}
-
+ @if (currentPasskeys is { Count: >= MaxPasskeyCount })
+ {
+ You have reached the maximum number of allowed passkeys. Please delete one before adding a new one.
+ }
+ else
+ {
+ Add a new passkey
+ }
+
+
@code {
+ private const int MaxPasskeyCount = 100;
+
private ApplicationUser? user;
private IList? currentPasskeys;
@@ -118,22 +126,21 @@
return;
}
- var options = await SignInManager.RetrievePasskeyCreationOptionsAsync();
- if (options is null)
+ if (currentPasskeys!.Count >= MaxPasskeyCount)
{
- RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not retrieve passkey creation options.", HttpContext);
+ RedirectManager.RedirectToCurrentPageWithStatus($"Error: You have reached the maximum number of allowed passkeys.", HttpContext);
return;
}
- var attestationResult = await SignInManager.PerformPasskeyAttestationAsync(Input.CredentialJson, options);
+ var attestationResult = await SignInManager.PerformPasskeyAttestationAsync(Input.CredentialJson);
if (!attestationResult.Succeeded)
{
RedirectManager.RedirectToCurrentPageWithStatus($"Error: Could not add the passkey: {attestationResult.Failure.Message}", HttpContext);
return;
}
- var setPasskeyResult = await UserManager.SetPasskeyAsync(user, attestationResult.Passkey);
- if (!setPasskeyResult.Succeeded)
+ var addPasskeyResult = await UserManager.AddOrUpdatePasskeyAsync(user, attestationResult.Passkey);
+ if (!addPasskeyResult.Succeeded)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be added to your account.", HttpContext);
return;
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor
index a77cc5e69e..17f3034226 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor
@@ -1,7 +1,7 @@
@page "/Account/Manage/PersonalData"
@using Microsoft.AspNetCore.Identity
-@using TemplateWithPasskey.Data
+@using BlazorWeb_CSharp.Data
@inject UserManager UserManager
@inject IdentityRedirectManager RedirectManager
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/RenamePasskey.razor b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/RenamePasskey.razor
index fef70ae37c..7a18252d5e 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/RenamePasskey.razor
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/RenamePasskey.razor
@@ -1,6 +1,6 @@
@page "/Account/Manage/RenamePasskey/{Id}"
-@using TemplateWithPasskey.Data
+@using BlazorWeb_CSharp.Data
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@using System.Buffers.Text
@@ -79,7 +79,7 @@
private async Task Rename()
{
passkey!.Name = Input.Name;
- var result = await UserManager.SetPasskeyAsync(user!, passkey);
+ var result = await UserManager.AddOrUpdatePasskeyAsync(user!, passkey);
if (!result.Succeeded)
{
RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The passkey could not be updated.", HttpContext);
@@ -92,6 +92,7 @@
private sealed class InputModel
{
[Required]
+ [StringLength(200, ErrorMessage = "Passkey names must be no longer than {1} characters.")]
public string Name { get; set; } = "";
}
}
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor
index db0c616c80..2cb62fe137 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor
@@ -2,7 +2,7 @@
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
-@using TemplateWithPasskey.Data
+@using BlazorWeb_CSharp.Data
@inject UserManager UserManager
@inject SignInManager SignInManager
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor
index 964879329a..b7740f85a9 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor
@@ -2,7 +2,7 @@
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Identity
-@using TemplateWithPasskey.Data
+@using BlazorWeb_CSharp.Data
@inject UserManager UserManager
@inject SignInManager SignInManager
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor
index e20206d9c7..78c2028632 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor
@@ -1,7 +1,20 @@
-@ChildContent
-
+@using Microsoft.AspNetCore.Antiforgery
+@inject IServiceProvider Services
+@ChildContent
+
+
@code {
+ private AntiforgeryTokenSet? tokens;
+
+ [CascadingParameter]
+ private HttpContext HttpContext { get; set; } = default!;
+
[Parameter]
[EditorRequired]
public PasskeyOperation Operation { get; set; }
@@ -18,4 +31,9 @@
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary? AdditionalAttributes { get; set; }
+
+ protected override void OnInitialized()
+ {
+ tokens = Services.GetService()?.GetTokens(HttpContext);
+ }
}
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor.js b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor.js
index 42d5d150aa..55a83bcc7b 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor.js
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Account/Shared/PasskeySubmit.razor.js
@@ -17,9 +17,10 @@ async function fetchWithErrorHandling(url, options = {}) {
return response;
}
-async function createCredential(signal) {
+async function createCredential(headers, signal) {
const optionsResponse = await fetchWithErrorHandling('/Account/PasskeyCreationOptions', {
method: 'POST',
+ headers,
signal,
});
const optionsJson = await optionsResponse.json();
@@ -27,9 +28,10 @@ async function createCredential(signal) {
return await navigator.credentials.create({ publicKey: options, signal });
}
-async function requestCredential(email, mediation, signal) {
+async function requestCredential(email, mediation, headers, signal) {
const optionsResponse = await fetchWithErrorHandling(`/Account/PasskeyRequestOptions?username=${email}`, {
method: 'POST',
+ headers,
signal,
});
const optionsJson = await optionsResponse.json();
@@ -46,6 +48,8 @@ customElements.define('passkey-submit', class extends HTMLElement {
operation: this.getAttribute('operation'),
name: this.getAttribute('name'),
emailName: this.getAttribute('email-name'),
+ requestTokenName: this.getAttribute('request-token-name'),
+ requestTokenValue: this.getAttribute('request-token-value'),
};
this.internals.form.addEventListener('submit', (event) => {
@@ -67,12 +71,16 @@ customElements.define('passkey-submit', class extends HTMLElement {
throw new Error('Some passkey features are missing. Please update your browser.');
}
+ const headers = {
+ [this.attrs.requestTokenName]: this.attrs.requestTokenValue,
+ };
+
if (this.attrs.operation === 'Create') {
- return await createCredential(signal);
+ return await createCredential(headers, signal);
} else if (this.attrs.operation === 'Request') {
const email = new FormData(this.internals.form).get(this.attrs.emailName);
const mediation = useConditionalMediation ? 'conditional' : undefined;
- return await requestCredential(email, mediation, signal);
+ return await requestCredential(email, mediation, headers, signal);
} else {
throw new Error(`Unknown passkey operation '${this.attrs.operation}'.`);
}
@@ -88,11 +96,14 @@ customElements.define('passkey-submit', class extends HTMLElement {
const credentialJson = JSON.stringify(credential);
formData.append(`${this.attrs.name}.CredentialJson`, credentialJson);
} catch (error) {
+ if (error.name === 'AbortError') {
+ // The user explicitly canceled the operation - return without error.
+ return;
+ }
console.error(error);
- if (useConditionalMediation || error.name === 'AbortError') {
- // We do not relay the error to the user if:
- // 1. We are attempting conditional mediation, meaning the user did not initiate the operation.
- // 2. The user explicitly canceled the operation.
+ if (useConditionalMediation) {
+ // An error occurred during conditional mediation, which is not user-initiated.
+ // We log the error in the console but do not relay it to the user.
return;
}
const errorMessage = error.name === 'NotAllowedError'
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.js b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.js
index f58438240a..e52a190bac 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.js
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.js
@@ -32,7 +32,7 @@ async function retry() {
if (!successful) {
// We have been able to reach the server, but the circuit is no longer available.
// We'll reload the page so the user can continue using the app as quickly as possible.
- const resumeSuccessful = await Blazor.resume();
+ const resumeSuccessful = await Blazor.resumeCircuit();
if (!resumeSuccessful) {
location.reload();
} else {
@@ -47,7 +47,7 @@ async function retry() {
async function resume() {
try {
- const successful = await Blazor.resume();
+ const successful = await Blazor.resumeCircuit();
if (!successful) {
location.reload();
}
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.Designer.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.Designer.cs
index ae1764e8d3..659ea417e7 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.Designer.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.Designer.cs
@@ -187,40 +187,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasMaxLength(1024)
.HasColumnType("BLOB");
- b.Property("AttestationObject")
- .IsRequired()
- .HasColumnType("BLOB");
-
- b.Property("ClientDataJson")
- .IsRequired()
- .HasColumnType("BLOB");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT");
-
- b.Property("IsBackedUp")
- .HasColumnType("INTEGER");
-
- b.Property("IsBackupEligible")
- .HasColumnType("INTEGER");
-
- b.Property("IsUserVerified")
- .HasColumnType("INTEGER");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("PublicKey")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("BLOB");
-
- b.Property("SignCount")
- .HasColumnType("INTEGER");
-
- b.PrimitiveCollection("Transports")
- .HasColumnType("TEXT");
-
b.Property("UserId")
.IsRequired()
.HasColumnType("TEXT");
@@ -302,6 +268,57 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
+
+ b.OwnsOne("Microsoft.AspNetCore.Identity.IdentityPasskeyData", "Data", b1 =>
+ {
+ b1.Property("IdentityUserPasskeyCredentialId")
+ .HasColumnType("BLOB");
+
+ b1.Property("AttestationObject")
+ .IsRequired()
+ .HasColumnType("BLOB");
+
+ b1.Property("ClientDataJson")
+ .IsRequired()
+ .HasColumnType("BLOB");
+
+ b1.Property("CreatedAt")
+ .HasColumnType("TEXT");
+
+ b1.Property("IsBackedUp")
+ .HasColumnType("INTEGER");
+
+ b1.Property("IsBackupEligible")
+ .HasColumnType("INTEGER");
+
+ b1.Property("IsUserVerified")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Name")
+ .HasColumnType("TEXT");
+
+ b1.Property("PublicKey")
+ .IsRequired()
+ .HasColumnType("BLOB");
+
+ b1.Property("SignCount")
+ .HasColumnType("INTEGER");
+
+ b1.PrimitiveCollection("Transports")
+ .HasColumnType("TEXT");
+
+ b1.HasKey("IdentityUserPasskeyCredentialId");
+
+ b1.ToTable("AspNetUserPasskeys");
+
+ b1.ToJson("Data");
+
+ b1.WithOwner()
+ .HasForeignKey("IdentityUserPasskeyCredentialId");
+ });
+
+ b.Navigation("Data")
+ .IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.cs
index 92e0a0ea2c..b8e73dede8 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/00000000000000_CreateIdentitySchema.cs
@@ -118,16 +118,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
{
CredentialId = table.Column(type: "BLOB", maxLength: 1024, nullable: false),
UserId = table.Column(type: "TEXT", nullable: false),
- PublicKey = table.Column(type: "BLOB", maxLength: 1024, nullable: false),
- Name = table.Column(type: "TEXT", nullable: true),
- CreatedAt = table.Column(type: "TEXT", nullable: false),
- SignCount = table.Column(type: "INTEGER", nullable: false),
- Transports = table.Column(type: "TEXT", nullable: true),
- IsUserVerified = table.Column(type: "INTEGER", nullable: false),
- IsBackupEligible = table.Column(type: "INTEGER", nullable: false),
- IsBackedUp = table.Column(type: "INTEGER", nullable: false),
- AttestationObject = table.Column(type: "BLOB", nullable: false),
- ClientDataJson = table.Column(type: "BLOB", nullable: false)
+ Data = table.Column(type: "TEXT", nullable: false)
},
constraints: table =>
{
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/ApplicationDbContextModelSnapshot.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/ApplicationDbContextModelSnapshot.cs
index f6bdeaf144..005717115a 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/ApplicationDbContextModelSnapshot.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlLite/ApplicationDbContextModelSnapshot.cs
@@ -184,40 +184,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasMaxLength(1024)
.HasColumnType("BLOB");
- b.Property("AttestationObject")
- .IsRequired()
- .HasColumnType("BLOB");
-
- b.Property("ClientDataJson")
- .IsRequired()
- .HasColumnType("BLOB");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT");
-
- b.Property("IsBackedUp")
- .HasColumnType("INTEGER");
-
- b.Property("IsBackupEligible")
- .HasColumnType("INTEGER");
-
- b.Property("IsUserVerified")
- .HasColumnType("INTEGER");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("PublicKey")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("BLOB");
-
- b.Property("SignCount")
- .HasColumnType("INTEGER");
-
- b.PrimitiveCollection("Transports")
- .HasColumnType("TEXT");
-
b.Property("UserId")
.IsRequired()
.HasColumnType("TEXT");
@@ -299,6 +265,57 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
+
+ b.OwnsOne("Microsoft.AspNetCore.Identity.IdentityPasskeyData", "Data", b1 =>
+ {
+ b1.Property("IdentityUserPasskeyCredentialId")
+ .HasColumnType("BLOB");
+
+ b1.Property("AttestationObject")
+ .IsRequired()
+ .HasColumnType("BLOB");
+
+ b1.Property("ClientDataJson")
+ .IsRequired()
+ .HasColumnType("BLOB");
+
+ b1.Property("CreatedAt")
+ .HasColumnType("TEXT");
+
+ b1.Property("IsBackedUp")
+ .HasColumnType("INTEGER");
+
+ b1.Property("IsBackupEligible")
+ .HasColumnType("INTEGER");
+
+ b1.Property("IsUserVerified")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Name")
+ .HasColumnType("TEXT");
+
+ b1.Property("PublicKey")
+ .IsRequired()
+ .HasColumnType("BLOB");
+
+ b1.Property("SignCount")
+ .HasColumnType("INTEGER");
+
+ b1.PrimitiveCollection("Transports")
+ .HasColumnType("TEXT");
+
+ b1.HasKey("IdentityUserPasskeyCredentialId");
+
+ b1.ToTable("AspNetUserPasskeys");
+
+ b1.ToJson("Data");
+
+ b1.WithOwner()
+ .HasForeignKey("IdentityUserPasskeyCredentialId");
+ });
+
+ b.Navigation("Data")
+ .IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.Designer.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.Designer.cs
index c92d84f26d..19e1603ce9 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.Designer.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.Designer.cs
@@ -198,40 +198,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasMaxLength(1024)
.HasColumnType("varbinary(1024)");
- b.Property("AttestationObject")
- .IsRequired()
- .HasColumnType("varbinary(max)");
-
- b.Property("ClientDataJson")
- .IsRequired()
- .HasColumnType("varbinary(max)");
-
- b.Property("CreatedAt")
- .HasColumnType("datetimeoffset");
-
- b.Property("IsBackedUp")
- .HasColumnType("bit");
-
- b.Property("IsBackupEligible")
- .HasColumnType("bit");
-
- b.Property("IsUserVerified")
- .HasColumnType("bit");
-
- b.Property("Name")
- .HasColumnType("nvarchar(max)");
-
- b.Property("PublicKey")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("varbinary(1024)");
-
- b.Property("SignCount")
- .HasColumnType("bigint");
-
- b.PrimitiveCollection("Transports")
- .HasColumnType("nvarchar(max)");
-
b.Property("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
@@ -313,6 +279,57 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
+
+ b.OwnsOne("Microsoft.AspNetCore.Identity.IdentityPasskeyData", "Data", b1 =>
+ {
+ b1.Property("IdentityUserPasskeyCredentialId")
+ .HasColumnType("varbinary(1024)");
+
+ b1.Property("AttestationObject")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b1.Property("ClientDataJson")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b1.Property("CreatedAt")
+ .HasColumnType("datetimeoffset");
+
+ b1.Property("IsBackedUp")
+ .HasColumnType("bit");
+
+ b1.Property("IsBackupEligible")
+ .HasColumnType("bit");
+
+ b1.Property("IsUserVerified")
+ .HasColumnType("bit");
+
+ b1.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b1.Property("PublicKey")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b1.Property("SignCount")
+ .HasColumnType("bigint");
+
+ b1.PrimitiveCollection("Transports")
+ .HasColumnType("nvarchar(max)");
+
+ b1.HasKey("IdentityUserPasskeyCredentialId");
+
+ b1.ToTable("AspNetUserPasskeys");
+
+ b1.ToJson("Data");
+
+ b1.WithOwner()
+ .HasForeignKey("IdentityUserPasskeyCredentialId");
+ });
+
+ b.Navigation("Data")
+ .IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.cs
index 8d26035044..aa1117d1b0 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/00000000000000_CreateIdentitySchema.cs
@@ -118,16 +118,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
{
CredentialId = table.Column(type: "varbinary(1024)", maxLength: 1024, nullable: false),
UserId = table.Column(type: "nvarchar(450)", nullable: false),
- PublicKey = table.Column(type: "varbinary(1024)", maxLength: 1024, nullable: false),
- Name = table.Column(type: "nvarchar(max)", nullable: true),
- CreatedAt = table.Column(type: "datetimeoffset", nullable: false),
- SignCount = table.Column(type: "bigint", nullable: false),
- Transports = table.Column(type: "nvarchar(max)", nullable: true),
- IsUserVerified = table.Column(type: "bit", nullable: false),
- IsBackupEligible = table.Column(type: "bit", nullable: false),
- IsBackedUp = table.Column(type: "bit", nullable: false),
- AttestationObject = table.Column(type: "varbinary(max)", nullable: false),
- ClientDataJson = table.Column(type: "varbinary(max)", nullable: false)
+ Data = table.Column(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
@@ -241,6 +232,9 @@ protected override void Down(MigrationBuilder migrationBuilder)
migrationBuilder.DropTable(
name: "AspNetUserLogins");
+ migrationBuilder.DropTable(
+ name: "AspNetUserPasskeys");
+
migrationBuilder.DropTable(
name: "AspNetUserRoles");
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/ApplicationDbContextModelSnapshot.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/ApplicationDbContextModelSnapshot.cs
index 3f5e8fe8be..6e9366f22d 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/ApplicationDbContextModelSnapshot.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Data/SqlServer/ApplicationDbContextModelSnapshot.cs
@@ -195,40 +195,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasMaxLength(1024)
.HasColumnType("varbinary(1024)");
- b.Property("AttestationObject")
- .IsRequired()
- .HasColumnType("varbinary(max)");
-
- b.Property("ClientDataJson")
- .IsRequired()
- .HasColumnType("varbinary(max)");
-
- b.Property("CreatedAt")
- .HasColumnType("datetimeoffset");
-
- b.Property("IsBackedUp")
- .HasColumnType("bit");
-
- b.Property("IsBackupEligible")
- .HasColumnType("bit");
-
- b.Property("IsUserVerified")
- .HasColumnType("bit");
-
- b.Property("Name")
- .HasColumnType("nvarchar(max)");
-
- b.Property("PublicKey")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("varbinary(1024)");
-
- b.Property("SignCount")
- .HasColumnType("bigint");
-
- b.PrimitiveCollection("Transports")
- .HasColumnType("nvarchar(max)");
-
b.Property("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
@@ -310,6 +276,57 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
+
+ b.OwnsOne("Microsoft.AspNetCore.Identity.IdentityPasskeyData", "Data", b1 =>
+ {
+ b1.Property("IdentityUserPasskeyCredentialId")
+ .HasColumnType("varbinary(1024)");
+
+ b1.Property("AttestationObject")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b1.Property("ClientDataJson")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b1.Property("CreatedAt")
+ .HasColumnType("datetimeoffset");
+
+ b1.Property("IsBackedUp")
+ .HasColumnType("bit");
+
+ b1.Property("IsBackupEligible")
+ .HasColumnType("bit");
+
+ b1.Property("IsUserVerified")
+ .HasColumnType("bit");
+
+ b1.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b1.Property("PublicKey")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b1.Property("SignCount")
+ .HasColumnType("bigint");
+
+ b1.PrimitiveCollection("Transports")
+ .HasColumnType("nvarchar(max)");
+
+ b1.HasKey("IdentityUserPasskeyCredentialId");
+
+ b1.ToTable("AspNetUserPasskeys");
+
+ b1.ToJson("Data");
+
+ b1.WithOwner()
+ .HasForeignKey("IdentityUserPasskeyCredentialId");
+ });
+
+ b.Navigation("Data")
+ .IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.Main.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.Main.cs
index 597fdbc05e..115ae78ce7 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.Main.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.Main.cs
@@ -109,8 +109,7 @@ public static void Main(string[] args)
#endif
}
- app.UseStatusCodePagesWithReExecute("/not-found", createScopeForErrors: true);
-
+ app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
#if (HasHttpsProfile)
app.UseHttpsRedirection();
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.cs b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.cs
index 41451382dc..4460cc6737 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.cs
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Program.cs
@@ -102,8 +102,7 @@
app.UseHsts();
#endif
}
-app.UseStatusCodePagesWithReExecute("/not-found", createScopeForErrors: true);
-
+app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
#if (HasHttpsProfile)
app.UseHttpsRedirection();
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Properties/launchSettings.json b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Properties/launchSettings.json
index 0d554caaa1..26a3dada5e 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Properties/launchSettings.json
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/Properties/launchSettings.json
@@ -6,14 +6,18 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
- //#if (UseWebAssembly)
+ //#if (UseWebAssembly)
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
- //#endif
+ //#endif
+ //#if (LocalhostTld)
+ "applicationUrl": "http://blazorweb_csharp.dev.localhost:5500",
+ //#else
"applicationUrl": "http://localhost:5500",
+ //#endif
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
- //#if (HasHttpsProfile)
+ //#if (HasHttpsProfile)
},
//#else
}
@@ -27,7 +31,11 @@
//#if (UseWebAssembly)
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
//#endif
+ //#if (LocalhostTld)
+ "applicationUrl": "https://blazorweb_csharp.dev.localhost:5501;http://blazorweb_csharp.dev.localhost:5500",
+ //#else
"applicationUrl": "https://localhost:5501;http://localhost:5500",
+ //#endif
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
diff --git a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/appsettings.json b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/appsettings.json
index 3a18c82e2d..2a8ba926d3 100644
--- a/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/appsettings.json
+++ b/src/Templates/templates/blazorweb-csharp-10/BlazorWeb-CSharp/appsettings.json
@@ -4,7 +4,7 @@
//#if (UseLocalDB)
// "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-BlazorWeb_CSharp-53bc9b9d-9d6a-45d4-8429-2a2761773502;Trusted_Connection=True;MultipleActiveResultSets=true"
//#else
-// "DefaultConnection": "DataSource=Data\\app.db;Cache=Shared"
+// "DefaultConnection": "DataSource=Data/app.db;Cache=Shared"
//#endif
// },
////#endif
diff --git a/tests/Core/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj b/tests/Core/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj
index d15e4e1fdc..c77108ea05 100644
--- a/tests/Core/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj
+++ b/tests/Core/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
enable
enable
latest
diff --git a/tests/Core/_StartCodeCoverage.cmd b/tests/Core/_StartCodeCoverage.cmd
index c43f2f62be..c5f47dc9e2 100644
--- a/tests/Core/_StartCodeCoverage.cmd
+++ b/tests/Core/_StartCodeCoverage.cmd
@@ -19,5 +19,5 @@ echo on
cls
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura
-reportgenerator "-reports:coverage.net9.0.cobertura.xml" "-targetdir:C:\Temp\FluentUI\Coverage" -reporttypes:HtmlInline_AzurePipelines -classfilters:"-Microsoft.FluentUI.AspNetCore.Components.DesignTokens.*"
+reportgenerator "-reports:coverage.net10.0.cobertura.xml" "-targetdir:C:\Temp\FluentUI\Coverage" -reporttypes:HtmlInline_AzurePipelines -classfilters:"-Microsoft.FluentUI.AspNetCore.Components.DesignTokens.*"
start "" "C:\Temp\FluentUI\Coverage\index.htm"