1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-06 11:43:51 +00:00

Add annotation validation

This commit is contained in:
Bernd Schoolmann
2025-07-22 14:25:25 +02:00
parent 481910b823
commit e31f4844c8
3 changed files with 47 additions and 26 deletions

View File

@@ -9,6 +9,7 @@ import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.i
import { Encrypted } from "@bitwarden/common/platform/interfaces/encrypted";
import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { required, validate } from "@bitwarden/common/platform/misc/validate";
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PureCrypto } from "@bitwarden/sdk-internal";
@@ -61,36 +62,22 @@ export class EncryptServiceImplementation implements EncryptService {
return PureCrypto.symmetric_decrypt_filedata(encBuffer.buffer, key.toEncoded());
}
@validate
async wrapDecapsulationKey(
decapsulationKeyPkcs8: Uint8Array,
wrappingKey: SymmetricCryptoKey,
@required decapsulationKeyPkcs8: Uint8Array,
@required wrappingKey: SymmetricCryptoKey,
): Promise<EncString> {
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()),
);
}
@validate
async wrapEncapsulationKey(
encapsulationKeySpki: Uint8Array,
wrappingKey: SymmetricCryptoKey,
@required encapsulationKeySpki: Uint8Array,
@required wrappingKey: SymmetricCryptoKey,
): Promise<EncString> {
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()),

View File

@@ -115,15 +115,11 @@ describe("EncryptService", () => {
});
it("fails if encapsulation key is null", async () => {
const wrappingKey = new SymmetricCryptoKey(makeStaticByteArray(64));
await expect(encryptService.wrapEncapsulationKey(null, wrappingKey)).rejects.toThrow(
"No encapsulation key provided for wrapping.",
);
expect(() => encryptService.wrapEncapsulationKey(null, wrappingKey)).toThrow();
});
it("fails if wrapping key is null", async () => {
const encapsulationKey = makeStaticByteArray(64);
await expect(encryptService.wrapEncapsulationKey(encapsulationKey, null)).rejects.toThrow(
"No wrappingKey provided for wrapping.",
);
expect(() => encryptService.wrapEncapsulationKey(encapsulationKey, null)).toThrow();
});
});

View File

@@ -0,0 +1,38 @@
import "reflect-metadata";
const requiredMetadataKey = Symbol("required");
export function required(target: object, propertyKey: string | symbol, parameterIndex: number) {
const existingRequiredParameters: number[] =
Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || [];
existingRequiredParameters.push(parameterIndex);
Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey);
}
export function validate(
target: any,
propertyName: string,
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
descriptor: TypedPropertyDescriptor<Function>,
) {
const method = descriptor.value!;
descriptor.value = function (...args: any[]) {
const requiredParameters: number[] = Reflect.getOwnMetadata(
requiredMetadataKey,
target,
propertyName,
);
if (requiredParameters) {
for (const parameterIndex of requiredParameters) {
if (
parameterIndex >= args.length ||
args[parameterIndex] === undefined ||
args[parameterIndex] === null
) {
throw new Error("Missing required argument.");
}
}
}
return method.apply(this, args);
};
}