mirror of
https://github.com/bitwarden/browser
synced 2026-02-06 11:43:51 +00:00
Add annotation validation
This commit is contained in:
@@ -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()),
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
38
libs/common/src/platform/misc/validate.ts
Normal file
38
libs/common/src/platform/misc/validate.ts
Normal 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);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user