chore: fall back when id_generator return wrong uuidv4#320
chore: fall back when id_generator return wrong uuidv4#320duyhungtnn wants to merge 11 commits intomainfrom
Conversation
Validate and prefer native crypto.randomUUID but fallback to a compliant UUIDv4 generator using crypto.getRandomValues. Adds UUID v4 regex, a createUuidV4 helper, and logic to call randomUUID only if it returns a valid v4 string. Adds tests covering the native-valid and native-invalid cases, and updates test setup to provide webcrypto.getRandomValues on global.self.crypto.
Introduce a module-level useNativeRandomUUID IIFE that checks once whether globalThis.crypto.randomUUID is available and returns a valid UUIDv4, and simplify BrowserIdGenerator.newId to use this cached boolean instead of validating every call. Update tests to reset modules and dynamically import the generator so the IIFE runs per test, add explicit UUIDv4 regex specs, and add tests covering: valid native randomUUID, invalid-version randomUUID fallback, absent randomUUID behavior, that validity is only checked once at module init, and that the getRandomValues fallback is used on every newId() when randomUUID is unavailable.
There was a problem hiding this comment.
Pull request overview
This PR hardens the browser-side ID generator against environments where crypto.randomUUID() can return non–RFC 4122 v4 UUIDs (notably Edge Enterprise under certain IT policies) by validating randomUUID output once at module load and falling back to a local v4 generator using crypto.getRandomValues().
Changes:
- Add UUID v4 validation and a
getRandomValues-based UUID v4 fallback inBrowserIdGenerator. - Update browser test setup to provide
crypto.getRandomValuesin the happy-dom environment. - Add unit tests covering native-vs-fallback selection behavior for the browser ID generator.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
src/internal/IdGenerator.browser.ts |
Validates crypto.randomUUID() output and falls back to a local RFC 4122 v4 generator via getRandomValues. |
test/setup.browser.ts |
Polyfills the browser test environment with crypto.randomUUID and crypto.getRandomValues. |
test/internal/IdGenerator.browser.spec.ts |
Adds tests for v4 validation and fallback behavior (module-init probe + per-call behavior). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Wrap crypto.randomUUID() usage in a try/catch so environments that throw (e.g. insecure contexts or policy-restricted runtimes) are treated as lacking native randomUUID. Clarify comments about getRandomValues being available as a fallback, polyfill behavior, and reliability signals. Adjust the test to directly assert crypto.randomUUID() matches the UUID v4 regex (removing the conditional), surfacing unsupported environments in CI. Minor comment cleanups included.
Export the UUID_V4_REGEX constant from src/internal/IdGenerator.browser.ts and update the browser test to import it instead of redefining the regex. This removes duplication and centralizes the UUID v4 pattern for reuse in tests.
There was a problem hiding this comment.
Pull request overview
Adds a defensive fallback for browser UUID generation to handle environments (notably Edge Enterprise 105 under certain policies) where crypto.randomUUID() can return a non-v4 UUID, ensuring IDs remain RFC 4122 v4 compliant.
Changes:
- Implement UUID v4 validation and a
getRandomValues-based UUID v4 generator fallback in the browser ID generator. - Update browser test setup to provide
crypto.getRandomValuesin the browser test environment. - Add unit tests covering valid native UUIDs, invalid UUIDs (e.g. v3), and missing/invalid
randomUUIDscenarios.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/internal/IdGenerator.browser.ts |
Validates native randomUUID() once at module init; falls back to an RFC 4122 v4 generator using getRandomValues. |
test/setup.browser.ts |
Extends browser test crypto shim to include getRandomValues. |
test/internal/IdGenerator.browser.spec.ts |
Adds coverage for UUID v4 regex validation and native-vs-fallback behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add spies and expectations in test/internal/IdGenerator.browser.spec.ts to verify that crypto.getRandomValues is invoked when generating IDs. Ensures BrowserIdGenerator falls back to getRandomValues in cases where randomUUID is stubbed, undefined, or not a function.
There was a problem hiding this comment.
Pull request overview
This PR hardens the browser-side ID generation to ensure UUIDs sent to the backend are RFC 4122 v4, even when crypto.randomUUID() is missing, throws, or returns a non-v4 UUID in certain environments (e.g., Edge Enterprise / patched APIs).
Changes:
- Add UUID v4 validation and a
getRandomValues-based UUID v4 generator fallback inBrowserIdGenerator. - Update browser test setup to expose
crypto.getRandomValuesin the test environment. - Add browser-focused tests covering v4 validation and fallback behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/internal/IdGenerator.browser.ts |
Adds v4 regex validation, getRandomValues UUIDv4 generator, and native/fallback selection logic. |
test/setup.browser.ts |
Extends test crypto shim to include getRandomValues for fallback-path tests. |
test/internal/IdGenerator.browser.spec.ts |
Adds test coverage for v4 regex and fallback behavior under various randomUUID failure modes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
This PR hardens the browser ID generator by verifying that crypto.randomUUID() yields an RFC4122 UUID v4 at module initialization time and falling back to a getRandomValues-based v4 generator when it doesn’t.
Changes:
- Add
UUID_V4_REGEXand use it to validatecrypto.randomUUID()output during module init inBrowserIdGenerator. - Implement an internal
getRandomValues-based UUID v4 generator for the browser fallback path. - Add browser-focused tests for the validation + fallback behavior and update the browser test setup to provide
crypto.getRandomValues.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/internal/IdGenerator.browser.ts |
Adds module-init validation of native randomUUID and a getRandomValues fallback UUID v4 generator. |
src/utils/regex.ts |
Introduces a shared UUID v4 validation regex constant. |
test/setup.browser.ts |
Extends the browser test crypto shim to include getRandomValues. |
test/internal/IdGenerator.browser.spec.ts |
Adds test coverage for UUID v4 regex behavior and native-vs-fallback selection logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Small comment update in BrowserIdGenerator: removed the phrase "throws or" so the comment only references randomUUID returning a malformed UUID at runtime. This is a documentation-only tweak to clarify expected runtime failure mode; no functional change.
There was a problem hiding this comment.
Pull request overview
This PR hardens the browser ID generation path to ensure generated event IDs are valid RFC 4122 UUID v4 values, even when crypto.randomUUID() is unavailable or returns a non-v4 UUID.
Changes:
- Add a UUID v4 validator (
UUID_V4_REGEX) and use it at module load to decide whether to trustcrypto.randomUUID(). - Implement a UUID v4 generator based on
crypto.getRandomValues()as a fallback. - Extend browser test setup to provide
crypto.getRandomValuesand add browser-focused tests covering the new fallback behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/setup.browser.ts | Adds crypto.getRandomValues to the happy-dom test crypto shim. |
| test/internal/IdGenerator.browser.spec.ts | New tests verifying v4 validation, fallback selection, and call-count behavior. |
| src/utils/regex.ts | Introduces UUID_V4_REGEX used to validate UUID v4 format. |
| src/internal/IdGenerator.browser.ts | Adds v4 validation + getRandomValues-based fallback UUID generator. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Both APIs can be polyfilled, but if `getRandomValues` is broken, many other | ||
| // web APIs will likely be broken too — making it a more reliable signal of a | ||
| // non-compliant environment. | ||
|
|
There was a problem hiding this comment.
Thanks, but I don’t think we will handle this case. When this happens, all UUID libraries available on npm are also broken.
#319
Issue:
crypto.randomUUIDmay return non-v4 UUIDs in certain environmentscrypto.randomUUIDis a high-level API that returns a formatted UUID string, but its output is not guaranteed to always be a v4 UUID in every environment:randomUUIDis restricted to secure contexts and will throw or be undefined, whilegetRandomValuescontinues to work.randomUUID.crypto.randomUUIDon the page context, producing non-standard output.randomUUIDincorrectly and return a non-v4 UUID.randomUUIDat all (it was added in Chrome 92 / Safari 15.4).Why do we still trust
crypto.getRandomValues?getRandomValuesourselves, so the output format is always under our control.getRandomValuesis the only crypto API guaranteed to work in insecure contexts.getRandomValuesis broken, many other web APIs will likely be broken too — making it a more reliable signal of a non-compliant environment.What changed:
The SDK validates the output of
crypto.randomUUIDat module load time. If the value is not a valid v4 UUID (or if the call fails), we fall back to our internal UUID v4 generator built ongetRandomValues.