Skip to content

Commit 6711ea3

Browse files
authored
Merge pull request #1013 from semantic-release/verify-auth
2 parents 1e5ad5e + 8d7149f commit 6711ea3

File tree

4 files changed

+208
-2
lines changed

4 files changed

+208
-2
lines changed

package-lock.json

Lines changed: 114 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
"semantic-release": "24.2.9",
4848
"sinon": "21.0.0",
4949
"stream-buffers": "3.0.3",
50-
"strip-ansi": "7.1.2"
50+
"strip-ansi": "7.1.2",
51+
"testdouble": "3.20.2"
5152
},
5253
"engines": {
5354
"node": ">=20.8.1"

test/integration.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,26 @@ test("Throws error if NPM token is invalid", async (t) => {
111111
t.is(error.message, "Invalid npm token.");
112112
});
113113

114+
test("Throws error if NPM token is not provided", async (t) => {
115+
const cwd = temporaryDirectory();
116+
const env = { DEFAULT_NPM_REGISTRY: npmRegistry.url };
117+
const pkg = { name: "published", version: "1.0.0", publishConfig: { registry: npmRegistry.url } };
118+
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);
119+
120+
const {
121+
errors: [error],
122+
} = await t.throwsAsync(
123+
t.context.m.verifyConditions(
124+
{},
125+
{ cwd, env, options: {}, stdout: t.context.stdout, stderr: t.context.stderr, logger: t.context.logger }
126+
)
127+
);
128+
129+
t.is(error.name, "SemanticReleaseError");
130+
t.is(error.code, "ENONPMTOKEN");
131+
t.is(error.message, "No npm token specified.");
132+
});
133+
114134
test("Skip Token validation if the registry configured is not the default one", async (t) => {
115135
const cwd = temporaryDirectory();
116136
const env = { NPM_TOKEN: "wrong_token" };

test/verify-auth.test.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import test from "ava";
2+
import * as td from "testdouble";
3+
4+
let execa, verifyAuth, getRegistry, setNpmrcAuth;
5+
const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org/";
6+
const npmrc = "npmrc contents";
7+
const pkg = {};
8+
const otherEnvVars = { foo: "bar" };
9+
const env = { DEFAULT_NPM_REGISTRY, ...otherEnvVars };
10+
const cwd = "./path/to/current/working/directory";
11+
const context = { env, cwd };
12+
13+
test.beforeEach(async (t) => {
14+
({ execa } = await td.replaceEsm("execa"));
15+
({ default: getRegistry } = await td.replaceEsm("../lib/get-registry.js"));
16+
({ default: setNpmrcAuth } = await td.replaceEsm("../lib/set-npmrc-auth.js"));
17+
18+
({ default: verifyAuth } = await import("../lib/verify-auth.js"));
19+
});
20+
21+
test.afterEach.always((t) => {
22+
td.reset();
23+
});
24+
25+
test.serial(
26+
"that the provided token is verified with `npm whoami` when trusted publishing is not established for the official registry",
27+
async (t) => {
28+
td.when(getRegistry(pkg, context)).thenReturn(DEFAULT_NPM_REGISTRY);
29+
td.when(
30+
execa("npm", ["whoami", "--userconfig", npmrc, "--registry", DEFAULT_NPM_REGISTRY], {
31+
cwd,
32+
env: otherEnvVars,
33+
preferLocal: true,
34+
})
35+
).thenReturn({
36+
stdout: { pipe: () => undefined },
37+
stderr: { pipe: () => undefined },
38+
});
39+
40+
await t.notThrowsAsync(verifyAuth(npmrc, pkg, context));
41+
}
42+
);
43+
44+
test.serial(
45+
"that the auth context for the official registry is considered invalid when no token is provided and trusted publishing is not established",
46+
async (t) => {
47+
td.when(getRegistry(pkg, context)).thenReturn(DEFAULT_NPM_REGISTRY);
48+
td.when(
49+
execa("npm", ["whoami", "--userconfig", npmrc, "--registry", DEFAULT_NPM_REGISTRY], {
50+
cwd,
51+
env: otherEnvVars,
52+
preferLocal: true,
53+
})
54+
).thenThrow(new Error());
55+
56+
const {
57+
errors: [error],
58+
} = await t.throwsAsync(verifyAuth(npmrc, pkg, context));
59+
60+
t.is(error.name, "SemanticReleaseError");
61+
t.is(error.code, "EINVALIDNPMTOKEN");
62+
t.is(error.message, "Invalid npm token.");
63+
}
64+
);
65+
66+
// since alternative registries are not consistent in implementing `npm whoami`,
67+
// we do not attempt to verify the provided token when publishing to them
68+
test.serial("that `npm whoami` is not invoked when publishing to a custom registry", async (t) => {
69+
td.when(getRegistry(pkg, context)).thenReturn("https://other.registry.org");
70+
71+
await t.notThrowsAsync(verifyAuth(npmrc, pkg, context));
72+
});

0 commit comments

Comments
 (0)