Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/org/labkey/test/tests/PackageLockJsonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
public class PackageLockJsonTest
{
private static final Set<String> ALLOWED_DEPENDENCY_HOSTS = Set.of("registry.npmjs.org", "labkey.jfrog.io");
// Allow-list of '@isaacs/cliui' dependencies
private static final Set<String> ALLOWED_NONSTANDARD_VERSIONS = Set.of("npm:string-width@^4.2.0", "npm:strip-ansi@^6.0.1", "npm:wrap-ansi@^7.0.0");
private static final File SERVER_MODULES_DIR = new File(TestFileUtils.getLabKeyRoot(), "server/modules");

private final List<String> errors = new ArrayList<>();
private final File moduleDir;
Expand All @@ -44,11 +43,10 @@ public static Collection<Object[]> data()
{
List<File> allModules = new ArrayList<>();

File modulesDir = new File(TestFileUtils.getLabKeyRoot(), "server/modules");
File[] files = modulesDir.listFiles();
File[] files = SERVER_MODULES_DIR.listFiles();
if (files == null)
{
throw new RuntimeException("No files found in modules directory: " + modulesDir.getAbsolutePath());
throw new RuntimeException("No files found in modules directory: " + SERVER_MODULES_DIR.getAbsolutePath());
}
for (File file : files)
{
Expand Down Expand Up @@ -96,17 +94,19 @@ public void testPackageLock() throws Exception
}
}

Assert.assertTrue("Bad sources: " + errors, errors.isEmpty());
Assert.assertTrue("Untrusted package sources:\n" + String.join("\n", errors), errors.isEmpty());
}

/// Verify that a package reference in a package-lock.json file only resolves to known hosts and has a valid version
/// Also checks sub-dependencies
private void verifyPackage(String packageName, JSONObject packageJson, File packageLockFile)
{
String relPath = SERVER_MODULES_DIR.toPath().relativize(packageLockFile.toPath()).toString();

String resolved = packageJson.optString("resolved");
if (resolved.isBlank())
{
TestLogger.debug("Resolved field is blank for package " + packageName + " in " + packageLockFile.getAbsolutePath());
TestLogger.debug("Resolved field is blank for package " + packageName + " in " + relPath);
}
else
{
Expand All @@ -116,14 +116,14 @@ private void verifyPackage(String packageName, JSONObject packageJson, File pack
String host = resolvedURL.getHost();
if (!ALLOWED_DEPENDENCY_HOSTS.contains(host))
{
String message = "Package " + packageName + " resolved to unrecognized host [" + host + "] in " + packageLockFile.getAbsolutePath();
String message = "Package " + packageName + " resolved to unrecognized host [" + host + "] in " + relPath;
errors.add(message);
TestLogger.error(message);
}
}
catch (URISyntaxException e)
{
String message = "Package " + packageName + " resolved to an invalid location [" + resolved + "] in " + packageLockFile.getAbsolutePath();
String message = "Package " + packageName + " resolved to an invalid location [" + resolved + "] in " + relPath;
errors.add(message);
TestLogger.error(message);
}
Expand All @@ -132,7 +132,7 @@ private void verifyPackage(String packageName, JSONObject packageJson, File pack
String version = packageJson.optString("version");
if (version.isBlank() || !CharUtils.isAsciiNumeric(version.charAt(0)))
{
String message = "Package " + packageName + " has bad version [" + version + "] in " + packageLockFile.getAbsolutePath();
String message = "Package " + packageName + " has bad version [" + version + "] in " + relPath;
errors.add(message);
TestLogger.error(message);
}
Expand All @@ -148,9 +148,9 @@ private void verifyPackage(String packageName, JSONObject packageJson, File pack
else
{
String tVer = transitiveDeps.optString(tDep);
if (tVer == null || tVer.contains(":") && !ALLOWED_NONSTANDARD_VERSIONS.contains(tVer)) // URL, file, or workspace dependency
if (tVer == null || tVer.replaceAll("^npm:", "").contains(":")) // URL, file, or workspace dependency
{
String message = "Package " + packageName + " has bad transitive dependency [" + tVer + "] in " + packageLockFile.getAbsolutePath();
String message = "Package " + packageName + " has bad transitive dependency [" + tVer + "] in " + relPath;
errors.add(message);
TestLogger.error(message);
}
Expand Down