From 111e8590e1e00a7d4b37137f104e192192b8c1bf Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 28 Jul 2025 14:54:06 +0200 Subject: [PATCH] Add non-null annotation --- .../encrypt.service.implementation.ts | 59 +++++-------------- libs/common/src/key-management/util.ts | 13 ++++ 2 files changed, 29 insertions(+), 43 deletions(-) create mode 100644 libs/common/src/key-management/util.ts diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts index 3e36fd334ec..f29b1466424 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts @@ -14,6 +14,7 @@ import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/sym import { PureCrypto } from "@bitwarden/sdk-internal"; import { ServerConfig } from "../../../platform/abstractions/config/server-config"; +import { strictNonNullArgs } from "../../util"; import { EncryptService } from "../abstractions/encrypt.service"; export class EncryptServiceImplementation implements EncryptService { @@ -36,67 +37,59 @@ export class EncryptServiceImplementation implements EncryptService { return new EncString(PureCrypto.symmetric_encrypt_string(plainValue, key.toEncoded())); } + @strictNonNullArgs async encryptBytes(plainValue: Uint8Array, key: SymmetricCryptoKey): Promise { await SdkLoadService.Ready; return new EncString(PureCrypto.symmetric_encrypt_bytes(plainValue, key.toEncoded())); } + @strictNonNullArgs async encryptFileData(plainValue: Uint8Array, key: SymmetricCryptoKey): Promise { await SdkLoadService.Ready; return new EncArrayBuffer(PureCrypto.symmetric_encrypt_filedata(plainValue, key.toEncoded())); } + @strictNonNullArgs async decryptString(encString: EncString, key: SymmetricCryptoKey): Promise { await SdkLoadService.Ready; return PureCrypto.symmetric_decrypt_string(encString.encryptedString, key.toEncoded()); } + @strictNonNullArgs async decryptBytes(encString: EncString, key: SymmetricCryptoKey): Promise { await SdkLoadService.Ready; return PureCrypto.symmetric_decrypt_bytes(encString.encryptedString, key.toEncoded()); } + @strictNonNullArgs async decryptFileData(encBuffer: EncArrayBuffer, key: SymmetricCryptoKey): Promise { await SdkLoadService.Ready; return PureCrypto.symmetric_decrypt_filedata(encBuffer.buffer, key.toEncoded()); } + @strictNonNullArgs async wrapDecapsulationKey( decapsulationKeyPkcs8: Uint8Array, wrappingKey: SymmetricCryptoKey, ): Promise { - if (decapsulationKeyPkcs8 == null) { - throw new Error("No decapsulation key provided for wrapping."); - } - - if (wrappingKey == null) { - throw new Error("No wrappingKey provided for wrapping."); - } - await SdkLoadService.Ready; return new EncString( PureCrypto.wrap_decapsulation_key(decapsulationKeyPkcs8, wrappingKey.toEncoded()), ); } + @strictNonNullArgs async wrapEncapsulationKey( encapsulationKeySpki: Uint8Array, wrappingKey: SymmetricCryptoKey, ): Promise { - if (encapsulationKeySpki == null) { - throw new Error("No encapsulation key provided for wrapping."); - } - - if (wrappingKey == null) { - throw new Error("No wrappingKey provided for wrapping."); - } - await SdkLoadService.Ready; return new EncString( PureCrypto.wrap_encapsulation_key(encapsulationKeySpki, wrappingKey.toEncoded()), ); } + @strictNonNullArgs async wrapSymmetricKey( keyToBeWrapped: SymmetricCryptoKey, wrappingKey: SymmetricCryptoKey, @@ -115,23 +108,19 @@ export class EncryptServiceImplementation implements EncryptService { ); } + @strictNonNullArgs async unwrapDecapsulationKey( wrappedDecapsulationKey: EncString, wrappingKey: SymmetricCryptoKey, ): Promise { - if (wrappedDecapsulationKey == null) { - throw new Error("No wrappedDecapsulationKey provided for unwrapping."); - } - if (wrappingKey == null) { - throw new Error("No wrappingKey provided for unwrapping."); - } - await SdkLoadService.Ready; return PureCrypto.unwrap_decapsulation_key( wrappedDecapsulationKey.encryptedString, wrappingKey.toEncoded(), ); } + + @strictNonNullArgs async unwrapEncapsulationKey( wrappedEncapsulationKey: EncString, wrappingKey: SymmetricCryptoKey, @@ -149,17 +138,12 @@ export class EncryptServiceImplementation implements EncryptService { wrappingKey.toEncoded(), ); } + + @strictNonNullArgs async unwrapSymmetricKey( keyToBeUnwrapped: EncString, wrappingKey: SymmetricCryptoKey, ): Promise { - if (keyToBeUnwrapped == null) { - throw new Error("No keyToBeUnwrapped provided for unwrapping."); - } - if (wrappingKey == null) { - throw new Error("No wrappingKey provided for unwrapping."); - } - await SdkLoadService.Ready; return new SymmetricCryptoKey( PureCrypto.unwrap_symmetric_key(keyToBeUnwrapped.encryptedString, wrappingKey.toEncoded()), @@ -201,33 +185,22 @@ export class EncryptServiceImplementation implements EncryptService { return PureCrypto.symmetric_decrypt_array_buffer(buffer, key.toEncoded()); } + @strictNonNullArgs async encapsulateKeyUnsigned( sharedKey: SymmetricCryptoKey, encapsulationKey: Uint8Array, ): Promise { - if (sharedKey == null) { - throw new Error("No sharedKey provided for encapsulation"); - } - if (encapsulationKey == null) { - throw new Error("No encapsulationKey provided for encapsulation"); - } await SdkLoadService.Ready; return new EncString( PureCrypto.encapsulate_key_unsigned(sharedKey.toEncoded(), encapsulationKey), ); } + @strictNonNullArgs async decapsulateKeyUnsigned( encryptedSharedKey: EncString, decapsulationKey: Uint8Array, ): Promise { - if (encryptedSharedKey == null) { - throw new Error("No encryptedSharedKey provided for decapsulation"); - } - if (decapsulationKey == null) { - throw new Error("No decapsulationKey provided for decapsulation"); - } - const keyBytes = PureCrypto.decapsulate_key_unsigned( encryptedSharedKey.encryptedString, decapsulationKey, diff --git a/libs/common/src/key-management/util.ts b/libs/common/src/key-management/util.ts new file mode 100644 index 00000000000..c7cb5c4c564 --- /dev/null +++ b/libs/common/src/key-management/util.ts @@ -0,0 +1,13 @@ +/** + * Methods annotated with this decorator will throw if any of the arguments are null or undefined. + * This is useful when the class uses ts-strict, but the callers do not yet use ts-strict. + */ +export function strictNonNullArgs(target: any, key: string, descriptor: PropertyDescriptor) { + const originalMethod = descriptor.value; + descriptor.value = function (...args: any[]) { + if (args.some((arg) => arg === null || arg === undefined)) { + throw new Error(`Method ${key} cannot be called with null or undefined arguments.`); + } + return originalMethod.apply(this, args); + }; +}