From f4ac06bbe71e12a2de218e498e084b898caac87c Mon Sep 17 00:00:00 2001 From: htranho Date: Mon, 29 Sep 2025 18:43:05 -0400 Subject: [PATCH 1/3] MMT-4087: Replace crypto call to get uuid by v4 --- serverless/src/createTemplate/handler.js | 4 ++-- .../components/ErrorPageNotFound/ErrorPageNotFound.jsx | 4 +++- .../__tests__/ErrorPageNotFound.test.jsx | 6 ++---- static/src/js/components/MetadataForm/MetadataForm.jsx | 5 +++-- .../js/components/PublishPreview/PublishPreview.jsx | 3 ++- static/src/js/components/TemplateForm/TemplateForm.jsx | 3 ++- .../js/components/TemplatePreview/TemplatePreview.jsx | 3 ++- static/src/js/pages/DraftListPage/DraftListPage.jsx | 3 ++- test-setup.js | 10 ++++------ vite.config.js | 8 +++++++- 10 files changed, 29 insertions(+), 20 deletions(-) diff --git a/serverless/src/createTemplate/handler.js b/serverless/src/createTemplate/handler.js index fa3f17e14..774c24f96 100644 --- a/serverless/src/createTemplate/handler.js +++ b/serverless/src/createTemplate/handler.js @@ -1,5 +1,5 @@ import { PutObjectCommand } from '@aws-sdk/client-s3' -import crypto from 'crypto' +import { v4 as uuidv4 } from 'uuid' import { getApplicationConfig } from '../../../sharedUtils/getConfig' import { getS3Client } from '../utils/getS3Client' @@ -22,7 +22,7 @@ const createTemplate = async (event) => { const { TemplateName: templateName } = JSON.parse(body) const hashedName = Buffer.from(templateName).toString('base64') - const guid = crypto.randomUUID() + const guid = uuidv4() const { COLLECTION_TEMPLATES_BUCKET_NAME: collectionTemplatesBucketName } = process.env const createCommand = new PutObjectCommand({ diff --git a/static/src/js/components/ErrorPageNotFound/ErrorPageNotFound.jsx b/static/src/js/components/ErrorPageNotFound/ErrorPageNotFound.jsx index 014f54beb..3e4d6a081 100644 --- a/static/src/js/components/ErrorPageNotFound/ErrorPageNotFound.jsx +++ b/static/src/js/components/ErrorPageNotFound/ErrorPageNotFound.jsx @@ -1,5 +1,7 @@ import React from 'react' +import { v4 as uuidv4 } from 'uuid' + import errorLogger from '@/js/utils/errorLogger' import Header from '../Header/Header' @@ -7,7 +9,7 @@ import Header from '../Header/Header' import './ErrorPageNotFound.scss' const ErrorPageNotFound = () => { - const guid = crypto.randomUUID() + const guid = uuidv4() errorLogger(`404 Not Found see ${guid}`, 'user attempted to access a page that does not exist') diff --git a/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx b/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx index 806973f9f..aa4883cf7 100644 --- a/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx +++ b/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx @@ -11,10 +11,8 @@ import AuthContext from '@/js/context/AuthContext' import ErrorPageNotFound from '../ErrorPageNotFound' vi.mock('@/js/utils/errorLogger') -vi.mock('crypto', () => ({ - default: { - randomUUID: () => 'mock-uuid' - } +vi.mock('uuid', () => ({ + v4: () => 'mock-uuid' })) const setup = () => { diff --git a/static/src/js/components/MetadataForm/MetadataForm.jsx b/static/src/js/components/MetadataForm/MetadataForm.jsx index f1d6c8533..c4507e851 100644 --- a/static/src/js/components/MetadataForm/MetadataForm.jsx +++ b/static/src/js/components/MetadataForm/MetadataForm.jsx @@ -9,6 +9,7 @@ import pluralize from 'pluralize' import React, { useEffect, useState } from 'react' import Row from 'react-bootstrap/Row' import validator from '@rjsf/validator-ajv8' +import { v4 as uuidv4 } from 'uuid' import BoundingRectangleField from '@/js/components/BoundingRectangleField/BoundingRectangleField' import CustomArrayTemplate from '@/js/components/CustomArrayFieldTemplate/CustomArrayFieldTemplate' @@ -164,8 +165,8 @@ const MetadataForm = () => { // Add '-draft' to the end of nativeId if it doesn't already end with it. // Can be removed after CMR-10545 is complete derivedConceptType === 'Visualization' || derivedConceptType === 'Citation' - ? `MMT_${crypto.randomUUID()}-draft` - : `MMT_${crypto.randomUUID()}` + ? `MMT_${uuidv4()}-draft` + : `MMT_${uuidv4()}` ) const schema = getUmmSchema(derivedConceptType) diff --git a/static/src/js/components/PublishPreview/PublishPreview.jsx b/static/src/js/components/PublishPreview/PublishPreview.jsx index 377fff11f..ec40a2627 100644 --- a/static/src/js/components/PublishPreview/PublishPreview.jsx +++ b/static/src/js/components/PublishPreview/PublishPreview.jsx @@ -20,6 +20,7 @@ import { FaEye, FaTrash } from 'react-icons/fa' +import { v4 as uuidv4 } from 'uuid' import conceptTypeQueries from '@/js//constants/conceptTypeQueries' import deleteMutationTypes from '@/js//constants/deleteMutationTypes' @@ -138,7 +139,7 @@ const PublishPreviewHeader = () => { // Calls ingestDraft mutation with a new nativeId const handleClone = () => { - const cloneNativeId = `MMT_${crypto.randomUUID()}` + const cloneNativeId = `MMT_${uuidv4()}` // Removes the value from the metadata that has to be unique const modifiedMetadata = removeMetadataKeys(ummMetadata, ['Name', 'LongName', 'ShortName', 'EntryTitle']) diff --git a/static/src/js/components/TemplateForm/TemplateForm.jsx b/static/src/js/components/TemplateForm/TemplateForm.jsx index 9d0b99c5a..3b129caf6 100644 --- a/static/src/js/components/TemplateForm/TemplateForm.jsx +++ b/static/src/js/components/TemplateForm/TemplateForm.jsx @@ -6,6 +6,7 @@ import Row from 'react-bootstrap/Row' import Form from '@rjsf/core' import validator from '@rjsf/validator-ajv8' import { isEmpty, kebabCase } from 'lodash-es' +import { v4 as uuidv4 } from 'uuid' import useAppContext from '@/js/hooks/useAppContext' @@ -217,7 +218,7 @@ const TemplateForm = () => { } if (type === saveTypes.saveAndCreateDraft) { - const nativeId = `MMT_${crypto.randomUUID()}` + const nativeId = `MMT_${uuidv4()}` delete ummMetadata.TemplateName diff --git a/static/src/js/components/TemplatePreview/TemplatePreview.jsx b/static/src/js/components/TemplatePreview/TemplatePreview.jsx index b1a26916a..fe3f12fac 100644 --- a/static/src/js/components/TemplatePreview/TemplatePreview.jsx +++ b/static/src/js/components/TemplatePreview/TemplatePreview.jsx @@ -7,6 +7,7 @@ import validator from '@rjsf/validator-ajv8' import camelcaseKeys from 'camelcase-keys' import { FaCopy, FaTrash } from 'react-icons/fa' import { CollectionPreview } from '@edsc/metadata-preview' +import { v4 as uuidv4 } from 'uuid' import collectionsTemplateConfiguration from '@/js/schemas/uiForms/collectionTemplatesConfiguration' import ummCTemplateSchema from '@/js/schemas/umm/ummCTemplateSchema' @@ -109,7 +110,7 @@ const TemplatePreview = () => { const handleCreateCollectionDraft = () => { const { ummMetadata } = draft - const nativeId = `MMT_${crypto.randomUUID()}` + const nativeId = `MMT_${uuidv4()}` delete ummMetadata.TemplateName diff --git a/static/src/js/pages/DraftListPage/DraftListPage.jsx b/static/src/js/pages/DraftListPage/DraftListPage.jsx index aea17c321..73955e9bf 100644 --- a/static/src/js/pages/DraftListPage/DraftListPage.jsx +++ b/static/src/js/pages/DraftListPage/DraftListPage.jsx @@ -1,6 +1,7 @@ import React, { Suspense, useState } from 'react' import { useNavigate, useParams } from 'react-router' import { FaPlus, FaFileUpload } from 'react-icons/fa' +import { v4 as uuidv4 } from 'uuid' import urlValueTypeToConceptTypeStringMap from '@/js/constants/urlValueToConceptStringMap' @@ -67,7 +68,7 @@ const DraftListPageHeader = () => { variables: { conceptType, metadata: removeEmpty(draftToSave), - nativeId: `MMT_${crypto.randomUUID()}`, + nativeId: `MMT_${uuidv4()}`, providerId, ummVersion: getUmmVersion(conceptType) }, diff --git a/test-setup.js b/test-setup.js index 75276cdac..d5fdd3366 100644 --- a/test-setup.js +++ b/test-setup.js @@ -16,14 +16,12 @@ vi.mock('lodash-es', async () => ({ debounce: vi.fn((fn) => fn) })) -vi.mock('crypto', () => ({ - default: { - randomUUID: () => 'mock-uuid' - } +vi.mock('uuid', () => ({ + v4: () => 'mock-uuid' })) -Object.defineProperty(globalThis, 'crypto', { +Object.defineProperty(globalThis, 'uuid', { value: { - randomUUID: () => 'mock-uuid' + v4: () => 'mock-uuid' } }) diff --git a/vite.config.js b/vite.config.js index 2b80eeda5..72ff5e058 100644 --- a/vite.config.js +++ b/vite.config.js @@ -14,7 +14,13 @@ const { enabled, propertyId } = localIdentifier export default defineConfig({ plugins: [ react(), - nodePolyfills(), + nodePolyfills({ + include: [ + 'buffer', + 'stream', + 'util' + ] + }), ViteEjsPlugin({ gtmPropertyId, environment: process.env.NODE_ENV || 'development', From 9edae3e18b95f05d060a57d46410cd0f00a80a45 Mon Sep 17 00:00:00 2001 From: Ed Olivares <34591886+eudoroolivares2016@users.noreply.github.com> Date: Mon, 6 Oct 2025 15:20:14 -0400 Subject: [PATCH 2/3] MMT-4087: Running npm audit fix --- package-lock.json | 137 ---------------------------------------------- 1 file changed, 137 deletions(-) diff --git a/package-lock.json b/package-lock.json index 14c224be3..7cdc00424 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9240,30 +9240,6 @@ "node": ">=0.1.90" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@csstools/css-parser-algorithms": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.2.tgz", @@ -13979,34 +13955,6 @@ "node": ">=10.13.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "optional": true, - "peer": true - }, "node_modules/@types/aria-query": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.2.tgz", @@ -15253,13 +15201,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "optional": true, - "peer": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -18630,16 +18571,6 @@ "node": ">=4.5.0" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "optional": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -24249,13 +24180,6 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "optional": true, - "peer": true - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -31720,50 +31644,6 @@ "node": ">=8" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -32373,13 +32253,6 @@ "uuid": "dist/esm/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "optional": true, - "peer": true - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -34554,16 +34427,6 @@ "node": ">= 4.0.0" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", From bc901b7f2b842e0e1f09f0876da29747fea6295d Mon Sep 17 00:00:00 2001 From: Ed Olivares <34591886+eudoroolivares2016@users.noreply.github.com> Date: Mon, 6 Oct 2025 19:21:12 -0400 Subject: [PATCH 3/3] MMT-4087: Do not need mock because its being called in jest.config --- .../ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx b/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx index aa4883cf7..0a8ebf651 100644 --- a/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx +++ b/static/src/js/components/ErrorPageNotFound/__tests__/ErrorPageNotFound.test.jsx @@ -11,9 +11,6 @@ import AuthContext from '@/js/context/AuthContext' import ErrorPageNotFound from '../ErrorPageNotFound' vi.mock('@/js/utils/errorLogger') -vi.mock('uuid', () => ({ - v4: () => 'mock-uuid' -})) const setup = () => { const context = {