verify-npm-package-access.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. "use strict";
  2. const access = require("libnpmaccess");
  3. const { pulseTillDone } = require("@lerna/pulse-till-done");
  4. const { ValidationError } = require("@lerna/validation-error");
  5. const { getFetchConfig } = require("./fetch-config");
  6. module.exports.verifyNpmPackageAccess = verifyNpmPackageAccess;
  7. /**
  8. * Throw an error if the logged-in user does not have read-write access to all packages.
  9. * @param {{ name: string; }[]} packages
  10. * @param {string} username
  11. * @param {import("./fetch-config").FetchConfig} options
  12. * @returns {Promise<void>}
  13. */
  14. function verifyNpmPackageAccess(packages, username, options) {
  15. const opts = getFetchConfig(options, {
  16. // don't wait forever for third-party failures to be dealt with
  17. fetchRetries: 0,
  18. });
  19. opts.log.silly("verifyNpmPackageAccess");
  20. return pulseTillDone(access.lsPackages(username, opts)).then(success, failure);
  21. function success(result) {
  22. // when _no_ results received, access.lsPackages returns null
  23. // we can only assume that the packages in question have never been published
  24. if (result === null) {
  25. opts.log.warn(
  26. "",
  27. "The logged-in user does not have any previously-published packages, skipping permission checks..."
  28. );
  29. } else {
  30. for (const pkg of packages) {
  31. if (pkg.name in result && result[pkg.name] !== "read-write") {
  32. throw new ValidationError(
  33. "EACCESS",
  34. `You do not have write permission required to publish "${pkg.name}"`
  35. );
  36. }
  37. }
  38. }
  39. }
  40. function failure(err) {
  41. // pass if registry does not support ls-packages endpoint
  42. if (err.code === "E500" || err.code === "E404") {
  43. // most likely a private registry (npm Enterprise, verdaccio, etc)
  44. opts.log.warn(
  45. "EREGISTRY",
  46. "Registry %j does not support `npm access ls-packages`, skipping permission checks...",
  47. // registry
  48. opts.registry
  49. );
  50. // don't log redundant errors
  51. return;
  52. }
  53. // Log the error cleanly to stderr
  54. opts.log.pause();
  55. console.error(err.message); // eslint-disable-line no-console
  56. opts.log.resume();
  57. throw new ValidationError("EWHOAMI", "Authentication error. Use `npm whoami` to troubleshoot.");
  58. }
  59. }