diff --git a/libs/auth/src/common/services/auth-request/auth-request.service.ts b/libs/auth/src/common/services/auth-request/auth-request.service.ts index 89aad0cdbd7..ba4b9eaf174 100644 --- a/libs/auth/src/common/services/auth-request/auth-request.service.ts +++ b/libs/auth/src/common/services/auth-request/auth-request.service.ts @@ -213,9 +213,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction { ); const masterKey = new SymmetricCryptoKey(decryptedMasterKeyArrayBuffer) as MasterKey; - const masterKeyHash = Utils.fromBufferToUtf8( - decryptedMasterKeyHashArrayBuffer.buffer as ArrayBuffer, - ); + const masterKeyHash = Utils.fromBufferToUtf8(decryptedMasterKeyHashArrayBuffer); return { masterKey, diff --git a/libs/common/src/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction.ts b/libs/common/src/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction.ts index 191bcaf44a8..6000f964055 100644 --- a/libs/common/src/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction.ts @@ -7,11 +7,11 @@ export abstract class WebAuthnLoginPrfKeyServiceAbstraction { /** * Get the salt used to generate the PRF-output used when logging in with WebAuthn. */ - abstract getLoginWithPrfSalt(): Promise; + abstract getLoginWithPrfSalt(): Promise; /** * Create a symmetric key from the PRF-output by stretching it. * This should be used as `UpstreamKey` with `RotateableKeySet`. */ - abstract createSymmetricKeyFromPrf(prf: ArrayBuffer): Promise; + abstract createSymmetricKeyFromPrf(prf: Uint8Array): Promise; } diff --git a/libs/common/src/auth/models/domain/admin-auth-req-storable.ts b/libs/common/src/auth/models/domain/admin-auth-req-storable.ts index 34f1d367ffc..bdb74ebbc6b 100644 --- a/libs/common/src/auth/models/domain/admin-auth-req-storable.ts +++ b/libs/common/src/auth/models/domain/admin-auth-req-storable.ts @@ -17,7 +17,7 @@ export class AdminAuthRequestStorable { toJSON() { return { id: this.id, - privateKey: Utils.fromBufferToByteString(this.privateKey.buffer as ArrayBuffer), + privateKey: Utils.fromBufferToByteString(this.privateKey), }; } diff --git a/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts b/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts index 746a0962e86..d5093c01357 100644 --- a/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts +++ b/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts @@ -25,10 +25,10 @@ export class WebAuthnLoginAssertionResponseRequest extends WebAuthnLoginResponse } this.response = { - authenticatorData: Utils.fromBufferToUrlB64(credential.response.authenticatorData), - signature: Utils.fromBufferToUrlB64(credential.response.signature), - clientDataJSON: Utils.fromBufferToUrlB64(credential.response.clientDataJSON), - userHandle: Utils.fromBufferToUrlB64(credential.response.userHandle), + authenticatorData: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.authenticatorData)), + signature: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.signature)), + clientDataJSON: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.clientDataJSON)), + userHandle: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.userHandle)), }; } diff --git a/libs/common/src/auth/services/webauthn-login/request/webauthn-login-response.request.ts b/libs/common/src/auth/services/webauthn-login/request/webauthn-login-response.request.ts index 4b1eff4d471..0f87bc63fe0 100644 --- a/libs/common/src/auth/services/webauthn-login/request/webauthn-login-response.request.ts +++ b/libs/common/src/auth/services/webauthn-login/request/webauthn-login-response.request.ts @@ -8,7 +8,7 @@ export abstract class WebAuthnLoginResponseRequest { constructor(credential: PublicKeyCredential) { this.id = credential.id; - this.rawId = Utils.fromBufferToUrlB64(credential.rawId); + this.rawId = Utils.fromBufferToUrlB64(new Uint8Array(credential.rawId)); this.type = credential.type; // WARNING: do not add PRF information here by mapping diff --git a/libs/common/src/auth/services/webauthn-login/response/assertion-options.response.ts b/libs/common/src/auth/services/webauthn-login/response/assertion-options.response.ts index b7ac7354f27..846ce7f0252 100644 --- a/libs/common/src/auth/services/webauthn-login/response/assertion-options.response.ts +++ b/libs/common/src/auth/services/webauthn-login/response/assertion-options.response.ts @@ -19,7 +19,7 @@ export class AssertionOptionsResponse ...c, id: Utils.fromUrlB64ToArray(c.id).buffer, })); - this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge")); + this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge")).buffer as ArrayBuffer; this.extensions = this.getResponseProperty("extensions"); this.rpId = this.getResponseProperty("rpId"); this.timeout = this.getResponseProperty("timeout"); diff --git a/libs/common/src/auth/services/webauthn-login/webauthn-login-prf-key.service.ts b/libs/common/src/auth/services/webauthn-login/webauthn-login-prf-key.service.ts index 7c57d62c131..94c8c1a1b4e 100644 --- a/libs/common/src/auth/services/webauthn-login/webauthn-login-prf-key.service.ts +++ b/libs/common/src/auth/services/webauthn-login/webauthn-login-prf-key.service.ts @@ -8,12 +8,12 @@ const LoginWithPrfSalt = "passwordless-login"; export class WebAuthnLoginPrfKeyService implements WebAuthnLoginPrfKeyServiceAbstraction { constructor(private cryptoFunctionService: CryptoFunctionService) {} - async getLoginWithPrfSalt(): Promise { - return await this.cryptoFunctionService.hash(LoginWithPrfSalt, "sha256"); + async getLoginWithPrfSalt(): Promise { + return (await this.cryptoFunctionService.hash(LoginWithPrfSalt, "sha256")); } - async createSymmetricKeyFromPrf(prf: ArrayBuffer): Promise { - return (await this.stretchKey(new Uint8Array(prf))) as PrfKey; + async createSymmetricKeyFromPrf(prf: Uint8Array): Promise { + return (await this.stretchKey(prf)) as PrfKey; } // TODO: use keyGenerationService.stretchKey diff --git a/libs/common/src/auth/services/webauthn-login/webauthn-login.service.spec.ts b/libs/common/src/auth/services/webauthn-login/webauthn-login.service.spec.ts index b848cb2f902..ebc8b2b954c 100644 --- a/libs/common/src/auth/services/webauthn-login/webauthn-login.service.spec.ts +++ b/libs/common/src/auth/services/webauthn-login/webauthn-login.service.spec.ts @@ -39,7 +39,7 @@ describe("WebAuthnLoginService", () => { // We must do this to make the mocked classes available for all the // assertCredential(...) tests. global.PublicKeyCredential = MockPublicKeyCredential as any; - global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse; + global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse as any; // Save the original navigator originalNavigator = global.window.navigator; @@ -143,7 +143,7 @@ describe("WebAuthnLoginService", () => { publicKeyCredential.getClientExtensionResults().prf?.results?.first; const prfKey = new SymmetricCryptoKey(new Uint8Array(prfResult)) as PrfKey; - webAuthnLoginPrfKeyService.getLoginWithPrfSalt.mockResolvedValue(saltArrayBuffer); + webAuthnLoginPrfKeyService.getLoginWithPrfSalt.mockResolvedValue(new Uint8Array(saltArrayBuffer)); webAuthnLoginPrfKeyService.createSymmetricKeyFromPrf.mockResolvedValue(prfKey); // Mock implementations @@ -271,23 +271,23 @@ function randomBytes(length: number): Uint8Array { // so we need to mock them and assign them to the global object to make them available // for the tests class MockAuthenticatorAssertionResponse implements AuthenticatorAssertionResponse { - clientDataJSON: ArrayBuffer = randomBytes(32).buffer; - authenticatorData: ArrayBuffer = randomBytes(196).buffer; - signature: ArrayBuffer = randomBytes(72).buffer; - userHandle: ArrayBuffer = randomBytes(16).buffer; + clientDataJSON: ArrayBuffer = randomBytes(32).buffer as ArrayBuffer; + authenticatorData: ArrayBuffer = randomBytes(196).buffer as ArrayBuffer; + signature: ArrayBuffer = randomBytes(72).buffer as ArrayBuffer; + userHandle: ArrayBuffer = randomBytes(16).buffer as ArrayBuffer; - clientDataJSONB64Str = Utils.fromBufferToUrlB64(this.clientDataJSON); - authenticatorDataB64Str = Utils.fromBufferToUrlB64(this.authenticatorData); - signatureB64Str = Utils.fromBufferToUrlB64(this.signature); - userHandleB64Str = Utils.fromBufferToUrlB64(this.userHandle); + clientDataJSONB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.clientDataJSON)); + authenticatorDataB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.authenticatorData)); + signatureB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.signature)); + userHandleB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.userHandle)); } class MockPublicKeyCredential implements PublicKeyCredential { authenticatorAttachment = "cross-platform"; id = "mockCredentialId"; type = "public-key"; - rawId: ArrayBuffer = randomBytes(32).buffer; - rawIdB64Str = Utils.fromBufferToUrlB64(this.rawId); + rawId: ArrayBuffer = randomBytes(32).buffer as ArrayBuffer; + rawIdB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.rawId)); response: MockAuthenticatorAssertionResponse = new MockAuthenticatorAssertionResponse(); diff --git a/libs/common/src/key-management/crypto/key-generation/default-key-generation.service.ts b/libs/common/src/key-management/crypto/key-generation/default-key-generation.service.ts index ef1057c51e6..5f5da741707 100644 --- a/libs/common/src/key-management/crypto/key-generation/default-key-generation.service.ts +++ b/libs/common/src/key-management/crypto/key-generation/default-key-generation.service.ts @@ -30,7 +30,7 @@ export class DefaultKeyGenerationService implements KeyGenerationService { ): Promise<{ salt: string; material: CsprngArray; derivedKey: SymmetricCryptoKey }> { if (salt == null) { const bytes = await this.cryptoFunctionService.randomBytes(32); - salt = Utils.fromBufferToUtf8(bytes.buffer as ArrayBuffer); + salt = Utils.fromBufferToUtf8(bytes); } const material = await this.cryptoFunctionService.aesGenerateKey(bitLength); const key = await this.cryptoFunctionService.hkdf(material, salt, purpose, 64, "sha256"); diff --git a/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts b/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts index ee0b5cab902..aa315f23b8a 100644 --- a/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts +++ b/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts @@ -40,14 +40,14 @@ export class WebCryptoFunctionService implements CryptoFunctionService { const pbkdf2Params: Pbkdf2Params = { name: "PBKDF2", - salt: saltBuf, + salt: saltBuf as BufferSource, iterations: iterations, hash: { name: this.toWebCryptoAlgorithm(algorithm) }, }; const impKey = await this.subtle.importKey( "raw", - passwordBuf, + passwordBuf as BufferSource, { name: "PBKDF2" } as any, false, ["deriveBits"], @@ -68,12 +68,12 @@ export class WebCryptoFunctionService implements CryptoFunctionService { const hkdfParams: HkdfParams = { name: "HKDF", - salt: saltBuf, - info: infoBuf, + salt: saltBuf as BufferSource, + info: infoBuf as BufferSource, hash: { name: this.toWebCryptoAlgorithm(algorithm) }, }; - const impKey = await this.subtle.importKey("raw", ikm, { name: "HKDF" } as any, false, [ + const impKey = await this.subtle.importKey("raw", ikm as BufferSource, { name: "HKDF" } as any, false, [ "deriveBits", ]); const buffer = await this.subtle.deriveBits(hkdfParams as any, impKey, outputByteSize * 8); @@ -130,7 +130,7 @@ export class WebCryptoFunctionService implements CryptoFunctionService { const valueBuf = this.toBuf(value); const buffer = await this.subtle.digest( { name: this.toWebCryptoAlgorithm(algorithm) }, - valueBuf, + valueBuf as BufferSource, ); return new Uint8Array(buffer); } @@ -145,8 +145,14 @@ export class WebCryptoFunctionService implements CryptoFunctionService { hash: { name: this.toWebCryptoAlgorithm(algorithm) }, }; - const impKey = await this.subtle.importKey("raw", key, signingAlgorithm, false, ["sign"]); - const buffer = await this.subtle.sign(signingAlgorithm, impKey, value); + const impKey = await this.subtle.importKey( + "raw", + key as BufferSource, + signingAlgorithm, + false, + ["sign"], + ); + const buffer = await this.subtle.sign(signingAlgorithm, impKey, value as BufferSource); return new Uint8Array(buffer); } @@ -194,15 +200,15 @@ export class WebCryptoFunctionService implements CryptoFunctionService { return { iv: forge.util.decode64(iv), data: forge.util.decode64(data), - encKey: forge.util.createBuffer(innerKey.encryptionKey).getBytes(), + encKey: forge.util.createBuffer(innerKey.encryptionKey.buffer as ArrayBuffer).getBytes(), } as CbcDecryptParameters; } else if (innerKey.type === EncryptionType.AesCbc256_HmacSha256_B64) { const macData = forge.util.decode64(iv) + forge.util.decode64(data); return { iv: forge.util.decode64(iv), data: forge.util.decode64(data), - encKey: forge.util.createBuffer(innerKey.encryptionKey).getBytes(), - macKey: forge.util.createBuffer(innerKey.authenticationKey).getBytes(), + encKey: forge.util.createBuffer(innerKey.encryptionKey.buffer as ArrayBuffer).getBytes(), + macKey: forge.util.createBuffer(innerKey.authenticationKey.buffer as ArrayBuffer).getBytes(), mac: forge.util.decode64(mac!), macData, } as CbcDecryptParameters; @@ -248,15 +254,23 @@ export class WebCryptoFunctionService implements CryptoFunctionService { const result = await this.aesDecryptFast({ mode: "ecb", parameters }); return Utils.fromByteStringToArray(result); } - const impKey = await this.subtle.importKey("raw", key, { name: "AES-CBC" } as any, false, [ - "decrypt", - ]); + const impKey = await this.subtle.importKey( + "raw", + key as BufferSource, + { name: "AES-CBC" } as any, + false, + ["decrypt"], + ); // CBC if (iv == null) { throw new Error("IV is required for CBC mode."); } - const buffer = await this.subtle.decrypt({ name: "AES-CBC", iv: iv }, impKey, data); + const buffer = await this.subtle.decrypt( + { name: "AES-CBC", iv: iv as BufferSource }, + impKey, + data as BufferSource, + ); return new Uint8Array(buffer); } diff --git a/libs/common/src/platform/misc/utils.spec.ts b/libs/common/src/platform/misc/utils.spec.ts index 664c6e22b3a..8bf84b74f78 100644 --- a/libs/common/src/platform/misc/utils.spec.ts +++ b/libs/common/src/platform/misc/utils.spec.ts @@ -447,7 +447,7 @@ describe("Utils Service", () => { "should correctly round trip convert from base64 to ArrayBuffer and back", () => { // Convert known base64 string to ArrayBuffer - const bufferFromB64 = Utils.fromB64ToArray(b64HelloWorldString).buffer; + const bufferFromB64 = Utils.fromB64ToArray(b64HelloWorldString).buffer as ArrayBuffer; // Convert the ArrayBuffer back to a base64 string const roundTrippedB64String = Utils.fromBufferToB64(bufferFromB64); @@ -487,13 +487,13 @@ describe("Utils Service", () => { } runInBothEnvironments("should convert an ArrayBuffer to a hex string", () => { - const buffer = new Uint8Array([0, 1, 10, 16, 255]).buffer; + const buffer = new Uint8Array([0, 1, 10, 16, 255]); const hexString = Utils.fromBufferToHex(buffer); expect(hexString).toBe("00010a10ff"); }); runInBothEnvironments("should handle an empty buffer", () => { - const buffer = new ArrayBuffer(0); + const buffer = new Uint8Array(0); const hexString = Utils.fromBufferToHex(buffer); expect(hexString).toBe(""); }); @@ -501,7 +501,7 @@ describe("Utils Service", () => { runInBothEnvironments( "should correctly convert a large buffer containing a repeating sequence of all 256 unique byte values to hex", () => { - const largeBuffer = new Uint8Array(1024).map((_, index) => index % 256).buffer; + const largeBuffer = new Uint8Array(1024).map((_, index) => index % 256); const hexString = Utils.fromBufferToHex(largeBuffer); const expectedHexString = createSequentialHexByteString(256).repeat(4); expect(hexString).toBe(expectedHexString); @@ -509,7 +509,7 @@ describe("Utils Service", () => { ); runInBothEnvironments("should correctly convert a buffer with a single byte to hex", () => { - const singleByteBuffer = new Uint8Array([0xab]).buffer; + const singleByteBuffer = new Uint8Array([0xab]); const hexString = Utils.fromBufferToHex(singleByteBuffer); expect(hexString).toBe("ab"); }); @@ -517,7 +517,7 @@ describe("Utils Service", () => { runInBothEnvironments( "should correctly convert a buffer with an odd number of bytes to hex", () => { - const oddByteBuffer = new Uint8Array([0x01, 0x23, 0x45, 0x67, 0x89]).buffer; + const oddByteBuffer = new Uint8Array([0x01, 0x23, 0x45, 0x67, 0x89]); const hexString = Utils.fromBufferToHex(oddByteBuffer); expect(hexString).toBe("0123456789"); }, @@ -527,7 +527,7 @@ describe("Utils Service", () => { describe("hexStringToArrayBuffer(...)", () => { test("should convert a hex string to an ArrayBuffer correctly", () => { const hexString = "ff0a1b"; // Arbitrary hex string - const expectedResult = new Uint8Array([255, 10, 27]).buffer; + const expectedResult = new Uint8Array([255, 10, 27]).buffer as ArrayBuffer; const result = Utils.hexStringToArrayBuffer(hexString); expect(new Uint8Array(result)).toEqual(new Uint8Array(expectedResult)); }); @@ -541,7 +541,7 @@ describe("Utils Service", () => { test("should convert a hex string representing zero to an ArrayBuffer correctly", () => { const hexString = "00"; - const expectedResult = new Uint8Array([0]).buffer; + const expectedResult = new Uint8Array([0]).buffer as ArrayBuffer; const result = Utils.hexStringToArrayBuffer(hexString); expect(new Uint8Array(result)).toEqual(new Uint8Array(expectedResult)); }); @@ -556,7 +556,7 @@ describe("Utils Service", () => { test("should convert a long hex string to an ArrayBuffer correctly", () => { const hexString = "0102030405060708090a0b0c0d0e0f"; const expectedResult = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) - .buffer; + .buffer as ArrayBuffer; const result = Utils.hexStringToArrayBuffer(hexString); expect(new Uint8Array(result)).toEqual(new Uint8Array(expectedResult)); }); @@ -566,10 +566,10 @@ describe("Utils Service", () => { runInBothEnvironments( "should allow round-trip conversion from ArrayBuffer to hex and back", () => { - const originalBuffer = new Uint8Array([10, 20, 30, 40, 255]).buffer; // arbitrary buffer + const originalBuffer = new Uint8Array([10, 20, 30, 40, 255]); // arbitrary buffer const hexString = Utils.fromBufferToHex(originalBuffer); const roundTripBuffer = Utils.hexStringToArrayBuffer(hexString); - expect(new Uint8Array(roundTripBuffer)).toEqual(new Uint8Array(originalBuffer)); + expect(new Uint8Array(roundTripBuffer)).toEqual(originalBuffer); }, ); @@ -578,7 +578,7 @@ describe("Utils Service", () => { () => { const hexString = "0a141e28ff"; // arbitrary hex string const bufferFromHex = Utils.hexStringToArrayBuffer(hexString); - const roundTripHexString = Utils.fromBufferToHex(bufferFromHex); + const roundTripHexString = Utils.fromBufferToHex(new Uint8Array(bufferFromHex)); expect(roundTripHexString).toBe(hexString); }, ); @@ -761,13 +761,13 @@ describe("Utils Service", () => { }); runInBothEnvironments("should convert an ArrayBuffer to a utf8 string", () => { - const buffer = new Uint8Array(asciiHelloWorldArray).buffer; + const buffer = new Uint8Array(asciiHelloWorldArray); const str = Utils.fromBufferToUtf8(buffer); expect(str).toBe(asciiHelloWorld); }); runInBothEnvironments("should handle an empty buffer", () => { - const buffer = new ArrayBuffer(0); + const buffer = new Uint8Array(0); const str = Utils.fromBufferToUtf8(buffer); expect(str).toBe(""); }); @@ -798,7 +798,7 @@ describe("Utils Service", () => { ]; cases.forEach((c) => { - const buffer = new Uint8Array(c.input).buffer; + const buffer = new Uint8Array(c.input); const str = Utils.fromBufferToUtf8(buffer); // Match the expected output expect(str).toBe(c.output); diff --git a/libs/common/src/platform/misc/utils.ts b/libs/common/src/platform/misc/utils.ts index 136b0ac394f..605eff9d002 100644 --- a/libs/common/src/platform/misc/utils.ts +++ b/libs/common/src/platform/misc/utils.ts @@ -205,7 +205,7 @@ export class Utils { } } - static fromBufferToUrlB64(buffer: ArrayBuffer): string { + static fromBufferToUrlB64(buffer: Uint8Array): string { return Utils.fromB64toUrlB64(Utils.fromBufferToB64(buffer)); } @@ -213,16 +213,16 @@ export class Utils { return b64Str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); } - static fromBufferToUtf8(buffer: ArrayBuffer): string { + static fromBufferToUtf8(buffer: Uint8Array): string { return BufferLib.from(buffer).toString("utf8"); } - static fromBufferToByteString(buffer: ArrayBuffer): string { - return String.fromCharCode.apply(null, new Uint8Array(buffer)); + static fromBufferToByteString(buffer: Uint8Array): string { + return String.fromCharCode.apply(null, buffer); } // ref: https://stackoverflow.com/a/40031979/1090359 - static fromBufferToHex(buffer: ArrayBuffer): string { + static fromBufferToHex(buffer: Uint8Array): string { if (Utils.isNode) { return Buffer.from(buffer).toString("hex"); } else { diff --git a/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.spec.ts b/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.spec.ts index 6d9457389ca..65fcbfb14b9 100644 --- a/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.spec.ts +++ b/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.spec.ts @@ -28,7 +28,10 @@ const mockUser1 = "testUser1" as UserId; const createSub = (key: string) => { return { - options: { applicationServerKey: Utils.fromUrlB64ToArray(key), userVisibleOnly: true }, + options: { + applicationServerKey: Utils.fromUrlB64ToArray(key).buffer as ArrayBuffer, + userVisibleOnly: true, + }, endpoint: `web.push.endpoint/?${Utils.newGuid()}`, expirationTime: 5, getKey: () => null, diff --git a/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.ts b/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.ts index 8b38ebd5b17..0065e3dcdef 100644 --- a/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.ts +++ b/libs/common/src/platform/server-notifications/internal/worker-webpush-connection.service.ts @@ -173,7 +173,7 @@ class MyWebPushConnector implements WebPushConnector { // REASON: `Utils.fromBufferToUrlB64` handles null by returning null back to it. // its annotation should be updated and then this assertion can be removed. // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain - existingSubscription.options?.applicationServerKey!, + new Uint8Array(existingSubscription.options?.applicationServerKey!) ); if (subscriptionKey !== key) { diff --git a/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts b/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts index 1f2217ccd63..770b080fc44 100644 --- a/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts +++ b/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts @@ -9,7 +9,7 @@ describe("credential-id-utils", () => { new Uint8Array([ 0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07, 0xe7, - ]).buffer, + ]).buffer as ArrayBuffer, ); }); @@ -20,7 +20,7 @@ describe("credential-id-utils", () => { new Uint8Array([ 0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07, 0xe7, - ]).buffer, + ]).buffer as ArrayBuffer, ); }); @@ -39,8 +39,8 @@ describe("credential-id-utils", () => { describe("compareCredentialIds", () => { it("returns true when the two credential IDs are equal", () => { - const a = new Uint8Array([0x01, 0x02, 0x03]); - const b = new Uint8Array([0x01, 0x02, 0x03]); + const a = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer; + const b = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer; const result = compareCredentialIds(a, b); @@ -48,8 +48,8 @@ describe("credential-id-utils", () => { }); it("returns false when the two credential IDs are not equal", () => { - const a = new Uint8Array([0x01, 0x02, 0x03]); - const b = new Uint8Array([0x01, 0x02, 0x04]); + const a = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer; + const b = new Uint8Array([0x01, 0x02, 0x04]).buffer as ArrayBuffer; const result = compareCredentialIds(a, b); @@ -57,8 +57,8 @@ describe("credential-id-utils", () => { }); it("returns false when the two credential IDs have different lengths", () => { - const a = new Uint8Array([0x01, 0x02, 0x03]); - const b = new Uint8Array([0x01, 0x02, 0x03, 0x04]); + const a = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer; + const b = new Uint8Array([0x01, 0x02, 0x03, 0x04]).buffer as ArrayBuffer; const result = compareCredentialIds(a, b); diff --git a/libs/common/src/platform/services/fido2/credential-id-utils.ts b/libs/common/src/platform/services/fido2/credential-id-utils.ts index 08ea33114f5..4c0bb1f8e2c 100644 --- a/libs/common/src/platform/services/fido2/credential-id-utils.ts +++ b/libs/common/src/platform/services/fido2/credential-id-utils.ts @@ -9,7 +9,7 @@ export function parseCredentialId(encodedCredentialId: string): ArrayBuffer { return Fido2Utils.stringToBuffer(encodedCredentialId.slice(4)); } - return guidToRawFormat(encodedCredentialId).buffer; + return guidToRawFormat(encodedCredentialId).buffer as ArrayBuffer; } catch { return undefined; } diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts index 9c50bd1ab65..e1c88a36ba0 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts @@ -433,7 +433,7 @@ describe("FidoAuthenticatorService", () => { ], excludeCredentialDescriptorList: params.excludeCredentialDescriptorList ?? [ { - id: randomBytes(16), + id: randomBytes(16).buffer as ArrayBuffer, transports: ["internal"], type: "public-key", }, diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts index d1081e9f7b2..a3e31de7d55 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts @@ -348,12 +348,12 @@ export class Fido2AuthenticatorService< }); return { - authenticatorData, + authenticatorData: authenticatorData.buffer as ArrayBuffer, selectedCredential: { id: parseCredentialId(selectedCredentialId), userHandle: Fido2Utils.stringToBuffer(selectedFido2Credential.userHandle), }, - signature, + signature: signature.buffer as ArrayBuffer, }; } catch (error) { this.logService?.error( @@ -537,7 +537,10 @@ async function generateAuthData(params: AuthDataParams) { const authData: Array = []; const rpIdHash = new Uint8Array( - await crypto.subtle.digest({ name: "SHA-256" }, Utils.fromByteStringToArray(params.rpId)), + await crypto.subtle.digest( + { name: "SHA-256" }, + Utils.fromByteStringToArray(params.rpId) as BufferSource, + ), ); authData.push(...rpIdHash); diff --git a/libs/common/src/platform/services/fido2/fido2-autofill-utils.ts b/libs/common/src/platform/services/fido2/fido2-autofill-utils.ts index a58b2d470e6..d4d148ca78c 100644 --- a/libs/common/src/platform/services/fido2/fido2-autofill-utils.ts +++ b/libs/common/src/platform/services/fido2/fido2-autofill-utils.ts @@ -21,7 +21,7 @@ export async function getCredentialsForAutofill( // Credentials are stored as a GUID or b64 string with `b64.` prepended, // but we need to return them as a URL-safe base64 string - const credId = Utils.fromBufferToUrlB64(parseCredentialId(credential.credentialId)); + const credId = Utils.fromBufferToUrlB64(new Uint8Array(parseCredentialId(credential.credentialId))); return { cipherId: cipher.id, diff --git a/libs/common/src/platform/services/fido2/fido2-client.service.spec.ts b/libs/common/src/platform/services/fido2/fido2-client.service.spec.ts index 4fd91fb19e6..9c7d78f6190 100644 --- a/libs/common/src/platform/services/fido2/fido2-client.service.spec.ts +++ b/libs/common/src/platform/services/fido2/fido2-client.service.spec.ts @@ -572,7 +572,7 @@ describe("FidoAuthenticatorService", () => { const allowedCredentialIds = [ Fido2Utils.bufferToString(guidToRawFormat(Utils.newGuid())), Fido2Utils.bufferToString(guidToRawFormat(Utils.newGuid())), - Fido2Utils.bufferToString(Utils.fromByteStringToArray("not-a-guid")), + Fido2Utils.bufferToString(Utils.fromByteStringToArray("not-a-guid") as BufferSource), ]; const params = createParams({ userVerification: "required", @@ -700,11 +700,11 @@ describe("FidoAuthenticatorService", () => { function createAuthenticatorAssertResult(): Fido2AuthenticatorGetAssertionResult { return { selectedCredential: { - id: randomBytes(32), - userHandle: randomBytes(32), + id: randomBytes(32).buffer as ArrayBuffer, + userHandle: randomBytes(32).buffer as ArrayBuffer, }, - authenticatorData: randomBytes(64), - signature: randomBytes(64), + authenticatorData: randomBytes(64).buffer as ArrayBuffer, + signature: randomBytes(64).buffer as ArrayBuffer, }; } }); diff --git a/libs/common/src/platform/services/fido2/fido2-client.service.ts b/libs/common/src/platform/services/fido2/fido2-client.service.ts index 503ffef8241..feee67177e6 100644 --- a/libs/common/src/platform/services/fido2/fido2-client.service.ts +++ b/libs/common/src/platform/services/fido2/fido2-client.service.ts @@ -181,7 +181,7 @@ export class Fido2ClientService< }; const clientDataJSON = JSON.stringify(collectedClientData); const clientDataJSONBytes = Utils.fromByteStringToArray(clientDataJSON); - const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes); + const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes.buffer as ArrayBuffer); const makeCredentialParams = mapToMakeCredentialParams({ params, credTypesAndPubKeyAlgs, @@ -248,7 +248,7 @@ export class Fido2ClientService< credentialId: Fido2Utils.bufferToString(makeCredentialResult.credentialId), attestationObject: Fido2Utils.bufferToString(makeCredentialResult.attestationObject), authData: Fido2Utils.bufferToString(makeCredentialResult.authData), - clientDataJSON: Fido2Utils.bufferToString(clientDataJSONBytes), + clientDataJSON: Fido2Utils.bufferToString(new Uint8Array(clientDataJSONBytes)), publicKey: Fido2Utils.bufferToString(makeCredentialResult.publicKey), publicKeyAlgorithm: makeCredentialResult.publicKeyAlgorithm, transports: ["internal", "hybrid"], @@ -308,7 +308,7 @@ export class Fido2ClientService< ); } - const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes); + const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes.buffer as ArrayBuffer); const getAssertionParams = mapToGetAssertionParams({ params, clientDataHash }); if (abortController.signal.aborted) { @@ -402,7 +402,7 @@ export class Fido2ClientService< ]; assumeUserPresence = true; - const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes); + const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes.buffer as ArrayBuffer); const getAssertionParams = mapToGetAssertionParams({ params, clientDataHash, @@ -429,8 +429,8 @@ export class Fido2ClientService< ): AssertCredentialResult { return { authenticatorData: Fido2Utils.bufferToString(getAssertionResult.authenticatorData), - clientDataJSON: Fido2Utils.bufferToString(clientDataJSONBytes), - credentialId: Fido2Utils.bufferToString(getAssertionResult.selectedCredential.id), + clientDataJSON: Fido2Utils.bufferToString(new Uint8Array(clientDataJSONBytes)), + credentialId: Fido2Utils.bufferToString(new Uint8Array(getAssertionResult.selectedCredential.id)), userHandle: getAssertionResult.selectedCredential.userHandle !== undefined ? Fido2Utils.bufferToString(getAssertionResult.selectedCredential.userHandle) diff --git a/libs/common/src/platform/services/fido2/fido2-utils.ts b/libs/common/src/platform/services/fido2/fido2-utils.ts index 8efd4734d81..35e9f2a8d0c 100644 --- a/libs/common/src/platform/services/fido2/fido2-utils.ts +++ b/libs/common/src/platform/services/fido2/fido2-utils.ts @@ -43,14 +43,14 @@ export class Fido2Utils { } static bufferToString(bufferSource: BufferSource): string { - return Fido2Utils.fromBufferToB64(Fido2Utils.bufferSourceToUint8Array(bufferSource)) + return Fido2Utils.fromBufferToB64(Fido2Utils.bufferSourceToUint8Array(bufferSource).buffer as ArrayBuffer) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=/g, ""); } static stringToBuffer(str: string): ArrayBuffer { - return Fido2Utils.fromB64ToArray(Fido2Utils.fromUrlB64ToB64(str)).buffer; + return Fido2Utils.fromB64ToArray(Fido2Utils.fromUrlB64ToB64(str)).buffer as ArrayBuffer; } static bufferSourceToUint8Array(bufferSource: BufferSource): Uint8Array { diff --git a/libs/common/src/platform/services/fido2/guid-utils.spec.ts b/libs/common/src/platform/services/fido2/guid-utils.spec.ts index c58bd2720fa..d7794eade4f 100644 --- a/libs/common/src/platform/services/fido2/guid-utils.spec.ts +++ b/libs/common/src/platform/services/fido2/guid-utils.spec.ts @@ -43,7 +43,7 @@ describe("guid-utils", () => { it.each(workingExamples)( "returns UUID in standard format when given a valid UUID array buffer", (expected, input) => { - const result = guidToStandardFormat(input); + const result = guidToStandardFormat(input.buffer as ArrayBuffer); expect(result).toEqual(expected); }, diff --git a/libs/common/src/platform/services/file-upload/azure-file-upload.service.ts b/libs/common/src/platform/services/file-upload/azure-file-upload.service.ts index 02adcfee22e..52d1d2f7efd 100644 --- a/libs/common/src/platform/services/file-upload/azure-file-upload.service.ts +++ b/libs/common/src/platform/services/file-upload/azure-file-upload.service.ts @@ -31,7 +31,7 @@ export class AzureFileUploadService { }); const request = new Request(url, { - body: data.buffer, + body: data.buffer.buffer as ArrayBuffer, cache: "no-store", method: "PUT", headers: headers, diff --git a/libs/common/src/platform/services/file-upload/bitwarden-file-upload.service.ts b/libs/common/src/platform/services/file-upload/bitwarden-file-upload.service.ts index 93594405302..621505f17fd 100644 --- a/libs/common/src/platform/services/file-upload/bitwarden-file-upload.service.ts +++ b/libs/common/src/platform/services/file-upload/bitwarden-file-upload.service.ts @@ -10,7 +10,7 @@ export class BitwardenFileUploadService { const fd = new FormData(); if (Utils.isBrowser) { - const blob = new Blob([encryptedFileData.buffer], { type: "application/octet-stream" }); + const blob = new Blob([encryptedFileData.buffer.buffer as ArrayBuffer], { type: "application/octet-stream" }); fd.append("data", blob, encryptedFileName); } else if (Utils.isNode) { fd.append( diff --git a/libs/common/src/platform/services/key-state/user-key.state.spec.ts b/libs/common/src/platform/services/key-state/user-key.state.spec.ts index 2ea3c31bc1b..f79164bdab1 100644 --- a/libs/common/src/platform/services/key-state/user-key.state.spec.ts +++ b/libs/common/src/platform/services/key-state/user-key.state.spec.ts @@ -20,17 +20,3 @@ describe("Ever had user key", () => { expect(result).toEqual(everHadUserKey); }); }); - -describe("Encrypted private key", () => { - const sut = USER_ENCRYPTED_PRIVATE_KEY; - - it("should deserialize encrypted private key", () => { - const encryptedPrivateKey = makeEncString().encryptedString; - - const result = sut.deserializer( - JSON.parse(JSON.stringify(encryptedPrivateKey as unknown)) as unknown as EncryptedString, - ); - - expect(result).toEqual(encryptedPrivateKey); - }); -}); diff --git a/libs/common/src/tools/password-strength/password-strength.service.ts b/libs/common/src/tools/password-strength/password-strength.service.ts index 77854943acd..3d9df6dd1ab 100644 --- a/libs/common/src/tools/password-strength/password-strength.service.ts +++ b/libs/common/src/tools/password-strength/password-strength.service.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import * as zxcvbn from "zxcvbn"; +import zxcvbn from "zxcvbn"; import { PasswordStrengthServiceAbstraction } from "./password-strength.service.abstraction"; diff --git a/libs/common/src/vault/abstractions/cipher.service.ts b/libs/common/src/vault/abstractions/cipher.service.ts index 0d3a0b99fcb..266e16f3f5b 100644 --- a/libs/common/src/vault/abstractions/cipher.service.ts +++ b/libs/common/src/vault/abstractions/cipher.service.ts @@ -157,7 +157,7 @@ export abstract class CipherService implements UserKeyRotationDataProvider; diff --git a/libs/common/src/vault/services/cipher.service.ts b/libs/common/src/vault/services/cipher.service.ts index d25aa62ea3a..e19801edf97 100644 --- a/libs/common/src/vault/services/cipher.service.ts +++ b/libs/common/src/vault/services/cipher.service.ts @@ -1803,7 +1803,7 @@ export class CipherService implements CipherServiceAbstraction { const fd = new FormData(); try { - const blob = new Blob([encData.buffer], { type: "application/octet-stream" }); + const blob = new Blob([encData.buffer.buffer as ArrayBuffer], { type: "application/octet-stream" }); fd.append("key", dataEncKey[1].encryptedString); fd.append("data", blob, encFileName.encryptedString); fd.append("lastKnownRevisionDate", lastKnownRevisionDate.toISOString()); diff --git a/libs/key-management-ui/package.json b/libs/key-management-ui/package.json index 9a05bf07c63..1ea2f8a326e 100644 --- a/libs/key-management-ui/package.json +++ b/libs/key-management-ui/package.json @@ -14,7 +14,7 @@ "license": "GPL-3.0", "scripts": { "clean": "rimraf dist", - "build": "npm run clean && tsc", + "build": "npm run clean && tsgo", "build:watch": "npm run clean && tsc -watch", "test": "jest" } diff --git a/libs/key-management/package.json b/libs/key-management/package.json index 6751163e6e8..9d2922e3add 100644 --- a/libs/key-management/package.json +++ b/libs/key-management/package.json @@ -14,7 +14,7 @@ "license": "GPL-3.0", "scripts": { "clean": "rimraf dist", - "build": "npm run clean && tsc", + "build": "npm run clean && tsgo", "build:watch": "npm run clean && tsc -watch", "test": "jest" } diff --git a/tsconfig.base.json b/tsconfig.base.json index d91e8cb9890..27996e6ec0a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -12,12 +12,12 @@ "emitDecoratorMetadata": true, "declaration": false, "outDir": "dist", - "baseUrl": ".", "resolveJsonModule": true, "allowJs": true, "sourceMap": true, "skipLibCheck": true, "paths": { + "*": ["../../*"], "@bitwarden/admin-console/common": ["./libs/admin-console/src/common"], "@bitwarden/angular/*": ["./libs/angular/src/*"], "@bitwarden/assets": ["./libs/assets/src/index.ts"],