mirror of
https://github.com/bitwarden/browser
synced 2026-02-18 02:19:18 +00:00
[PM-31620] Browser - Incorrect "Copy link" message when Send is shared with specific people (#18982)
* add existing Send creation messages to browser * remove unused method and associated tests
This commit is contained in:
@@ -3080,6 +3080,45 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"durationTimeHours": {
|
||||
"message": "$HOURS$ hours",
|
||||
"placeholders": {
|
||||
"hours": {
|
||||
"content": "$1",
|
||||
"example": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendCreatedDescriptionV2": {
|
||||
"message": "Copy and share this Send link. The Send will be available to anyone with the link for the next $TIME$.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.",
|
||||
"placeholders": {
|
||||
"time": {
|
||||
"content": "$1",
|
||||
"example": "7 days, 1 hour, 1 day"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendCreatedDescriptionPassword": {
|
||||
"message": "Copy and share this Send link. The Send will be available to anyone with the link and password you set for the next $TIME$.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.",
|
||||
"placeholders": {
|
||||
"time": {
|
||||
"content": "$1",
|
||||
"example": "7 days, 1 hour, 1 day"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendCreatedDescriptionEmail": {
|
||||
"message": "Copy and share this Send link. It can be viewed by the people you specified for the next $TIME$.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.",
|
||||
"placeholders": {
|
||||
"time": {
|
||||
"content": "$1",
|
||||
"example": "7 days, 1 hour, 1 day"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendLinkCopied": {
|
||||
"message": "Send link copied",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
|
||||
@@ -20,7 +20,13 @@
|
||||
{{ "createdSendSuccessfully" | i18n }}
|
||||
</h3>
|
||||
<p class="tw-text-center">
|
||||
{{ formatExpirationDate() }}
|
||||
@let translationKey =
|
||||
send.authType === AuthType.Email
|
||||
? "sendCreatedDescriptionEmail"
|
||||
: send.authType === AuthType.Password
|
||||
? "sendCreatedDescriptionPassword"
|
||||
: "sendCreatedDescriptionV2";
|
||||
{{ translationKey | i18n: formattedExpirationTime }}
|
||||
</p>
|
||||
<button bitButton type="button" buttonType="primary" (click)="copyLink()">
|
||||
<b>{{ "copyLink" | i18n }}</b>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
|
||||
import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service";
|
||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
|
||||
import { AuthType } from "@bitwarden/common/tools/send/types/auth-type";
|
||||
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
|
||||
import { ButtonModule, I18nMockService, SvgModule, ToastService } from "@bitwarden/components";
|
||||
|
||||
@@ -50,6 +51,7 @@ describe("SendCreatedComponent", () => {
|
||||
|
||||
sendView = {
|
||||
id: sendId,
|
||||
authType: AuthType.None,
|
||||
deletionDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
type: SendType.Text,
|
||||
accessId: "abc",
|
||||
@@ -101,6 +103,13 @@ describe("SendCreatedComponent", () => {
|
||||
sendExpiresInDays: (days) => `sendExpiresInDays ${days}`,
|
||||
sendExpiresInDaysSingle: "sendExpiresInDaysSingle",
|
||||
sendLinkCopied: "sendLinkCopied",
|
||||
oneHour: "one hour",
|
||||
durationTimeHours: (hours) => `${hours} hours`,
|
||||
oneDay: "one day",
|
||||
days: (days) => `${days} days`,
|
||||
sendCreatedDescriptionV2: (time) => `Send ready for ${time}`,
|
||||
sendCreatedDescriptionPassword: (time) => `Password-protected Send ready for ${time}`,
|
||||
sendCreatedDescriptionEmail: (time) => `Email-verified Send ready for ${time}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -147,37 +156,66 @@ describe("SendCreatedComponent", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatExpirationDate", () => {
|
||||
it("returns days plural if expiry is more than 24 hours", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 168 * 60 * 60 * 1000);
|
||||
describe("formattedExpirationTime", () => {
|
||||
it("returns formatted time for hours plural", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 5 * 60 * 60 * 1000);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.formatExpirationDate()).toBe("sendExpiresInDays 7");
|
||||
expect(component.formattedExpirationTime).toBe("5 hours");
|
||||
});
|
||||
|
||||
it("returns days singular if expiry is 24 hours", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.formatExpirationDate()).toBe("sendExpiresInDaysSingle");
|
||||
});
|
||||
|
||||
it("returns hours plural if expiry is more than 1 hour but less than 24", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 2 * 60 * 60 * 1000);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.formatExpirationDate()).toBe("sendExpiresInHours 2");
|
||||
});
|
||||
|
||||
it("returns hours singular if expiry is in 1 hour", () => {
|
||||
it("returns formatted time for hours singular", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 1 * 60 * 60 * 1000);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.formatExpirationDate()).toBe("sendExpiresInHoursSingle");
|
||||
expect(component.formattedExpirationTime).toBe("one hour");
|
||||
});
|
||||
|
||||
it("returns formatted time for days plural", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.formattedExpirationTime).toBe("7 days");
|
||||
});
|
||||
|
||||
it("returns formatted time for days singular", () => {
|
||||
sendView.deletionDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.formattedExpirationTime).toBe("one day");
|
||||
});
|
||||
});
|
||||
|
||||
describe("auth type specific messages", () => {
|
||||
it("should show the correct message for Sends with no authentication", () => {
|
||||
sendView.authType = AuthType.None;
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.nativeElement.textContent).toContain("createdSendSuccessfully");
|
||||
expect(fixture.nativeElement.textContent).toContain("Send ready for");
|
||||
});
|
||||
|
||||
it("should show the correct message for Sends with password authentication", () => {
|
||||
sendView.authType = AuthType.Password;
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.nativeElement.textContent).toContain("createdSendSuccessfully");
|
||||
expect(fixture.nativeElement.textContent).toContain("Password-protected Send ready for");
|
||||
});
|
||||
|
||||
it("should show the correct message for Sends with email authentication", () => {
|
||||
sendView.authType = AuthType.Email;
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.nativeElement.textContent).toContain("createdSendSuccessfully");
|
||||
expect(fixture.nativeElement.textContent).toContain("Email-verified Send ready for");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
|
||||
import { AuthType } from "@bitwarden/common/tools/send/types/auth-type";
|
||||
import { ButtonModule, SvgModule, ToastService } from "@bitwarden/components";
|
||||
|
||||
import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component";
|
||||
@@ -38,6 +39,7 @@ import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page
|
||||
],
|
||||
})
|
||||
export class SendCreatedComponent {
|
||||
readonly AuthType = AuthType;
|
||||
protected sendCreatedIcon = ActiveSendIcon;
|
||||
protected send: SendView;
|
||||
protected daysAvailable = 0;
|
||||
@@ -63,15 +65,18 @@ export class SendCreatedComponent {
|
||||
});
|
||||
}
|
||||
|
||||
formatExpirationDate(): string {
|
||||
get formattedExpirationTime(): string {
|
||||
if (!this.send?.deletionDate) {
|
||||
return "";
|
||||
}
|
||||
if (this.hoursAvailable < 24) {
|
||||
return this.hoursAvailable === 1
|
||||
? this.i18nService.t("sendExpiresInHoursSingle")
|
||||
: this.i18nService.t("sendExpiresInHours", String(this.hoursAvailable));
|
||||
? this.i18nService.t("oneHour").toLowerCase()
|
||||
: this.i18nService.t("durationTimeHours", String(this.hoursAvailable)).toLowerCase();
|
||||
}
|
||||
return this.daysAvailable === 1
|
||||
? this.i18nService.t("sendExpiresInDaysSingle")
|
||||
: this.i18nService.t("sendExpiresInDays", String(this.daysAvailable));
|
||||
? this.i18nService.t("oneDay").toLowerCase()
|
||||
: this.i18nService.t("days", String(this.daysAvailable)).toLowerCase();
|
||||
}
|
||||
|
||||
getHoursAvailable(send: SendView): number {
|
||||
|
||||
Reference in New Issue
Block a user