Skip to content

Conversation

@bmbitwarden
Copy link

🎟️ Tracking

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

📔 Objective

After creating a send, we would like to show a success status, where the user can easily copy the send link.

📸 Screenshots

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

@bmbitwarden bmbitwarden requested review from a team as code owners December 4, 2025 12:36
@bmbitwarden bmbitwarden added the needs-qa Marks a PR as requiring QA approval label Dec 4, 2025
@claude
Copy link

claude bot commented Dec 4, 2025

Claude finished @bmbitwarden's task —— View job


Code Review Complete ✅

I've completed a comprehensive review of PR #17814. Overall, the implementation is solid and adds the requested success page functionality. However, there are several issues that should be addressed before merging.


🔴 Critical Issues

1. Remove FIXME comment

File: libs/tools/send/send-ui/src/add-edit/send-add-edit-dialog.component.ts:96

The FIXME comment should be removed as requested in the review feedback. The functionality has now been implemented with SendSuccessDrawerDialogComponent.

// FIXME: Display success dialog with link - Remove this comment

2. Async initialization race condition

File: apps/web/src/app/tools/send/shared/send-success-drawer-dialog.component.ts:34

Calling void this.initLink() in the constructor with OnPush change detection can cause the template to render before the sendLink signal is populated, resulting in an empty link input.

Fix: Move async initialization to ngOnInit() lifecycle hook:

async ngOnInit() {
  await this.initLink();
}

// Remove from constructor

3. Missing error handling

File: apps/web/src/app/tools/send/shared/send-success-drawer-dialog.component.ts:37-40

No error handling for environment service failures. If getSendUrl() fails or returns incomplete data, the link will be silently empty.

Fix: Add try-catch block with user-facing error notification:

private async initLink() {
  try {
    const env = await firstValueFrom(this.environmentService.environment$);
    this.sendLink.set(env.getSendUrl() + this.send.accessId + "/" + this.send.urlB64Key);
  } catch (error) {
    this.toastService.showToast({
      variant: "error",
      title: this.i18nService.t("errorOccurred"),
      message: this.i18nService.t("unexpectedError"),
    });
  }
}

⚠️ Important Issues

4. Missing expiration date display

Files:

  • apps/web/src/app/tools/send/shared/send-success-drawer-dialog.component.ts
  • apps/web/src/locales/en/messages.json:5590

The browser extension's send-created component shows specific expiration information ("Send expires in 7 days"), but this web component shows generic placeholder text ("next N days"). This was noted in review feedback by @mcamirault and @Hinton.

The browser component at apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts includes formatExpirationDate() and getHoursAvailable() methods that should be replicated here for feature parity.

Required localization keys (from browser component):

  • sendExpiresInHours
  • sendExpiresInHoursSingle
  • sendExpiresInDays
  • sendExpiresInDaysSingle

5. Code duplication with browser component

Files:

  • apps/web/src/app/tools/send/shared/send-success-drawer-dialog.component.ts (new)
  • apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts (existing)

Significant logic duplication between these components. As noted by reviewers, consider extracting shared logic into a service in @bitwarden/send-ui (libs/tools/send/send-ui) to maintain consistency across platforms. This could be done in a follow-up ticket if preferred.


💭 Suggestions

6. Add unit tests

No unit tests were added for the new component. Consider adding tests for:

  • Link construction
  • Copy functionality
  • Toast notifications
  • Dialog title computation
  • Error handling

7. Duplicate copy buttons

File: apps/web/src/app/tools/send/shared/send-success-drawer-dialog.component.html

The template has two copy buttons (one as input suffix on line 21, one in footer on line 38). Is this intentional? The browser extension only has footer buttons. If intentional, this is fine, but wanted to call it out.


✅ Security Review

No security concerns identified:

  • No encryption/decryption logic added
  • No logging of sensitive data
  • Link construction follows established patterns
  • Uses appropriate services for environment and clipboard operations

✅ Angular Pattern Compliance

Mostly compliant with Bitwarden's ADRs:

  • ✅ Uses OnPush change detection
  • ✅ Uses signals appropriately for component state
  • ✅ No TypeScript enums used (SendType is const object per ADR-0025)
  • ✅ Uses firstValueFrom for Observable conversion
  • ❌ Async initialization in constructor (should be in ngOnInit per best practices)

✅ Localization

New keys added correctly:

  • sendCreatedSuccessfully
  • sendCreatedDescription (though needs dynamic expiration text)
  • newTextSend
  • newFileSend

Missing keys for expiration formatting that the browser extension already has.


Summary

The PR successfully implements the core success page functionality. The main concerns are:

  1. Critical: Fix the race condition by moving async init to ngOnInit
  2. Critical: Add error handling for link construction
  3. Critical: Remove the FIXME comment
  4. Important: Address the expiration date display (either implement it or create a follow-up ticket)
  5. Important: Consider consolidating with browser component to reduce duplication (could be a follow-up)

@github-actions
Copy link
Contributor

github-actions bot commented Dec 4, 2025

Logo
Checkmarx One – Scan Summary & Detailse2866bd9-14e2-42a9-a153-e20c2c48b8b1

Great job! No new security vulnerabilities introduced in this pull request

BryanCunningham
BryanCunningham previously approved these changes Dec 4, 2025
Copy link
Contributor

@mcamirault mcamirault 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 overall, one discussion to be had regarding the message we show

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

Labels

needs-qa Marks a PR as requiring QA approval

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants