@pnpm/network.web-auth 1101.5.0 → 1101.6.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @pnpm/network.web-auth
2
2
 
3
+ ## 1101.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - `pnpm unpublish` now completes the two-factor authentication a registry asks for instead of failing with `ERR_PNPM_UNAUTHORIZED` while logged in. A 401 that is an OTP challenge starts the web-based authentication flow, or prompts for a classic one-time password. The obtained password is reused by every request of the run [#14464](https://github.com/pnpm/pnpm/issues/14464).
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies:
12
+ - @pnpm/error@1100.1.4
13
+
3
14
  ## 1101.5.0
4
15
 
5
16
  ### Minor Changes
@@ -96,6 +96,13 @@ export declare class SyntheticOtpError extends Error implements OtpError {
96
96
  readonly code = "EOTP";
97
97
  readonly body?: OtpErrorBody;
98
98
  constructor(body: OtpErrorBody | undefined);
99
+ /**
100
+ * The challenge a `401` response body carries, or `undefined` when the body
101
+ * is a plain authentication failure. A JSON body with both `authUrl` and
102
+ * `doneUrl` is the web-based flow; a body mentioning `one-time pass` (npm's
103
+ * classic wording) is a classic OTP challenge.
104
+ */
105
+ static fromUnauthorizedBody(body: string): SyntheticOtpError | undefined;
99
106
  static fromUnknownBody(globalWarn: OtpContext['globalWarn'], body: unknown): SyntheticOtpError;
100
107
  }
101
108
  export declare class OtpNonInteractiveError extends PnpmError {
@@ -116,6 +116,25 @@ export class SyntheticOtpError extends Error {
116
116
  super('This error was meant to be caught by `withOtpHandling`, not to propagate to other parts of the code');
117
117
  this.body = body;
118
118
  }
119
+ /**
120
+ * The challenge a `401` response body carries, or `undefined` when the body
121
+ * is a plain authentication failure. A JSON body with both `authUrl` and
122
+ * `doneUrl` is the web-based flow; a body mentioning `one-time pass` (npm's
123
+ * classic wording) is a classic OTP challenge.
124
+ */
125
+ static fromUnauthorizedBody(body) {
126
+ const parsed = tryParseJson(body);
127
+ if (parsed != null && typeof parsed === 'object' && 'authUrl' in parsed && 'doneUrl' in parsed) {
128
+ return new SyntheticOtpError({
129
+ authUrl: typeof parsed.authUrl === 'string' ? parsed.authUrl : undefined,
130
+ doneUrl: typeof parsed.doneUrl === 'string' ? parsed.doneUrl : undefined,
131
+ });
132
+ }
133
+ if (body.toLowerCase().includes('one-time pass')) {
134
+ return new SyntheticOtpError(undefined);
135
+ }
136
+ return undefined;
137
+ }
119
138
  static fromUnknownBody(globalWarn, body) {
120
139
  if (body == null || typeof body !== 'object') {
121
140
  return new SyntheticOtpError(undefined);
@@ -141,6 +160,14 @@ export class SyntheticOtpError extends Error {
141
160
  return new SyntheticOtpError({ authUrl, doneUrl });
142
161
  }
143
162
  }
163
+ function tryParseJson(body) {
164
+ try {
165
+ return JSON.parse(body);
166
+ }
167
+ catch {
168
+ return undefined;
169
+ }
170
+ }
144
171
  export class OtpNonInteractiveError extends PnpmError {
145
172
  authUrl;
146
173
  doneUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/network.web-auth",
3
- "version": "1101.5.0",
3
+ "version": "1101.6.0",
4
4
  "description": "Web-based authentication flow with QR code display and token polling",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -28,13 +28,13 @@
28
28
  "!*.map"
29
29
  ],
30
30
  "dependencies": {
31
- "@pnpm/error": "1100.1.3",
32
- "open": "^11.0.1",
31
+ "@pnpm/error": "1100.1.4",
32
+ "open": "^11.0.2",
33
33
  "qrcode-terminal": "^0.12.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@jest/globals": "30.4.1",
37
- "@pnpm/network.web-auth": "1101.5.0",
37
+ "@pnpm/network.web-auth": "1101.6.0",
38
38
  "@types/qrcode-terminal": "^0.12.2"
39
39
  },
40
40
  "engines": {