v0.1.3
Keep the vendored copies out of this package's coverage floor
src/vendor/** is generated and identical in every package that carries it, so
measuring it here counts the same lines N times and holds this package to a
floor for code it cannot change — which is what pushed several suites under
their thresholds the moment the copies landed.
The behaviour is not left unmeasured: it is pinned where it broke, in bay's
quasar-bridge suite, which now covers both manager shapes the loader has to
accept.
Fold back into 0.1.3, which was never published
0.1.3 exists as a tag and never reached npm, so incrementing past it left a
version number nobody can install and a tag marking nothing. The rule is to
fold into an unpublished version and move its tag.
Sort the imports the vendored switch left out of order
Take nodeEnv from the vendored copy
The file was identical to the copies in the other packages, and they had
drifted apart only in their comments. It is generated from
scripts/vendor/nodeEnv.ts now and never edited here.
Take the quasar loader from the vendored copy
Seven packages carried the same optional-peer loader: the runtime specifier,
the manager guard, the command check and the messages around them. Only three
things differed — the commands each issues, what it does with them, and how it
builds an error — so those are passed in and the rest is generated from
scripts/vendor/quasarConnection.ts.
Two things the packages' own tests caught while it was being unified, and both
are now properties of the shared copy rather than of one package:
The module namespace is probed with in before it is read. Reading an export a
namespace does not have is not always harmless — under a test double it raises
instead of answering undefined, so the probe failed on the mock rather than
falling through to the default export.
The error is built by the caller. nova raises NovaError with E_NOVA_* codes
that a caller catches on, and a shared helper throwing a bare Error would have
dropped them silently. Packages that offer a client object instead of a
connection name keep saying so, too: unifying the wording had removed the
alternative from the one message where it was actionable.
Release the SSO manager when the application stops
The provider seated the manager and never released it, so a stopped
application left a live TransitManager reachable through services/main — and
that one holds the SSO providers, so a stale manager answers sign-ins for an
application that no longer exists. It clears its own now, and only its own.
Bound what an unverified message may cost
A SAML response is parsed before its signature is checked — it has to be, the
signature is inside it — so the parser ran on bytes an unauthenticated caller
chose, with no limit on any of them. It duplicated the whole string to
normalise line endings before looking at its size, and it recursed once per
nesting level, so a deep enough document overflowed the stack that had not
verified anything yet.
parseXml now takes limits and defaults them: a megabyte, a hundred levels,
fifty thousand nodes, and two hundred and fifty-six attributes on an element.
The length is checked before the copy, and the depth on the way into the
recursion.
An LDAP length header declares how much is coming before any of it arrives, and
four length bytes can ask for four gigabytes — so the declaration is refused
above eight megabytes rather than the bytes being accumulated. A peer that
sends without ever completing a message is cut off and the socket destroyed.
Lint this package the way its own repository will
biome's configuration lived only at the workspace root. This package is
built from its own repository, where that file does not exist and biome
falls back to its defaults — so lint in CI has been checking a different
set of rules from lint here, and the bans this project actually cares
about were never enforced where it counts.
The config is now the package's own, and says the same thing the root one
did.
Lint the tests, and stop hiding a throw behind an optional chain
Same shape as elsewhere: an optional chain in front of a cast reads like a
guard and is not one. The form bodies now go through a formBody helper
that names the call it read.
Plus the rest of the gates the package already declared.
Changes since v0.1.2.