mirror of
https://github.com/runbear-io/beardrive.git
synced 2026-08-25 08:08:08 +02:00
An org owner minted /join/<token>, pasted it into Slack, and the recipient signed up and landed on a list of projects with nothing saying which one they were invited for. The page that finishes the job — /<project-id>/install, which bakes this hub's origin and this project's id into the agent paste prompt — was one click away and nobody told them to click it. The link may now carry ?p=<project-id>, minted from a project's Settings, and the joiner lands on that project's install page. Three edits and one hook: - inviteTokenFromNext cuts `next` at the FIRST "?" before the /join/<hex> check. Without it a logged-out invitee on an invite-only hub (the default posture) silently loses the account-creation form — the recipient who most needs the feature is the one it broke. Every existing negative stays closed: "/wiki/note.md?x=/join/<tok>" cuts to "/wiki/note.md" and still fails the prefix. - useFetchProjects: useProjects is disabled while the join screen is up and invalidateQueries never fetches a disabled query, so the "does p resolve" check had to fetch rather than refresh — otherwise it silently always fails. - HubApp navigates to /<p>/install only when p is in the list the server just returned. That resolve IS the validator: p="/evil.com" would build "//evil.com/install" and pushState throws on a cross-origin target. Anything unresolvable lands on "/", never on "Project not found" — right for a typed URL, wrong as a new teammate's first screen. - ProjectSettings People card gains an owners-only "Invite a teammate" button, gated on org.role (handleInviteCreate 403s a project admin who is a plain org member). No invite-record change, no schema change, no new route. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
17 lines
793 B
HTML
17 lines
793 B
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>BearDrive</title>
|
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='%23f5a623'><rect x='4' y='4' width='5.6' height='24'/><rect x='11.2' y='4' width='14.4' height='11.2'/><rect x='11.2' y='16.8' width='16.8' height='11.2'/></svg>">
|
|
<script type="module" crossorigin src="/assets/index-DC3fmGe9.js"></script>
|
|
<link rel="modulepreload" crossorigin href="/assets/_commonjsHelpers-CqkleIqs.js">
|
|
<link rel="modulepreload" crossorigin href="/assets/mermaid-DQuCJ8Gi.js">
|
|
<link rel="stylesheet" crossorigin href="/assets/index-L-I4D1mx.css">
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
</body>
|
|
</html>
|