nestjs-slightly-better-auth 1.5.0 → 1.5.1
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/README.md +2 -1
- package/dist/testing/conformance.cjs +14 -7
- package/dist/testing/conformance.cjs.map +1 -1
- package/dist/testing/conformance.d.cts.map +1 -1
- package/dist/testing/conformance.d.mts.map +1 -1
- package/dist/testing/conformance.mjs +14 -7
- package/dist/testing/conformance.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -387,7 +387,7 @@ runConformance(
|
|
|
387
387
|
|
|
388
388
|
Every case boots real Nest applications or modules with a real Better Auth instance that includes `conformanceProbePlugin()`. The probe counts and faults every operation of the instance's database adapter, so storage outages reach endpoints that would swallow them, and records the `Set-Cookie` lines each call produces. `createConformanceAuth({ plugins })` builds such an instance: memory adapter, `testUtils()`, `bearer()`, the probe plugin, `nestjs()` last, and `session.updateAge: 0` and origin checks on, whatever `options` says. The principal-source and policy kits take that instance as `auth`; the principal-source kit rejects an instance without `session.updateAge: 0`. The transport kit creates its own instance and passes it to your `createApp` harness together with the kit's API-key source in `principals`, a `logger` to boot with, and the `globalScope`, `appEnhancers`, `fieldResolverEnhancers` and `federation` settings of each boot. Apply every fixture decorator, including the kit's `SetMetadata()` marker, which maps the transport's claims to fixtures. On a connection-shaped browser leg, the kit's cookie credential carries the instance's base URL, `http://localhost:3000`, as `Origin`, as a browser page of that origin does; the `T-ws-origin-*` cases pass their own `Origin`, `Host` and forwarding headers, which the harness sends in the handshake.
|
|
389
389
|
|
|
390
|
-
This repository runs the platform kit against Express and Fastify; the transport kit against the built-in HTTP transport, an in-process reference transport, Socket.IO and `ws` (each with and without a principal TTL),
|
|
390
|
+
This repository runs the platform kit against Express and Fastify; the transport kit against the built-in HTTP transport, an in-process reference transport, Socket.IO and `ws` (each with and without a principal TTL), the RPC transport over TCP (standalone and hybrid), gRPC, NATS, RabbitMQ, MQTT, Redis and Kafka, and the Apollo (Express and Fastify) and Mercurius transports over HTTP and over graphql-ws (with and without a subscription principal TTL; Mercurius also without `mercuriusSubscriptionContext()`), with federation 2 subgraphs and a federation 1 run of `T-reference-resolver`; the principal-source kit against the session and API-key sources; and the policy kit against the admin, organization, API-key and fresh-session policies. gRPC skips `T-error-shape`, because it delivers only a status and a message. The kit reads each call's browser leg while its invocation runs, because the GraphQL transports reject a completed request. Mutation tests confirm that each of these defects fails the intended case: a platform merging `Set-Cookie`, a transport sharing invocation state across aliases, a transport without a browser leg on safe operations, a `defineExtension()` transport with a lineage or nesting and no helper, a WebSocket transport that enforces its handshake like a safe read, exempts handshakes that carry a token, builds its leg URL from the bare handshake path or from forwarded headers, or answers internal errors with their cause, a GraphQL transport whose aliases share one invocation, whose lineage gives every field of an operation one position, whose field resolvers do not inherit their root's access, or that serves reference resolvers without field guards, a GraphQL harness that omits `invokeGraph`, `invokeEntities` or `invokeConnection`, a source throwing its denial, a source dropping its refresh cookie, a source turning a storage outage into a 401, and a policy widening delegated principals.
|
|
391
391
|
|
|
392
392
|
## Develop in this monorepo
|
|
393
393
|
|
|
@@ -410,6 +410,7 @@ The shared toolchain uses Node.js LTS, pnpm, tsdown, TypeScript and Vitest. Buil
|
|
|
410
410
|
Each example application registers a default and a named instance, reads the signed-in user through the `@CurrentUser()` principal parameter and starts without external services:
|
|
411
411
|
|
|
412
412
|
- [Express](../../examples/better-auth-express/README.md) and [Fastify](../../examples/better-auth-fastify/README.md) guard HTTP routes on their platforms.
|
|
413
|
+
- [Apollo GraphQL](../../examples/better-auth-graphql/README.md) authenticates queries and mutations over HTTP and every graphql-ws operation, with the named instance bound to its own resolver.
|
|
413
414
|
- [Socket.IO](../../examples/better-auth-websockets/README.md) authenticates gateway connections and every message, with the named instance on its own namespace.
|
|
414
415
|
- [TCP microservice](../../examples/better-auth-rpc/README.md) authenticates the messages of a hybrid application through the payload credential carrier.
|
|
415
416
|
|
|
@@ -2414,12 +2414,18 @@ function instrument(app) {
|
|
|
2414
2414
|
const state = {
|
|
2415
2415
|
consumed: [],
|
|
2416
2416
|
contexts: [],
|
|
2417
|
-
|
|
2417
|
+
legs: [],
|
|
2418
|
+
unavailable: false,
|
|
2419
|
+
recordLegs: false
|
|
2418
2420
|
};
|
|
2419
2421
|
const original = registry.describe.bind(registry);
|
|
2420
2422
|
registry.describe = (context, transport) => {
|
|
2421
2423
|
const call = original(context, transport);
|
|
2422
2424
|
state.contexts.push(context);
|
|
2425
|
+
if (state.recordLegs) {
|
|
2426
|
+
const browser = call.browser;
|
|
2427
|
+
state.legs.push(browser === void 0 ? "none" : browser.key === call.key ? "operation" : "connection");
|
|
2428
|
+
}
|
|
2423
2429
|
const read = (name, get) => {
|
|
2424
2430
|
state.consumed.push(name);
|
|
2425
2431
|
if (state.unavailable) throw require_auth_errors.BetterAuthConfigurationError.atRequest("CONFORMANCE_EXTRACTION_UNAVAILABLE", "The conformance kit made request extraction unavailable");
|
|
@@ -2573,12 +2579,11 @@ async function transportHas(options, env, member) {
|
|
|
2573
2579
|
async function connectionShaped(options) {
|
|
2574
2580
|
let shaped = false;
|
|
2575
2581
|
await withApp(options, await environment(), async ({ app, instrumentation }) => {
|
|
2582
|
+
instrumentation.recordLegs = true;
|
|
2576
2583
|
succeeded(await options.invoke(app, "optional", {}), "an anonymous optional invocation");
|
|
2577
|
-
const [
|
|
2578
|
-
node_assert_strict.default.ok(
|
|
2579
|
-
|
|
2580
|
-
const browser = call.browser;
|
|
2581
|
-
shaped = browser !== void 0 && browser.key !== call.key;
|
|
2584
|
+
const [leg] = instrumentation.legs;
|
|
2585
|
+
node_assert_strict.default.ok(leg, "the guard described no invocation");
|
|
2586
|
+
shaped = leg === "connection";
|
|
2582
2587
|
});
|
|
2583
2588
|
return shaped;
|
|
2584
2589
|
}
|
|
@@ -2674,8 +2679,10 @@ function transportConformance(options) {
|
|
|
2674
2679
|
add("T-selection", "handles() accepts its contexts with and without credentials and rejects foreign ones", (env) => withApp(options, env, async ({ app, instrumentation }) => {
|
|
2675
2680
|
const transport = resolvedTransport(app, options.transport);
|
|
2676
2681
|
const registry = app.get(require_decorate.TRANSPORT_REGISTRY, { strict: false });
|
|
2682
|
+
instrumentation.recordLegs = !options.expectBrowserLeg;
|
|
2677
2683
|
succeeded(await options.invoke(app, "optional", {}));
|
|
2678
|
-
|
|
2684
|
+
instrumentation.recordLegs = false;
|
|
2685
|
+
for (const leg of instrumentation.legs) node_assert_strict.default.equal(leg, "none", "the transport describes a browser leg, so expectBrowserLeg must be true");
|
|
2679
2686
|
succeeded(await options.invoke(app, "optional", cookie(env)));
|
|
2680
2687
|
node_assert_strict.default.ok(instrumentation.contexts.length >= 2, "the guard described no invocation");
|
|
2681
2688
|
for (const context of instrumentation.contexts) {
|