Skip to content

Commit

Permalink
fix: remove support for legacy auth
Browse files Browse the repository at this point in the history
BREAKING CHANGE: legacy authentication using `NPM_USERNAME` and `NPM_PASSWORD` is no longer supported. Use `NPM_TOKEN` instead.
  • Loading branch information
gr2m committed Jan 13, 2023
1 parent c5036aa commit 51ab3c8
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 119 deletions.
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,8 @@ Both the [token](https://docs.npmjs.com/getting-started/working_with_tokens) and
| Variable | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `NPM_TOKEN` | Npm token created via [npm token create](https://docs.npmjs.com/getting-started/working_with_tokens#how-to-create-new-tokens) |
| `NPM_USERNAME` | Npm username created via [npm adduser](https://docs.npmjs.com/cli/adduser) or on [npmjs.com](https://www.npmjs.com) |
| `NPM_PASSWORD` | Password of the npm user. |
| `NPM_EMAIL` | Email address associated with the npm user |
| `NPM_CONFIG_USERCONFIG` | Path to non-default .npmrc file |

Use either `NPM_TOKEN` for token authentication or `NPM_USERNAME`, `NPM_PASSWORD` and `NPM_EMAIL` for legacy authentication

### Options

| Options | Description | Default |
Expand Down
9 changes: 0 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { castArray, defaultTo } from "lodash-es";
import AggregateError from "aggregate-error";
import { temporaryFile } from "tempy";
import setLegacyToken from "./lib/set-legacy-token.js";
import getPkg from "./lib/get-pkg.js";
import verifyNpmConfig from "./lib/verify-config.js";
import verifyNpmAuth from "./lib/verify-auth.js";
Expand All @@ -26,8 +25,6 @@ export async function verifyConditions(pluginConfig, context) {

const errors = verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
const pkg = await getPkg(pluginConfig, context);

Expand All @@ -49,8 +46,6 @@ export async function verifyConditions(pluginConfig, context) {
export async function prepare(pluginConfig, context) {
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
// Reload package.json in case a previous external step updated it
const pkg = await getPkg(pluginConfig, context);
Expand All @@ -73,8 +68,6 @@ export async function publish(pluginConfig, context) {
let pkg;
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
// Reload package.json in case a previous external step updated it
pkg = await getPkg(pluginConfig, context);
Expand All @@ -100,8 +93,6 @@ export async function addChannel(pluginConfig, context) {
let pkg;
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
// Reload package.json in case a previous external step updated it
pkg = await getPkg(pluginConfig, context);
Expand Down
6 changes: 0 additions & 6 deletions lib/set-legacy-token.js

This file was deleted.

14 changes: 2 additions & 12 deletions lib/set-npmrc-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import nerfDart from "nerf-dart";
import AggregateError from "aggregate-error";
import getError from "./get-error.js";

export default async function (
npmrc,
registry,
{ cwd, env: { NPM_TOKEN, NPM_CONFIG_USERCONFIG, NPM_USERNAME, NPM_PASSWORD, NPM_EMAIL }, logger }
) {
export default async function (npmrc, registry, { cwd, env: { NPM_TOKEN, NPM_CONFIG_USERCONFIG }, logger }) {
logger.log("Verify authentication for registry %s", registry);
const { configs, ...rcConfig } = rc(
"npm",
Expand All @@ -29,13 +25,7 @@ export default async function (
return;
}

if (NPM_USERNAME && NPM_PASSWORD && NPM_EMAIL) {
await fs.outputFile(
npmrc,
`${currentConfig ? `${currentConfig}\n` : ""}_auth = \${LEGACY_TOKEN}\nemail = \${NPM_EMAIL}`
);
logger.log(`Wrote NPM_USERNAME, NPM_PASSWORD and NPM_EMAIL to ${npmrc}`);
} else if (NPM_TOKEN) {
if (NPM_TOKEN) {
await fs.outputFile(
npmrc,
`${currentConfig ? `${currentConfig}\n` : ""}${nerfDart(registry)}:_authToken = \${NPM_TOKEN}`
Expand Down
21 changes: 14 additions & 7 deletions test/helpers/npm-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import path from "path";
import delay from "delay";
import pRetry from "p-retry";

const IMAGE = "verdaccio/verdaccio:4";
const IMAGE = "verdaccio/verdaccio:5";
const REGISTRY_PORT = 4873;
const REGISTRY_HOST = "localhost";
const NPM_USERNAME = "integration";
Expand All @@ -16,7 +16,7 @@ const NPM_EMAIL = "integration@test.com";
const docker = new Docker();
const __dirname = dirname(fileURLToPath(import.meta.url));

let container;
let container, npmToken;

/**
* Download the `npm-registry-docker` Docker image, create a new container and start it.
Expand Down Expand Up @@ -57,16 +57,23 @@ export async function start() {
email: NPM_EMAIL,
},
});

// Create token for user
({ token: npmToken } = await got(`http://${REGISTRY_HOST}:${REGISTRY_PORT}/-/npm/v1/tokens`, {
username: NPM_USERNAME,
password: NPM_PASSWORD,
method: "POST",
headers: { "content-type": "application/json" },
json: { password: NPM_PASSWORD, readonly: false, cidr_whitelist: [] },
}).json());
}

export const url = `http://${REGISTRY_HOST}:${REGISTRY_PORT}/`;

export const authEnv = {
export const authEnv = () => ({
npm_config_registry: url, // eslint-disable-line camelcase
NPM_USERNAME,
NPM_PASSWORD,
NPM_EMAIL,
};
NPM_TOKEN: npmToken,
});

/**
* Stop and remove the `npm-registry-docker` Docker container.
Expand Down
53 changes: 26 additions & 27 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ import * as npmRegistry from "./helpers/npm-registry.js";
/* eslint camelcase: ["error", {properties: "never"}] */

// Environment variables used only for the local npm command used to do verification
const testEnv = {
...process.env,
...npmRegistry.authEnv,
npm_config_registry: npmRegistry.url,
LEGACY_TOKEN: Buffer.from(`${npmRegistry.authEnv.NPM_USERNAME}:${npmRegistry.authEnv.NPM_PASSWORD}`, "utf8").toString(
"base64"
),
};
let testEnv;

test.before(async () => {
// Start the local NPM registry
await npmRegistry.start();

testEnv = {
...process.env,
...npmRegistry.authEnv(),
npm_config_registry: npmRegistry.url,
};
});

test.after.always(async () => {
Expand Down Expand Up @@ -131,7 +130,7 @@ test("Verify npm auth and package", async (t) => {
{},
{
cwd,
env: npmRegistry.authEnv,
env: npmRegistry.authEnv(),
options: {},
stdout: t.context.stdout,
stderr: t.context.stderr,
Expand All @@ -150,7 +149,7 @@ test("Verify npm auth and package from a sub-directory", async (t) => {
{ pkgRoot: "dist" },
{
cwd,
env: npmRegistry.authEnv,
env: npmRegistry.authEnv(),
options: {},
stdout: t.context.stdout,
stderr: t.context.stderr,
Expand All @@ -169,7 +168,7 @@ test('Verify npm auth and package with "npm_config_registry" env var set by yarn
{},
{
cwd,
env: { ...npmRegistry.authEnv, npm_config_registry: "https://registry.yarnpkg.com" },
env: { ...npmRegistry.authEnv(), npm_config_registry: "https://registry.yarnpkg.com" },
options: { publish: [] },
stdout: t.context.stdout,
stderr: t.context.stderr,
Expand Down Expand Up @@ -216,7 +215,7 @@ test("Throw SemanticReleaseError Array if config option are not valid in verifyC

test("Publish the package", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "publish", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand All @@ -241,7 +240,7 @@ test("Publish the package", async (t) => {

test("Publish the package on a dist-tag", async (t) => {
const cwd = temporaryDirectory();
const env = { ...npmRegistry.authEnv, DEFAULT_NPM_REGISTRY: npmRegistry.url };
const env = { ...npmRegistry.authEnv(), DEFAULT_NPM_REGISTRY: npmRegistry.url };
const pkg = { name: "publish-tag", version: "0.0.0", publishConfig: { registry: npmRegistry.url, tag: "next" } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand Down Expand Up @@ -270,7 +269,7 @@ test("Publish the package on a dist-tag", async (t) => {

test("Publish the package from a sub-directory", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "publish-sub-dir", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "dist/package.json"), pkg);

Expand All @@ -295,7 +294,7 @@ test("Publish the package from a sub-directory", async (t) => {

test('Create the package and skip publish ("npmPublish" is false)', async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "skip-publish", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand All @@ -320,7 +319,7 @@ test('Create the package and skip publish ("npmPublish" is false)', async (t) =>

test('Create the package and skip publish ("package.private" is true)', async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = {
name: "skip-publish-private",
version: "0.0.0",
Expand Down Expand Up @@ -350,7 +349,7 @@ test('Create the package and skip publish ("package.private" is true)', async (t

test('Create the package and skip publish from a sub-directory ("npmPublish" is false)', async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "skip-publish-sub-dir", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "dist/package.json"), pkg);

Expand All @@ -375,7 +374,7 @@ test('Create the package and skip publish from a sub-directory ("npmPublish" is

test('Create the package and skip publish from a sub-directory ("package.private" is true)', async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = {
name: "skip-publish-sub-dir-private",
version: "0.0.0",
Expand Down Expand Up @@ -440,7 +439,7 @@ test("Throw SemanticReleaseError Array if config option are not valid in publish

test("Prepare the package", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "prepare", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand All @@ -463,7 +462,7 @@ test("Prepare the package", async (t) => {

test("Prepare the package from a sub-directory", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "prepare-sub-dir", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "dist/package.json"), pkg);

Expand Down Expand Up @@ -521,7 +520,7 @@ test("Throw SemanticReleaseError Array if config option are not valid in prepare

test("Publish the package and add to default dist-tag", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "add-channel", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand Down Expand Up @@ -557,7 +556,7 @@ test("Publish the package and add to default dist-tag", async (t) => {

test("Publish the package and add to lts dist-tag", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "add-channel-legacy", version: "1.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand Down Expand Up @@ -596,7 +595,7 @@ test("Publish the package and add to lts dist-tag", async (t) => {

test('Skip adding the package to a channel ("npmPublish" is false)', async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "skip-add-channel", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand All @@ -619,7 +618,7 @@ test('Skip adding the package to a channel ("npmPublish" is false)', async (t) =

test('Skip adding the package to a channel ("package.private" is true)', async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = {
name: "skip-add-channel-private",
version: "0.0.0",
Expand Down Expand Up @@ -647,7 +646,7 @@ test('Skip adding the package to a channel ("package.private" is true)', async (

test("Create the package in addChannel step", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "add-channel-pkg", version: "0.0.0", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand All @@ -670,7 +669,7 @@ test("Create the package in addChannel step", async (t) => {

test("Throw SemanticReleaseError Array if config option are not valid in addChannel", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);
const npmPublish = 42;
Expand Down Expand Up @@ -706,7 +705,7 @@ test("Throw SemanticReleaseError Array if config option are not valid in addChan

test("Verify token and set up auth only on the fist call, then prepare on prepare call only", async (t) => {
const cwd = temporaryDirectory();
const env = npmRegistry.authEnv;
const env = npmRegistry.authEnv();
const pkg = { name: "test-module", version: "0.0.0-dev", publishConfig: { registry: npmRegistry.url } };
await fs.outputJson(path.resolve(cwd, "package.json"), pkg);

Expand Down
Loading

0 comments on commit 51ab3c8

Please sign in to comment.