diff --git a/docs/buzz-help.md b/docs/buzz-help.md
index 964380f44c..56e3c3700c 100644
--- a/docs/buzz-help.md
+++ b/docs/buzz-help.md
@@ -72,6 +72,9 @@ the interface unless an available tool actually supports that action.
unavailable until you sign in. Sign-in, sign-out and when the current
sign-in ends also live under
**Settings → Buzz → Identity → Organization sign-in**.
+- When a community requires organization sign-in, the sidebar or join dialog
+ explains why and offers **Sign in with** the organization’s name or server
+ address. Complete sign-in to reconnect; in the join dialog, choose **Continue**.
- Signed in to more than one organization server? **Organization sign-in**
lists each one you're signed in to, with the communities it's used by, and
each **Sign out** ends only that server's sign-in. Your organization's own
diff --git a/src/app/shell/PrimarySidebar.sign-in.test.tsx b/src/app/shell/PrimarySidebar.sign-in.test.tsx
index 4334c97142..b60d433e54 100644
--- a/src/app/shell/PrimarySidebar.sign-in.test.tsx
+++ b/src/app/shell/PrimarySidebar.sign-in.test.tsx
@@ -60,11 +60,18 @@ it("offers explicit sign-in when the live socket refuses a protected community",
const h = await refusedLive("Federated sign-in is required");
// The cached channel list stays; nothing signs in on its own.
expect(screen.getByRole("button", { name: "Chats" })).toBeVisible();
+ expect(
+ await screen.findByText(
+ "This community requires builderlab.example sign-in.",
+ ),
+ ).toBeVisible();
expect(h.identity.service.signIn).not.toHaveBeenCalled();
expect(h.connects()).toBe(1);
- await userEvent
- .setup()
- .click(await screen.findByRole("button", { name: "Sign in" }));
+ await userEvent.setup().click(
+ await screen.findByRole("button", {
+ name: "Sign in with builderlab.example",
+ }),
+ );
expect(h.identity.service.signIn).toHaveBeenCalledOnce();
// A completed sign-in reconnects the live socket with the new session.
await waitFor(() => expect(h.connects()).toBe(2));
@@ -76,7 +83,9 @@ it.each([
])("shows %s recovery from the live socket", async (refusal, text) => {
await refusedLive(refusal);
expect(await screen.findByRole("alert")).toHaveTextContent(text);
- expect(screen.queryByRole("button", { name: "Sign in" })).toBeNull();
+ expect(
+ screen.queryByRole("button", { name: "Sign in with builderlab.example" }),
+ ).toBeNull();
});
it.each(["adapter-refused", "grant-refused", "invalid-response"])(
@@ -87,7 +96,9 @@ it.each(["adapter-refused", "grant-refused", "invalid-response"])(
"Restart Buzz to try again",
);
expect(screen.getByRole("button", { name: "Chats" })).toBeVisible();
- expect(screen.queryByRole("button", { name: "Sign in" })).toBeNull();
+ expect(
+ screen.queryByRole("button", { name: "Sign in with builderlab.example" }),
+ ).toBeNull();
expect(h.connects()).toBe(1);
},
);
diff --git a/src/features/communities/CommunityDialog.test.tsx b/src/features/communities/CommunityDialog.test.tsx
index abbc575532..649a9a5627 100644
--- a/src/features/communities/CommunityDialog.test.tsx
+++ b/src/features/communities/CommunityDialog.test.tsx
@@ -680,13 +680,22 @@ it("offers federated sign-in when joining refuses for it, then lets Continue run
"wss://relay.example",
);
await user.click(screen.getByRole("button", { name: "Continue" }));
- const signIn = await screen.findByRole("button", { name: "Sign in" });
+ expect(
+ await screen.findByText(
+ "This community requires builderlab.example sign-in.",
+ ),
+ ).toBeVisible();
+ const signIn = await screen.findByRole("button", {
+ name: "Sign in with builderlab.example",
+ });
refuse = false;
const requests = vi.mocked(fetch).mock.calls.length;
await user.click(signIn);
expect(h.service.signIn).toHaveBeenCalledOnce();
await waitFor(() =>
- expect(screen.queryByRole("button", { name: "Sign in" })).toBeNull(),
+ expect(
+ screen.queryByRole("button", { name: "Sign in with builderlab.example" }),
+ ).toBeNull(),
);
// Completing login replays nothing captured before it.
expect(vi.mocked(fetch).mock.calls.length).toBe(requests);
@@ -748,7 +757,11 @@ it.each(["edit", "close"])(
const field = screen.getByLabelText("Community URL");
await user.type(field, "wss://old.example");
await user.click(screen.getByRole("button", { name: "Continue" }));
- await user.click(await screen.findByRole("button", { name: "Sign in" }));
+ await user.click(
+ await screen.findByRole("button", {
+ name: "Sign in with builderlab.example",
+ }),
+ );
if (change === "close") view.unmount();
else {
await user.clear(field);
diff --git a/src/features/federated-identity/CommunitySignIn.test.tsx b/src/features/federated-identity/CommunitySignIn.test.tsx
index bf27211aa7..de3d423b44 100644
--- a/src/features/federated-identity/CommunitySignIn.test.tsx
+++ b/src/features/federated-identity/CommunitySignIn.test.tsx
@@ -27,22 +27,32 @@ it.each(["storage-unavailable", "storage-denied"])(
expect(h.service.signIn).not.toHaveBeenCalled();
},
);
-it("requires explicit sign-in before retrying protected community admission", async () => {
- const h = federatedFixture();
- const retry = vi.fn();
- render(
-
This community requires {server} sign-in.
{(failure || state.failure) && (