Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions packages/client-runtime/src/connection/onboarding.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,10 @@ describe("connection onboarding", () => {
}),
},
] as const)(
"leaves a platform-managed $kind environment untouched when its id is paired",
({ registration }) =>
Effect.gen(function* () {
"refuses to pair a host reporting the platform-managed $kind environment's id, keeping the code",
({ registration }) => {
const calls: Array<{ readonly url: string; readonly init: RequestInit }> = [];
return Effect.gen(function* () {
const registry = yield* EnvironmentRegistry.EnvironmentRegistry;
const onboarding = yield* Onboarding.ConnectionOnboarding;
yield* registry.reconcilePlatform([registration]);
Expand All @@ -455,11 +456,18 @@ describe("connection onboarding", () => {
unsupportedReason: UNSUPPORTED_ERROR.message,
});

const environmentId = yield* onboarding.registerPairing(PAIRING_INPUT);
const error = yield* onboarding.registerPairing(PAIRING_INPUT).pipe(Effect.flip);

expect(environmentId).toBe(PAIRED_ENVIRONMENT_ID);
expect(error).toMatchObject({
_tag: "ConnectionBlockedError",
reason: "configuration",
});
expect(calls.map((call) => call.url)).toEqual([
"https://remote.example.test/.well-known/t3/environment",
]);
expect(yield* SubscriptionRef.get(registry.entries)).toEqual(before);
}).pipe(Effect.provide(layerPairingOnboarding())),
}).pipe(Effect.provide(layerPairingOnboarding(undefined, calls)));
},
);

it.effect("leaves a switched-off environment unchanged when the pairing exchange fails", () =>
Expand Down
18 changes: 12 additions & 6 deletions packages/client-runtime/src/connection/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ export class EnvironmentRegistry extends Context.Service<
options?: { readonly knownAddressOnly?: boolean },
) => Effect.Effect<boolean, Persistence.ConnectionPersistenceError | ConnectionBlockedError>;
/**
* Fails when the route would add a new address to a saved user environment. Pairing that does
* not target an environment checks this, because the server reports its own environment id.
* Fails when the route would add a new address to a saved user environment, or names a
* platform-managed one. Pairing that does not target an environment checks this, because the
* server reports its own environment id.
*/
readonly assertKnownAddress: (
route: ConnectionRoute,
Expand Down Expand Up @@ -545,8 +546,13 @@ export const make = Effect.gen(function* () {
route: ConnectionRoute,
) {
const environmentId = route.target.environmentId;
if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) return;
const saved = (yield* SubscriptionRef.get(entries)).get(environmentId);
if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) {
return yield* new ConnectionBlockedError({
reason: "configuration",
detail: `That machine reports the same environment ID as ${saved?.target.label ?? "an environment this app already manages"}, so it can't be added. This happens when one machine's T3 data was copied to another.`,
});
}
if (
saved !== undefined &&
findRouteToSameAddress(connectionRoutes(saved), route) === undefined
Expand All @@ -568,12 +574,12 @@ export const make = Effect.gen(function* () {
return yield* withLeaseLock(
environmentId,
Effect.gen(function* () {
if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) {
return false;
}
if (options?.knownAddressOnly === true) {
yield* assertKnownAddress(route);
}
if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) {
return false;
}
const previous = (yield* SubscriptionRef.get(entries)).get(environmentId);
let entry = registered;
if (previous !== undefined) {
Expand Down
Loading