From 157665d4f5342fe82cafa15aa508a66f564f9680 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Wed, 16 Oct 2024 08:19:16 -0500 Subject: [PATCH 01/19] added remove versions file that gets run after build --- services/ui-src/package.json | 2 +- services/ui-src/remove-versions.js | 37 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 services/ui-src/remove-versions.js diff --git a/services/ui-src/package.json b/services/ui-src/package.json index e9cb3cc62..2198670f2 100644 --- a/services/ui-src/package.json +++ b/services/ui-src/package.json @@ -41,7 +41,7 @@ }, "scripts": { "start": "react-scripts start", - "build": "react-scripts build", + "build": "react-scripts build && node remove-version.js", "test": "react-scripts test --unhandled-rejections=strict", "eject": "react-scripts eject" }, diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js new file mode 100644 index 000000000..7457a65e8 --- /dev/null +++ b/services/ui-src/remove-versions.js @@ -0,0 +1,37 @@ +const fs = require('fs'); +const path = require('path'); + +// Define the directory of the build output +const buildDir = path.join(__dirname, 'build', 'static', 'js'); + +// Define the regular expression to match the version pattern +const regex = /\b\d+\.\d+\.\d+\b/g; + +// Function to remove the version from files +const removeVersionFromFiles = (dir) => { + fs.readdir(dir, (err, files) => { + if (err) throw err; + + files.forEach(file => { + const filePath = path.join(dir, file); + + // Check if the file is a JavaScript file + if (file.endsWith('.js')) { + fs.readFile(filePath, 'utf8', (err, data) => { + if (err) throw err; + + // Replace the version pattern + const result = data.replace(regex, ''); + + // Write the modified content back to the file + fs.writeFile(filePath, result, 'utf8', (err) => { + if (err) throw err; + console.log(`Removed version from ${file}`); + }); + }); + } + }); + }); +}; + +removeVersionFromFiles(buildDir); From b62783fc863d7881cb56550647ff15ca029b20dc Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Wed, 16 Oct 2024 10:12:14 -0500 Subject: [PATCH 02/19] added s to match actual file name --- services/ui-src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ui-src/package.json b/services/ui-src/package.json index 2198670f2..4913b861a 100644 --- a/services/ui-src/package.json +++ b/services/ui-src/package.json @@ -41,7 +41,7 @@ }, "scripts": { "start": "react-scripts start", - "build": "react-scripts build && node remove-version.js", + "build": "react-scripts build && node remove-versions.js", "test": "react-scripts test --unhandled-rejections=strict", "eject": "react-scripts eject" }, From b628d3a2bb1a0eb894f090c71c0b56a61250cfc4 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Wed, 16 Oct 2024 21:16:57 -0500 Subject: [PATCH 03/19] only strip versions that start with 4, specific to loadash --- services/ui-src/remove-versions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index 7457a65e8..b0eab29b0 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -5,7 +5,7 @@ const path = require('path'); const buildDir = path.join(__dirname, 'build', 'static', 'js'); // Define the regular expression to match the version pattern -const regex = /\b\d+\.\d+\.\d+\b/g; +const regex = /^4\.\d{1,2}\.\d{1,2}$/; // Function to remove the version from files const removeVersionFromFiles = (dir) => { From 0ee47fbcfe7d45e16f55bb6592453b93fe5d95ee Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Wed, 16 Oct 2024 21:42:24 -0500 Subject: [PATCH 04/19] match occurences not exact string match --- services/ui-src/remove-versions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index b0eab29b0..657f9919e 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -5,7 +5,7 @@ const path = require('path'); const buildDir = path.join(__dirname, 'build', 'static', 'js'); // Define the regular expression to match the version pattern -const regex = /^4\.\d{1,2}\.\d{1,2}$/; +const regex = /4\.\d{1,2}\.\d{1,2}/g; // Added 'g' flag for global matching // Function to remove the version from files const removeVersionFromFiles = (dir) => { @@ -21,7 +21,7 @@ const removeVersionFromFiles = (dir) => { if (err) throw err; // Replace the version pattern - const result = data.replace(regex, ''); + const result = data.replace(regex, ''); // Remove matched versions // Write the modified content back to the file fs.writeFile(filePath, result, 'utf8', (err) => { @@ -34,4 +34,4 @@ const removeVersionFromFiles = (dir) => { }); }; -removeVersionFromFiles(buildDir); +removeVersionFromFiles(buildDir); \ No newline at end of file From cb65bbf0dc07951723c55b68813aa5179059442d Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Wed, 16 Oct 2024 22:08:16 -0500 Subject: [PATCH 05/19] only match 4.17. any number --- services/ui-src/remove-versions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index 657f9919e..e584bee83 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -4,8 +4,8 @@ const path = require('path'); // Define the directory of the build output const buildDir = path.join(__dirname, 'build', 'static', 'js'); -// Define the regular expression to match the version pattern -const regex = /4\.\d{1,2}\.\d{1,2}/g; // Added 'g' flag for global matching +// Define the regular expression to match the version pattern 4.17.xx +const regex = /4\.17\.\d{2}/g; // Matches versions like 4.17.01, 4.17.99 // Function to remove the version from files const removeVersionFromFiles = (dir) => { From 78d0f2e3796dab470bf4e75c913cf9791a10fa35 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Wed, 16 Oct 2024 22:28:32 -0500 Subject: [PATCH 06/19] 4.xx.yy where xx is any number 17 or above --- services/ui-src/remove-versions.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index e584bee83..f0b842163 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -4,8 +4,9 @@ const path = require('path'); // Define the directory of the build output const buildDir = path.join(__dirname, 'build', 'static', 'js'); -// Define the regular expression to match the version pattern 4.17.xx -const regex = /4\.17\.\d{2}/g; // Matches versions like 4.17.01, 4.17.99 +// Define the regular expression to match the version pattern 4.xx.yy +// where xx is 17 or above and yy is any two-digit number +const regex = /4\.(1[7-9]|[2-9][0-9])\.\d{2}/g; // Matches versions like 4.17.01, 4.25.99 // Function to remove the version from files const removeVersionFromFiles = (dir) => { @@ -34,4 +35,4 @@ const removeVersionFromFiles = (dir) => { }); }; -removeVersionFromFiles(buildDir); \ No newline at end of file +removeVersionFromFiles(buildDir); From a104eac90419e880d48d570098ee4bc033e39df0 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Thu, 17 Oct 2024 11:19:06 -0500 Subject: [PATCH 07/19] change regex to include any version 4.17 or above --- services/ui-src/remove-versions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index f0b842163..d521776ce 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -4,9 +4,9 @@ const path = require('path'); // Define the directory of the build output const buildDir = path.join(__dirname, 'build', 'static', 'js'); -// Define the regular expression to match the version pattern 4.xx.yy -// where xx is 17 or above and yy is any two-digit number -const regex = /4\.(1[7-9]|[2-9][0-9])\.\d{2}/g; // Matches versions like 4.17.01, 4.25.99 +// Define the regular expression to match the version pattern z.xx.yy +// where if the first z is 4, xx is 17 or above; if z>=5, xx can be anything; +const regex = /(4\.(1[7-9]|[2-9][0-9])|5\.\d{2}|[6-9]\.\d{2})\.\d{2}/g; // Matches versions like 4.17.01, 5.25.99, 7.10.87 // Function to remove the version from files const removeVersionFromFiles = (dir) => { From d1b55f17f32d9c1fffb06cc8a012bf2aeffdc256 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 10:58:21 -0500 Subject: [PATCH 08/19] only remove version if it occurs after Bn.VERSION --- services/ui-src/remove-versions.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index d521776ce..0f907b828 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -4,9 +4,9 @@ const path = require('path'); // Define the directory of the build output const buildDir = path.join(__dirname, 'build', 'static', 'js'); -// Define the regular expression to match the version pattern z.xx.yy -// where if the first z is 4, xx is 17 or above; if z>=5, xx can be anything; -const regex = /(4\.(1[7-9]|[2-9][0-9])|5\.\d{2}|[6-9]\.\d{2})\.\d{2}/g; // Matches versions like 4.17.01, 5.25.99, 7.10.87 +// Define the regular expression to match the version pattern +// where the match occurs right after Bn.VERSION = " +const regex = /(?<=Bn\.VERSION = ")(4\.(1[7-9]|[2-9][0-9])\.\d{2}|5\.\d{2}\.\d{2}|[6-9]\.\d{2}\.\d{2})/g; // Matches versions like 4.17.01, 5.25.99, 9.10.11 // Function to remove the version from files const removeVersionFromFiles = (dir) => { @@ -21,7 +21,7 @@ const removeVersionFromFiles = (dir) => { fs.readFile(filePath, 'utf8', (err, data) => { if (err) throw err; - // Replace the version pattern + // Replace the version pattern only after Bn.VERSION = " const result = data.replace(regex, ''); // Remove matched versions // Write the modified content back to the file From 79747209e13f0358cf0d8dcbd3e706a695a62a44 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 11:26:43 -0500 Subject: [PATCH 09/19] only remove version if it occurs after Bn.VERSION --- services/ui-src/remove-versions.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index 0f907b828..0f8c73ed4 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -5,8 +5,8 @@ const path = require('path'); const buildDir = path.join(__dirname, 'build', 'static', 'js'); // Define the regular expression to match the version pattern -// where the match occurs right after Bn.VERSION = " -const regex = /(?<=Bn\.VERSION = ")(4\.(1[7-9]|[2-9][0-9])\.\d{2}|5\.\d{2}\.\d{2}|[6-9]\.\d{2}\.\d{2})/g; // Matches versions like 4.17.01, 5.25.99, 9.10.11 +// Specifically targeting the line with Bn.VERSION +const regex = /(Bn\.VERSION = ")(4\.(1[7-9]|[2-9][0-9])\.\d{2}|5\.\d{2}\.\d{2}|[6-9]\.\d{2}\.\d{2})(")/g; // Function to remove the version from files const removeVersionFromFiles = (dir) => { @@ -22,7 +22,7 @@ const removeVersionFromFiles = (dir) => { if (err) throw err; // Replace the version pattern only after Bn.VERSION = " - const result = data.replace(regex, ''); // Remove matched versions + const result = data.replace(regex, '$1"$4'); // Keep the surrounding parts and replace the version // Write the modified content back to the file fs.writeFile(filePath, result, 'utf8', (err) => { @@ -36,3 +36,4 @@ const removeVersionFromFiles = (dir) => { }; removeVersionFromFiles(buildDir); + From 7ba174fa788dd76e3ae666406337f8a160a51bc1 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 11:49:21 -0500 Subject: [PATCH 10/19] change to NEW_VERSION instead --- services/ui-src/remove-versions.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index 0f8c73ed4..ae78cfb0e 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -5,7 +5,7 @@ const path = require('path'); const buildDir = path.join(__dirname, 'build', 'static', 'js'); // Define the regular expression to match the version pattern -// Specifically targeting the line with Bn.VERSION +// specifically targeting the line with Bn.VERSION const regex = /(Bn\.VERSION = ")(4\.(1[7-9]|[2-9][0-9])\.\d{2}|5\.\d{2}\.\d{2}|[6-9]\.\d{2}\.\d{2})(")/g; // Function to remove the version from files @@ -22,7 +22,7 @@ const removeVersionFromFiles = (dir) => { if (err) throw err; // Replace the version pattern only after Bn.VERSION = " - const result = data.replace(regex, '$1"$4'); // Keep the surrounding parts and replace the version + const result = data.replace(regex, '$1"NEW_VERSION"$4'); // Replace version with NEW_VERSION // Write the modified content back to the file fs.writeFile(filePath, result, 'utf8', (err) => { @@ -36,4 +36,3 @@ const removeVersionFromFiles = (dir) => { }; removeVersionFromFiles(buildDir); - From 98720100823ac9a2eef609df46f6811e39e1f631 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 12:40:46 -0500 Subject: [PATCH 11/19] try .replace instead --- services/ui-src/remove-versions.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index ae78cfb0e..81ec8bc64 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -4,10 +4,6 @@ const path = require('path'); // Define the directory of the build output const buildDir = path.join(__dirname, 'build', 'static', 'js'); -// Define the regular expression to match the version pattern -// specifically targeting the line with Bn.VERSION -const regex = /(Bn\.VERSION = ")(4\.(1[7-9]|[2-9][0-9])\.\d{2}|5\.\d{2}\.\d{2}|[6-9]\.\d{2}\.\d{2})(")/g; - // Function to remove the version from files const removeVersionFromFiles = (dir) => { fs.readdir(dir, (err, files) => { @@ -21,8 +17,8 @@ const removeVersionFromFiles = (dir) => { fs.readFile(filePath, 'utf8', (err, data) => { if (err) throw err; - // Replace the version pattern only after Bn.VERSION = " - const result = data.replace(regex, '$1"NEW_VERSION"$4'); // Replace version with NEW_VERSION + // Replace the version pattern only if it matches the Bn.VERSION line + const result = data.replace(/(Bn\.VERSION = ")[0-9]+\.[0-9]+\.[0-9]+(")/, 'BN.VERSION = ""'); // Write the modified content back to the file fs.writeFile(filePath, result, 'utf8', (err) => { @@ -36,3 +32,4 @@ const removeVersionFromFiles = (dir) => { }; removeVersionFromFiles(buildDir); + From e861e4a2f6f7f43b4dfe25c0133b1783faf55067 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 13:33:17 -0500 Subject: [PATCH 12/19] try different regex --- services/ui-src/remove-versions.js | 31 +++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index 81ec8bc64..fa0ab89c6 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -7,7 +7,10 @@ const buildDir = path.join(__dirname, 'build', 'static', 'js'); // Function to remove the version from files const removeVersionFromFiles = (dir) => { fs.readdir(dir, (err, files) => { - if (err) throw err; + if (err) { + console.error("Error reading directory:", err); + return; + } files.forEach(file => { const filePath = path.join(dir, file); @@ -15,15 +18,32 @@ const removeVersionFromFiles = (dir) => { // Check if the file is a JavaScript file if (file.endsWith('.js')) { fs.readFile(filePath, 'utf8', (err, data) => { - if (err) throw err; + if (err) { + console.error("Error reading file:", err); + return; + } + + console.log(`Original content of ${file}:`); + console.log(data); // Log original content // Replace the version pattern only if it matches the Bn.VERSION line - const result = data.replace(/(Bn\.VERSION = ")[0-9]+\.[0-9]+\.[0-9]+(")/, 'BN.VERSION = ""'); + const regex = /(Bn\.VERSION = ")(4\.\d{2}\.\d{2})(")/; + const result = data.replace(regex, '$1NEW_VERSION$3'); + + if (data !== result) { + console.log(`Updated content of ${file}:`); + console.log(result); // Log updated content + } else { + console.log(`No version found in ${file}`); + } // Write the modified content back to the file fs.writeFile(filePath, result, 'utf8', (err) => { - if (err) throw err; - console.log(`Removed version from ${file}`); + if (err) { + console.error("Error writing file:", err); + } else { + console.log(`Version removed from ${file}`); + } }); }); } @@ -33,3 +53,4 @@ const removeVersionFromFiles = (dir) => { removeVersionFromFiles(buildDir); + From fece78a6ca1400e8deb6d79a701918fba9d97867 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 13:54:13 -0500 Subject: [PATCH 13/19] try exact string match instead of regex --- services/ui-src/remove-versions.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index fa0ab89c6..a03db205d 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -26,15 +26,17 @@ const removeVersionFromFiles = (dir) => { console.log(`Original content of ${file}:`); console.log(data); // Log original content - // Replace the version pattern only if it matches the Bn.VERSION line - const regex = /(Bn\.VERSION = ")(4\.\d{2}\.\d{2})(")/; - const result = data.replace(regex, '$1NEW_VERSION$3'); + // Replace the exact version string + const oldVersion = 'Bn.VERSION = "4.17.21"'; + const newVersion = 'Bn.VERSION = "NEW_VERSION"'; // Change this to your desired new version + + const result = data.replace(oldVersion, newVersion); if (data !== result) { console.log(`Updated content of ${file}:`); console.log(result); // Log updated content } else { - console.log(`No version found in ${file}`); + console.log(`No matching version found in ${file}`); } // Write the modified content back to the file @@ -42,7 +44,7 @@ const removeVersionFromFiles = (dir) => { if (err) { console.error("Error writing file:", err); } else { - console.log(`Version removed from ${file}`); + console.log(`Version updated in ${file}`); } }); }); @@ -54,3 +56,4 @@ const removeVersionFromFiles = (dir) => { removeVersionFromFiles(buildDir); + From 2a56acab1edcf3f064b7ed94592ee99b0fac46eb Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 14:27:18 -0500 Subject: [PATCH 14/19] remove spaces that were causing mismatch --- services/ui-src/remove-versions.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index a03db205d..a630fbba9 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -26,17 +26,15 @@ const removeVersionFromFiles = (dir) => { console.log(`Original content of ${file}:`); console.log(data); // Log original content - // Replace the exact version string - const oldVersion = 'Bn.VERSION = "4.17.21"'; - const newVersion = 'Bn.VERSION = "NEW_VERSION"'; // Change this to your desired new version - - const result = data.replace(oldVersion, newVersion); + // Replace the version pattern only if it matches the Bn.VERSION line + const regex = /(Bn\.VERSION=")(4\.\d{2}\.\d{2})(")/; + const result = data.replace(regex, 'Bn.VERSION=""'); if (data !== result) { console.log(`Updated content of ${file}:`); console.log(result); // Log updated content } else { - console.log(`No matching version found in ${file}`); + console.log(`No version found in ${file}`); } // Write the modified content back to the file @@ -44,7 +42,7 @@ const removeVersionFromFiles = (dir) => { if (err) { console.error("Error writing file:", err); } else { - console.log(`Version updated in ${file}`); + console.log(`Version removed from ${file}`); } }); }); From 6dc27b46d5530f93d38dc26042f449e17d31ee93 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 14:42:56 -0500 Subject: [PATCH 15/19] allow for major version greater then 4 --- services/ui-src/remove-versions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index a630fbba9..8620349be 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -27,7 +27,7 @@ const removeVersionFromFiles = (dir) => { console.log(data); // Log original content // Replace the version pattern only if it matches the Bn.VERSION line - const regex = /(Bn\.VERSION=")(4\.\d{2}\.\d{2})(")/; + const regex = /(Bn\.VERSION=")([4-9]\.\d{2}\.\d{2})(")/; const result = data.replace(regex, 'Bn.VERSION=""'); if (data !== result) { From 2adbbda90651389eeb097e7ab9586a549f989252 Mon Sep 17 00:00:00 2001 From: Alex Youssefinia Date: Fri, 18 Oct 2024 14:45:37 -0500 Subject: [PATCH 16/19] remove console logs --- services/ui-src/remove-versions.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/services/ui-src/remove-versions.js b/services/ui-src/remove-versions.js index 8620349be..de4ccc778 100644 --- a/services/ui-src/remove-versions.js +++ b/services/ui-src/remove-versions.js @@ -23,20 +23,16 @@ const removeVersionFromFiles = (dir) => { return; } - console.log(`Original content of ${file}:`); - console.log(data); // Log original content - // Replace the version pattern only if it matches the Bn.VERSION line const regex = /(Bn\.VERSION=")([4-9]\.\d{2}\.\d{2})(")/; const result = data.replace(regex, 'Bn.VERSION=""'); if (data !== result) { console.log(`Updated content of ${file}:`); - console.log(result); // Log updated content } else { console.log(`No version found in ${file}`); } - + // Write the modified content back to the file fs.writeFile(filePath, result, 'utf8', (err) => { if (err) { From 7789875bcccb45da5f54c57a438a68698280c792 Mon Sep 17 00:00:00 2001 From: bflynn-cms Date: Thu, 5 Dec 2024 08:25:59 -0600 Subject: [PATCH 17/19] Launch Darkly for Subsequent Documentation (#1552) * launchdarkly setup for subsequent submission * update routes with flag * check route path rather than component name --- services/app-api/getDetail.js | 2 +- services/app-api/getMyPackages.js | 182 +++++++++++------------ services/app-api/package-lock.json | 67 ++++++++- services/app-api/package.json | 3 +- services/app-api/serverless.yml | 2 + services/app-api/utils/actionDelegate.js | 51 ++++++- services/ui-src/src/Routes.tsx | 16 +- 7 files changed, 218 insertions(+), 105 deletions(-) diff --git a/services/app-api/getDetail.js b/services/app-api/getDetail.js index 054fa52c5..774d4a2bd 100644 --- a/services/app-api/getDetail.js +++ b/services/app-api/getDetail.js @@ -87,7 +87,7 @@ export const getDetails = async (event) => { if (!userRoleObj.isCMSUser && result.Item.reviewTeam) delete result.Item.reviewTeam; - result.Item.actions = getActionsForPackage( + result.Item.actions = await getActionsForPackage( result.Item.componentType, originalStatus, !!result.Item.latestRaiResponseTimestamp, diff --git a/services/app-api/getMyPackages.js b/services/app-api/getMyPackages.js index 91cb1f4ee..38dd8e607 100644 --- a/services/app-api/getMyPackages.js +++ b/services/app-api/getMyPackages.js @@ -19,106 +19,102 @@ export const getMyPackages = async (email, group) => { if (!email) return RESPONSE_CODE.USER_NOT_FOUND; if (!group) return RESPONSE_CODE.DATA_MISSING; - return getUser(email) - .then((user) => { - if (!user) throw RESPONSE_CODE.USER_NOT_AUTHORIZED; + try { + const user = await getUser(email); + if (!user) throw RESPONSE_CODE.USER_NOT_AUTHORIZED; - const userRoleObj = getUserRoleObj(user.roleList); - const territoryList = getActiveTerritories(user.roleList); - const statusMap = userRoleObj.isCMSUser - ? cmsStatusUIMap - : stateStatusUIMap; + const userRoleObj = getUserRoleObj(user.roleList); + const territoryList = getActiveTerritories(user.roleList); + const statusMap = userRoleObj.isCMSUser ? cmsStatusUIMap : stateStatusUIMap; - if ( - !userRoleObj.canAccessDashboard || - (Array.isArray(territoryList) && territoryList.length === 0) - ) { - throw RESPONSE_CODE.USER_NOT_AUTHORIZED; - } + if ( + !userRoleObj.canAccessDashboard || + (Array.isArray(territoryList) && territoryList.length === 0) + ) { + throw RESPONSE_CODE.USER_NOT_AUTHORIZED; + } - const baseParams = { - TableName: process.env.oneMacTableName, - IndexName: "GSI1", - ExclusiveStartKey: null, - ScanIndexForward: false, - ProjectionExpression: - "componentId,componentType,currentStatus,submissionTimestamp,latestRaiResponseTimestamp,lastActivityTimestamp,submitterName,submitterEmail,waiverAuthority, cpocName, reviewTeam, subStatus, finalDispositionDate", - }; - const grouppk = "OneMAC#" + group; - let paramList = []; - if (territoryList[0] !== "N/A") { - paramList = territoryList.map((territory) => { - return { - ...baseParams, - KeyConditionExpression: "GSI1pk = :pk AND begins_with(GSI1sk,:t1)", - ExpressionAttributeValues: { - ":pk": grouppk, - ":t1": territory, - }, - }; - }); - } else { - paramList = [ - { - ...baseParams, - KeyConditionExpression: "GSI1pk = :pk", - ExpressionAttributeValues: { - ":pk": grouppk, - }, + const baseParams = { + TableName: process.env.oneMacTableName, + IndexName: "GSI1", + ExclusiveStartKey: null, + ScanIndexForward: false, + ProjectionExpression: + "componentId,componentType,currentStatus,submissionTimestamp,latestRaiResponseTimestamp,lastActivityTimestamp,submitterName,submitterEmail,waiverAuthority, cpocName, reviewTeam, subStatus, finalDispositionDate", + }; + const grouppk = "OneMAC#" + group; + let paramList = []; + if (territoryList[0] !== "N/A") { + paramList = territoryList.map((territory) => { + return { + ...baseParams, + KeyConditionExpression: "GSI1pk = :pk AND begins_with(GSI1sk,:t1)", + ExpressionAttributeValues: { + ":pk": grouppk, + ":t1": territory, }, - ]; - } + }; + }); + } else { + paramList = [ + { + ...baseParams, + KeyConditionExpression: "GSI1pk = :pk", + ExpressionAttributeValues: { + ":pk": grouppk, + }, + }, + ]; + } - return Promise.all( - paramList.map(async (params) => { - const promiseItems = []; - do { - const results = await dynamoDb.query(params); - results.Items.map((oneItem) => { - oneItem.actions = getActionsForPackage( - oneItem.componentType, - oneItem.currentStatus, - !!oneItem.latestRaiResponseTimestamp, - oneItem.subStatus, - userRoleObj, - "package" - ); - if (oneItem.waiverAuthority) - oneItem.temporaryExtensionType = oneItem.waiverAuthority.slice( - 0, - 7 - ); + // Using a for...of loop to ensure async operations are awaited correctly + const allItems = []; + for (const params of paramList) { + const promiseItems = []; + do { + const results = await dynamoDb.query(params); + for (const oneItem of results.Items) { + oneItem.actions = await getActionsForPackage( + oneItem.componentType, + oneItem.currentStatus, + !!oneItem.latestRaiResponseTimestamp, + oneItem.subStatus, + userRoleObj, + "package" + ); + if (oneItem.waiverAuthority) + oneItem.temporaryExtensionType = oneItem.waiverAuthority.slice( + 0, + 7 + ); - if (statusMap[oneItem.subStatus]) { - oneItem.subStatus = statusMap[oneItem.subStatus]; - } + if (statusMap[oneItem.subStatus]) { + oneItem.subStatus = statusMap[oneItem.subStatus]; + } - if (!statusMap[oneItem.currentStatus]) - console.log( - "%s status of %s not mapped!", - oneItem.pk, - oneItem.currentStatus - ); - else { - oneItem.currentStatus = statusMap[oneItem.currentStatus]; - if ( - oneItem.currentStatus !== Workflow.ONEMAC_STATUS.INACTIVATED - ) - promiseItems.push(oneItem); - } - }); - params.ExclusiveStartKey = results.LastEvaluatedKey; - } while (params.ExclusiveStartKey); - return promiseItems; - }) - ).then((values) => { - return values.flat(); - }); - }) - .catch((error) => { - console.log("error is: ", error); - return error; - }); + if (!statusMap[oneItem.currentStatus]) + console.log( + "%s status of %s not mapped!", + oneItem.pk, + oneItem.currentStatus + ); + else { + oneItem.currentStatus = statusMap[oneItem.currentStatus]; + if (oneItem.currentStatus !== Workflow.ONEMAC_STATUS.INACTIVATED) + promiseItems.push(oneItem); + } + } + params.ExclusiveStartKey = results.LastEvaluatedKey; + } while (params.ExclusiveStartKey); + + allItems.push(...promiseItems); + } + + return allItems; // Flattened list of all items + } catch (error) { + console.log("error is: ", error); + return error; + } }; // get the approver list for a rols and possibly a territory diff --git a/services/app-api/package-lock.json b/services/app-api/package-lock.json index 95df4ad6d..c93cdca26 100644 --- a/services/app-api/package-lock.json +++ b/services/app-api/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "CC0-1.0", "dependencies": { + "@launchdarkly/node-server-sdk": "^9.7.2", "cmscommonlib": "file:../common", "date-fns": "^2.16.1", "dynamodb-local": "^0.0.32", @@ -5995,6 +5996,60 @@ "dev": true, "peer": true }, + "node_modules/@launchdarkly/js-sdk-common": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@launchdarkly/js-sdk-common/-/js-sdk-common-2.12.0.tgz", + "integrity": "sha512-HIDxvgo1vksC9hsYy3517sgW0Ql+iW3fgwlq/CEigeBNmaa9/J1Pxo7LrKPzezEA0kaGedmt/DCzVVxVBmxSsQ==" + }, + "node_modules/@launchdarkly/js-server-sdk-common": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@launchdarkly/js-server-sdk-common/-/js-server-sdk-common-2.10.0.tgz", + "integrity": "sha512-zbqpmEFQW/ZElZnRYX6N4gMZMpviE0F75/IyxcifLAFsjGNouxllpOOPbdtrLiJnJ0ixzt5vbtnem4tbhlYNOw==", + "dependencies": { + "@launchdarkly/js-sdk-common": "2.12.0", + "semver": "7.5.4" + } + }, + "node_modules/@launchdarkly/js-server-sdk-common/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@launchdarkly/js-server-sdk-common/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@launchdarkly/js-server-sdk-common/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/@launchdarkly/node-server-sdk": { + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/@launchdarkly/node-server-sdk/-/node-server-sdk-9.7.2.tgz", + "integrity": "sha512-gcRarEh0yQrlwbWDORwbfTk19M/FtZje60EIo/c4298D/sqJ906MYq0J2MmyklEuIdQx/V4qPK+ss9LCCLpm/Q==", + "dependencies": { + "@launchdarkly/js-server-sdk-common": "2.10.0", + "https-proxy-agent": "^5.0.1", + "launchdarkly-eventsource": "2.0.3" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7434,8 +7489,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "peer": true, "dependencies": { "debug": "4" }, @@ -11468,8 +11521,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -15575,6 +15626,14 @@ "node": ">=6" } }, + "node_modules/launchdarkly-eventsource": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/launchdarkly-eventsource/-/launchdarkly-eventsource-2.0.3.tgz", + "integrity": "sha512-VhFjppK7jXlcEKaS7bxdoibB5j01NKyeDR7a8XfssdDGNWCTsbF0/5IExSmPi44eDncPhkoPNxlSZhEZvrbD5w==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/lazystream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", diff --git a/services/app-api/package.json b/services/app-api/package.json index 57adc4c08..8c91d0120 100644 --- a/services/app-api/package.json +++ b/services/app-api/package.json @@ -14,8 +14,8 @@ }, "devDependencies": { "@types/jest": "^29.5.5", - "aws-sdk-client-mock": "^0.5.6", "aws-sdk": "^2.752.0", + "aws-sdk-client-mock": "^0.5.6", "esbuild": "^0.19.4", "esbuild-jest": "^0.5.0", "jest": "^29.7.0", @@ -28,6 +28,7 @@ "xstate": "^4.26.0" }, "dependencies": { + "@launchdarkly/node-server-sdk": "^9.7.2", "cmscommonlib": "file:../common", "date-fns": "^2.16.1", "dynamodb-local": "^0.0.32", diff --git a/services/app-api/serverless.yml b/services/app-api/serverless.yml index 94450caa3..b1b736d96 100644 --- a/services/app-api/serverless.yml +++ b/services/app-api/serverless.yml @@ -33,6 +33,7 @@ custom: applicationEndpoint: ${cf:ui-${self:custom.stage}.ApplicationEndpointUrl, "onemac.cms.gov"} attachmentsBucket: ${cf:uploads-${self:custom.stage}.AttachmentsBucketName} attachmentsBucketArn: ${cf:uploads-${self:custom.stage}.AttachmentsBucketArn} + launchDarklySdkKey: ${ssm:/configuration/${self:custom.stage}/launchdarkly/sdkkey, ssm:/configuration/default/launchdarkly/sdkkey} warmupEnabled: production: true development: false @@ -87,6 +88,7 @@ provider: applicationEndpoint: ${self:custom.applicationEndpoint} attachmentsBucket: ${self:custom.attachmentsBucket} configurationSetName: 'email-${self:custom.stage}-configuration' + launchDarklySdkKey: ${self:custom.launchDarklySdkKey} tracing: apiGateway: true lambda: true diff --git a/services/app-api/utils/actionDelegate.js b/services/app-api/utils/actionDelegate.js index 68b6acc04..ee6340968 100644 --- a/services/app-api/utils/actionDelegate.js +++ b/services/app-api/utils/actionDelegate.js @@ -1,4 +1,26 @@ import { Workflow } from "cmscommonlib"; +import { init } from "@launchdarkly/node-server-sdk"; + +// Global variable to hold the LD client so it's reused on subsequent invocations +let ldClient; + +async function initializeLaunchDarkly() { + if (!ldClient) { + ldClient = init(process.env.launchDarklySdkKey, { + baseUri: "https://clientsdk.launchdarkly.us", + streamUri: "https://clientstream.launchdarkly.us", + eventsUri: "https://events.launchdarkly.us", + }); + + try { + await ldClient.waitForInitialization({ timeout: 10 }); + console.log("LD Initialization successful"); + } catch (err) { + console.error("LD Initialization failed:", err.message || err); + } + } +} + function getDefaultActions( packageStatus, hasRaiResponse, @@ -74,7 +96,7 @@ function getWaiverExtensionActions(packageStatus, userRole) { return actions; } -export function getActionsForPackage( +export async function getActionsForPackage( packageType, packageStatus, hasRaiResponse, @@ -82,6 +104,16 @@ export function getActionsForPackage( userRole, formSource ) { + // Initialize LaunchDarkly client (if not already initialized) + await initializeLaunchDarkly(); + + const ENABLE_SUBSEQUENT_SUBMISSION = await ldClient.variation( + "enableSubsequentDocumentation", + { key: userRole }, + false + ); + console.log("Flag value:", ENABLE_SUBSEQUENT_SUBMISSION); + let actions = getDefaultActions( packageStatus, hasRaiResponse, @@ -114,9 +146,18 @@ export function getActionsForPackage( ); break; } - // Filter out duplicates - const uniqueActions = actions.filter( - (action, index) => actions.indexOf(action) === index - ); + + const uniqueActions = actions.filter((action, index) => { + // Filter out SUBSEQUENT_SUBMISSION if not enabled + const isNotSubsequentSubmission = + action !== Workflow.PACKAGE_ACTION.SUBSEQUENT_SUBMISSION || + ENABLE_SUBSEQUENT_SUBMISSION; + + // Remove duplicates: only keep the first occurrence of each action + const isUnique = actions.indexOf(action) === index; + + return isNotSubsequentSubmission && isUnique; + }); + return uniqueActions; } diff --git a/services/ui-src/src/Routes.tsx b/services/ui-src/src/Routes.tsx index 058692650..7c7b4e6d4 100644 --- a/services/ui-src/src/Routes.tsx +++ b/services/ui-src/src/Routes.tsx @@ -4,6 +4,7 @@ import React, { FC } from "react"; import { Redirect, Route, Switch } from "react-router-dom"; +import { useFlags } from "launchdarkly-react-client-sdk"; import { ROUTES, @@ -88,9 +89,22 @@ const RouteListRenderer: FC<{ routes: RouteSpec[] }> = ({ routes }) => { if (!useAppContext()?.isAuthenticated) { clearTableStateStorageKeys(); } + + const { enableSubsequentDocumentation } = useFlags(); + let filteredRoutes; + if (!enableSubsequentDocumentation) { + // Filter out objects where the component includes a SubsequentSubmission form + // This is not currently looking for subroutes since all subsub routes are at the root of the route object + filteredRoutes = routes.filter( + (route) => !route.path.includes("subsequent-submission") + ); + } else { + filteredRoutes = routes; + } + return ( - {routes.map((routeSpec) => ( + {filteredRoutes.map((routeSpec) => ( Date: Tue, 10 Dec 2024 08:48:24 -0600 Subject: [PATCH 18/19] Update deploy.yml (#1560) --- .github/workflows/deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4e29be7cf..c4271f469 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -59,6 +59,8 @@ jobs: name: ${{ startsWith(github.ref_name, 'snyk-') && 'snyk' || github.ref_name }} url: "https://onemac.cms.gov" steps: + - name: Check GITHUB_REF + run: echo "GITHUB_REF is $GITHUB_REF" - name: set branch_name run: echo "branch_name=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV - name: Check branch name is a legal serverless stage name From 35fbd0017c0d4dc3489455e9bdcc8efa48c47746 Mon Sep 17 00:00:00 2001 From: Andie Swift Date: Wed, 11 Dec 2024 10:38:05 -0600 Subject: [PATCH 19/19] encoded the email portion of URL for profile/`useremail` (#1561) --- services/ui-src/src/containers/PackageList.js | 2 +- services/ui-src/src/containers/UserManagement.js | 2 +- services/ui-src/src/containers/UserPage.js | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/services/ui-src/src/containers/PackageList.js b/services/ui-src/src/containers/PackageList.js index fc23ff21d..0c7a377e4 100644 --- a/services/ui-src/src/containers/PackageList.js +++ b/services/ui-src/src/containers/PackageList.js @@ -218,7 +218,7 @@ const PackageList = () => { ({ value, row }) => ( {value} diff --git a/services/ui-src/src/containers/UserManagement.js b/services/ui-src/src/containers/UserManagement.js index 328e63ca7..1cba6f28b 100644 --- a/services/ui-src/src/containers/UserManagement.js +++ b/services/ui-src/src/containers/UserManagement.js @@ -166,7 +166,7 @@ const UserManagement = () => { ({ value, row }) => ( {value} diff --git a/services/ui-src/src/containers/UserPage.js b/services/ui-src/src/containers/UserPage.js index fff126682..011497c34 100644 --- a/services/ui-src/src/containers/UserPage.js +++ b/services/ui-src/src/containers/UserPage.js @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { useLocation, useParams } from "react-router-dom"; +import { useLocation, useParams, useHistory } from "react-router-dom"; import { Button, Review } from "@cmsgov/design-system"; import { @@ -157,6 +157,7 @@ export const GroupDivisionDisplay = ({ profileData = {} }) => { * Component housing data belonging to a particular user */ const UserPage = () => { + const history = useHistory(); const { userProfile, setUserInfo, updatePhoneNumber, userRole, userStatus } = useAppContext(); const location = useLocation(); @@ -174,10 +175,10 @@ const UserPage = () => { const [isEditingPhone, setIsEditingPhone] = useState(false); const isReadOnly = location.pathname !== ROUTES.PROFILE && - decodeURIComponent(userId) !== userProfile.email; + decodeURIComponent(userId) !== window.btoa(userProfile.email); useEffect(() => { - const getProfile = async (profileEmail) => { + const getProfile = async (encodedProfileEmail) => { if (!isReadOnly) { return [{ ...userProfile.userData }, userRole, userStatus]; } @@ -187,6 +188,7 @@ const UserPage = () => { tempProfileStatus = "status"; try { + const profileEmail = window.atob(encodedProfileEmail); tempProfileData = await UserDataApi.userProfile(profileEmail); const profileAccess = effectiveRoleForUser(tempProfileData?.roleList); if (profileAccess !== null) @@ -194,6 +196,8 @@ const UserPage = () => { } catch (e) { console.error("Error fetching user data", e); setAlertCode(RESPONSE_CODE[e.message]); + // redirect if the user is not found + history.push("/notfound"); } return [tempProfileData, tempProfileRole, tempProfileStatus]; @@ -209,7 +213,7 @@ const UserPage = () => { console.error("Error fetching user data", e); setAlertCode(RESPONSE_CODE[e.message]); }); - }, [isReadOnly, userId, userProfile, userRole, userStatus]); + }, [isReadOnly, userId, userProfile, userRole, userStatus, history]); const onPhoneNumberCancel = useCallback(() => { setIsEditingPhone(false);