Skip to content

Conversation

@JimmyVo16
Copy link
Contributor

@JimmyVo16 JimmyVo16 commented Dec 16, 2025

🎟️ Tracking

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

📔 Objective

  1. Add SendOrganizationConfirmationCommand to send out organization confirmation emails using the newly generated MJML templates.
  2. Update some mailer subjects to support dynamic text.
  3. Register handlebar shared layouts.
  4. Add tests.

📸 Screenshots

image image

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@github-actions
Copy link
Contributor

github-actions bot commented Dec 16, 2025

Logo
Checkmarx One – Scan Summary & Details08031b65-4506-48ee-a556-ccd76341c7fe

New Issues (3)

Checkmarx found the following issues in this Pull Request

# Severity Issue Source File / Package Checkmarx Insight
1 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1511
detailsMethod at line 1511 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
2 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1387
detailsMethod at line 1387 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
3 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 245
detailsMethod at line 245 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
Fixed Issues (1)

Great job! The following issues were fixed in this Pull Request

Severity Issue Source File / Package
MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 732

handlebars.RegisterTemplate("FullHtmlLayout", layoutSource);

// Register Full layouts
var fullHtmlLayoutSource = await ReadSourceAsync(assembly, "Bit.Core.MailTemplates.Handlebars.Layouts.Full.html.hbs");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need this so that shared layouts for the text.hbs files will work. For example, TitleContactUs.text.hbs for OrganizationConfirmationEnterpriseTeamsView.text.hbs

@codecov
Copy link

codecov bot commented Dec 18, 2025

Codecov Report

❌ Patch coverage is 99.15966% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 55.01%. Comparing base (1b17d99) to head (c86f5ef).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
...onfirmation/SendOrganizationConfirmationCommand.cs 98.68% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6743      +/-   ##
==========================================
+ Coverage   54.96%   55.01%   +0.04%     
==========================================
  Files        1930     1934       +4     
  Lines       85507    85616     +109     
  Branches     7654     7660       +6     
==========================================
+ Hits        47002    47100      +98     
- Misses      36718    36728      +10     
- Partials     1787     1788       +1     

☔ 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.

/// The subject of the email.
/// </summary>
public abstract string Subject { get; }
public abstract string Subject { get; set; }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The subject for the organization confirmation email is dynamic since we have to include the organization name in it. I had to update this to include a set, which caused a cascading effect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ViewModel names need to match the templates. Our templates use kebab-case (MJML), while the ViewModels use PascalCase. We should standardize these conventions, but this is outside the AC team’s scope. The owner of the mailer and MJML should decide this.

I don’t recommend creating a script to map one naming convention to another. That adds complexity and could introduce more issues over time.

@JimmyVo16 JimmyVo16 self-assigned this Dec 18, 2025
@JimmyVo16 JimmyVo16 marked this pull request as ready for review December 18, 2025 21:46
@JimmyVo16 JimmyVo16 requested review from a team as code owners December 18, 2025 21:46
@claude
Copy link
Contributor

claude bot commented Dec 18, 2025

Claude finished @JimmyVo16's task in 2m 22s —— View job


Code Review Complete

Overall Assessment: REQUEST CHANGES - One critical bug found


Critical Issue

Missing accessSecretsManager parameter in auto-confirm flow

In src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/AutoConfirmUser/AutomaticallyConfirmOrganizationUserCommand.cs:200, the call to SendConfirmationAsync is missing the accessSecretsManager parameter:

await sendOrganizationConfirmationCommand.SendConfirmationAsync(organization, userEmail);

Should be:

await sendOrganizationConfirmationCommand.SendConfirmationAsync(organization, userEmail, accessSecretsManager);

Impact: Users who have Secrets Manager access and are auto-confirmed will receive the wrong vault URL in their confirmation email (standard vault URL instead of Secrets Manager URL).

Fix: Pass request.OrganizationUser.AccessSecretsManager (available at line 150) to the method call.

Note: ConfirmOrganizationUserCommand.cs:366 correctly passes this parameter, so this appears to be an oversight.


Additional Observations

Missing test coverage: No test verifies that accessSecretsManager parameter correctly changes the WebVaultUrl. Consider adding a test to ensure the parameter properly affects URL selection.

Question about HTML decoding: SendOrganizationConfirmationCommand.cs:26 uses WebUtility.HtmlDecode on organization names before passing to Handlebars templates (which auto-escape). If names aren't stored encoded in the database, this decode has no effect. If they are encoded, this decode-then-reencode pattern seems unnecessary.


Positive Notes

  • Excellent test coverage for plan routing, multiple recipients, and edge cases
  • Clean separation of concerns with dedicated command
  • Proper feature flag gating for safe rollout
  • Good security practices (path traversal protection in HandlebarMailRenderer)
  • Well-structured template system with shared layouts

Copy link
Contributor

@r-tome r-tome left a comment

Choose a reason for hiding this comment

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

Looks good! Just a few thoughts


namespace Bit.Core.AdminConsole.Models.Mail.Mailer.OrganizationConfirmation;

#nullable enable
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be removed


namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.OrganizationConfirmation;

#nullable enable
Copy link
Contributor

Choose a reason for hiding this comment

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

Not necessary

</ItemGroup>

<ItemGroup>
<Folder Include="MailTemplates\Handlebars\MJML\AdminConsole\OrganizationConfirmation\" />
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Is this necessary?

View = new OrganizationConfirmationEnterpriseTeamsView
{
OrganizationName = organizationName,
TitleFirst = "You're confirmed as a member of ",
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider placing this hardcoded string in a const variable because it is repeated below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, normally I abstract them when it hits three, but we can do it now.

@JimmyVo16 JimmyVo16 requested a review from r-tome January 5, 2026 20:07
Copy link
Contributor

@amorask-bitwarden amorask-bitwarden left a comment

Choose a reason for hiding this comment

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

Looks like Billing changes are just formatting, so looks good for us.

@JimmyVo16 JimmyVo16 merged commit 63784e1 into main Jan 6, 2026
51 checks passed
@JimmyVo16 JimmyVo16 deleted the ac/pm-27882/add-sendorganizationconfirmationcommand branch January 6, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants