-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(crypto): added a hook for utilizing the crypto.subtle api
- Loading branch information
1 parent
69d6542
commit 26859a9
Showing
8 changed files
with
109 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/swcrc", | ||
"sourceMaps": true, | ||
"jsc": { | ||
"parser": { | ||
"syntax": "typescript", | ||
"tsx": true | ||
}, | ||
"transform": { | ||
"react": { | ||
"runtime": "automatic" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,19 @@ | ||
import type { JestConfigWithTsJest } from 'ts-jest'; | ||
import type { Config } from 'jest'; | ||
import { readFileSync } from 'fs'; | ||
|
||
const jestConfig: JestConfigWithTsJest = { | ||
const config = JSON.parse(readFileSync(`${__dirname}/.swcrc`, 'utf-8')); | ||
|
||
export default { | ||
roots: ['<rootDir>/src'], | ||
testEnvironment: 'jsdom', | ||
testEnvironment: '@happy-dom/jest-environment', | ||
|
||
transform: { | ||
'^.+\\.tsx?$': [ | ||
'ts-jest', | ||
{ | ||
tsconfig: 'tsconfig.json', | ||
}, | ||
], | ||
'^.+\\.(t|j)sx?$': ['@swc/jest', config], | ||
}, | ||
|
||
setupFiles: ['@inrupt/jest-jsdom-polyfills'], | ||
collectCoverageFrom: ['<rootDir>/src/**/*'], | ||
|
||
coveragePathIgnorePatterns: ['__tests__'], | ||
|
||
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], | ||
}; | ||
|
||
export default jestConfig; | ||
extensionsToTreatAsEsm: ['.ts', '.tsx'], | ||
} satisfies Config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { render, waitFor } from '@testing-library/react'; | ||
import Chance from 'chance'; | ||
import { useSubtleCrypto } from '../use-subtle-crypto'; | ||
import { hash } from '../../utils/subtle-crypto'; | ||
|
||
const chance = new Chance(); | ||
|
||
describe('Crypto Hooks', () => { | ||
describe('hook(useSubtleCrypto)', () => { | ||
type ExampleComponentProps = { | ||
value: string; | ||
}; | ||
|
||
function ExampleComponent({ value }: ExampleComponentProps) { | ||
const hashedValue = useSubtleCrypto('SHA-256', value); | ||
|
||
return <div data-testid="example">{hashedValue}</div>; | ||
} | ||
|
||
it('should cache the value', async () => { | ||
const value = chance.string(); | ||
const expectedValue = await hash('SHA-256', value); | ||
|
||
const component = render(<ExampleComponent value={value} />); | ||
|
||
await waitFor(() => expect(component.getByText(expectedValue)).toBeTruthy()); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { useEffect, useState } from 'react'; | ||
import { Algorithms, hash } from '../utils/subtle-crypto'; | ||
|
||
/** | ||
* Returns a hashed version of the value provided | ||
* @param algorithm the hashing algorithm to use | ||
* @param value the value to hash | ||
* @returns the hashed value | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#browser_compatibility | ||
*/ | ||
export function useSubtleCrypto(algorithm: Algorithms, value?: string | null): string | undefined { | ||
const [hashedValue, setHashedValue] = useState<string>(); | ||
|
||
useEffect(() => { | ||
if (value) { | ||
hash(algorithm, value).then(setHashedValue); | ||
} | ||
}, [algorithm, value]); | ||
|
||
return hashedValue; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Algorithms, hash } from '../../utils/subtle-crypto'; | ||
|
||
describe('Crypto Utils', () => { | ||
describe('fn(hash)', () => { | ||
it.each([ | ||
['SHA-1', 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3'], | ||
['SHA-256', '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'], | ||
['SHA-384', '768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9'], | ||
[ | ||
'SHA-512', | ||
'ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff', | ||
], | ||
])('should support %s', async (algorithm: Algorithms, expectedValue: string) => { | ||
await expect(hash(algorithm, 'test')).resolves.toEqual(expectedValue); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export type Algorithms = 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512'; | ||
|
||
export async function hash(algorithm: Algorithms, message: string): Promise<string> { | ||
const msgBuffer = new TextEncoder().encode(message); | ||
|
||
// hash the message | ||
const hashBuffer = await crypto.subtle.digest(algorithm, msgBuffer); | ||
|
||
// convert ArrayBuffer to Array | ||
const hashArray = Array.from(new Uint8Array(hashBuffer)); | ||
|
||
// convert bytes to hex string | ||
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
} |