mirror of
https://github.com/bitwarden/browser
synced 2026-02-06 19:53:59 +00:00
PM-21845: Add autotype to desktop settings and add a barebones service
This commit is contained in:
@@ -489,6 +489,22 @@
|
||||
"enableDuckDuckGoBrowserIntegrationDesc" | i18n
|
||||
}}</small>
|
||||
</div>
|
||||
<div class="form-group" *ngIf="showEnableAutotype">
|
||||
<div class="checkbox">
|
||||
<label for="enableAutotype">
|
||||
<input
|
||||
id="enableAutotype"
|
||||
type="checkbox"
|
||||
formControlName="enableAutotype"
|
||||
(change)="saveEnableAutotype()"
|
||||
/>
|
||||
{{ "enableAutotype" | i18n }}
|
||||
</label>
|
||||
</div>
|
||||
<small class="help-block">{{
|
||||
"enableAutotypeDesc" | i18n
|
||||
}}</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="theme">{{ "theme" | i18n }}</label>
|
||||
<select
|
||||
|
||||
@@ -71,6 +71,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
showAlwaysShowDock = false;
|
||||
requireEnableTray = false;
|
||||
showDuckDuckGoIntegrationOption = false;
|
||||
showEnableAutotype = false;
|
||||
showOpenAtLoginOption = false;
|
||||
isWindows: boolean;
|
||||
isLinux: boolean;
|
||||
@@ -132,6 +133,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
sshAgentPromptBehavior: SshAgentPromptType.Always,
|
||||
allowScreenshots: false,
|
||||
enableDuckDuckGoBrowserIntegration: false,
|
||||
enableAutotype: false,
|
||||
theme: [null as Theme | null],
|
||||
locale: [null as string | null],
|
||||
});
|
||||
@@ -164,6 +166,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
|
||||
const isWindows = this.platformUtilsService.getDevice() === DeviceType.WindowsDesktop;
|
||||
|
||||
// Workaround to avoid ghosting trays https://github.com/electron/electron/issues/17622
|
||||
this.requireEnableTray = this.platformUtilsService.getDevice() === DeviceType.LinuxDesktop;
|
||||
@@ -189,6 +192,9 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
// DuckDuckGo browser is only for macos initially
|
||||
this.showDuckDuckGoIntegrationOption = isMac;
|
||||
|
||||
// Autotype is only for Windows initially
|
||||
this.showEnableAutotype = isWindows;
|
||||
|
||||
const localeOptions: any[] = [];
|
||||
this.i18nService.supportedTranslationLocales.forEach((locale) => {
|
||||
let name = locale;
|
||||
@@ -331,6 +337,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
this.desktopSettingsService.sshAgentPromptBehavior$,
|
||||
),
|
||||
allowScreenshots: !(await firstValueFrom(this.desktopSettingsService.preventScreenshots$)),
|
||||
enableAutotype: await firstValueFrom(this.desktopSettingsService.autotypeEnabled$),
|
||||
theme: await firstValueFrom(this.themeStateService.selectedTheme$),
|
||||
locale: await firstValueFrom(this.i18nService.userSetLocale$),
|
||||
};
|
||||
@@ -834,6 +841,10 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
async saveEnableAutotype() {
|
||||
await this.desktopSettingsService.setAutotypeEnabled(this.form.value.enableAutotype);
|
||||
}
|
||||
|
||||
private async generateVaultTimeoutOptions(): Promise<VaultTimeoutOption[]> {
|
||||
let vaultTimeoutOptions: VaultTimeoutOption[] = [
|
||||
{ name: this.i18nService.t("oneMinute"), value: 1 },
|
||||
|
||||
@@ -24,6 +24,7 @@ import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { KeyService as KeyServiceAbstraction } from "@bitwarden/key-management";
|
||||
|
||||
import { DesktopAutofillService } from "../../autofill/services/desktop-autofill.service";
|
||||
import { DesktopAutotypeService } from "../../autofill/services/desktop-autotype.service";
|
||||
import { SshAgentService } from "../../autofill/services/ssh-agent.service";
|
||||
import { I18nRendererService } from "../../platform/services/i18n.renderer.service";
|
||||
import { VersionService } from "../../platform/services/version.service";
|
||||
@@ -50,6 +51,7 @@ export class InitService {
|
||||
private versionService: VersionService,
|
||||
private sshAgentService: SshAgentService,
|
||||
private autofillService: DesktopAutofillService,
|
||||
private autotypeService: DesktopAutotypeService,
|
||||
private sdkLoadService: SdkLoadService,
|
||||
private configService: ConfigService,
|
||||
private bulkEncryptService: BulkEncryptService,
|
||||
@@ -100,6 +102,7 @@ export class InitService {
|
||||
containerService.attachToGlobal(this.win);
|
||||
|
||||
await this.autofillService.init();
|
||||
await this.autotypeService.init();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ import { DesktopSetPasswordJitService } from "./desktop-set-password-jit.service
|
||||
import { InitService } from "./init.service";
|
||||
import { NativeMessagingManifestService } from "./native-messaging-manifest.service";
|
||||
import { RendererCryptoFunctionService } from "./renderer-crypto-function.service";
|
||||
import { DesktopAutotypeService } from "../../autofill/services/desktop-autotype.service";
|
||||
|
||||
const RELOAD_CALLBACK = new SafeInjectionToken<() => any>("RELOAD_CALLBACK");
|
||||
|
||||
@@ -451,6 +452,14 @@ const safeProviders: SafeProvider[] = [
|
||||
useClass: DefaultSshImportPromptService,
|
||||
deps: [DialogService, ToastService, PlatformUtilsServiceAbstraction, I18nServiceAbstraction],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: DesktopAutotypeService,
|
||||
deps: [
|
||||
CipherServiceAbstraction,
|
||||
LogService,
|
||||
DesktopSettingsService,
|
||||
],
|
||||
}),
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Injectable, OnDestroy } from "@angular/core";
|
||||
import {
|
||||
catchError,
|
||||
combineLatest,
|
||||
concatMap,
|
||||
EMPTY,
|
||||
filter,
|
||||
firstValueFrom,
|
||||
from,
|
||||
map,
|
||||
of,
|
||||
skip,
|
||||
Subject,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
timeout,
|
||||
TimeoutError,
|
||||
timer,
|
||||
withLatestFrom,
|
||||
} from "rxjs";
|
||||
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
|
||||
import { DesktopSettingsService } from "../../platform/services/desktop-settings.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class DesktopAutotypeService implements OnDestroy {
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private cipherService: CipherService,
|
||||
private logService: LogService,
|
||||
private desktopSettingsService: DesktopSettingsService,
|
||||
) {}
|
||||
|
||||
async init() {
|
||||
let autotypeEnabled = await firstValueFrom(this.desktopSettingsService.autotypeEnabled$);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
}
|
||||
@@ -43,11 +43,11 @@ if (
|
||||
const Main = require("./main").Main;
|
||||
|
||||
// Testing autotype hotkey registration
|
||||
const r = autotype.registerHotkey();
|
||||
//const r = autotype.registerHotkey();
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("registerHotkey(): ");
|
||||
//console.log("registerHotkey(): ");
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(r);
|
||||
//console.log(r);
|
||||
|
||||
const main = new Main();
|
||||
main.bootstrap();
|
||||
|
||||
@@ -3812,5 +3812,11 @@
|
||||
"message": "Learn more about SSH agent",
|
||||
"description": "Two part message",
|
||||
"example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent"
|
||||
},
|
||||
"enableAutotype": {
|
||||
"message": "Enable Autotype"
|
||||
},
|
||||
"enableAutotypeDesc": {
|
||||
"message": "Warning: Bitwarden gives you full control of autotype, and does not validate input locations. Please be careful! (Currently this feature is available on Windows only.)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@ const PREVENT_SCREENSHOTS = new KeyDefinition<boolean>(
|
||||
},
|
||||
);
|
||||
|
||||
const AUTOTYPE_ENABLED = new KeyDefinition<boolean>(DESKTOP_SETTINGS_DISK, "autotypeEnabled", {
|
||||
deserializer: (b) => b,
|
||||
});
|
||||
|
||||
/**
|
||||
* Various settings for controlling application behavior specific to the desktop client.
|
||||
*/
|
||||
@@ -193,6 +197,12 @@ export class DesktopSettingsService {
|
||||
|
||||
modalMode$ = this.modalModeState.state$;
|
||||
|
||||
private readonly autotypeEnabled = this.stateProvider.getGlobal(AUTOTYPE_ENABLED);
|
||||
/**
|
||||
* The application setting for whether or not autotype is enabled.
|
||||
*/
|
||||
autotypeEnabled$ = this.autotypeEnabled.state$.pipe(map(Boolean));
|
||||
|
||||
constructor(private stateProvider: StateProvider) {
|
||||
this.window$ = this.windowState.state$.pipe(
|
||||
map((window) =>
|
||||
@@ -339,4 +349,12 @@ export class DesktopSettingsService {
|
||||
async setPreventScreenshots(value: boolean) {
|
||||
await this.preventScreenshotState.update(() => value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the setting for whether or not autotype is enabled.
|
||||
* @param value `true` if autotype is enabled, `false` if it is not.
|
||||
*/
|
||||
async setAutotypeEnabled(value: boolean) {
|
||||
await this.autotypeEnabled.update(() => value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user