mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-25 12:15:18 +01:00
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704)
* Only pass necessary service to power-monitor
PowerMonitorMain only requires the messagingService instead of a full reference to Main
* Remove never changing constructor params
Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside
hideTitleBar is always true, so there is no need to make it a param
* Remove projectName from updater
This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore
* Only pass necessary service to MenuMain
MenuMain only needs service references instead of a full reference to Main
* Refactor biometrics service
Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details
Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error)
Add unit tests
Isolate biometrics import/exports with a barrel file
* Fix #3148
recordActivity was only getting called when user-activity in the main window is recognized
When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked
* Improve reloading with biometrics
* Mock import of desktop-native
* Add mock for "@bitwarden/desktop-native-linux-x64-musl"
* Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl""
This reverts commit 69771b94bf
.
* mock the exports of desktop-native
* Pass process.platform inot BiometricsService
This commit is contained in:
parent
e480f7cfbc
commit
e9d0f75b8a
@ -156,6 +156,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||||||
switch (message.command) {
|
switch (message.command) {
|
||||||
case "loggedIn":
|
case "loggedIn":
|
||||||
case "unlocked":
|
case "unlocked":
|
||||||
|
this.recordActivity();
|
||||||
this.notificationsService.updateConnection();
|
this.notificationsService.updateConnection();
|
||||||
this.updateAppMenu();
|
this.updateAppMenu();
|
||||||
this.systemService.cancelProcessReload();
|
this.systemService.cancelProcessReload();
|
||||||
@ -198,6 +199,12 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||||||
await this.systemService.clearPendingClipboard();
|
await this.systemService.clearPendingClipboard();
|
||||||
await this.systemService.startProcessReload(this.authService);
|
await this.systemService.startProcessReload(this.authService);
|
||||||
break;
|
break;
|
||||||
|
case "startProcessReload":
|
||||||
|
this.systemService.startProcessReload(this.authService);
|
||||||
|
break;
|
||||||
|
case "cancelProcessReload":
|
||||||
|
this.systemService.cancelProcessReload();
|
||||||
|
break;
|
||||||
case "reloadProcess":
|
case "reloadProcess":
|
||||||
(window.location as any).reload(true);
|
(window.location as any).reload(true);
|
||||||
break;
|
break;
|
||||||
|
@ -7,7 +7,7 @@ import { GlobalState } from "@bitwarden/common/models/domain/global-state";
|
|||||||
import { MemoryStorageService } from "@bitwarden/common/services/memoryStorage.service";
|
import { MemoryStorageService } from "@bitwarden/common/services/memoryStorage.service";
|
||||||
import { StateService } from "@bitwarden/common/services/state.service";
|
import { StateService } from "@bitwarden/common/services/state.service";
|
||||||
|
|
||||||
import { BiometricMain } from "./main/biometric/biometric.main";
|
import { BiometricsService, BiometricsServiceAbstraction } from "./main/biometric/index";
|
||||||
import { DesktopCredentialStorageListener } from "./main/desktop-credential-storage-listener";
|
import { DesktopCredentialStorageListener } from "./main/desktop-credential-storage-listener";
|
||||||
import { MenuMain } from "./main/menu/menu.main";
|
import { MenuMain } from "./main/menu/menu.main";
|
||||||
import { MessagingMain } from "./main/messaging.main";
|
import { MessagingMain } from "./main/messaging.main";
|
||||||
@ -37,7 +37,7 @@ export class Main {
|
|||||||
menuMain: MenuMain;
|
menuMain: MenuMain;
|
||||||
powerMonitorMain: PowerMonitorMain;
|
powerMonitorMain: PowerMonitorMain;
|
||||||
trayMain: TrayMain;
|
trayMain: TrayMain;
|
||||||
biometricMain: BiometricMain;
|
biometricsService: BiometricsServiceAbstraction;
|
||||||
nativeMessagingMain: NativeMessagingMain;
|
nativeMessagingMain: NativeMessagingMain;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -98,40 +98,37 @@ export class Main {
|
|||||||
this.windowMain = new WindowMain(
|
this.windowMain = new WindowMain(
|
||||||
this.stateService,
|
this.stateService,
|
||||||
this.logService,
|
this.logService,
|
||||||
true,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
(arg) => this.processDeepLink(arg),
|
(arg) => this.processDeepLink(arg),
|
||||||
(win) => this.trayMain.setupWindowListeners(win)
|
(win) => this.trayMain.setupWindowListeners(win)
|
||||||
);
|
);
|
||||||
this.messagingMain = new MessagingMain(this, this.stateService);
|
this.messagingMain = new MessagingMain(this, this.stateService);
|
||||||
this.updaterMain = new UpdaterMain(this.i18nService, this.windowMain, "bitwarden");
|
this.updaterMain = new UpdaterMain(this.i18nService, this.windowMain);
|
||||||
this.menuMain = new MenuMain(this);
|
|
||||||
this.powerMonitorMain = new PowerMonitorMain(this);
|
|
||||||
this.trayMain = new TrayMain(this.windowMain, this.i18nService, this.stateService);
|
this.trayMain = new TrayMain(this.windowMain, this.i18nService, this.stateService);
|
||||||
|
|
||||||
this.messagingService = new ElectronMainMessagingService(this.windowMain, (message) => {
|
this.messagingService = new ElectronMainMessagingService(this.windowMain, (message) => {
|
||||||
this.messagingMain.onMessage(message);
|
this.messagingMain.onMessage(message);
|
||||||
});
|
});
|
||||||
|
this.powerMonitorMain = new PowerMonitorMain(this.messagingService);
|
||||||
|
this.menuMain = new MenuMain(
|
||||||
|
this.i18nService,
|
||||||
|
this.messagingService,
|
||||||
|
this.stateService,
|
||||||
|
this.windowMain,
|
||||||
|
this.updaterMain
|
||||||
|
);
|
||||||
|
|
||||||
if (process.platform === "win32") {
|
this.biometricsService = new BiometricsService(
|
||||||
// eslint-disable-next-line
|
|
||||||
const BiometricWindowsMain = require("./main/biometric/biometric.windows.main").default;
|
|
||||||
this.biometricMain = new BiometricWindowsMain(
|
|
||||||
this.i18nService,
|
this.i18nService,
|
||||||
this.windowMain,
|
this.windowMain,
|
||||||
this.stateService,
|
this.stateService,
|
||||||
this.logService
|
this.logService,
|
||||||
|
this.messagingService,
|
||||||
|
process.platform
|
||||||
);
|
);
|
||||||
} else if (process.platform === "darwin") {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
const BiometricDarwinMain = require("./main/biometric/biometric.darwin.main").default;
|
|
||||||
this.biometricMain = new BiometricDarwinMain(this.i18nService, this.stateService);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.desktopCredentialStorageListener = new DesktopCredentialStorageListener(
|
this.desktopCredentialStorageListener = new DesktopCredentialStorageListener(
|
||||||
"Bitwarden",
|
"Bitwarden",
|
||||||
this.biometricMain
|
this.biometricsService
|
||||||
);
|
);
|
||||||
|
|
||||||
this.nativeMessagingMain = new NativeMessagingMain(
|
this.nativeMessagingMain = new NativeMessagingMain(
|
||||||
@ -163,8 +160,8 @@ export class Main {
|
|||||||
}
|
}
|
||||||
this.powerMonitorMain.init();
|
this.powerMonitorMain.init();
|
||||||
await this.updaterMain.init();
|
await this.updaterMain.init();
|
||||||
if (this.biometricMain != null) {
|
if (this.biometricsService != null) {
|
||||||
await this.biometricMain.init();
|
await this.biometricsService.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -3,9 +3,9 @@ import { ipcMain, systemPreferences } from "electron";
|
|||||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
|
|
||||||
import { BiometricMain } from "../biometric/biometric.main";
|
import { BiometricsServiceAbstraction } from "./biometrics.service.abstraction";
|
||||||
|
|
||||||
export default class BiometricDarwinMain implements BiometricMain {
|
export default class BiometricDarwinMain implements BiometricsServiceAbstraction {
|
||||||
constructor(private i18nservice: I18nService, private stateService: StateService) {}
|
constructor(private i18nservice: I18nService, private stateService: StateService) {}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
|
@ -7,9 +7,9 @@ import { biometrics } from "@bitwarden/desktop-native";
|
|||||||
|
|
||||||
import { WindowMain } from "../window.main";
|
import { WindowMain } from "../window.main";
|
||||||
|
|
||||||
import { BiometricMain } from "./biometric.main";
|
import { BiometricsServiceAbstraction } from "./biometrics.service.abstraction";
|
||||||
|
|
||||||
export default class BiometricWindowsMain implements BiometricMain {
|
export default class BiometricWindowsMain implements BiometricsServiceAbstraction {
|
||||||
constructor(
|
constructor(
|
||||||
private i18nservice: I18nService,
|
private i18nservice: I18nService,
|
||||||
private windowMain: WindowMain,
|
private windowMain: WindowMain,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export abstract class BiometricMain {
|
export abstract class BiometricsServiceAbstraction {
|
||||||
init: () => Promise<void>;
|
init: () => Promise<void>;
|
||||||
supportsBiometric: () => Promise<boolean>;
|
supportsBiometric: () => Promise<boolean>;
|
||||||
authenticateBiometric: () => Promise<boolean>;
|
authenticateBiometric: () => Promise<boolean>;
|
81
apps/desktop/src/main/biometric/biometrics.service.spec.ts
Normal file
81
apps/desktop/src/main/biometric/biometrics.service.spec.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
|
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||||
|
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||||
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
|
|
||||||
|
import { WindowMain } from "../window.main";
|
||||||
|
|
||||||
|
import BiometricDarwinMain from "./biometric.darwin.main";
|
||||||
|
import BiometricWindowsMain from "./biometric.windows.main";
|
||||||
|
import { BiometricsService } from "./biometrics.service";
|
||||||
|
import { BiometricsServiceAbstraction } from "./biometrics.service.abstraction";
|
||||||
|
|
||||||
|
jest.mock("@bitwarden/desktop-native", () => {
|
||||||
|
return {
|
||||||
|
biometrics: jest.fn(),
|
||||||
|
passwords: jest.fn(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("biometrics tests", function () {
|
||||||
|
const i18nService = mock<I18nService>();
|
||||||
|
const windowMain = mock<WindowMain>();
|
||||||
|
const stateService = mock<StateService>();
|
||||||
|
const logService = mock<LogService>();
|
||||||
|
const messagingService = mock<MessagingService>();
|
||||||
|
|
||||||
|
it("Should call the platformspecific methods", () => {
|
||||||
|
const sut = new BiometricsService(
|
||||||
|
i18nService,
|
||||||
|
windowMain,
|
||||||
|
stateService,
|
||||||
|
logService,
|
||||||
|
messagingService,
|
||||||
|
process.platform
|
||||||
|
);
|
||||||
|
|
||||||
|
const mockService = mock<BiometricsServiceAbstraction>();
|
||||||
|
(sut as any).platformSpecificService = mockService;
|
||||||
|
sut.init();
|
||||||
|
expect(mockService.init).toBeCalled();
|
||||||
|
|
||||||
|
sut.supportsBiometric();
|
||||||
|
expect(mockService.supportsBiometric).toBeCalled();
|
||||||
|
|
||||||
|
sut.authenticateBiometric();
|
||||||
|
expect(mockService.authenticateBiometric).toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Should create a platform specific service", function () {
|
||||||
|
it("Should create a biometrics service specific for Windows", () => {
|
||||||
|
const sut = new BiometricsService(
|
||||||
|
i18nService,
|
||||||
|
windowMain,
|
||||||
|
stateService,
|
||||||
|
logService,
|
||||||
|
messagingService,
|
||||||
|
"win32"
|
||||||
|
);
|
||||||
|
|
||||||
|
const internalService = (sut as any).platformSpecificService;
|
||||||
|
expect(internalService).not.toBeNull();
|
||||||
|
expect(internalService).toBeInstanceOf(BiometricWindowsMain);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should create a biometrics service specific for MacOs", () => {
|
||||||
|
const sut = new BiometricsService(
|
||||||
|
i18nService,
|
||||||
|
windowMain,
|
||||||
|
stateService,
|
||||||
|
logService,
|
||||||
|
messagingService,
|
||||||
|
"darwin"
|
||||||
|
);
|
||||||
|
const internalService = (sut as any).platformSpecificService;
|
||||||
|
expect(internalService).not.toBeNull();
|
||||||
|
expect(internalService).toBeInstanceOf(BiometricDarwinMain);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
65
apps/desktop/src/main/biometric/biometrics.service.ts
Normal file
65
apps/desktop/src/main/biometric/biometrics.service.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
|
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||||
|
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||||
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
|
|
||||||
|
import { WindowMain } from "../window.main";
|
||||||
|
|
||||||
|
import { BiometricsServiceAbstraction } from "./biometrics.service.abstraction";
|
||||||
|
|
||||||
|
export class BiometricsService implements BiometricsServiceAbstraction {
|
||||||
|
private platformSpecificService: BiometricsServiceAbstraction;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private i18nService: I18nService,
|
||||||
|
private windowMain: WindowMain,
|
||||||
|
private stateService: StateService,
|
||||||
|
private logService: LogService,
|
||||||
|
private messagingService: MessagingService,
|
||||||
|
private platform: NodeJS.Platform
|
||||||
|
) {
|
||||||
|
this.loadPlatformSpecificService(this.platform);
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadPlatformSpecificService(platform: NodeJS.Platform) {
|
||||||
|
if (platform === "win32") {
|
||||||
|
this.loadWindowsHelloService();
|
||||||
|
} else if (platform === "darwin") {
|
||||||
|
this.loadMacOSService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadWindowsHelloService() {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const BiometricWindowsMain = require("./biometric.windows.main").default;
|
||||||
|
this.platformSpecificService = new BiometricWindowsMain(
|
||||||
|
this.i18nService,
|
||||||
|
this.windowMain,
|
||||||
|
this.stateService,
|
||||||
|
this.logService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadMacOSService() {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const BiometricDarwinMain = require("./biometric.darwin.main").default;
|
||||||
|
this.platformSpecificService = new BiometricDarwinMain(this.i18nService, this.stateService);
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
return await this.platformSpecificService.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
async supportsBiometric(): Promise<boolean> {
|
||||||
|
return await this.platformSpecificService.supportsBiometric();
|
||||||
|
}
|
||||||
|
|
||||||
|
async authenticateBiometric(): Promise<boolean> {
|
||||||
|
this.messagingService.send("cancelProcessReload");
|
||||||
|
const response = await this.platformSpecificService.authenticateBiometric();
|
||||||
|
if (!response) {
|
||||||
|
this.messagingService.send("startProcessReload");
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
2
apps/desktop/src/main/biometric/index.ts
Normal file
2
apps/desktop/src/main/biometric/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from "./biometrics.service.abstraction";
|
||||||
|
export * from "./biometrics.service";
|
@ -2,13 +2,16 @@ import { ipcMain } from "electron";
|
|||||||
|
|
||||||
import { passwords } from "@bitwarden/desktop-native";
|
import { passwords } from "@bitwarden/desktop-native";
|
||||||
|
|
||||||
import { BiometricMain } from "./biometric/biometric.main";
|
import { BiometricsServiceAbstraction } from "./biometric/index";
|
||||||
|
|
||||||
const AuthRequiredSuffix = "_biometric";
|
const AuthRequiredSuffix = "_biometric";
|
||||||
const AuthenticatedActions = ["getPassword"];
|
const AuthenticatedActions = ["getPassword"];
|
||||||
|
|
||||||
export class DesktopCredentialStorageListener {
|
export class DesktopCredentialStorageListener {
|
||||||
constructor(private serviceName: string, private biometricService: BiometricMain) {}
|
constructor(
|
||||||
|
private serviceName: string,
|
||||||
|
private biometricService: BiometricsServiceAbstraction
|
||||||
|
) {}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
ipcMain.handle("keytar", async (event: any, message: any) => {
|
ipcMain.handle("keytar", async (event: any, message: any) => {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { app, Menu } from "electron";
|
import { app, Menu } from "electron";
|
||||||
|
|
||||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
|
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||||
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
|
|
||||||
import { Main } from "../../main";
|
import { UpdaterMain } from "../updater.main";
|
||||||
import { WindowMain } from "../window.main";
|
import { WindowMain } from "../window.main";
|
||||||
|
|
||||||
import { MenuUpdateRequest } from "./menu.updater";
|
import { MenuUpdateRequest } from "./menu.updater";
|
||||||
@ -11,13 +13,13 @@ import { Menubar } from "./menubar";
|
|||||||
const cloudWebVaultUrl = "https://vault.bitwarden.com";
|
const cloudWebVaultUrl = "https://vault.bitwarden.com";
|
||||||
|
|
||||||
export class MenuMain {
|
export class MenuMain {
|
||||||
private i18nService: I18nService;
|
constructor(
|
||||||
private windowMain: WindowMain;
|
private i18nService: I18nService,
|
||||||
|
private messagingService: MessagingService,
|
||||||
constructor(private main: Main) {
|
private stateService: StateService,
|
||||||
this.i18nService = main.i18nService;
|
private windowMain: WindowMain,
|
||||||
this.windowMain = main.windowMain;
|
private updaterMain: UpdaterMain
|
||||||
}
|
) {}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
this.initContextMenu();
|
this.initContextMenu();
|
||||||
@ -31,9 +33,9 @@ export class MenuMain {
|
|||||||
private async setMenu(updateRequest?: MenuUpdateRequest) {
|
private async setMenu(updateRequest?: MenuUpdateRequest) {
|
||||||
Menu.setApplicationMenu(
|
Menu.setApplicationMenu(
|
||||||
new Menubar(
|
new Menubar(
|
||||||
this.main.i18nService,
|
this.i18nService,
|
||||||
this.main.messagingService,
|
this.messagingService,
|
||||||
this.main.updaterMain,
|
this.updaterMain,
|
||||||
this.windowMain,
|
this.windowMain,
|
||||||
await this.getWebVaultUrl(),
|
await this.getWebVaultUrl(),
|
||||||
app.getVersion(),
|
app.getVersion(),
|
||||||
@ -44,7 +46,7 @@ export class MenuMain {
|
|||||||
|
|
||||||
private async getWebVaultUrl() {
|
private async getWebVaultUrl() {
|
||||||
let webVaultUrl = cloudWebVaultUrl;
|
let webVaultUrl = cloudWebVaultUrl;
|
||||||
const urlsObj: any = await this.main.stateService.getEnvironmentUrls();
|
const urlsObj = await this.stateService.getEnvironmentUrls();
|
||||||
if (urlsObj != null) {
|
if (urlsObj != null) {
|
||||||
if (urlsObj.base != null) {
|
if (urlsObj.base != null) {
|
||||||
webVaultUrl = urlsObj.base;
|
webVaultUrl = urlsObj.base;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { powerMonitor } from "electron";
|
import { powerMonitor } from "electron";
|
||||||
|
|
||||||
import { Main } from "../main";
|
import { ElectronMainMessagingService } from "../services/electron-main-messaging.service";
|
||||||
import { isSnapStore } from "../utils";
|
import { isSnapStore } from "../utils";
|
||||||
|
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
@ -10,21 +10,21 @@ const IdleCheckInterval = 30 * 1000; // 30 seconds
|
|||||||
export class PowerMonitorMain {
|
export class PowerMonitorMain {
|
||||||
private idle = false;
|
private idle = false;
|
||||||
|
|
||||||
constructor(private main: Main) {}
|
constructor(private messagingService: ElectronMainMessagingService) {}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// ref: https://github.com/electron/electron/issues/13767
|
// ref: https://github.com/electron/electron/issues/13767
|
||||||
if (!isSnapStore()) {
|
if (!isSnapStore()) {
|
||||||
// System sleep
|
// System sleep
|
||||||
powerMonitor.on("suspend", () => {
|
powerMonitor.on("suspend", () => {
|
||||||
this.main.messagingService.send("systemSuspended");
|
this.messagingService.send("systemSuspended");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform !== "linux") {
|
if (process.platform !== "linux") {
|
||||||
// System locked
|
// System locked
|
||||||
powerMonitor.on("lock-screen", () => {
|
powerMonitor.on("lock-screen", () => {
|
||||||
this.main.messagingService.send("systemLocked");
|
this.messagingService.send("systemLocked");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ export class PowerMonitorMain {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.main.messagingService.send("systemIdle");
|
this.messagingService.send("systemIdle");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.idle = idle;
|
this.idle = idle;
|
||||||
|
@ -16,11 +16,7 @@ export class UpdaterMain {
|
|||||||
private doingUpdateCheckWithFeedback = false;
|
private doingUpdateCheckWithFeedback = false;
|
||||||
private canUpdate = false;
|
private canUpdate = false;
|
||||||
|
|
||||||
constructor(
|
constructor(private i18nService: I18nService, private windowMain: WindowMain) {
|
||||||
private i18nService: I18nService,
|
|
||||||
private windowMain: WindowMain,
|
|
||||||
private projectName: string
|
|
||||||
) {
|
|
||||||
autoUpdater.logger = log;
|
autoUpdater.logger = log;
|
||||||
|
|
||||||
const linuxCanUpdate = process.platform === "linux" && isAppImage();
|
const linuxCanUpdate = process.platform === "linux" && isAppImage();
|
||||||
@ -49,8 +45,7 @@ export class UpdaterMain {
|
|||||||
|
|
||||||
const result = await dialog.showMessageBox(this.windowMain.win, {
|
const result = await dialog.showMessageBox(this.windowMain.win, {
|
||||||
type: "info",
|
type: "info",
|
||||||
title:
|
title: this.i18nService.t("bitwarden") + " - " + this.i18nService.t("updateAvailable"),
|
||||||
this.i18nService.t(this.projectName) + " - " + this.i18nService.t("updateAvailable"),
|
|
||||||
message: this.i18nService.t("updateAvailable"),
|
message: this.i18nService.t("updateAvailable"),
|
||||||
detail: this.i18nService.t("updateAvailableDesc"),
|
detail: this.i18nService.t("updateAvailableDesc"),
|
||||||
buttons: [this.i18nService.t("yes"), this.i18nService.t("no")],
|
buttons: [this.i18nService.t("yes"), this.i18nService.t("no")],
|
||||||
@ -87,7 +82,7 @@ export class UpdaterMain {
|
|||||||
|
|
||||||
const result = await dialog.showMessageBox(this.windowMain.win, {
|
const result = await dialog.showMessageBox(this.windowMain.win, {
|
||||||
type: "info",
|
type: "info",
|
||||||
title: this.i18nService.t(this.projectName) + " - " + this.i18nService.t("restartToUpdate"),
|
title: this.i18nService.t("bitwarden") + " - " + this.i18nService.t("restartToUpdate"),
|
||||||
message: this.i18nService.t("restartToUpdate"),
|
message: this.i18nService.t("restartToUpdate"),
|
||||||
detail: this.i18nService.t("restartToUpdateDesc", info.version),
|
detail: this.i18nService.t("restartToUpdateDesc", info.version),
|
||||||
buttons: [this.i18nService.t("restart"), this.i18nService.t("later")],
|
buttons: [this.i18nService.t("restart"), this.i18nService.t("later")],
|
||||||
|
@ -20,12 +20,12 @@ export class WindowMain {
|
|||||||
private windowStates: { [key: string]: WindowState } = {};
|
private windowStates: { [key: string]: WindowState } = {};
|
||||||
private enableAlwaysOnTop = false;
|
private enableAlwaysOnTop = false;
|
||||||
|
|
||||||
|
readonly defaultWidth = 950;
|
||||||
|
readonly defaultHeight = 600;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private hideTitleBar = false,
|
|
||||||
private defaultWidth = 950,
|
|
||||||
private defaultHeight = 600,
|
|
||||||
private argvCallback: (argv: string[]) => void = null,
|
private argvCallback: (argv: string[]) => void = null,
|
||||||
private createWindowCallback: (win: BrowserWindow) => void
|
private createWindowCallback: (win: BrowserWindow) => void
|
||||||
) {}
|
) {}
|
||||||
@ -118,7 +118,7 @@ export class WindowMain {
|
|||||||
y: this.windowStates[mainWindowSizeKey].y,
|
y: this.windowStates[mainWindowSizeKey].y,
|
||||||
title: app.name,
|
title: app.name,
|
||||||
icon: process.platform === "linux" ? path.join(__dirname, "/images/icon.png") : undefined,
|
icon: process.platform === "linux" ? path.join(__dirname, "/images/icon.png") : undefined,
|
||||||
titleBarStyle: this.hideTitleBar && process.platform === "darwin" ? "hiddenInset" : undefined,
|
titleBarStyle: process.platform === "darwin" ? "hiddenInset" : undefined,
|
||||||
show: false,
|
show: false,
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
alwaysOnTop: this.enableAlwaysOnTop,
|
alwaysOnTop: this.enableAlwaysOnTop,
|
||||||
|
@ -45,34 +45,23 @@ export class SystemService implements SystemServiceAbstraction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.cancelProcessReload();
|
this.cancelProcessReload();
|
||||||
this.reloadInterval = setInterval(async () => await this.executeProcessReload(), 10000);
|
await this.executeProcessReload();
|
||||||
}
|
|
||||||
|
|
||||||
private async inactiveMoreThanSeconds(seconds: number): Promise<boolean> {
|
|
||||||
const lastActive = await this.stateService.getLastActive();
|
|
||||||
if (lastActive != null) {
|
|
||||||
const diffMs = new Date().getTime() - lastActive;
|
|
||||||
return diffMs >= seconds * 1000;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async executeProcessReload() {
|
private async executeProcessReload() {
|
||||||
const accounts = await firstValueFrom(this.stateService.accounts$);
|
|
||||||
const doRefresh =
|
|
||||||
accounts == null ||
|
|
||||||
Object.keys(accounts).length == 0 ||
|
|
||||||
(await this.inactiveMoreThanSeconds(5));
|
|
||||||
|
|
||||||
const biometricLockedFingerprintValidated =
|
const biometricLockedFingerprintValidated =
|
||||||
await this.stateService.getBiometricFingerprintValidated();
|
await this.stateService.getBiometricFingerprintValidated();
|
||||||
if (doRefresh && !biometricLockedFingerprintValidated) {
|
if (!biometricLockedFingerprintValidated) {
|
||||||
clearInterval(this.reloadInterval);
|
clearInterval(this.reloadInterval);
|
||||||
this.reloadInterval = null;
|
this.reloadInterval = null;
|
||||||
this.messagingService.send("reloadProcess");
|
this.messagingService.send("reloadProcess");
|
||||||
if (this.reloadCallback != null) {
|
if (this.reloadCallback != null) {
|
||||||
await this.reloadCallback();
|
await this.reloadCallback();
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.reloadInterval == null) {
|
||||||
|
this.reloadInterval = setInterval(async () => await this.executeProcessReload(), 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user