Repository navigation
feat: link bio mentions to their dev/null profile - #1266
Conversation
…ll profile Bio and company badges open /@handle when the account is on dev/null, and GitHub otherwise. A user's bio and company organizations are looked up when their GitHub profile syncs, and users:look-up-organizations queues that for existing users.
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Shared organization lookup app/Actions/UpdateMentionedOrganizations.php, app/Actions/UpdateCommitTopics.php |
The new action handles profile matching, lookup limits, not-found caching, rate-limit pauses, and organization updates or deletions. UpdateCommitTopics delegates its lookups to this action. |
User lookup jobs app/Jobs/LookUpUserOrganizations.php, app/Actions/UpdateUserProfile.php, app/Http/Controllers/SessionController.php, app/Console/Commands/LookUpUserOrganizationsCommand.php, tests/Feature/Commands/*, tests/Feature/Controllers/SessionControllerTest.php, tests/Unit/Actions/UpdateUserProfileTest.php, tests/Unit/Jobs/LookUpUserOrganizationsTest.php |
The job extracts handles from user bios and companies and releases when the lookup action returns a retry time. Profile updates, sign-in, and the console command dispatch eligible lookups. Tests cover dispatch and lookup behavior. |
Bio profile response data app/Queries/BioProfilesQuery.php, app/Http/Controllers/UserController.php, app/Http/Controllers/UserPreviewController.php, app/Http/Middleware/HandleInertiaRequests.php, tests/Feature/Controllers/UserControllerTest.php, tests/Feature/Controllers/UserPreviewControllerTest.php, tests/Unit/Queries/BioProfilesQueryTest.php |
The query maps mentioned handles to existing profiles. User pages, previews, and authenticated page props include the mapping. Tests cover matches, missing handles, and guest responses. |
Mention link rendering resources/js/components/app-aside.tsx, resources/js/components/bio-text.tsx, resources/js/components/user-preview.tsx, resources/js/pages/user/show.tsx, resources/js/types/auth.ts, tests/Unit/BioText.test.tsx |
Bio and company mentions use the profile mapping to link known handles to dev/null profiles. Other mentions retain GitHub links and avatars. |
Priority:
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Feature
Sequence Diagram(s)
sequenceDiagram
participant ProfileUpdate as UpdateUserProfile
participant SignIn as SessionController
participant Command as LookUpUserOrganizationsCommand
participant Job as LookUpUserOrganizations
participant Lookup as UpdateMentionedOrganizations
participant GitHub
participant Organization as UpdateOrCreateOrganization
ProfileUpdate->>Job: dispatchFor user
SignIn->>Job: dispatchFor user
Command->>Job: dispatchFor eligible users
Job->>Lookup: handle extracted handles
Lookup->>GitHub: look up organization handles
GitHub-->>Lookup: organization response
Lookup->>Organization: update organization profile
Possibly related issues
- [RFC] Orgs #938: The RFC covers organization profiles and mentions; this pull request implements organization lookup and profile links for those mentions.
Possibly related PRs
- dev-null-sh/dev-null.sh#1262: Adds organization profiles and the original organization lookup flow that this pull request centralizes and reuses.
- dev-null-sh/dev-null.sh#1156: Establishes the profile handle contract used by the new query and mention rendering.
- dev-null-sh/dev-null.sh#1160: Changes the GitHub mention badge behavior that this pull request also updates.
Suggested reviewers: xheaven, 0z3, nunomaduro
Merge Risk: 
Minimal · up to 9c22d
-
Profile mention links and organization lookups appear mergeable after normal checks. A lookup processes at most five handles per run, as intended.
Security architecture risk: 
Low · up to 9c22d
-
The change reuses existing organization identity, persistence, and rate-limit controls. No introduced security vulnerability was established. The main remaining uncertainty is whether additional background work could interfere with shared GitHub capacity under production concurrency.
Retained concerns
No architecture-level concerns identified.Security review details
-
Security Blast Radius
- inferred — The affected shared resources are application-wide organization profiles, organization commit-topic links, queue capacity, and GitHub API capacity. Organization discovery and SSH-key synchronization use the same GitHub client, so quota interference could extend beyond the user whose bio initiated discovery. Actual interference is not established.
Trust Boundaries and Controls
- observed — User-controlled bio and company text is reduced to distinct lowercase handles using a constrained alphanumeric-and-hyphen pattern. These handles select fixed GitHub account endpoints, rather than attacker-supplied URLs. Browser fallback links use HTTPS GitHub URLs with noopener and noreferrer.
- observed — Web and API profile synchronization bind to the authenticated current user and apply profile-sync throttling. Sign-in dispatch follows GitHub identity screening. Profile synchronization performs SSH-key synchronization before queuing organization discovery, whereas sign-in enqueues the two jobs independently.
Resilience and Maintainability Implications
- observed — The shared pause uses separate cache reads, requests, and writes, rather than an atomic quota reservation. This behavior predates extraction. The five-request cap, negative cache, and freshness filtering constrain ordinary work but do not serialize concurrent jobs. Repeated sign-in already scheduled SSH-key requests before this PR, which is important counterevidence against attributing shared-quota exhaustion solely to the new lookup.
- inferred — Missing-model handling covers users absent when queued models are restored, but does not cancel a worker that already restored the user before deletion. Such work can still perform public organization maintenance. Whether that bounded race conflicts with account-deletion policy remains unresolved; it is not evidence of user resurrection or a privileged identity write.
Hardening Proposals
- proposed — For high-concurrency deployments, consider an atomic shared quota reservation or explicit capacity isolation for optional organization enrichment versus SSH-key synchronization. This is defense in depth for an existing advisory-pause design, not a verified vulnerability introduced by this PR.
-
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 15 functions across 23 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
Summary
Follow-up to #1262. The
@handlebadges in a bio and a company now open the profile on dev/null when the account is here, a user or an organization, instead of always opening GitHub. Other handles still open GitHub in a new tab.Changes
UpdateMentionedOrganizations: the GitHub lookup moved out ofUpdateCommitTopics, unchanged: 5 lookups at most, the 1000-request floor, a day of not-found cache, and waiting for the reset. Commits and bios share it. It now also skips handles a user has, in the same query.LookUpUserOrganizationsjob: queued on sign-in and profile sync, only when the bio or company mentions someone. It has the same retry rules asLinkCommitTopics.BioProfilesQuery: maps lowercase handle → handle for the mentions that have a profile. It is sent asbioProfileson the profile page and in the hovercard JSON, and asauth.bioProfilesfor the sidebar. It is one query on thelower(handle)index, and none when the text mentions no one.BioText: links those handles with an InertiaLinkto/@handle(the profile's own case), and keeps the GitHub link for the rest. The badge looks the same either way.users:look-up-organizations: queues the job for existing users.Data
No new column or table.
After deploy
Run
php artisan users:look-up-organizationsonce, so the bios of people who don't sign in again soon get their organizations.Validation
Run locally against a throwaway Postgres 18 with pgvector. Hosted CI is pending.
tscpasses, for the app and for the tests.vp fmt --check resources/is clean, andvp lintexits 0.BioTexttests.node --testpassed.@laravel(org)/@laravel@tailwindlabs(org)/@tailwindlabs@mnapoli(user)/@mnapoli@php-fig(not on dev/null)@laravel/@laravel@laravel,@taylorotwell/@laravel,/@taylorotwell@bref(not on dev/null)PerformanceObserver:production.@laravelbadge to the organization page: 0Visual evidence
Before is
production(3a6eabe) and after is this branch. Both run locally on the same seeded data, signed in as@mnapoli.The badges look the same; only where they lead changes. Desktop is 1440×900, laptop 1366×650 and mobile 390×844.
Profile:
@laraveland@tailwindlabsare organizations,@mnapolia user,@php-figneitherClicking
@laravelin the bio opens the organization page, as a client-side visitHovercard and sidebar
Device verification
Independent review
Independent agents reviewed the diff
3a6eabe2..9c22db7aand the captures above.9c22db7a. The first pass found that an emptybioProfilesarrives as a JSON array, so@lengthwould have linked to/@0. That is fixed and tested. Its non-blocking nits are listed under Limitations.57c14696, which only differs in that empty-array case. Every before/after pair is pixel-identical. The reviewer also tabbed through the badges in both themes and found the focus ring unchanged.Limitations
Summary by CodeRabbit