Skip to content

[PM-34774] Add GET endpoint for organization invite links#7534

Draft
r-tome wants to merge 2 commits intoac/pm-34387/create-invite-link-commandfrom
ac/pm-34774/get-invite-link-query-and-endpoint
Draft

[PM-34774] Add GET endpoint for organization invite links#7534
r-tome wants to merge 2 commits intoac/pm-34387/create-invite-link-commandfrom
ac/pm-34774/get-invite-link-query-and-endpoint

Conversation

@r-tome
Copy link
Copy Markdown
Contributor

@r-tome r-tome commented Apr 23, 2026

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-34774

📔 Objective

Adds GET /organizations/{orgId}/invite-link to retrieve an organization's existing invite link. Returns 404 if none exists.

…vite links by organization ID

- Implemented a new GET endpoint to fetch an invite link based on the organization ID.
- Integrated IOrganizationInviteLinkRepository to handle data retrieval.
- Updated tests to validate the new functionality, ensuring correct responses for existing and non-existing links.
- Refactored service registration for invite link commands to improve clarity.
@r-tome r-tome changed the base branch from main to ac/pm-34387/create-invite-link-command April 23, 2026 14:09
@r-tome r-tome added the ai-review-vnext Request a Claude code review using the vNext workflow label Apr 23, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Logo
Checkmarx One – Scan Summary & Details51f5d63d-abb8-406d-b8ca-2c950e5c7011


Fixed Issues (2) Great job! The following issues were fixed in this Pull Request
Severity Issue Source File / Package
MEDIUM CSRF src/Api/Vault/Controllers/CiphersController.cs: 1558
MEDIUM CSRF src/Api/Vault/Controllers/CiphersController.cs: 1385

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 14.45%. Comparing base (59c220e) to head (c34522f).

Files with missing lines Patch % Lines
...eatures/OrganizationServiceCollectionExtensions.cs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                            Coverage Diff                             @@
##           ac/pm-34387/create-invite-link-command    #7534      +/-   ##
==========================================================================
- Coverage                                   14.45%   14.45%   -0.01%     
==========================================================================
  Files                                        1281     1281              
  Lines                                       55596    55607      +11     
  Branches                                     4303     4305       +2     
==========================================================================
  Hits                                         8037     8037              
- Misses                                      47419    47430      +11     
  Partials                                      140      140              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Adds GET /organizations/{orgId}/invite-link to retrieve an organization's existing invite link, returning 404 when none exists. Authorization uses ManageUsersRequirement and the controller-level RequireFeature(GenerateInviteLink) flag, and the change is covered by unit tests and an updated integration test. The changes are small, focused, and align with the parent PR (pm-34387/create-invite-link-command).

Code Review Details
  • 🎨 : Controller calls the repository directly instead of a query class; branch name and renamed AddOrganizationInviteLinkCommandsQueries extension both imply a query was intended, and sibling OrganizationDomains follows the CQS pattern.
    • src/Api/AdminConsole/Controllers/OrganizationInviteLinksController.cs:26
  • ❓ : Get does not check the UseInviteLinks organization ability, while CreateOrganizationInviteLinkCommand does — is this intentional?
    • src/Api/AdminConsole/Controllers/OrganizationInviteLinksController.cs:22

[Authorize<ManageUsersRequirement>]
public async Task<IResult> Get(Guid orgId)
{
var link = await organizationInviteLinkRepository.GetByOrganizationIdAsync(orgId);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 SUGGESTED: Controller calls repository directly instead of a query class; breaks the CQS pattern used elsewhere in this codebase.

Details and fix

The branch name (get-invite-link-query-and-endpoint) and the renamed DI extension (AddOrganizationInviteLinkCommandsQueries, plural) both imply a query class was intended, but only a command is still registered. The controller now injects IOrganizationInviteLinkRepository directly.

The sibling feature OrganizationDomains follows the expected pattern — see GetOrganizationDomainByOrganizationIdQuery registered alongside its commands. Per ADR-0008 (CQS), new features should use query classes for reads.

Suggested fix: introduce IGetOrganizationInviteLinkByOrganizationIdQuery / GetOrganizationInviteLinkByOrganizationIdQuery in src/Core/AdminConsole/OrganizationFeatures/InviteLinks/, register it in AddOrganizationInviteLinkCommandsQueries, and inject it into the controller instead of the repository. This also gives a natural home for the UseInviteLinks ability check raised in the other comment.

Comment on lines +22 to +31
[HttpGet("")]
[Authorize<ManageUsersRequirement>]
public async Task<IResult> Get(Guid orgId)
{
var link = await organizationInviteLinkRepository.GetByOrganizationIdAsync(orgId);

return link is null
? TypedResults.NotFound()
: TypedResults.Ok(new OrganizationInviteLinkResponseModel(link));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QUESTION: Should Get also check the UseInviteLinks organization ability, consistent with CreateOrganizationInviteLinkCommand?

Details

CreateOrganizationInviteLinkCommand gates creation on OrganizationAbility.UseInviteLinks (commit 7acba07). If that ability is later disabled for an org that already has a link, this Get endpoint will still return the link, while Create would reject a new one. The controller-level RequireFeature(GenerateInviteLink) is a platform-wide flag, and ManageUsersRequirement is RBAC — neither is equivalent to the per-org ability check.

Is the intent for admins to continue to see/manage an existing link after the ability is turned off, or should Get also 404 when UseInviteLinks is false? A short comment or a consistency check here would clarify.

@sonarqubecloud
Copy link
Copy Markdown

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

Labels

ai-review-vnext Request a Claude code review using the vNext workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant