Commit Graph
6 Commits
Author SHA1 Message Date
Zoltan Kochan f880d91124 fix(pnpr): recognise a unique violation reported by Turso (#17223)
The libsql auth backend classified a duplicate row only through SQLite
result codes. Turso's remote protocol reports it as a Hrana stream error
whose message carries the code name, so the counter seed on a second
start against the same database failed instead of being tolerated, and
pnpr exited at startup. A taken username reported the same way answered
500 instead of the login or name-taken path.

Parse the Hrana message the way the lock-conflict check already does.
Related to https://github.com/pnpm/tasks/issues/183.
2026-10-22 17:36:24 +02:00
Zoltan Kochan 157994e9f4 docs(pnpr): document reverse-proxy and TLS setup, webhooks, lifecycle, and pnprServer (#17013)
* docs(pnpr): document reverse-proxy and TLS setup, webhooks, lifecycle, and pnprServer

Document production deployment and operational architecture for pnpr and
pnpm (Section C13 and Section F of https://github.com/pnpm/tasks/issues/131):

- Add Reverse proxy and TLS deployment guide (pnpr/docs/tls-and-reverse-proxy.md)
  with architecture rationale and configuration recipes for Nginx, Caddy,
  Traefik, and AWS ALB.
- Add Webhooks and event notifications guide (pnpr/docs/webhooks.md)
  documenting the decoupled event architecture, structured audit logs
  (pnpr::audit), and object storage bucket notifications.
- Document signals, readiness probe state transitions, process lifecycle, and
  standard exit codes in pnpr/docs/cli.md.
- Document S3 commit journal lifecycle, multi-replica considerations, and
  disaster recovery caveats in pnpr/docs/storage.md.
- Document the pnprServer workspace setting reference in
  pnpm/docs/settings/dependency-resolution.md and pnpm11/docs/settings/dependency-resolution.md.
- Update sidebars and quick start navigation.

Related to https://github.com/pnpm/tasks/issues/131

* docs(pnpr): clarify pnprServer offloads resolution and streams package metadata

Clarify that pnprServer offloads dependency resolution rather than file
fetching: the server streams back resolved package metadata frames as it walks
the graph so the client can prefetch tarballs from registries in parallel.

* docs(pnpr): address review feedback on Vector remap and pnprServer tarball fetch boundary

- Add remap transform in Vector example in pnpr/docs/webhooks.md to parse
  raw JSON from Docker container logs before filtering audit events.
- Clarify direct public tarball fetching and server-side private upstream
  credential boundaries in pnpm/docs/settings/dependency-resolution.md and
  pnpm11/docs/settings/dependency-resolution.md.

* docs(pnpr): correct probe endpoints, shutdown lifecycle, and log shippers

* docs(pnpr): correct S3 commit journal staging paths and write-ahead sequence

* docs(pnpr): clarify proxy hop coverage and orphan pruning scope

* docs(pnpr): distinguish X-Real-IP from hop traversal and document ALB target port restriction
2026-10-17 11:08:04 +02:00
Zoltan Kochan bc35481b80 feat(pnpr): add maintenance tooling and verdaccio htpasswd support (#17002)
Add maintenance subcommands and migration tooling for pnpr (Section C12 of
https://github.com/pnpm/tasks/issues/131):

- Implement `pnpr config check` (`pnpr config-check`) to validate configuration
  and report diagnostic details on routes, upstreams, auth, storage, and surfaces.
- Implement `pnpr verify` to audit hosted package documents against storage
  blobs, checking for missing files, corrupted checksums, and unreferenced orphans.
- Implement `pnpr export --out <dir>` to dump packages, documents, and blobs,
  with optional `--include-auth` support.
- Implement `pnpr migrate-storage` to migrate hosted packages and blobs from local
  filesystem storage to an S3-compatible object store.
- Support Apache/Verdaccio `{SHA}` format in `pnpr-auth`, automatically upgrading
  authenticated users to bcrypt upon first login, and provide `pnpr import-htpasswd`.
- Add backup and disaster recovery documentation in `pnpr/docs/backup-and-restore.md`
  and update CLI documentation.

Related to https://github.com/pnpm/tasks/issues/131
2026-10-17 01:24:35 +02:00
Zoltan Kochan 7e4db25f84 feat(pnpr): serve the web UI at /-/ui/ (#16769)
pnpr now serves its web UI at /-/ui/ from the same origin, so the UI
needs no CORS setup and no server URL. The UI ships as the separate
`@pnpm/pnpr-ui` package, an optional peer dependency of `@pnpm/pnpr`.
pnpr finds it next to its own package (npm and pnpm both link a resolved
peer beside the package that declares it), or reads it from `ui.dir`,
and `ui.enabled: false` turns it off.

- Serving: files from the UI directory, `index.html` for every other
  path outside `assets/`, a 404 for a missing hashed asset. The page
  gets a relative `<base>` so deep routes and path prefixes work without
  an absolute Vite base. Responses carry a CSP that keeps scripts and
  requests on this origin.
- The UI source stays on bit.cloud. `pnpr/ui` is a workspace of its own
  that pins `@pnpm/pnpr.apps.pnpr-web` from bit.cloud's registry and
  builds it into `pnpr/npm/pnpr-ui/dist`.
- Release: a `build-pnpr-ui` job builds the bundle. The verify and
  publish jobs download it. The smoke test installs the UI beside the
  wrapper and checks that pnpr serves it. `@pnpm/pnpr-ui` releases in a
  fixed group with `@pnpm/pnpr`.
2026-10-09 00:56:04 +02:00
Zoltan Kochan 3b5af3f793 feat(pnpr): deprovision accounts through SCIM (#16742)
With `auth.scim.token`, pnpr serves the SCIM 2.0 `Users` endpoints and
discovery documents under `/-/pnpr/v0/scim/v2`, authenticated only by that
token.

An OIDC sign-in creates no account row and its session lives in one
replica's memory, so deleting an account is not enough to deprovision
anyone. The SCIM directory is therefore one record in the hosted store,
reloaded on the managed-state TTL like rosters and rules. Authentication
refuses any user identity the directory marks inactive, and so does the
npm login endpoint. Deactivating or deleting a user also revokes its
stored tokens, removes its password account, and drops this replica's
browser sessions for it.

A deleted user stays in the record as inactive and unlisted, so the
username keeps being refused until it is provisioned again. Provisioning
creates no password: the identity provider is the sign-in path.

Follow-up of pnpm/tasks#111.
2026-10-08 19:08:16 +02:00
Zoltan Kochan 07839df5c3 docs: move product documentation beside its implementation (#16385)
* docs: move website documentation into the pnpm repository

* docs: keep v11 and v12 documentation beside their implementations

* docs(pnpr): keep registry documentation beside its implementation

* ci: classify product documentation as documentation changes

* test: cover product documentation in Rust CI exclusions

* ci: isolate documentation publishing and support manual sync

* test: make dependency status fixture timestamps deterministic
2026-09-29 15:56:43 +02:00