Skip to content

Invitation landing never reads the signed-out invitation preview (#26020 landed server-only): login/register still cannot name the organization or inviter #26473

Closed

Description

@objectstack-fleet

Filing gate ① a follow-up owed by landed work (class a, public door: the invitation link). reach: one browser, local stack, cloud PR #3297 head 4e7ee6d5 + framework pin 6390fe52, zh-CN, 2026-10-27. Signed out, opening an invitation link shows 「接受邀请 · 请使用收到邀请的邮箱。 · 注册并加入」, and 注册并加入 shows 「注册账号并加入」. Neither page names the inviting organization or the inviter, and the email is not prefilled. The server read built for exactly this works anonymously on the same stack: GET /api/v1/auth/organization/invitation-preview?id=EKPx8… → {"organizationName":"晓林装饰工作室","inviterName":"林晓","email":"z***@example.com"} (unknown id → 404).

Batch-of: 5 · 2026-10-27 re-test of the 2026-10-25 desktop E2E after the fixes. Filed at the maintainer's request: 「完整的再测试一遍」 / 「必要的合理的建议都可以立卡」. Reviewed in-session before filing.

Business reason. Every seat after the first arrives through this page. The point of #25886 and #26020 was that an invitee sees "林晓 invited you to 晓林装饰工作室" before being asked for anything. That read exists now, but nothing displays it. The ui read fell between two closes: #26020's body says "After it lands, the ui seat reads the new route in LoginPage.tsx / AcceptInvitationPage.tsx under #25886, which stays open for that". But #25886 closed COMPLETED (2026-10-26T16:55Z, "the server half was split to #26020"), and #26020 closed on PR #26151, which touched no ui/ file.

Reader who acts. The domain:ui seat: ui/packages/auth (client method) and ui/packages/app-shell/src/console/auth + organizations/manage.

Where (pin 6390fe52; no ui consumer on objectstack main either)

  • No reader: git grep -l "invitation-preview|invitationPreview" -- ui/ finds nothing. The ui auth client has only the session-gated getInvitation (ui/packages/auth/src/createAuthClient.ts:1005).
  • The server route: packages/plugins/plugin-auth/src/invitation-preview.ts, ledgered in auth-route-ledger.ts:261 (closed query set { id }, masked email, uniform 404, per-address rate limit).
  • Pages that should read it:
    • app-shell/src/console/auth/LoginPage.tsx:121-134, 196-208 (generic invitation title/description)
    • RegisterPage.tsx:230-233
    • invitationArrival.tsx:48
    • ui/apps/console/src/pages/auth/LoginPage.tsx:330-341
    • organizations/manage/AcceptInvitationPage.tsx:25-32, 211-240 (names org/inviter only when signed in, via get-invitation)

Expected

  • On an /accept-invitation/<id> redirect, login, register and accept read the preview and say 「林晓 邀请你加入 晓林装饰工作室」.
  • Register shows the masked address as the expected one and warns when the typed address doesn't match its pattern. Full prefill isn't possible from a masked value.
  • An unknown or expired id falls back to today's generic copy.
  • Optional: the environment-host login's 「欢迎回来」 on a member's first visit could greet "from ObjectOS Cloud" now that PR cloud#3286 carries an entry identity. Taste; take it only if trivial.

Dedupe

gh api search/issues, incl. closed:

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: audit line · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T05:14Z

    ⛔ Not a claim, ⛔ not a dispatch. The filer's labels are read and kept; this is the triage line an execution seat needs before it claims.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 12 · 2026-10-27T05:26Z
    Session: session_01SMps7wq7rBTk53e8KTSEup
    Account: os-steve
    Branch: claude/issue-26473-invitation-preview-landing
    Worktree: objectstack-issue-26473
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: ui/packages/app-shell/src/console/auth/invitationArrival.tsx, ui/packages/app-shell/src/console/organizations/manage/AcceptInvitationPage.tsx, the console sign-up page it hands to, ui/packages/auth/src/createAuthClient.ts (a read method if one is missing), tests beside them, root .changeset/. ⛔ signUpOffer.ts (open PR #26483). ⛔ locale packs under ui/packages/i18n unless the card needs a new key (then en + zh only, and say so), ui/.github/**, root ci.yml.
    Container & model: M, mode:subagent, model: default tier, effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: an invitee who opens an invitation link signed out | GET /api/v1/auth/organization/invitation-preview (#26020) | every invited seat after the first
    Thread-read: none
    Premise: holds 2026-10-27T05:26Z at origin/main 00a4593ad7: invitationArrival.tsx / AcceptInvitationPage.tsx never call the invitation-preview read; the card measured the page naming neither the organization nor the inviter.
    Serial constraints cleared: #26020 (server read) closed; no open PR touches these files except signUpOffer.ts (#26483), which is off this surface.
    Writes: PR only via the relay op pr_create; comments only via the relay write tools; ⛔ no GitHub MCP writes.

    • Seat's route: signed out, read the invitation preview by id and show 「INVITER 邀请你加入 ORG」 on the landing and the sign-up step; prefill nothing from the masked email (it is masked) but show it as the hint; an unknown id (404) keeps today's page. Pin red-first for found / 404 / read failure. Fixes #26473.
  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26473,
      "status": "done",
      "branch": "claude/issue-26473-invitation-preview-landing",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26554",
      "head": "b848d2b1",
      "session": "session_01SMps7wq7rBTk53e8KTSEup (subagent; the parent's id)",
      "premise_still_valid": true,
      "summary": "The auth client, AuthProvider and useAuth() gain getInvitationPreview(id), which sends one anonymous GET to /organization/invitation-preview. It returns the preview, null on 404, or rejects with code and status on any other failure. app-shell gains useInvitationPreview(redirect) and invitationArrivalCopy(page, preview, t). DefaultLoginPage, DefaultRegisterPage and the console's own /login and /register now title an invitation arrival 'INVITER invited you to join ORG' and show the masked address as the address to use. The email field is never prefilled. On a 404, a failed read or an older server, each page keeps today's generic copy and nothing throws. Four new keys are in all ten locale packs, not en+zh only (see deviations).",
      "tests": "Red first, under the lock: the 14 implementation files were restored to base 00a4593a in the working tree only and the new files run. auth file 5/5 failed (client.getInvitationPreview is not a function). app-shell file 9/10 failed; the passing one is the no-invitation preservation pin, as expected. console file 6/6 failed. Restore proven by hash comparison and an empty git diff HEAD. Green at b848d2b1: vitest over packages/auth/ + packages/i18n/ + the 13 app-shell test files that import the touched pages gave Test Files 136 passed (136), Tests 1781 passed | 13 skipped. Console project over the 21 console test files that import the console Login/Register pages gave Test Files 21 passed (21), Tests 110 passed (110). type-check exit 0 for @object-ui/auth, @object-ui/i18n, @object-ui/app-shell and @object-ui/console. Closure build pnpm --filter '@object-ui/console^...' build gave VERDICT command-exit 0. No ablation beyond the red leg.",
      "gates": "Derived (--commands, 34) at b848d2b1: 32 exit 0. pnpm --dir ui exec vitest run scripts/ exit 99, lock queue-timeout three times: NOT MEASURED. pnpm check:type-check-debt exit 3, PREREQUISITE NOT MET because its re-measure build never got a lock turn: NOT MEASURED. --ran: 34 accounted, 33 run, 1 NOT-MEASURED; the tool classifies exit 3 only, so the exit-99 run is NOT MEASURED too. Extra: node scripts/check-sdui-manifest.mjs exit 0 (no registry contract change, nothing regenerated), ui check:i18n-keys / check:i18n-drift / check:i18n-dead-keys exit 0, pnpm check:changeset-fixed exit 0 (the roster flagged for .changeset), check:nul-bytes exit 0. CI check-runs not yet concluded: in_progress at report time.",
      "dogfood_battery": "n/a: no '!' in the PR title and no (narrowing) arm",
      "line_budget": "26 files, +809 / -46 (855 changed lines; under the 3000 human-merge threshold)",
      "files_changed": [
        ".changeset/26473-invitation-preview-landing.md",
        "ui/packages/auth/src/{types,AuthContext,useAuth,index,createAuthClient}.ts, AuthProvider.tsx, __tests__/invitationPreview-26473.test.ts",
        "ui/packages/app-shell/src/console/auth/{invitationArrival,LoginPage,RegisterPage}.tsx, __tests__/invitationPreview-26473.test.tsx, src/index.ts",
        "ui/apps/console/src/pages/auth/{LoginPage,RegisterPage}.tsx, __tests__/invitationPreview-26473.test.tsx",
        "ui/packages/i18n/src/locales/{en,zh,ar,de,es,fr,ja,ko,pt,ru}.ts (4 added keys each; en comment updated)"
      ],
      "deviations": [
        "Locale packs: the dispatch said en and zh only. Measured under the lock, en+zh only reds ui/packages/i18n/src/__tests__/all-locales-key-parity.test.ts: Tests 8 failed | 40 passed, one per other locale ('ar is missing 4 key(s)'). The four keys are therefore in all ten packs, on new lines only, no existing value changed. The PR body says so. #26469 also edits these packs, so a conflict would be about line placement only.",
        "File surface: beyond the claim's named files, the diff touches both LoginPage.tsx and both RegisterPage.tsx (the card lists them), auth types.ts / AuthContext.ts / AuthProvider.tsx / useAuth.ts / index.ts (to reach the read from a page), and app-shell index.ts (export). AcceptInvitationPage.tsx is untouched: a signed-out visitor is redirected away from it before it renders. signUpOffer.ts is untouched (#26483).",
        "Two derived gates NOT MEASURED locally because of lock starvation; CI runs both. Holder at the last attempt: pid 11361, scratchpad/issue-26415/lock1.sh, held 1296s.",
        "The harness's own Co-Authored-By trailer instruction names a model; per AGENTS.md, commits carry the model-free pair (Claude-Session + Co-authored-by: Claude). Reported, not a deviation of record."
      ],
      "mcp_calls": "0. No MCP GitHub tool was called.",
      "api_writes": "2 relay strokes. (1) pr_create: POST /repos/objectstack-ai/objectstack/dispatches; the relay ran POST /repos/objectstack-ai/objectstack/pulls (draft #26554) + POST /repos/objectstack-ai/objectstack/issues/26554/assignees [os-steve], run 40471076863 success, body read back identical (9361 bytes). (2) This os-dev-report comment through post-stamped.mjs: POST /repos/objectstack-ai/objectstack/issues/26473/comments. git push is not counted.",
      "open_questions": [
        {
          "question": "The card also suggested a register-page warning when the typed address does not match the masked pattern. The seat's route did not include it, so it is not done. Add it in a follow-up?",
          "options": [
            "A: no; the server refuses a non-invitee's sign-up already and the masked address is shown",
            "B: a small follow-up that compares first letter + domain on blur"
          ],
          "recommendation": "A, because the server is the authority and a client-side pattern guess adds a second, weaker check"
        }
      ],
      "out_of_scope_findings": [
        "carrier: none (承接者:无) · invitationIdOf in invitationArrival.tsx and isInvitationRedirect in signUpOffer.ts read the same /accept-invitation/ segment; once #26483 lands, isInvitationRedirect can be invitationIdOf(r) !== null. Noted in Acceptance notes, not filed."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · seat 2 · 2026-10-27T09:02Z

    probe reading
    PR #26554 MERGED 2026-10-27T08:46Z, merge commit 319d6fa0, head b848d2b1 (+809/−46, seat record on #26554)
    origin/main contains it (git merge-base --is-ancestor exit 0)
    queue branch gh-readonly-queue/main/pr-26554-*: none left (consumed)
    card closed (completed) by Fixes #26473 on #26554

    Status: a signed-out visitor opening an invitation link sees who invited them and to which organization on the sign-in and sign-up pages (the server's masked invitee address as a hint, never prefilled); a missing or failed preview keeps the generic copy. pm:dispatched removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:identityLogin and identity — sign-up, sessions, organization membership, SSObugSomething isn't workingdomain:uipriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions