Public: anyone can read this; the crew can change it.

A visitor is told to put someone on a crew that is not theirs #517

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/231-a-visitor-is-told-to-put-someone-on-a-cr → main 1 commit fork

  • Merged. scout/231-a-visitor-is-told-to-put-someone-on-a-cr was merged into main as eb8461c.

Review

Sign in to review this change.
2 files changed +42 −2
src/web/studio/now.ts +5 −2
@@ -291,9 +291,12 @@ export async function nowCard(
291291 return row({
292292 lead: avatar("crew"),
293293 title: html`<a href="${tellHref(base, i.number)}">${i.title}</a>`,
294 // The invitation is a writer's (the shelf's rule, `ownerFacts`); the
295 // fact — nobody has taken it — stays for everyone.
294296 meta: html`told ${time(i.createdAt)} ·
295 <span class="muted">nobody on the crew to take it —</span>
296 <a href="${base}/settings">add someone</a>`,
297 <span class="muted">nobody on the crew to take it</span>${ownerFacts
298 ? html` — <a href="${base}/settings">add someone</a>`
299 : null}`,
297300 trail: wordBadge("told"),
298301 });
299302 }),
test/studio.test.ts +37
@@ -4592,6 +4592,43 @@ describe('a tell nobody on the crew can take is not "quiet"', () => {
45924592 expect(shelfRow).not.toContain("quiet — tell the crew something");
45934593 expect(shelfRow).toContain("nobody on the crew to take it");
45944594 });
4595
4596 test("a reader of the public app sees the fact, not the owner's invitation or a link to settings", async () => {
4597 app.db.run("UPDATE repo SET visibility = 'public' WHERE id = ?", [
4598 repo.id,
4599 ]);
4600 const b = await createUser(app.db, {
4601 username: "bob",
4602 email: "[email protected]",
4603 password: "a-good-passphrase",
4604 });
4605 if (!b.ok) throw new Error(b.error);
4606 const bobCookie = (
4607 (
4608 await fetch(`${base}/signin`, {
4609 method: "POST",
4610 body: new URLSearchParams({
4611 username: "bob",
4612 password: "a-good-passphrase",
4613 }),
4614 redirect: "manual",
4615 })
4616 ).headers.get("set-cookie") ?? ""
4617 ).split(";")[0]!;
4618 const read = await (
4619 await fetch(`${base}/alice/pad`, {
4620 headers: { cookie: `${bobCookie}; forge_mode=studio` },
4621 })
4622 ).text();
4623 expect(read).toContain("Add a dark mode toggle.");
4624 expect(read).toContain("nobody on the crew to take it");
4625 expect(read).not.toContain("add someone");
4626 expect(read).not.toContain(`href="/alice/pad/settings"`);
4627 // The writer still gets the invitation, link included.
4628 const write = await (await get("/alice/pad")).text();
4629 expect(write).toContain("add someone");
4630 expect(write).toContain(`href="/alice/pad/settings"`);
4631 });
45954632 });
45964633
45974634 /**

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs