summaryrefslogtreecommitdiffhomepage
path: root/packages/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src')
-rw-r--r--packages/server/src/helpers/iso/isoCrypto/getWebCrypto.test.ts138
-rw-r--r--packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts9
2 files changed, 107 insertions, 40 deletions
diff --git a/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.test.ts b/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.test.ts
index c372559..5a1ad92 100644
--- a/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.test.ts
+++ b/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.test.ts
@@ -1,75 +1,137 @@
-import { assertEquals } from 'https://deno.land/std@0.198.0/assert/mod.ts';
+import { assertEquals, assertRejects } from 'https://deno.land/std@0.198.0/assert/mod.ts';
import { returnsNext, stub } from 'https://deno.land/std@0.198.0/testing/mock.ts';
-import { _getWebCryptoInternals, getWebCrypto } from './getWebCrypto.ts';
+import { _getWebCryptoInternals, getWebCrypto, MissingWebCrypto } from './getWebCrypto.ts';
-Deno.test('Should return globalThis.crypto when present', async () => {
- // Back up globalThis.crypto
- const originalCrypto = globalThis.crypto;
-
- // Overwrite globalThis.crypto
- const newCrypto = {};
- Object.defineProperty(globalThis, 'crypto', { value: newCrypto, writable: true });
+Deno.test('should return globalThis.crypto when present', async () => {
+ // Pretend globalThis.crypto exists
+ const newGlobalThisCrypto = {};
+ const mockGlobalThisCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisGlobalThisCrypto',
+ // @ts-ignore: globalThis.crypto
+ returnsNext([newGlobalThisCrypto]),
+ );
const returnedCrypto = await getWebCrypto();
- assertEquals(returnedCrypto, newCrypto);
+ assertEquals(returnedCrypto, newGlobalThisCrypto);
- // Restore globalThis.crypto
- Object.defineProperty(globalThis, 'crypto', { value: originalCrypto, writable: true });
+ mockGlobalThisCrypto.restore();
});
-Deno.test('Should return node:crypto.webcrypto when globalThis.crypto is missing', async () => {
+Deno.test('should return node:crypto.webcrypto when globalThis.crypto is missing', async () => {
+ // Pretend globalThis.crypto doesn't exist
+ const mockGlobalThisCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisGlobalThisCrypto',
+ // @ts-ignore: globalThis.crypto
+ returnsNext([undefined]),
+ );
+
// Mock out just enough of the 'node:crypto' module
const fakeNodeCrypto = { webcrypto: {} };
- const mockDecodeClientData = stub(
+ const mockImportNodeCrypto = stub(
_getWebCryptoInternals,
'stubThisImportNodeCrypto',
- // @ts-ignore: Pretending to return something from Node
+ // @ts-ignore: node:crypto
returnsNext([fakeNodeCrypto]),
);
- // Back up globalThis.crypto
- const originalCrypto = globalThis.crypto;
-
- // Overwrite globalThis.crypto
- const newCrypto = undefined;
- Object.defineProperty(globalThis, 'crypto', { value: newCrypto, writable: true });
-
const returnedCrypto = await getWebCrypto();
assertEquals(returnedCrypto, fakeNodeCrypto.webcrypto);
- // Restore globalThis.crypto
- Object.defineProperty(globalThis, 'crypto', { value: originalCrypto, writable: true });
- mockDecodeClientData.restore();
+ mockGlobalThisCrypto.restore();
+ mockImportNodeCrypto.restore();
});
Deno.test(
- 'Should return globalThis.crypto when present, while node:crypto is present but missing webcrypto',
+ 'should return globalThis.crypto when present, while node:crypto.webcrypto is present',
async () => {
+ // Pretend globalThis.crypto exists
+ const fakeGlobalThisCrypto = {};
+ const mockGlobalThisCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisGlobalThisCrypto',
+ // @ts-ignore: globalThis.crypto
+ returnsNext([fakeGlobalThisCrypto]),
+ );
+
// Mock out just enough of the 'node:crypto' module, but like we're in Node v14
- const fakeNodeCrypto = { webcrypto: undefined };
- const mockDecodeClientData = stub(
+ const fakeNodeCrypto = { webcrypto: {} };
+ const mockImportNodeCrypto = stub(
_getWebCryptoInternals,
'stubThisImportNodeCrypto',
- // @ts-ignore: Pretending to return something from Node
+ // @ts-ignore: node:crypto
returnsNext([fakeNodeCrypto]),
);
- // Back up globalThis.crypto
- const originalCrypto = globalThis.crypto;
+ const returnedCrypto = await getWebCrypto();
+
+ assertEquals(returnedCrypto, fakeGlobalThisCrypto);
+
+ mockGlobalThisCrypto.restore();
+ mockImportNodeCrypto.restore();
+ },
+);
+
+Deno.test(
+ 'should return globalThis.crypto when present, while node:crypto is present but missing webcrypto',
+ async () => {
+ // Pretend globalThis.crypto exists
+ const fakeGlobalThisCrypto = {};
+ const mockGlobalThisCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisGlobalThisCrypto',
+ // @ts-ignore: globalThis.crypto
+ returnsNext([fakeGlobalThisCrypto]),
+ );
- // Overwrite globalThis.crypto
- const fakeGlobalCrypto = {};
- Object.defineProperty(globalThis, 'crypto', { value: fakeGlobalCrypto, writable: true });
+ // Mock out just enough of the 'node:crypto' module, but like we're in Node v14
+ const fakeNodeCrypto = { webcrypto: undefined };
+ const mockImportNodeCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisImportNodeCrypto',
+ // @ts-ignore: node:crypto
+ returnsNext([fakeNodeCrypto]),
+ );
const returnedCrypto = await getWebCrypto();
- assertEquals(returnedCrypto, fakeGlobalCrypto);
+ assertEquals(returnedCrypto, fakeGlobalThisCrypto);
- // Restore globalThis.crypto
- Object.defineProperty(globalThis, 'crypto', { value: originalCrypto, writable: true });
- mockDecodeClientData.restore();
+ mockGlobalThisCrypto.restore();
+ mockImportNodeCrypto.restore();
},
);
+
+Deno.test('should raise MissingWebCrypto error when nothing is available', async () => {
+ // Clear whatever version of crypto might have been set
+ _getWebCryptoInternals.setCachedCrypto(undefined);
+
+ // Pretend globalThis.crypto doesn't exist
+ const mockGlobalThisCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisGlobalThisCrypto',
+ // @ts-ignore: globalThis.crypto
+ returnsNext([undefined]),
+ );
+
+ // Pretend node:crypto doesn't exist
+ const mockImportNodeCrypto = stub(
+ _getWebCryptoInternals,
+ 'stubThisImportNodeCrypto',
+ // @ts-ignore: node:crypto
+ returnsNext([undefined]),
+ );
+
+ await assertRejects(
+ () => getWebCrypto(),
+ MissingWebCrypto,
+ 'Crypto API could not be located',
+ );
+
+ mockGlobalThisCrypto.restore();
+ mockImportNodeCrypto.restore();
+});
diff --git a/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts b/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts
index 07ca8f8..fe86219 100644
--- a/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts
+++ b/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts
@@ -15,7 +15,7 @@ export async function getWebCrypto(): Promise<Crypto> {
* Naively attempt to access Crypto as a global object, which popular alternative run-times
* support.
*/
- const _crypto = globalThis.crypto;
+ const _crypto = _getWebCryptoInternals.stubThisGlobalThisCrypto();
if (_crypto) {
webCrypto = _crypto;
@@ -40,7 +40,7 @@ export async function getWebCrypto(): Promise<Crypto> {
throw new MissingWebCrypto();
}
-class MissingWebCrypto extends Error {
+export class MissingWebCrypto extends Error {
constructor() {
const message = 'An instance of the Crypto API could not be located';
super(message);
@@ -52,4 +52,9 @@ class MissingWebCrypto extends Error {
export const _getWebCryptoInternals = {
// dnt-shim-ignore
stubThisImportNodeCrypto: () => import('node:crypto'),
+ stubThisGlobalThisCrypto: () => globalThis.crypto,
+ // Make it possible to reset the `webCrypto` at the top of the file
+ setCachedCrypto: (newCrypto: Crypto | undefined) => {
+ webCrypto = newCrypto;
+ },
};