`pnpm unpublish` sent every registry mutation without `npm-auth-type` and
turned any 401 into ERR_PNPM_UNAUTHORIZED, so an account with 2FA
enforced could never unpublish even though it was logged in: the registry
answered with an OTP challenge the command did not recognize.
Both stacks now run the packument PUT and every tarball/packument DELETE
through the shared OTP session: the first attempt carries a configured
`--otp` (under `npm-auth-type: legacy`), otherwise `npm-auth-type: web`
requests the web-based challenge; a 401 whose body carries
`authUrl`/`doneUrl` starts the browser flow, one mentioning the classic
"one-time pass" wording prompts for a code, and the obtained password is
reused by the remaining requests of the run. Any other 401 stays a plain
authentication failure, now including the registry's body.
The 401-body classification that `dist-tag` and `setDistTag` each carried
privately moves to the web-auth packages
(`SyntheticOtpError.fromUnauthorizedBody` in TypeScript,
`otp_challenge_from_unauthorized_body` in Rust) so all call sites share
it. The Rust unpublish command becomes generic over the web-auth host so
its unit tests can script the challenge flow against a mocked registry.
Closespnpm/pnpm#14464