1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

[SG-900] Implement auto-fill callout (#4670)

* Implement autofill callouts

* Fix copy for dismissed callout

* Delay closing popup after using callout auto-fill
This commit is contained in:
Robyn MacCallum
2023-02-06 13:04:11 -05:00
committed by GitHub
parent 4ffe1c7e57
commit 4f7bd77560
7 changed files with 99 additions and 6 deletions

View File

@@ -962,7 +962,7 @@
"experimentalFeature": {
"message": "Compromised or untrusted websites can exploit auto-fill on page load."
},
"learnMoreAboutAutofill":{
"learnMoreAboutAutofill": {
"message": "Learn more about auto-fill"
},
"defaultAutoFillOnPageLoad": {
@@ -2103,5 +2103,26 @@
"example": "14"
}
}
},
"tryAutofillPageLoad": {
"message": "Try auto-fill on page load?"
},
"tryAutofill": {
"message": "How to auto-fill"
},
"autofillPageLoadInfo": {
"message": "Login forms will automatically fill in matching credentials if you turn on auto-fill on page load."
},
"autofillSelectInfo": {
"message": "Select an item from this page to auto-fill the active tab's form."
},
"autofillTurnedOn": {
"message": "Auto-fill on page load turned on"
},
"turnOn": {
"message": "Turn on"
},
"notNow": {
"message": "Not now"
}
}

View File

@@ -26,6 +26,11 @@
}
}
&.callout-half {
font-weight: bold;
max-width: 45%;
}
&:hover:not([disabled]) {
cursor: pointer;

View File

@@ -36,6 +36,27 @@
</div>
<ng-container *ngIf="loaded">
<app-vault-select (onVaultSelectionChanged)="load()"></app-vault-select>
<app-callout
*ngIf="showTryAutofillOnPageLoad"
type="info"
title="{{ 'tryAutofillPageLoad' | i18n }}"
>
<p>{{ "autofillPageLoadInfo" | i18n }}</p>
<button
type="button"
class="btn primary callout-half"
appStopClick
(click)="setAutofillOnPageLoad()"
>
{{ "turnOn" | i18n }}
</button>
<button type="button" class="btn callout-half" appStopClick (click)="notNow()">
{{ "notNow" | i18n }}
</button>
</app-callout>
<app-callout *ngIf="showSelectAutofillCallout" type="info" title="{{ 'tryAutofill' | i18n }}">
<p>{{ "autofillSelectInfo" | i18n }}</p>
</app-callout>
<div class="box list" *ngIf="loginCiphers">
<h2 class="box-header">
{{ "typeLogins" | i18n }}

View File

@@ -42,6 +42,8 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
loaded = false;
isLoading = false;
showOrganizations = false;
showTryAutofillOnPageLoad = false;
showSelectAutofillCallout = false;
protected search$ = new Subject<void>();
private destroy$ = new Subject<void>();
@@ -112,6 +114,11 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
this.search$
.pipe(debounceTime(500), takeUntil(this.destroy$))
.subscribe(() => this.searchVault());
this.showTryAutofillOnPageLoad =
this.loginCiphers.length > 0 &&
!(await this.stateService.getEnableAutoFillOnPageLoad()) &&
!(await this.stateService.getDismissedAutofillCallout());
}
ngOnDestroy() {
@@ -140,7 +147,7 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
this.router.navigate(["/view-cipher"], { queryParams: { cipherId: cipher.id } });
}
async fillCipher(cipher: CipherView) {
async fillCipher(cipher: CipherView, closePopupDelay?: number) {
if (
cipher.reprompt !== CipherRepromptType.None &&
!(await this.passwordRepromptService.showPasswordPrompt())
@@ -170,11 +177,15 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
this.platformUtilsService.copyToClipboard(this.totpCode, { window: window });
}
if (this.popupUtilsService.inPopup(window)) {
if (this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari()) {
BrowserApi.closePopup(window);
if (!closePopupDelay) {
if (this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari()) {
BrowserApi.closePopup(window);
} else {
// Slight delay to fix bug in Chromium browsers where popup closes without copying totp to clipboard
setTimeout(() => BrowserApi.closePopup(window), 50);
}
} else {
// Slight delay to fix bug in Chromium browsers where popup closes without copying totp to clipboard
setTimeout(() => BrowserApi.closePopup(window), 50);
setTimeout(() => BrowserApi.closePopup(window), closePopupDelay);
}
}
} catch {
@@ -262,4 +273,18 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
);
this.isLoading = this.loaded = true;
}
async setAutofillOnPageLoad() {
await this.stateService.setEnableAutoFillOnPageLoad(true);
this.platformUtilsService.showToast("success", null, this.i18nService.t("autofillTurnedOn"));
await this.fillCipher(this.loginCiphers[0], 3000);
await this.stateService.setDismissedAutofillCallout(true);
this.showTryAutofillOnPageLoad = false;
}
async notNow() {
await this.stateService.setDismissedAutofillCallout(true);
this.showTryAutofillOnPageLoad = false;
this.showSelectAutofillCallout = true;
}
}