Skip to content

Commit 76aed58

Browse files
committed
feat(scanner): add npm token based on registry for sdk calls
1 parent 49c5bbb commit 76aed58

File tree

7 files changed

+168
-40
lines changed

7 files changed

+168
-40
lines changed

.changeset/forty-waves-jog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nodesecure/scanner": minor
3+
---
4+
5+
feat(scanner): add npm token based on registry for sdk calls

package-lock.json

Lines changed: 57 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

workspaces/scanner/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@
7070
"type-fest": "^5.0.1"
7171
},
7272
"devDependencies": {
73+
"@npmcli/config": "^10.4.2",
7374
"@types/node": "^24.0.2",
75+
"@types/npmcli__config": "^6.0.3",
7476
"c8": "^10.1.3",
7577
"tsx": "^4.19.4",
7678
"typescript": "^5.8.3"

workspaces/scanner/src/depWalker.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ import { npm } from "@nodesecure/tree-walker";
1313
import { parseAuthor } from "@nodesecure/utils";
1414
import { ManifestManager, parseNpmSpec } from "@nodesecure/mama";
1515
import type { ManifestVersion, PackageJSON, WorkspacesPackageJSON } from "@nodesecure/npm-types";
16-
import { getNpmRegistryURL } from "@nodesecure/npm-registry-sdk";
16+
import { getNpmRegistryURL, getLocalRegistryURL } from "@nodesecure/npm-registry-sdk";
17+
import Config from "@npmcli/config";
1718

1819
// Import Internal Dependencies
1920
import {
2021
getDependenciesWarnings,
2122
addMissingVersionFlags,
2223
getUsedDeps,
23-
getManifestLinks
24+
getManifestLinks,
25+
NPM_TOKEN
2426
} from "./utils/index.js";
2527
import { NpmRegistryProvider } from "./registry/NpmRegistryProvider.js";
2628
import { TempDirectory } from "./class/TempDirectory.class.js";
@@ -79,6 +81,7 @@ const { version: packageVersion } = JSON.parse(
7981
type WalkerOptions = Omit<Options, "registry"> & {
8082
registry: string;
8183
location?: string;
84+
npmRcConfig?: Config;
8285
};
8386

8487
export async function depWalker(
@@ -93,9 +96,15 @@ export async function depWalker(
9396
maxDepth,
9497
location,
9598
vulnerabilityStrategy = Vulnera.strategies.NONE,
96-
registry
99+
registry,
100+
npmRcConfig
97101
} = options;
98102

103+
const registryToken = npmRcConfig?.get(NpmRegistryProvider.getTokenKey(getLocalRegistryURL()), "project") as string | undefined
104+
?? NPM_TOKEN.token;
105+
const publicRegistryToken = npmRcConfig?.get(NpmRegistryProvider.getTokenKey(getNpmRegistryURL())
106+
, "project") as string | undefined ?? NPM_TOKEN.token;
107+
99108
await using tempDir = await TempDirectory.create();
100109

101110
const dependencyConfusionWarnings: DependencyConfusionWarning[] = [];
@@ -150,7 +159,9 @@ export async function depWalker(
150159
const dep = dependencies.get(name)!;
151160
operationsQueue.push(
152161
new NpmRegistryProvider(name, version, {
153-
registry
162+
registry,
163+
registryToken,
164+
publicRegistryToken
154165
}).enrichDependencyVersion(dep, dependencyConfusionWarnings, org)
155166
);
156167

@@ -180,13 +191,19 @@ export async function depWalker(
180191
}
181192
else {
182193
fetchedMetadataPackages.add(name);
183-
const provider = new NpmRegistryProvider(name, version);
194+
const provider = new NpmRegistryProvider(name, version, {
195+
registry,
196+
registryToken,
197+
publicRegistryToken
198+
});
184199

185200
operationsQueue.push(provider.enrichDependency(logger, dependency));
186201
if (registry !== getNpmRegistryURL() && org) {
187202
operationsQueue.push(
188203
new NpmRegistryProvider(name, version, {
189-
registry
204+
registry,
205+
registryToken,
206+
publicRegistryToken
190207
}).enrichScopedDependencyConfusionWarnings(dependencyConfusionWarnings, org)
191208
);
192209
}

workspaces/scanner/src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import pacote from "pacote";
88
import { getLocalRegistryURL } from "@nodesecure/npm-registry-sdk";
99
import * as tarball from "@nodesecure/tarball";
1010
import type { PackageJSON } from "@nodesecure/npm-types";
11+
import Config from "@npmcli/config";
1112

1213
// Import Internal Dependencies
1314
import { depWalker } from "./depWalker.js";
@@ -27,9 +28,13 @@ const kDefaultCwdOptions = {
2728
export * from "./types.js";
2829
export * from "./extractors/index.js";
2930

31+
type CwdOptions = Options & {
32+
npmRcConfig?: Config;
33+
};
34+
3035
export async function cwd(
3136
location = process.cwd(),
32-
options: Options = {},
37+
options: CwdOptions = {},
3338
logger = new Logger()
3439
) {
3540
const registry = options.registry ?

workspaces/scanner/src/registry/NpmRegistryProvider.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ await i18n.extendFromSystemPath(
3030

3131
type PackumentNpmApiOptions = {
3232
registry: string;
33+
token?: string;
3334
};
3435

3536
export interface NpmApiClient {
@@ -42,12 +43,16 @@ export interface NpmRegistryProviderOptions {
4243
dateProvider?: DateProvider;
4344
npmApiClient?: NpmApiClient;
4445
registry?: string;
46+
registryToken?: string;
47+
publicRegistryToken?: string;
4548
}
4649

4750
export class NpmRegistryProvider {
4851
#date: DateProvider | undefined;
4952
#npmApiClient: NpmApiClient;
5053
#registry: string;
54+
#registryToken: string | undefined;
55+
#publicRegistryToken: string | undefined;
5156

5257
name: string;
5358
version: string;
@@ -60,7 +65,9 @@ export class NpmRegistryProvider {
6065
const {
6166
dateProvider = undefined,
6267
npmApiClient = npmRegistrySDK,
63-
registry = npmRegistrySDK.getLocalRegistryURL()
68+
registry = npmRegistrySDK.getLocalRegistryURL(),
69+
registryToken = undefined,
70+
publicRegistryToken = undefined
6471
} = options;
6572

6673
this.name = name;
@@ -69,14 +76,17 @@ export class NpmRegistryProvider {
6976
this.#date = dateProvider;
7077
this.#npmApiClient = npmApiClient;
7178
this.#registry = registry;
79+
this.#registryToken = registryToken;
80+
this.#publicRegistryToken = publicRegistryToken;
7281
}
7382

7483
async collectPackageVersionData() {
7584
const packumentVersion = await this.#npmApiClient.packumentVersion(
7685
this.name,
7786
this.version,
7887
{
79-
registry: this.#registry
88+
registry: this.#registry,
89+
token: this.#registryToken
8090
}
8191
);
8292

@@ -95,7 +105,8 @@ export class NpmRegistryProvider {
95105

96106
async collectPackageData() {
97107
const packument = await this.#npmApiClient.packument(this.name, {
98-
registry: this.#registry
108+
registry: this.#registry,
109+
token: this.#registryToken
99110
});
100111
const packumentVersion = packument.versions[this.version];
101112

@@ -167,7 +178,8 @@ export class NpmRegistryProvider {
167178
}
168179
try {
169180
const packumentVersionFromPublicRegistry = await this.#npmApiClient.packumentVersion(this.name, this.version, {
170-
registry: getNpmRegistryURL()
181+
registry: getNpmRegistryURL(),
182+
token: this.#publicRegistryToken
171183
});
172184
if (!this.#hasSameSignatures(signatures, packumentVersionFromPublicRegistry.dist.signatures)) {
173185
this.#addDependencyConfusionWarning(warnings, await i18n.getToken("scanner.dependency_confusion"));
@@ -185,6 +197,10 @@ export class NpmRegistryProvider {
185197
}
186198
}
187199

200+
static getTokenKey(registry: string) {
201+
return `${registry.replace(/https:|http:/, "")}:_authToken`;
202+
}
203+
188204
#hasSameSignatures(signatures: Signature[] | undefined, signaturesFromPublicRegistry: Signature[] | undefined) {
189205
if (!signatures || !signaturesFromPublicRegistry) {
190206
return false;

0 commit comments

Comments
 (0)