[PM-11312] Add "prevent screenshot" setting to windows and mac (#10707)

* Add screenshot protection to windows and mac

* Update messaging of screencapture prevention feature

* Set default state to false
This commit is contained in:
Bernd Schoolmann 2024-09-18 12:38:35 +02:00 committed by GitHub
parent 18ef74930c
commit 1b7bb014d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 63 additions and 0 deletions

View File

@ -419,6 +419,23 @@
"enableHardwareAccelerationDesc" | i18n "enableHardwareAccelerationDesc" | i18n
}}</small> }}</small>
</div> </div>
<div class="form-group" *ngIf="!isLinux">
<div class="checkbox">
<label for="allowScreenshots">
<input
id="allowScreenshots"
type="checkbox"
aria-describedby="allowScreenshotsHelp"
formControlName="allowScreenshots"
(change)="saveAllowScreenshots()"
/>
{{ "allowScreenshots" | i18n }}
</label>
</div>
<small id="allowScreenshotsHelp" class="help-block">{{
"allowScreenshotsDesc" | i18n
}}</small>
</div>
<div class="form-group" *ngIf="showDuckDuckGoIntegrationOption"> <div class="form-group" *ngIf="showDuckDuckGoIntegrationOption">
<div class="checkbox"> <div class="checkbox">
<label for="enableDuckDuckGoBrowserIntegration"> <label for="enableDuckDuckGoBrowserIntegration">

View File

@ -109,6 +109,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
disabled: true, disabled: true,
}), }),
enableHardwareAcceleration: true, enableHardwareAcceleration: true,
allowScreenshots: false,
enableDuckDuckGoBrowserIntegration: false, enableDuckDuckGoBrowserIntegration: false,
theme: [null as ThemeType | null], theme: [null as ThemeType | null],
locale: [null as string | null], locale: [null as string | null],
@ -277,6 +278,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
enableHardwareAcceleration: await firstValueFrom( enableHardwareAcceleration: await firstValueFrom(
this.desktopSettingsService.hardwareAcceleration$, this.desktopSettingsService.hardwareAcceleration$,
), ),
allowScreenshots: await firstValueFrom(this.desktopSettingsService.allowScreenshots$),
theme: await firstValueFrom(this.themeStateService.selectedTheme$), theme: await firstValueFrom(this.themeStateService.selectedTheme$),
locale: await firstValueFrom(this.i18nService.userSetLocale$), locale: await firstValueFrom(this.i18nService.userSetLocale$),
}; };
@ -727,6 +729,10 @@ export class SettingsComponent implements OnInit, OnDestroy {
); );
} }
async saveAllowScreenshots() {
await this.desktopSettingsService.setAllowScreenshots(this.form.value.allowScreenshots);
}
private async generateVaultTimeoutOptions(): Promise<VaultTimeoutOption[]> { private async generateVaultTimeoutOptions(): Promise<VaultTimeoutOption[]> {
let vaultTimeoutOptions: VaultTimeoutOption[] = [ let vaultTimeoutOptions: VaultTimeoutOption[] = [
{ name: this.i18nService.t("oneMinute"), value: 1 }, { name: this.i18nService.t("oneMinute"), value: 1 },

View File

@ -3077,6 +3077,12 @@
"textSends": { "textSends": {
"message": "Text Sends" "message": "Text Sends"
}, },
"allowScreenshots": {
"message": "Allow screen capture"
},
"allowScreenshotsDesc": {
"message": "Allow screen capture of the Bitwarden desktop application."
},
"ssoError": { "ssoError": {
"message": "No free ports could be found for the sso login." "message": "No free ports could be found for the sso login."
}, },

View File

@ -69,6 +69,13 @@ export class WindowMain {
this.logService.info("Render process reloaded"); this.logService.info("Render process reloaded");
}); });
this.desktopSettingsService.allowScreenshots$.subscribe((allowed) => {
if (this.win == null) {
return;
}
this.win.setContentProtection(!allowed);
});
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
try { try {
if (!isMacAppStore() && !isSnapStore()) { if (!isMacAppStore() && !isSnapStore()) {
@ -270,6 +277,14 @@ export class WindowMain {
}); });
}); });
firstValueFrom(this.desktopSettingsService.allowScreenshots$)
.then((allowScreenshots) => {
this.win.setContentProtection(!allowScreenshots);
})
.catch((e) => {
this.logService.error(e);
});
if (this.createWindowCallback) { if (this.createWindowCallback) {
this.createWindowCallback(this.win); this.createWindowCallback(this.win);
} }

View File

@ -71,6 +71,10 @@ const MINIMIZE_ON_COPY = new UserKeyDefinition<boolean>(DESKTOP_SETTINGS_DISK, "
clearOn: [], // User setting, no need to clear clearOn: [], // User setting, no need to clear
}); });
const ALLOW_SCREENSHOTS = new KeyDefinition<boolean>(DESKTOP_SETTINGS_DISK, "allowScreenshots", {
deserializer: (b) => b,
});
/** /**
* Various settings for controlling application behavior specific to the desktop client. * Various settings for controlling application behavior specific to the desktop client.
*/ */
@ -139,6 +143,13 @@ export class DesktopSettingsService {
browserIntegrationFingerprintEnabled$ = browserIntegrationFingerprintEnabled$ =
this.browserIntegrationFingerprintEnabledState.state$.pipe(map(Boolean)); this.browserIntegrationFingerprintEnabledState.state$.pipe(map(Boolean));
private readonly allowScreenshotState = this.stateProvider.getGlobal(ALLOW_SCREENSHOTS);
/**
* The application setting for whether or not to allow screenshots of the app.
*/
allowScreenshots$ = this.allowScreenshotState.state$.pipe(map(Boolean));
private readonly minimizeOnCopyState = this.stateProvider.getActive(MINIMIZE_ON_COPY); private readonly minimizeOnCopyState = this.stateProvider.getActive(MINIMIZE_ON_COPY);
/** /**
@ -255,4 +266,12 @@ export class DesktopSettingsService {
async setMinimizeOnCopy(value: boolean, userId: UserId) { async setMinimizeOnCopy(value: boolean, userId: UserId) {
await this.stateProvider.getUser(userId, MINIMIZE_ON_COPY).update(() => value); await this.stateProvider.getUser(userId, MINIMIZE_ON_COPY).update(() => value);
} }
/**
* Sets the setting for whether or not the screenshot protection is enabled.
* @param value `true` if the screenshot protection is enabled, `false` if it is not.
*/
async setAllowScreenshots(value: boolean) {
await this.allowScreenshotState.update(() => value);
}
} }