### Install Project Dependencies Source: https://github.com/lirantal/npq/blob/main/docs/development.md Run this command to install all necessary project dependencies after cloning the repository. ```sh npm install ``` -------------------------------- ### Before Fix: Signature Verification Failure Example Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md Demonstrates the error message encountered by users before the fix when attempting to install a package with a version range. ```bash $ npq install @angular/common@^20.2.4 Unable to verify package signature on registry: Version ^20.2.4 not found for package @angular/common ``` -------------------------------- ### Install npq with Homebrew Source: https://github.com/lirantal/npq/blob/main/README.md Installs the npq package using Homebrew on macOS or Linux systems. ```bash brew install npq ``` -------------------------------- ### Install a package using npq Source: https://github.com/lirantal/npq/blob/main/README.md Installs a specified package using the npq command. npq performs security checks before handing off to the package manager. ```bash npq install express ``` -------------------------------- ### Install npq globally with npm Source: https://github.com/lirantal/npq/blob/main/README.md Installs the npq package globally using npm. This method allows npq to automatically set up shell aliases. ```bash npm install -g npq ``` -------------------------------- ### Run Checks Without Installation Source: https://github.com/lirantal/npq/blob/main/README.md Use the --dry-run flag with the install command to audit dependencies without performing an actual installation. This is useful for previewing changes. ```sh npq install express --dry-run ``` -------------------------------- ### Run Alias Setup Tests with Jest Source: https://github.com/lirantal/npq/blob/main/docs/feature/alias.md Execute only the alias setup tests using Jest, targeting the scripts.test.js file. ```bash npx jest __tests__/scripts.test.js ``` -------------------------------- ### Dry-run npm package installation with npq Source: https://github.com/lirantal/npq/blob/main/README.md Use this command to perform a dry-run installation of an npm package. The `--dry-run` flag ensures that npq checks the package and exits without actually installing it, regardless of success or errors. ```bash $ npx npq install express --dry-run ``` -------------------------------- ### Automatic Alias Setup (Bash/Zsh) Source: https://github.com/lirantal/npq/blob/main/docs/feature/alias.md These aliases are automatically added to your shell profile during global installation of npq. They ensure that npm and yarn commands are routed through npq-hero for security checks. ```bash alias npm="npq-hero" alias yarn="NPQ_PKG_MGR=yarn npq-hero" ``` -------------------------------- ### Visual Display of Auto-Continue Countdown Source: https://github.com/lirantal/npq/blob/main/docs/feature/auto-continue.md This example demonstrates the visual output when the auto-continue feature is active, showing detected warnings and the countdown timer. ```text Packages with issues found: ┌─ │ > express@latest │ │ ⚠ Supply Chain Security · Unable to verify provenance: the package was published without any attestations └─ Summary: - Total packages: 1 - Total errors: 0 - Total warnings: 1 (press 'y' to proceed with install) Auto-continue with install in... 15 ``` -------------------------------- ### Test Mock for SignaturesMarshall Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md This test setup mocks the `SignaturesMarshall` and its dependencies to verify the new flow, specifically checking that `getPackageInfo` is called. ```javascript const testMarshall = new SignaturesMarshall({ packageRepoUtils: { getPackageInfo: jest.fn().mockResolvedValue(mockPackageData), parsePackageVersion: jest.fn().mockReturnValue('1.0.0') } }) // Verify version resolution is called expect(testMarshall.packageRepoUtils.getPackageInfo).toHaveBeenCalledWith('packageName') ``` -------------------------------- ### Initialize Marshall and Validate Package Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Instantiate the Marshall class with necessary utilities and then call the validate method to check a specific package version. This example demonstrates a successful validation where no errors or warnings are returned. ```javascript const marshall = new Marshall({ packageRepoUtils }) await marshall.validate({ packageName: 'express', packageVersion: '4.18.0' }) // Returns: undefined (no errors/warnings) ``` -------------------------------- ### Force Non-Rich Text Output Source: https://github.com/lirantal/npq/blob/main/README.md To ensure plain text output from the npq install command, use the --plain flag. This is useful for environments where rich text formatting is not supported or desired. ```sh npq install express --plain ``` -------------------------------- ### Example of Signature Verification Failure Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md This output shows a typical scenario where npq detects issues with signature verification for a package, indicating a recently published version with no attestations found. ```bash $ npq install @angular/common@^20.2.4 Packages with issues found: ┌─ │ > @angular/common@^20.2.4 │ │ ✖ Supply Chain Security · Detected a recently published version: published 6 days ago │ ⚠ Supply Chain Security · Unable to verify provenance: no attestations found └─ Continue install ? (y/N) ``` -------------------------------- ### Disable Auto-Continue with CLI Flag Source: https://github.com/lirantal/npq/blob/main/docs/feature/auto-continue.md Use the `--disable-auto-continue` flag with the `npq install` command to prevent the auto-continue countdown for a single operation. ```bash npq install express --disable-auto-continue ``` -------------------------------- ### Error Object on User Abort Source: https://github.com/lirantal/npq/blob/main/docs/feature/auto-continue.md When a user aborts the installation by pressing Ctrl+C during the countdown, a specific error object is thrown, indicating the operation was aborted by the user and providing an exit code. ```javascript // Error thrown on Ctrl+C { message: 'Operation aborted by user', code: 'USER_ABORT', exitCode: 1 } ``` -------------------------------- ### Disable Auto-Continue Countdown (CLI Flag) Source: https://github.com/lirantal/npq/blob/main/README.md Use the --disable-auto-continue flag to prevent npq from automatically proceeding with installation after a countdown when only warnings are detected. This ensures explicit confirmation is always required. ```sh npq install express --disable-auto-continue ``` -------------------------------- ### Manual Alias Setup for Package Managers Source: https://github.com/lirantal/npq/blob/main/docs/feature/alias.md Manually add these aliases to your shell profile to integrate npq with your preferred package manager. The NPQ_PKG_MGR environment variable specifies which package manager npq should delegate to. ```bash alias npm="npq-hero" ``` ```bash alias yarn="NPQ_PKG_MGR=yarn npq-hero" ``` ```bash alias pnpm="NPQ_PKG_MGR=pnpm npq-hero" ``` -------------------------------- ### OSV API Malicious Package Heuristics Source: https://github.com/lirantal/npq/blob/main/docs/feature/malicious-package.md The OSV API identifies malicious packages based on specific fields in its vulnerability data. This includes the presence of 'malicious-packages-origins' or a summary starting with 'malicious'. ```javascript 1. "malicious-packages-origins" If this property exists and its value is an **array** (including an empty array), the vuln counts as malicious. This matches OSV records that tie the advisory to the malicious-packages dataset. 2. `summary` prefix If `summary` is a string and, after lowercasing, it **starts with** "malicious", the vuln counts as malicious. This covers summaries such as “Malicious code in …” regardless of original casing. ``` -------------------------------- ### Disable Snyk Vulnerability Marshall Source: https://github.com/lirantal/npq/blob/main/README.md To disable the Snyk vulnerability marshall, set the MARSHALL_DISABLE_SNYK environment variable to 1 before running the npq install command. ```bash MARSHALL_DISABLE_SNYK=1 npq install express ``` -------------------------------- ### Run All Tests with npm Source: https://github.com/lirantal/npq/blob/main/docs/feature/alias.md Execute all tests for the npq project using the npm test command. ```bash npm test ``` -------------------------------- ### Test Cases for Version Range Resolution Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md These commands demonstrate various version specification formats that are now correctly handled by npq after the fix, ensuring consistent behavior with npm's standards. ```bash npq install @angular/common@^20.2.4 ``` ```bash npq install lodash@~4.17.0 ``` ```bash npq install express@>=4.0.0 ``` ```bash npq install @angular/common ``` ```bash npq install lodash@4.17.21 ``` -------------------------------- ### Run Test Suite Source: https://github.com/lirantal/npq/blob/main/docs/testing.md Execute the project's test suite using the npm test script. Ensure all tests pass before submitting changes. ```sh npm run test ``` -------------------------------- ### Correct Pattern for Package Manifest Retrieval Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md Illustrates the correct pattern for resolving a package version before fetching its manifest. This pattern is used by other marshalls and ensures version ranges are handled properly. ```javascript const resolvedVersion = await this.resolvePackageVersion(packageName, packageVersion) const packageData = await this.npmRegistry.getManifest(packageName, resolvedVersion) ``` -------------------------------- ### New Package Detection Logic Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Implements the check for newly published packages by comparing the package creation date difference against a threshold in milliseconds. ```javascript const pkgCreatedDate = data.time.created const dateDiff = Date.now() - Date.parse(pkgCreatedDate) const thresholdMs = PACKAGE_AGE_THRESHOLD * 24 * 60 * 60 * 1000 if (dateDiff < thresholdMs) { throw new Error(`Detected a newly published package (created < ${PACKAGE_AGE_THRESHOLD} days) act carefully`) } ``` -------------------------------- ### Control Pacote Dependency with Environment Variables Source: https://github.com/lirantal/npq/blob/main/docs/feature/pacote-dependency-reduction.md Use environment variables to control security features and optionally disable the 'pacote' dependency. This allows for a smaller footprint when advanced security checks are not needed. ```bash # Full security (default, no change) npq install express # Disable security features if needed export MARSHALL_DISABLE_SIGNATURES=true export MARSHALL_DISABLE_PROVENANCE=true npq install express ``` -------------------------------- ### Check pino packument for attestations Source: https://github.com/lirantal/npq/blob/main/docs/feature/provenance.md Use curl and node to inspect the npm registry packument for a specific package and version to see if it includes 'dist.attestations' metadata. ```bash curl -sS -H 'accept: application/json' 'https://registry.npmjs.org/pino' | node -e " const j = JSON.parse(require('fs').readFileSync(0, 'utf8')); for (const v of ['9.13.1', '9.14.0']) { const a = j.versions[v]?.dist?.attestations; console.log(v, a ? 'has dist.attestations' : 'no dist.attestations'); } " ``` -------------------------------- ### Add a Changeset Source: https://github.com/lirantal/npq/blob/main/RELEASE.md Run this command to add a changeset for user-facing package behavior changes. Documentation-only, test-only, and internal refactor PRs usually do not need a changeset unless they describe or accompany a release-worthy behavior change. ```sh npm run changeset ``` -------------------------------- ### Define Package Age Thresholds Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Defines constants for the minimum age of new packages and the maximum age for unmaintained packages in days. ```javascript const PACKAGE_AGE_THRESHOLD = 22 // specified in days const PACKAGE_AGE_UNMAINTAINED_RISK = 365 // specified in days ``` -------------------------------- ### Test npm Registry Interactions Source: https://github.com/lirantal/npq/blob/main/docs/feature/test-coverage-improvements.md This test suite focuses on the npm registry interactions, including fetching package manifests, verifying signatures, and handling attestations. It also covers network error scenarios. ```javascript describe('NpmRegistry', () => { describe('verifySignatures', () => { it('should verify signatures successfully', () => { // Test signature verification workflow }) }) }) ``` -------------------------------- ### Detect Newly Published Package Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Use Marshall to validate a package. If the package was created less than the defined threshold (e.g., 22 days), it throws an error indicating a potentially suspicious new package. ```javascript const marshall = new Marshall({ packageRepoUtils }) await marshall.validate({ packageName: 'suspicious-new-package', packageVersion: '1.0.0' }) // Throws: Error('Detected a newly published package (created < 22 days) act carefully') ``` -------------------------------- ### Test CLI Argument Parsing Source: https://github.com/lirantal/npq/blob/main/docs/feature/test-coverage-improvements.md This test suite covers the comprehensive parsing of command-line arguments for the CLI module. It ensures correct handling of packages, options, environment variables, and various error scenarios. ```javascript describe('CliParser', () => { describe('parseArgsFull', () => { it('should parse packages and options correctly', () => { // Test package extraction, option handling, environment variables }) }) }) ``` -------------------------------- ### Test Promise Throttler Utility Source: https://github.com/lirantal/npq/blob/main/docs/feature/test-coverage-improvements.md This test suite provides complete coverage for the promise throttling utility, ensuring it correctly manages concurrent requests, enforces minimum delays, and handles errors. ```javascript describe('PromiseThrottler', () => { describe('throttle method', () => { it('should respect minimum delay between requests', async () => { // Test rate limiting behavior }) }) }) ``` -------------------------------- ### Configure package manager with NPQ_PKG_MGR Source: https://github.com/lirantal/npq/blob/main/README.md Specify the package manager to be used by npq by setting the NPQ_PKG_MGR environment variable. This is useful when using Yarn or pnpm. ```bash alias yarn="NPQ_PKG_MGR=yarn npq-hero" ``` ```bash NPQ_PKG_MGR=yarn yarn run npq-hero ``` ```bash NPQ_PKG_MGR=yarn yarn exec npq-hero ``` ```bash NPQ_PKG_MGR=pnpm npx npq install fastify ``` ```bash alias pnpm="NPQ_PKG_MGR=pnpm npq-hero" ``` -------------------------------- ### Abandoned Package Detection Logic Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Detects potentially unmaintained packages by comparing the difference between the current time and the last version release date against a threshold in milliseconds. It also calculates the age in days for display purposes. ```javascript const versionDateDiff = Date.now() - Date.parse(versionReleaseDate) const versionDateDiffInDays = Math.round(versionDateDiff / (1000 * 60 * 60 * 24)) const unmaintainedThresholdMs = PACKAGE_AGE_UNMAINTAINED_RISK * 24 * 60 * 60 * 1000 if (versionDateDiff >= unmaintainedThresholdMs) { throw new Warning(`Detected an old package (created ${timeAgoNumber} ${timeAgoText} ago)`) } ``` -------------------------------- ### Disable Both Signature and Provenance Verification Source: https://github.com/lirantal/npq/blob/main/docs/optional-features.md Set both MARSHALL_DISABLE_SIGNATURES and MARSHALL_DISABLE_PROVENANCE environment variables to true to disable both signature and provenance verification. ```bash export MARSHALL_DISABLE_SIGNATURES=true export MARSHALL_DISABLE_PROVENANCE=true npq install express ``` -------------------------------- ### Fixed Date Calculation (After Fix) Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Shows the corrected date comparison logic that converts day thresholds into milliseconds for accurate comparison with date differences. ```javascript // FIXED CODE (after fix) const dateDiff = Date.now() - Date.parse(pkgCreatedDate) const thresholdMs = PACKAGE_AGE_THRESHOLD * 24 * 60 * 60 * 1000 if (dateDiff < thresholdMs) { // Now comparing ms to ms throw new Error(...) } // Also fixed for unmaintained packages const versionDateDiff = Date.now() - Date.parse(versionReleaseDate) const unmaintainedThresholdMs = PACKAGE_AGE_UNMAINTAINED_RISK * 24 * 60 * 60 * 1000 if (versionDateDiff >= unmaintainedThresholdMs) { // Now consistent ms to ms throw new Warning(...) } ``` -------------------------------- ### Buggy Date Calculation (Before Fix) Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Illustrates the incorrect date comparison logic where milliseconds were compared directly against day values, leading to inaccurate age calculations. ```javascript // BUGGY CODE (before fix) const dateDiff = Date.now() - Date.parse(pkgCreatedDate) if (dateDiff < PACKAGE_AGE_THRESHOLD) { // Comparing ms to days! throw new Error(...) } // Also buggy for unmaintained packages const versionDateDiff = new Date() - new Date(versionReleaseDate) const versionDateDiffInDays = Math.round(versionDateDiff / (1000 * 60 * 60 * 24)) if (versionDateDiffInDays >= PACKAGE_AGE_UNMAINTAINED_RISK) { // Inconsistent calculation! throw new Warning(...) } ``` -------------------------------- ### Alias npm to npq-hero Source: https://github.com/lirantal/npq/blob/main/README.md Embed npq into your daily npm usage by aliasing the npm command to npq-hero. This ensures all npm commands are pre-checked by npq. ```bash alias npm='npq-hero' ``` -------------------------------- ### Problematic Pattern in Signatures/Provenance Marshalls Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md Shows the problematic pattern where version ranges were passed directly to the npm registry API without resolution. This led to 'Version not found' errors. ```javascript const packageData = await this.npmRegistry.getManifest(packageName, packageVersion) ``` -------------------------------- ### Disable Provenance Checks with Environment Variable Source: https://github.com/lirantal/npq/blob/main/docs/feature/provenance.md Set the MARSHALL_DISABLE_PROVENANCE environment variable to true to disable all provenance verification for the current run. ```bash export MARSHALL_DISABLE_PROVENANCE=true ``` -------------------------------- ### Core Auto-Continue Function Signature Source: https://github.com/lirantal/npq/blob/main/docs/feature/auto-continue.md The core `autoContinue` function manages the countdown. It accepts a name for the result, a message to display, and the duration in seconds. The default duration is 5 seconds, but npq uses 15 seconds. ```javascript autoContinue({ name, message, timeInSeconds = 5 }) ``` -------------------------------- ### Detect Abandoned Package Source: https://github.com/lirantal/npq/blob/main/docs/age.marshall.md Validate a package using Marshall. If the package's version is older than the unmaintained risk threshold (e.g., 365 days), it throws a warning indicating that the package might be abandoned. ```javascript const marshall = new Marshall({ packageRepoUtils }) await marshall.validate({ packageName: 'old-unmaintained-package', packageVersion: '1.0.0' }) // Throws: Warning('Detected an old package (created 2 years ago)') ``` -------------------------------- ### Run Lint Checks Source: https://github.com/lirantal/npq/blob/main/docs/testing.md Perform linting checks to ensure code quality and style consistency using the npm run lint script. This helps maintain a clean codebase. ```sh npm run lint ``` -------------------------------- ### Disable Provenance Verification Source: https://github.com/lirantal/npq/blob/main/docs/optional-features.md Set the MARSHALL_DISABLE_PROVENANCE environment variable to true to disable package build provenance attestation verification and regression checks. ```bash export MARSHALL_DISABLE_PROVENANCE=true npq install express ``` -------------------------------- ### Exit Code Preservation Logic Source: https://github.com/lirantal/npq/blob/main/docs/feature/alias.md This JavaScript code demonstrates how npq preserves the exit code of the underlying package manager. It uses `process.exitCode` to ensure proper termination after pending I/O and cleanup. ```javascript .then((status) => { if (status && status.install === true) { return pkgMgr.process(packageManagerTool) } }) .then((exitCode) => { if (typeof exitCode === 'number') { process.exitCode = exitCode } }) ``` -------------------------------- ### Signature Verification Fix in signatures.marshall.js Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md This code snippet demonstrates the fix applied to `signatures.marshall.js`. It resolves the package version range to a specific version before calling `npmRegistry.verifySignatures`. ```javascript async validate(pkg) { // Resolve version range to specific version before signature verification const resolvedVersion = await this.resolvePackageVersion(pkg.packageName, pkg.packageVersion) if (!resolvedVersion) { this.setWarning(`Unable to resolve version ${pkg.packageVersion} for package ${pkg.packageName}`) return } try { // Use resolved version for registry API calls await this.npmRegistry.verifySignatures(pkg.packageName, resolvedVersion) // ... rest of validation logic } catch (error) { // ... error handling } } ``` -------------------------------- ### Breaking Change Commit Format Source: https://github.com/lirantal/npq/blob/main/CONTRIBUTING.md For breaking changes, append an exclamation mark to the type and provide a detailed explanation in the commit body. This format is crucial for release automation. ```text feat!: support multiple input files ``` -------------------------------- ### Conventional Commits Format Source: https://github.com/lirantal/npq/blob/main/CONTRIBUTING.md Use this format for commit messages to ensure consistency and enable automated changelog generation. Common types include feat, fix, docs, refactor, test, chore, and perf. ```text (): ``` ```text feat: support multiple input files ``` ```text fix(parser): handle empty input gracefully ``` ```text docs: clarify install instructions ``` -------------------------------- ### Provenance Verification Fix in provenance.marshall.js Source: https://github.com/lirantal/npq/blob/main/docs/feature/signature-verification-fix.md This code snippet shows the fix implemented in `provenance.marshall.js`. It resolves the package version range to a specific version before calling `npmRegistry.verifyAttestations`. ```javascript async validate(pkg) { // Resolve version range to specific version before provenance verification const resolvedVersion = await this.resolvePackageVersion(pkg.packageName, pkg.packageVersion) if (!resolvedVersion) { this.setWarning(`Unable to resolve version ${pkg.packageVersion} for package ${pkg.packageName}`) return } try { // Use resolved version for registry API calls await this.npmRegistry.verifyAttestations(pkg.packageName, resolvedVersion) // ... rest of validation logic } catch (error) { // ... error handling } } ``` -------------------------------- ### Run Specific Exit Code Tests with Jest Source: https://github.com/lirantal/npq/blob/main/docs/feature/alias.md Execute only the exit code related tests using Jest, targeting specific test files. ```bash npx jest __tests__/exitCode.test.js __tests__/packageManager.test.js ``` -------------------------------- ### Reporting Malicious Package Detection Source: https://github.com/lirantal/npq/blob/main/docs/feature/malicious-package.md The reporting mechanism in NPQ identifies malicious packages by checking if an error message includes the specific substring 'Malicious package found'. This check determines special handling for reporting. ```javascript error.message.includes("Malicious package found") ``` -------------------------------- ### NPQ Non-Malicious Vulnerability Error (Snyk) Source: https://github.com/lirantal/npq/blob/main/docs/feature/malicious-package.md If a package has non-malicious vulnerabilities and a Snyk token is configured, NPQ reports the number of vulnerabilities found via the Snyk advisory URL. ```text N vulnerable path(s) found: https://snyk.io/vuln/npm: ``` -------------------------------- ### NPQ Malicious Package Error Message Source: https://github.com/lirantal/npq/blob/main/docs/feature/malicious-package.md When a malicious package is detected, NPQ throws a specific error message that includes a Snyk advisory URL. This message format is used for both Snyk and OSV detection paths. ```text Malicious package found: https://snyk.io/vuln/npm: ``` -------------------------------- ### Disable Auto-Continue with Environment Variable Source: https://github.com/lirantal/npq/blob/main/docs/feature/auto-continue.md Set the `NPQ_DISABLE_AUTO_CONTINUE` environment variable to `true` to disable the auto-continue countdown. This can be done for a single command or set permanently in your shell profile. ```bash export NPQ_DISABLE_AUTO_CONTINUE=true npq install express ``` ```bash NPQ_DISABLE_AUTO_CONTINUE=true npq install express ``` ```bash export NPQ_DISABLE_AUTO_CONTINUE=true ``` -------------------------------- ### Disable Signature Verification Source: https://github.com/lirantal/npq/blob/main/docs/optional-features.md Set the MARSHALL_DISABLE_SIGNATURES environment variable to true to disable npm registry signature verification. ```bash export MARSHALL_DISABLE_SIGNATURES=true npq install express ``` -------------------------------- ### NPQ Non-Malicious Vulnerability Error (OSV) Source: https://github.com/lirantal/npq/blob/main/docs/feature/malicious-package.md When using only the OSV API and non-malicious vulnerabilities are found, NPQ reports the number of vulnerabilities detected by OSV for the specific package. ```text N vulnerabilities found by OSV for ``` -------------------------------- ### Snyk API Malicious Vulnerability Title Source: https://github.com/lirantal/npq/blob/main/docs/feature/malicious-package.md The Snyk API considers a package malicious if any of its vulnerabilities have the specific title 'Malicious Package'. ```text vulnerability.title === "Malicious Package" ```