@pnpm/auth.commands 1100.1.1 → 1100.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/login.d.ts CHANGED
@@ -32,12 +32,7 @@ export interface LoginFetchResponseHeaders {
32
32
  }
33
33
  export interface LoginFetchOptions {
34
34
  method?: 'GET' | 'POST' | 'PUT';
35
- headers?: {
36
- accept: 'application/json';
37
- 'content-type': 'application/json';
38
- 'npm-auth-type': 'web';
39
- 'npm-otp'?: string;
40
- };
35
+ headers?: Record<string, string>;
41
36
  body?: string;
42
37
  retry?: {
43
38
  factor?: number;
package/lib/login.js CHANGED
@@ -6,6 +6,7 @@ import { PnpmError } from '@pnpm/error';
6
6
  import { globalInfo, globalWarn } from '@pnpm/logger';
7
7
  import { fetch } from '@pnpm/network.fetch';
8
8
  import { generateQrCode, pollForWebAuthToken, promptBrowserOpen, SyntheticOtpError, withOtpHandling, } from '@pnpm/network.web-auth';
9
+ import { addUser, AddUserHttpError, AddUserNoTokenError } from '@pnpm/registry-access.client';
9
10
  import enquirer from 'enquirer';
10
11
  import normalizeRegistryUrl from 'normalize-registry-url';
11
12
  import { readIniFile } from 'read-ini-file';
@@ -164,63 +165,38 @@ async function classicLogin({ context, fetchOptions, registry, }) {
164
165
  if (!username || !password || !email) {
165
166
  throw new LoginMissingCredentialsError();
166
167
  }
167
- const loginUrl = new URL(`-/user/org.couchdb.user:${encodeURIComponent(username)}`, registry).href;
168
168
  const token = await withOtpHandling({
169
169
  context,
170
170
  fetchOptions,
171
171
  operation: async (otp) => {
172
- const response = await fetch(loginUrl, {
173
- method: 'PUT',
174
- headers: {
175
- 'content-type': 'application/json',
176
- accept: 'application/json',
177
- 'npm-auth-type': 'web',
178
- // Conditionally include npm-otp: some HTTP implementations coerce
179
- // `undefined` to the string "undefined", which would send a bad header
180
- // on the initial attempt (before OTP is known).
181
- ...(otp != null ? { 'npm-otp': otp } : {}),
182
- },
183
- body: JSON.stringify({
184
- _id: `org.couchdb.user:${username}`,
185
- name: username,
172
+ try {
173
+ const result = await addUser({
174
+ username,
186
175
  password,
187
176
  email,
188
- type: 'user',
189
- }),
190
- });
191
- if (!response.ok) {
192
- await throwIfOtpRequired(globalWarn, response);
193
- const text = await response.text();
194
- throw new ClassicLoginError(response.status, text);
177
+ otp,
178
+ registryUrl: registry,
179
+ fetch,
180
+ });
181
+ return result.token;
195
182
  }
196
- const body = await response.json();
197
- if (!body.token) {
198
- throw new LoginNoTokenError();
183
+ catch (err) {
184
+ if (err instanceof AddUserHttpError) {
185
+ if (err.status === 401 && err.responseHeaders.get('www-authenticate')?.includes('otp')) {
186
+ throw SyntheticOtpError.fromUnknownBody(globalWarn, err.responseJson);
187
+ }
188
+ throw new ClassicLoginError(err.status, err.responseText);
189
+ }
190
+ if (err instanceof AddUserNoTokenError) {
191
+ throw new LoginNoTokenError();
192
+ }
193
+ throw err;
199
194
  }
200
- return body.token;
201
195
  },
202
196
  });
203
197
  globalInfo(`Logged in as ${username}`);
204
198
  return token;
205
199
  }
206
- /**
207
- * Inspects a non-ok HTTP response for OTP requirements and throws an EOTP
208
- * error when detected. This mirrors the behaviour of npm-registry-fetch,
209
- * which checks the `www-authenticate` header for one-time password indicators.
210
- */
211
- async function throwIfOtpRequired(globalWarn, response) {
212
- if (response.status !== 401)
213
- return;
214
- const wwwAuth = response.headers.get('www-authenticate');
215
- if (!wwwAuth?.includes('otp'))
216
- return;
217
- let body;
218
- try {
219
- body = await response.json();
220
- }
221
- catch { }
222
- throw SyntheticOtpError.fromUnknownBody(globalWarn, body);
223
- }
224
200
  class LoginNonInteractiveError extends PnpmError {
225
201
  constructor() {
226
202
  super('LOGIN_NON_INTERACTIVE', 'The login command requires an interactive terminal');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/auth.commands",
3
- "version": "1100.1.1",
3
+ "version": "1100.1.2",
4
4
  "description": "Commands for authentication with npm registries",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -30,18 +30,19 @@
30
30
  "read-ini-file": "5.0.0",
31
31
  "render-help": "^2.0.0",
32
32
  "write-ini-file": "5.0.0",
33
- "@pnpm/cli.utils": "1101.0.7",
33
+ "@pnpm/cli.utils": "1101.0.8",
34
+ "@pnpm/config.reader": "1101.4.1",
35
+ "@pnpm/network.fetch": "1100.0.7",
34
36
  "@pnpm/error": "1100.0.0",
35
- "@pnpm/network.web-auth": "1101.0.0",
36
- "@pnpm/network.fetch": "1100.0.6",
37
- "@pnpm/config.reader": "1101.4.0"
37
+ "@pnpm/registry-access.client": "1100.0.1",
38
+ "@pnpm/network.web-auth": "1101.0.0"
38
39
  },
39
40
  "peerDependencies": {
40
- "@pnpm/logger": ">=1001.0.0 <1002.0.0"
41
+ "@pnpm/logger": "^1001.0.1"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@jest/globals": "30.3.0",
44
- "@pnpm/auth.commands": "1100.1.1",
45
+ "@pnpm/auth.commands": "1100.1.2",
45
46
  "@pnpm/logger": "1100.0.0"
46
47
  },
47
48
  "engines": {