-
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
- temporarily lock semantic-release to v22
- Loading branch information
1 parent
69d6542
commit 14d464c
Showing
10 changed files
with
139 additions
and
19 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
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,16 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/swcrc", | ||
"sourceMaps": "inline", | ||
"jsc": { | ||
"target": "es2022", | ||
"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
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 = { | ||
// Changed sourcemaps to inline resolving issues with https://github.com/swc-project/swc/issues/3854 | ||
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], | ||
}, | ||
|
||
collectCoverageFrom: ['<rootDir>/src/**/*'], | ||
|
||
coveragePathIgnorePatterns: ['__tests__'], | ||
|
||
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], | ||
}; | ||
|
||
export default jestConfig; | ||
setupFilesAfterEnv: ['@inrupt/jest-jsdom-polyfills', '@testing-library/jest-dom/extend-expect'], | ||
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,19 @@ | ||
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(() => { | ||
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,25 @@ | ||
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); | ||
}); | ||
|
||
it('should support being provided null', async () => { | ||
await expect(hash('SHA-256', null)).resolves.toEqual(null); | ||
}); | ||
|
||
it('should support being provided undefined', async () => { | ||
await expect(hash('SHA-256', undefined)).resolves.toEqual(null); | ||
}); | ||
}); | ||
}); |
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,16 @@ | ||
export type Algorithms = 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512'; | ||
|
||
export async function hash(algorithm: Algorithms, message?: string): Promise<string> { | ||
if (!message) return null; | ||
|
||
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(''); | ||
} |