Skip to content

Commit

Permalink
debt - add crypto.d.ts file defining the crypto-global that's share…
Browse files Browse the repository at this point in the history
…d between nodejs and browsers (#237465)
  • Loading branch information
jrieken authored Jan 8, 2025
1 parent 23b62bc commit 8ad5ac5
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 75 deletions.
83 changes: 83 additions & 0 deletions src/typings/crypto.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// NOTE that this is a partial copy from lib.dom.d.ts which is NEEDED because these utils are used in the /common/
// layer which has no dependency on the DOM/browser-context. However, `crypto` is available as global in all browsers and
// in nodejs. Therefore it's OK to spell out its typings here

declare global {

/**
* This Web Crypto API interface provides a number of low-level cryptographic functions. It is accessed via the Crypto.subtle properties available in a window context (via Window.crypto).
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto)
*/
interface SubtleCrypto {
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/decrypt) */
// decrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveBits) */
// deriveBits(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, length?: number | null): Promise<ArrayBuffer>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */
// deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/digest) */
digest(algorithm: { name: string } | string, data: ArrayBufferView | ArrayBuffer): Promise<ArrayBuffer>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/encrypt) */
// encrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/exportKey) */
// exportKey(format: "jwk", key: CryptoKey): Promise<JsonWebKey>;
// exportKey(format: Exclude<KeyFormat, "jwk">, key: CryptoKey): Promise<ArrayBuffer>;
// exportKey(format: KeyFormat, key: CryptoKey): Promise<ArrayBuffer | JsonWebKey>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */
// generateKey(algorithm: "Ed25519", extractable: boolean, keyUsages: ReadonlyArray<"sign" | "verify">): Promise<CryptoKeyPair>;
// generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKeyPair>;
// generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;
// generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKeyPair | CryptoKey>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */
// importKey(format: "jwk", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;
// importKey(format: Exclude<KeyFormat, "jwk">, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/sign) */
// sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */
// unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/verify) */
// verify(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean>;
// /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/wrapKey) */
// wrapKey(format: KeyFormat, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams): Promise<ArrayBuffer>;
}

/**
* Basic cryptography features available in the current context. It allows access to a cryptographically strong random number generator and to cryptographic primitives.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto)
*/
interface Crypto {
/**
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/subtle)
*/
readonly subtle: SubtleCrypto;
/**
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues)
*/
getRandomValues<T extends ArrayBufferView | null>(array: T): T;
/**
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
*/
randomUUID(): `${string}-${string}-${string}-${string}-${string}`;
}

var Crypto: {
prototype: Crypto;
new(): Crypto;
};

var crypto: Crypto;

}
export { }
7 changes: 1 addition & 6 deletions src/vs/base/common/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,7 @@ function objectHash(obj: any, initialHashVal: number): number {
}, initialHashVal);
}

// this is shared global between browsers and nodejs
declare const crypto: {
subtle: {
digest(a: string, b: ArrayBufferView): Promise<ArrayBuffer>;
};
};


/** Hashes the input as SHA-1, returning a hex-encoded string. */
export const hashAsync = (input: string | ArrayBufferView | VSBuffer) => {
Expand Down
70 changes: 1 addition & 69 deletions src/vs/base/common/uuid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,72 +10,4 @@ export function isUUID(value: string): boolean {
return _UUIDPattern.test(value);
}

declare const crypto: undefined | {
//https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#browser_compatibility
getRandomValues?(data: Uint8Array): Uint8Array;
//https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID#browser_compatibility
randomUUID?(): string;
};

export const generateUuid = (function (): () => string {

// use `randomUUID` if possible
if (typeof crypto === 'object' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID.bind(crypto);
}

// use `randomValues` if possible
let getRandomValues: (bucket: Uint8Array) => Uint8Array;
if (typeof crypto === 'object' && typeof crypto.getRandomValues === 'function') {
getRandomValues = crypto.getRandomValues.bind(crypto);

} else {
getRandomValues = function (bucket: Uint8Array): Uint8Array {
for (let i = 0; i < bucket.length; i++) {
bucket[i] = Math.floor(Math.random() * 256);
}
return bucket;
};
}

// prep-work
const _data = new Uint8Array(16);
const _hex: string[] = [];
for (let i = 0; i < 256; i++) {
_hex.push(i.toString(16).padStart(2, '0'));
}

return function generateUuid(): string {
// get data
getRandomValues(_data);

// set version bits
_data[6] = (_data[6] & 0x0f) | 0x40;
_data[8] = (_data[8] & 0x3f) | 0x80;

// print as string
let i = 0;
let result = '';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
return result;
};
})();
export const generateUuid: () => string = crypto.randomUUID.bind(crypto);

0 comments on commit 8ad5ac5

Please sign in to comment.