Skip to content
Merged
Show file tree
Hide file tree
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
17 changes: 1 addition & 16 deletions packages/angular/cli/src/utilities/package-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ export interface PackageManifest extends Manifest, NgPackageManifestProperties {
deprecated?: boolean;
}

interface PackageManagerOptions extends Record<string, unknown> {
forceAuth?: Record<string, unknown>;
}
type PackageManagerOptions = Record<string, unknown>;

let npmrc: PackageManagerOptions;
const npmPackageJsonCache = new Map<string, Promise<Partial<NpmRepositoryPackageJson>>>();
Expand Down Expand Up @@ -174,19 +172,6 @@ function normalizeOptions(
}

switch (key) {
// Unless auth options are scope with the registry url it appears that npm-registry-fetch ignores them,
// even though they are documented.
// https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/README.md
// https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/auth.js#L45-L91
case '_authToken':
case 'token':
case 'username':
case 'password':
case '_auth':
case 'auth':
options['forceAuth'] ??= {};
options['forceAuth'][key] = substitutedValue;
break;
case 'noproxy':
case 'no-proxy':
options['noProxy'] = substitutedValue;
Expand Down
17 changes: 3 additions & 14 deletions tests/legacy-cli/e2e/tests/commands/add/secure-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,14 @@ import { expectToFail } from '../../../utils/utils';
export default async function () {
// The environment variable has priority over the .npmrc
delete process.env['NPM_CONFIG_REGISTRY'];
delete process.env['YARN_REGISTRY'];
delete process.env['NPM_CONFIG__AUTH'];
delete process.env['NPM_CONFIG_ALWAYS_AUTH'];
const isNpm = getActivePackageManager() === 'npm';

const command = ['add', '@angular/pwa', '--skip-confirmation'];
await expectFileNotToExist('public/manifest.webmanifest');

// Works with unscoped registry authentication details
if (!isNpm) {
// NPM no longer support unscoped.
await createNpmConfigForAuthentication(false);
await ng(...command);
await expectFileToExist('public/manifest.webmanifest');
await git('clean', '-dxf');
}
// Works with scoped registry authentication details
await expectFileNotToExist('public/manifest.webmanifest');

Expand All @@ -28,12 +23,6 @@ export default async function () {
await expectFileToExist('public/manifest.webmanifest');

// Invalid authentication token
if (isNpm) {
// NPM no longer support unscoped.
await createNpmConfigForAuthentication(false, true);
await expectToFail(() => ng(...command));
}

await createNpmConfigForAuthentication(true, true);
await expectToFail(() => ng(...command));

Expand Down
6 changes: 6 additions & 0 deletions tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export default async function () {
await appendFile('.npmrc', '\nlegacy-peer-deps=true\n');
}

// If using yarn, ignore engines check. Otherwise installing '@latest' package versions
// might fail if they require a newer Node.js runtime version than the E2E test runner.
if (getActivePackageManager() === 'yarn') {
await appendFile('.yarnrc', '\nignore-engines true\n');
}

const tag = isPrereleaseCli() ? '@next' : '';

await ng('add', `@angular/localize${tag}`, '--skip-confirmation');
Expand Down
51 changes: 37 additions & 14 deletions tests/legacy-cli/e2e/tests/commands/add/yarn-env-vars.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { readFile, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { getGlobalVariable } from '../../../utils/env';
import { expectFileNotToExist, expectFileToExist } from '../../../utils/fs';
import { getActivePackageManager } from '../../../utils/packages';
import { git, ng } from '../../../utils/process';
import {
createNpmConfigForAuthentication,
setNpmEnvVarsForAuthentication,
} from '../../../utils/registry';
import { VALID_TOKEN } from '../../../utils/registry';

export default async function () {
// Yarn specific test that tests YARN_ env variables.
Expand All @@ -14,16 +14,39 @@ export default async function () {
}
const command = ['add', '@angular/pwa', '--skip-confirmation'];

// Environment variables only
await expectFileNotToExist('public/manifest.webmanifest');
setNpmEnvVarsForAuthentication(false, true);
await ng(...command);
await expectFileToExist('public/manifest.webmanifest');
await git('clean', '-dxf');
// Clean up any potential env vars first
delete process.env['NPM_CONFIG_REGISTRY'];
delete process.env['YARN_REGISTRY'];
delete process.env['NPM_CONFIG__AUTH'];
delete process.env['NPM_CONFIG_ALWAYS_AUTH'];

// Mix of config file and env vars works
await expectFileNotToExist('public/manifest.webmanifest');
await createNpmConfigForAuthentication(false, true);
await ng(...command);
await expectFileToExist('public/manifest.webmanifest');

// Set the registry via YARN_REGISTRY environment variable
const registryUrl = getGlobalVariable('package-secure-registry') as string;
process.env['YARN_REGISTRY'] = registryUrl;

// Read the original user config to restore later
const tempRoot = getGlobalVariable('tmp-root') as string;
const userNpmrcPath = join(tempRoot, '.npmrc');
const originalUserNpmrc = await readFile(userNpmrcPath, 'utf8');

// Write the scoped auth credentials to the user config .npmrc
const registryHost = registryUrl.replace(/^\w+:/, '');
await writeFile(
userNpmrcPath,
originalUserNpmrc +
`\n${registryHost}/:_auth="${VALID_TOKEN}"` +
`\n${registryHost}/:always-auth=true` +
`\nalways-auth=true\n`,
);

try {
await ng(...command);
await expectFileToExist('public/manifest.webmanifest');
} finally {
// Clean up and restore
delete process.env['YARN_REGISTRY'];
await writeFile(userNpmrcPath, originalUserNpmrc);
}
}
12 changes: 3 additions & 9 deletions tests/legacy-cli/e2e/tests/update/update-secure-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import assert from 'node:assert';
export default async function () {
// The environment variable has priority over the .npmrc
delete process.env['NPM_CONFIG_REGISTRY'];
delete process.env['YARN_REGISTRY'];
delete process.env['NPM_CONFIG__AUTH'];
delete process.env['NPM_CONFIG_ALWAYS_AUTH'];
const worksMessage = 'We analyzed your package.json';

const extraArgs: string[] = [];
Expand All @@ -16,22 +19,13 @@ export default async function () {
}

// Valid authentication token
await createNpmConfigForAuthentication(false);
const { stdout: stdout1 } = await ng('update', ...extraArgs);
if (!stdout1.includes(worksMessage)) {
throw new Error(`Expected stdout to contain "${worksMessage}"`);
}

await createNpmConfigForAuthentication(true);
const { stdout: stdout2 } = await ng('update', ...extraArgs);
if (!stdout2.includes(worksMessage)) {
throw new Error(`Expected stdout to contain "${worksMessage}"`);
}

// Invalid authentication token
await createNpmConfigForAuthentication(false, true);
await expectToFail(() => ng('update', ...extraArgs));

await createNpmConfigForAuthentication(true, true);
await expectToFail(() => ng('update', ...extraArgs));

Expand Down
6 changes: 4 additions & 2 deletions tests/legacy-cli/e2e/utils/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export async function createNpmRegistry(
}

// Token was generated using `echo -n 'testing:s3cret' | openssl base64`.
const VALID_TOKEN = `dGVzdGluZzpzM2NyZXQ=`;
export const VALID_TOKEN = `dGVzdGluZzpzM2NyZXQ=`;

export function createNpmConfigForAuthentication(
/**
Expand All @@ -69,7 +69,9 @@ export function createNpmConfigForAuthentication(
'.npmrc',
scopedAuthentication
? `
${registry}:_auth="${token}"
${registry}/:_auth="${token}"
${registry}/:always-auth=true
always-auth=true
registry=http:${registry}
`
: `
Expand Down
Loading