diff --git a/src/Api/KeyManagement/Controllers/UsersController.cs b/src/Api/KeyManagement/Controllers/UsersController.cs index 8532521d69..d62758407e 100644 --- a/src/Api/KeyManagement/Controllers/UsersController.cs +++ b/src/Api/KeyManagement/Controllers/UsersController.cs @@ -23,10 +23,9 @@ public class UsersController( } [HttpGet("{id}/keys")] - public async Task GetAccountKeysAsync(string id) + public async Task GetAccountKeysAsync([FromRoute]Guid id) { - var guidId = new Guid(id); - var user = await _userRepository.GetByIdAsync(guidId) ?? throw new NotFoundException(); + var user = await _userRepository.GetByIdAsync(id) ?? throw new NotFoundException(); var accountKeys = await _userAccountKeysQuery.Run(user) ?? throw new NotFoundException("User account keys not found."); return new PublicKeysResponseModel(accountKeys); } diff --git a/src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs b/src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs index c9b8e42144..667231c459 100644 --- a/src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs +++ b/src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs @@ -7,7 +7,7 @@ namespace Bit.Api.KeyManagement.Models.Response; #nullable enable /// -/// This response model is used to return the the asymmetric encryption keys, +/// This response model is used to return the asymmetric encryption keys, /// and signature keys of an entity. This includes the private keys of the key pairs, /// (private key, signing key), and the public keys of the key pairs (unsigned public key, /// signed public key, verification key). diff --git a/src/Core/KeyManagement/Entities/UserSignatureKeyPair.cs b/src/Core/KeyManagement/Entities/UserSignatureKeyPair.cs index f81811eb13..332fca3608 100644 --- a/src/Core/KeyManagement/Entities/UserSignatureKeyPair.cs +++ b/src/Core/KeyManagement/Entities/UserSignatureKeyPair.cs @@ -1,5 +1,4 @@ -using System.ComponentModel.DataAnnotations; -using Bit.Core.Entities; +using Bit.Core.Entities; using Bit.Core.KeyManagement.Enums; using Bit.Core.KeyManagement.Models.Data; using Bit.Core.Utilities; @@ -14,9 +13,7 @@ public class UserSignatureKeyPair : ITableObject, IRevisable public Guid UserId { get; set; } public SignatureAlgorithm SignatureAlgorithm { get; set; } - [MaxLength(500)] required public string VerifyingKey { get; set; } - [MaxLength(500)] required public string SigningKey { get; set; } public DateTime CreationDate { get; set; } = DateTime.UtcNow; diff --git a/src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs b/src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs index b502b9f749..0dfb7e6ac1 100644 --- a/src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs +++ b/src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs @@ -11,13 +11,13 @@ using Microsoft.Extensions.DependencyInjection; namespace Bit.Infrastructure.EntityFramework.KeyManagement.Repositories; -public class UserSignatureKeyPairRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) : Repository(serviceScopeFactory, mapper, context => context.UserSignatureKeyPair), IUserSignatureKeyPairRepository +public class UserSignatureKeyPairRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) : Repository(serviceScopeFactory, mapper, context => context.UserSignatureKeyPairs), IUserSignatureKeyPairRepository { public async Task GetByUserIdAsync(Guid userId) { await using var scope = ServiceScopeFactory.CreateAsyncScope(); var dbContext = GetDatabaseContext(scope); - var signingKeys = await dbContext.UserSignatureKeyPair.FindAsync(userId); + var signingKeys = await dbContext.UserSignatureKeyPairs.FindAsync(userId); if (signingKeys == null) { return null; @@ -42,7 +42,7 @@ public class UserSignatureKeyPairRepository(IServiceScopeFactory serviceScopeFac CreationDate = DateTime.UtcNow, RevisionDate = DateTime.UtcNow, }; - await dbContext.UserSignatureKeyPair.AddAsync(entity); + await dbContext.UserSignatureKeyPairs.AddAsync(entity); await dbContext.SaveChangesAsync(); }; } @@ -53,7 +53,7 @@ public class UserSignatureKeyPairRepository(IServiceScopeFactory serviceScopeFac { await using var scope = ServiceScopeFactory.CreateAsyncScope(); var dbContext = GetDatabaseContext(scope); - var entity = await dbContext.UserSignatureKeyPair.FirstOrDefaultAsync(x => x.UserId == grantorId); + var entity = await dbContext.UserSignatureKeyPairs.FirstOrDefaultAsync(x => x.UserId == grantorId); if (entity != null) { entity.SignatureAlgorithm = signingKeys.SignatureAlgorithm; diff --git a/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs b/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs index 3c2e8b2d50..a68a9767f1 100644 --- a/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs +++ b/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs @@ -71,7 +71,7 @@ public class DatabaseContext : DbContext public DbSet TaxRates { get; set; } public DbSet Transactions { get; set; } public DbSet Users { get; set; } - public DbSet UserSignatureKeyPair { get; set; } + public DbSet UserSignatureKeyPairs { get; set; } public DbSet AuthRequests { get; set; } public DbSet OrganizationDomains { get; set; } public DbSet WebAuthnCredentials { get; set; } diff --git a/util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql b/util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql index 5310aa1015..ca022f907b 100644 --- a/util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql +++ b/util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql @@ -1,14 +1,18 @@ -CREATE TABLE [dbo].[UserSignatureKeyPair] ( - [Id] UNIQUEIDENTIFIER NOT NULL, - [UserId] UNIQUEIDENTIFIER NOT NULL, - [SignatureKeyPairAlgorithm] TINYINT NOT NULL, - [SigningKey] VARCHAR(MAX) NOT NULL, - [VerifyingKey] VARCHAR(MAX) NOT NULL, - [CreationDate] DATETIME2 (7) NOT NULL, - [RevisionDate] DATETIME2 (7) NOT NULL, - CONSTRAINT [PK_UserSignatureKeyPair] PRIMARY KEY CLUSTERED ([Id] ASC), - CONSTRAINT [FK_UserSignatureKeyPair_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) -); +IF OBJECT_ID('[dbo].[UserSignatureKeyPair]') IS NULL +BEGIN + CREATE TABLE [dbo].[UserSignatureKeyPair] + ( + [Id] UNIQUEIDENTIFIER NOT NULL, + [UserId] UNIQUEIDENTIFIER NOT NULL, + [SignatureKeyPairAlgorithm] TINYINT NOT NULL, + [SigningKey] VARCHAR(MAX) NOT NULL, + [VerifyingKey] VARCHAR(MAX) NOT NULL, + [CreationDate] DATETIME2 (7) NOT NULL, + [RevisionDate] DATETIME2 (7) NOT NULL, + CONSTRAINT [PK_UserSignatureKeyPair] PRIMARY KEY CLUSTERED ([Id] ASC), + CONSTRAINT [FK_UserSignatureKeyPair_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) + ); +END GO IF NOT EXISTS(SELECT name @@ -29,7 +33,7 @@ FROM [dbo].[UserSignatureKeyPair] GO -CREATE PROCEDURE [dbo].[UserSignatureKeyPair_ReadByUserId] +CREATE OR ALTER PROCEDURE [dbo].[UserSignatureKeyPair_ReadByUserId] @UserId UNIQUEIDENTIFIER AS BEGIN @@ -39,7 +43,7 @@ BEGIN END GO -CREATE PROCEDURE [dbo].[UserSignatureKeyPair_UpdateForRotation] +CREATE OR ALTER PROCEDURE [dbo].[UserSignatureKeyPair_UpdateForRotation] @UserId UNIQUEIDENTIFIER, @SignatureKeyPairAlgorithm TINYINT, @SigningKey VARCHAR(MAX), @@ -56,7 +60,7 @@ BEGIN END GO -CREATE PROCEDURE [dbo].[UserSignatureKeyPair_SetForRotation] +CREATE OR ALTER PROCEDURE [dbo].[UserSignatureKeyPair_SetForRotation] @Id UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @SignatureKeyPairAlgorithm TINYINT, diff --git a/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs b/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs index 238ca3ab86..d1a0c8d98f 100644 --- a/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs +++ b/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs @@ -1752,16 +1752,14 @@ namespace Bit.MySqlMigrations.Migrations b.Property("SigningKey") .IsRequired() - .HasMaxLength(500) - .HasColumnType("varchar(500)"); + .HasColumnType("longtext"); b.Property("UserId") .HasColumnType("char(36)"); b.Property("VerifyingKey") .IsRequired() - .HasMaxLength(500) - .HasColumnType("varchar(500)"); + .HasColumnType("longtext"); b.HasKey("Id"); diff --git a/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs b/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs index 69cb237766..c0850cea68 100644 --- a/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs +++ b/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs @@ -1758,16 +1758,14 @@ namespace Bit.PostgresMigrations.Migrations b.Property("SigningKey") .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)"); + .HasColumnType("text"); b.Property("UserId") .HasColumnType("uuid"); b.Property("VerifyingKey") .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)"); + .HasColumnType("text"); b.HasKey("Id"); diff --git a/util/SqliteMigrations/Migrations/DatabaseContextModelSnapshot.cs b/util/SqliteMigrations/Migrations/DatabaseContextModelSnapshot.cs index ae3d7a0d47..dbfb180002 100644 --- a/util/SqliteMigrations/Migrations/DatabaseContextModelSnapshot.cs +++ b/util/SqliteMigrations/Migrations/DatabaseContextModelSnapshot.cs @@ -1741,7 +1741,6 @@ namespace Bit.SqliteMigrations.Migrations b.Property("SigningKey") .IsRequired() - .HasMaxLength(500) .HasColumnType("TEXT"); b.Property("UserId") @@ -1749,7 +1748,6 @@ namespace Bit.SqliteMigrations.Migrations b.Property("VerifyingKey") .IsRequired() - .HasMaxLength(500) .HasColumnType("TEXT"); b.HasKey("Id");