mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-27 16:10:08 +01:00
[PS-1175] Resolve issue with processReload not executing (#3240)
* Removed check for getBiometricLocked It always returned false even when no biometrics were used. * Remove the other check for getBiometricsLocked * Ensure that biometricFingerprintValidation is reset, when biometrics are disabled * Removed getBiometricsLocked and setBiometricsLocked With nothing in the codebase reading the state of getBiometricsLocked, I've removed all places where it was set or saved. * Refactor execution of reload into a separate method * Conditonally pass the window object to `BrowserApi.reloadExtension` * Clarify in comment, that the PIN has to be set with ask for Master Password on restart * Ensure the process reload is executed on logout * Use accounts instead of lastActive == null to determine a reload on logout * Moved identical logic from desktop and browser into system.service * Simplified check for refresh to handle no accounts found, logout, lock with lastActive longer than 5 seconds
This commit is contained in:
parent
df7377d305
commit
a1e536a5ef
apps
browser/src
background
popup
desktop/src/app
libs
angular/src/components
common
spec/misc/logInStrategies
src
abstractions
misc/logInStrategies
models/domain
services
@ -183,7 +183,7 @@ export default class MainBackground {
|
||||
await this.refreshBadgeAndMenu(true);
|
||||
if (this.systemService != null) {
|
||||
await this.systemService.clearPendingClipboard();
|
||||
await this.reloadProcess();
|
||||
await this.systemService.startProcessReload(this.authService);
|
||||
}
|
||||
};
|
||||
|
||||
@ -634,7 +634,7 @@ export default class MainBackground {
|
||||
await this.reseedStorage();
|
||||
this.notificationsService.updateConnection(false);
|
||||
await this.systemService.clearPendingClipboard();
|
||||
await this.reloadProcess();
|
||||
await this.systemService.startProcessReload(this.authService);
|
||||
}
|
||||
|
||||
async collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) {
|
||||
@ -1041,16 +1041,4 @@ export default class MainBackground {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async reloadProcess(): Promise<void> {
|
||||
const accounts = this.stateService.accounts.getValue();
|
||||
if (accounts != null) {
|
||||
for (const userId of Object.keys(accounts)) {
|
||||
if ((await this.authService.getAuthStatus(userId)) === AuthenticationStatus.Unlocked) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.systemService.startProcessReload();
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +323,6 @@ export class NativeMessagingBackground {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.stateService.setBiometricLocked(false);
|
||||
this.runtimeBackground.processMessage({ command: "unlocked" }, null, null);
|
||||
}
|
||||
break;
|
||||
|
@ -107,14 +107,15 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.showToast(msg);
|
||||
});
|
||||
} else if (msg.command === "reloadProcess") {
|
||||
const windowReload =
|
||||
const forceWindowReload =
|
||||
this.platformUtilsService.isSafari() ||
|
||||
this.platformUtilsService.isFirefox() ||
|
||||
this.platformUtilsService.isOpera();
|
||||
if (windowReload) {
|
||||
// Wait to make sure background has reloaded first.
|
||||
window.setTimeout(() => BrowserApi.reloadExtension(window), 2000);
|
||||
}
|
||||
// Wait to make sure background has reloaded first.
|
||||
window.setTimeout(
|
||||
() => BrowserApi.reloadExtension(forceWindowReload ? window : null),
|
||||
2000
|
||||
);
|
||||
} else if (msg.command === "reloadPopup") {
|
||||
this.ngZone.run(() => {
|
||||
this.router.navigate(["/"]);
|
||||
|
@ -293,7 +293,7 @@ export class SettingsComponent implements OnInit {
|
||||
]);
|
||||
} else {
|
||||
await this.stateService.setBiometricUnlock(null);
|
||||
await this.stateService.setBiometricLocked(false);
|
||||
await this.stateService.setBiometricFingerprintValidated(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,6 @@ export class SettingsComponent implements OnInit {
|
||||
if (!newValue || !this.supportsBiometric) {
|
||||
this.biometric = false;
|
||||
await this.stateService.setBiometricUnlock(null);
|
||||
await this.stateService.setBiometricLocked(false);
|
||||
await this.cryptoService.toggleKey();
|
||||
return;
|
||||
}
|
||||
@ -290,7 +289,6 @@ export class SettingsComponent implements OnInit {
|
||||
|
||||
this.biometric = true;
|
||||
await this.stateService.setBiometricUnlock(true);
|
||||
await this.stateService.setBiometricLocked(false);
|
||||
await this.cryptoService.toggleKey();
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ export class AppComponent implements OnInit {
|
||||
this.notificationsService.updateConnection();
|
||||
this.updateAppMenu();
|
||||
await this.systemService.clearPendingClipboard();
|
||||
await this.reloadProcess();
|
||||
await this.systemService.startProcessReload(this.authService);
|
||||
break;
|
||||
case "authBlocked":
|
||||
this.router.navigate(["login"]);
|
||||
@ -189,7 +189,7 @@ export class AppComponent implements OnInit {
|
||||
this.notificationsService.updateConnection();
|
||||
await this.updateAppMenu();
|
||||
await this.systemService.clearPendingClipboard();
|
||||
await this.reloadProcess();
|
||||
await this.systemService.startProcessReload(this.authService);
|
||||
break;
|
||||
case "reloadProcess":
|
||||
(window.location as any).reload(true);
|
||||
@ -470,8 +470,6 @@ export class AppComponent implements OnInit {
|
||||
this.keyConnectorService.clear(),
|
||||
]);
|
||||
|
||||
await this.stateService.setBiometricLocked(true, { userId: userBeingLoggedOut });
|
||||
|
||||
if (userBeingLoggedOut === this.activeUserId) {
|
||||
this.searchService.clearIndex();
|
||||
this.authService.logOut(async () => {
|
||||
@ -585,21 +583,6 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
private async reloadProcess(): Promise<void> {
|
||||
const accounts = this.stateService.accounts.getValue();
|
||||
if (accounts != null) {
|
||||
const keys = Object.keys(accounts);
|
||||
if (keys.length > 0) {
|
||||
for (const userId of keys) {
|
||||
if ((await this.authService.getAuthStatus(userId)) === AuthenticationStatus.Unlocked) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.systemService.startProcessReload();
|
||||
}
|
||||
|
||||
private async checkForSystemTimeout(timeout: number): Promise<void> {
|
||||
for (const userId in this.stateService.accounts.getValue()) {
|
||||
if (userId == null) {
|
||||
|
@ -237,7 +237,6 @@ export class LockComponent implements OnInit {
|
||||
}
|
||||
|
||||
private async doContinue() {
|
||||
await this.stateService.setBiometricLocked(false);
|
||||
await this.stateService.setEverBeenUnlocked(true);
|
||||
const disableFavicon = await this.stateService.getDisableFavicon();
|
||||
await this.stateService.setDisableFavicon(!!disableFavicon);
|
||||
|
@ -139,7 +139,6 @@ describe("LogInStrategy", () => {
|
||||
cryptoService.received(1).setEncKey(encKey);
|
||||
cryptoService.received(1).setEncPrivateKey(privateKey);
|
||||
|
||||
stateService.received(1).setBiometricLocked(false);
|
||||
messagingService.received(1).send("loggedIn");
|
||||
});
|
||||
|
||||
|
@ -53,8 +53,6 @@ export abstract class StateService<T extends Account = Account> {
|
||||
setBiometricAwaitingAcceptance: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||
getBiometricFingerprintValidated: (options?: StorageOptions) => Promise<boolean>;
|
||||
setBiometricFingerprintValidated: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||
getBiometricLocked: (options?: StorageOptions) => Promise<boolean>;
|
||||
setBiometricLocked: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||
getBiometricText: (options?: StorageOptions) => Promise<string>;
|
||||
setBiometricText: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getBiometricUnlock: (options?: StorageOptions) => Promise<boolean>;
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { AuthService } from "./auth.service";
|
||||
|
||||
export abstract class SystemService {
|
||||
startProcessReload: () => Promise<void>;
|
||||
startProcessReload: (authService: AuthService) => Promise<void>;
|
||||
cancelProcessReload: () => void;
|
||||
clearClipboard: (clipboardValue: string, timeoutMs?: number) => Promise<void>;
|
||||
clearPendingClipboard: () => Promise<any>;
|
||||
|
@ -138,7 +138,6 @@ export abstract class LogInStrategy {
|
||||
|
||||
await this.onSuccessfulLogin(response);
|
||||
|
||||
await this.stateService.setBiometricLocked(false);
|
||||
this.messagingService.send("loggedIn");
|
||||
|
||||
return result;
|
||||
|
@ -110,7 +110,6 @@ export class AccountProfile {
|
||||
export class AccountSettings {
|
||||
autoConfirmFingerPrints?: boolean;
|
||||
autoFillOnPageLoadDefault?: boolean;
|
||||
biometricLocked?: boolean;
|
||||
biometricUnlock?: boolean;
|
||||
clearClipboard?: number;
|
||||
collapsedGroupings?: string[];
|
||||
|
@ -324,24 +324,6 @@ export class StateService<
|
||||
);
|
||||
}
|
||||
|
||||
async getBiometricLocked(options?: StorageOptions): Promise<boolean> {
|
||||
return (
|
||||
(await this.getAccount(this.reconcileOptions(options, await this.defaultInMemoryOptions())))
|
||||
?.settings?.biometricLocked ?? false
|
||||
);
|
||||
}
|
||||
|
||||
async setBiometricLocked(value: boolean, options?: StorageOptions): Promise<void> {
|
||||
const account = await this.getAccount(
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions())
|
||||
);
|
||||
account.settings.biometricLocked = value;
|
||||
await this.saveAccount(
|
||||
account,
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions())
|
||||
);
|
||||
}
|
||||
|
||||
async getBiometricText(options?: StorageOptions): Promise<string> {
|
||||
return (
|
||||
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
||||
|
@ -255,7 +255,6 @@ export class StateMigrationService<
|
||||
autoFillOnPageLoadDefault:
|
||||
(await this.get<boolean>(v1Keys.autoFillOnPageLoadDefault)) ??
|
||||
defaultAccount.settings.autoFillOnPageLoadDefault,
|
||||
biometricLocked: null,
|
||||
biometricUnlock:
|
||||
(await this.get<boolean>(v1Keys.biometricUnlock)) ??
|
||||
defaultAccount.settings.biometricUnlock,
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { AuthService } from "../abstractions/auth.service";
|
||||
import { MessagingService } from "../abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "../abstractions/platformUtils.service";
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { SystemService as SystemServiceAbstraction } from "../abstractions/system.service";
|
||||
import { AuthenticationStatus } from "../enums/authenticationStatus";
|
||||
import { Utils } from "../misc/utils";
|
||||
|
||||
export class SystemService implements SystemServiceAbstraction {
|
||||
@ -16,35 +18,60 @@ export class SystemService implements SystemServiceAbstraction {
|
||||
private stateService: StateService
|
||||
) {}
|
||||
|
||||
async startProcessReload(): Promise<void> {
|
||||
if (
|
||||
(await this.stateService.getDecryptedPinProtected()) != null ||
|
||||
(await this.stateService.getBiometricLocked()) ||
|
||||
this.reloadInterval != null
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.cancelProcessReload();
|
||||
this.reloadInterval = setInterval(async () => {
|
||||
let doRefresh = false;
|
||||
const lastActive = await this.stateService.getLastActive();
|
||||
if (lastActive != null) {
|
||||
const diffSeconds = new Date().getTime() - lastActive;
|
||||
// Don't refresh if they are still active in the window
|
||||
doRefresh = diffSeconds >= 5000;
|
||||
}
|
||||
const biometricLockedFingerprintValidated =
|
||||
(await this.stateService.getBiometricFingerprintValidated()) &&
|
||||
(await this.stateService.getBiometricLocked());
|
||||
if (doRefresh && !biometricLockedFingerprintValidated) {
|
||||
clearInterval(this.reloadInterval);
|
||||
this.reloadInterval = null;
|
||||
this.messagingService.send("reloadProcess");
|
||||
if (this.reloadCallback != null) {
|
||||
await this.reloadCallback();
|
||||
async startProcessReload(authService: AuthService): Promise<void> {
|
||||
const accounts = this.stateService.accounts.getValue();
|
||||
if (accounts != null) {
|
||||
const keys = Object.keys(accounts);
|
||||
if (keys.length > 0) {
|
||||
for (const userId of keys) {
|
||||
if ((await authService.getAuthStatus(userId)) === AuthenticationStatus.Unlocked) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
// A reloadInterval has already been set and is executing
|
||||
if (this.reloadInterval != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// User has set a PIN, with ask for master password on restart, to protect their vault
|
||||
const decryptedPinProtected = await this.stateService.getDecryptedPinProtected();
|
||||
if (decryptedPinProtected != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cancelProcessReload();
|
||||
this.reloadInterval = setInterval(async () => await this.executeProcessReload(), 10000);
|
||||
}
|
||||
|
||||
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() {
|
||||
const accounts = this.stateService.accounts.getValue();
|
||||
const doRefresh =
|
||||
accounts == null ||
|
||||
Object.keys(accounts).length == 0 ||
|
||||
(await this.inactiveMoreThanSeconds(5));
|
||||
|
||||
const biometricLockedFingerprintValidated =
|
||||
await this.stateService.getBiometricFingerprintValidated();
|
||||
if (doRefresh && !biometricLockedFingerprintValidated) {
|
||||
clearInterval(this.reloadInterval);
|
||||
this.reloadInterval = null;
|
||||
this.messagingService.send("reloadProcess");
|
||||
if (this.reloadCallback != null) {
|
||||
await this.reloadCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cancelProcessReload(): void {
|
||||
|
@ -84,7 +84,6 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
||||
}
|
||||
|
||||
await this.stateService.setEverBeenUnlocked(true, { userId: userId });
|
||||
await this.stateService.setBiometricLocked(true, { userId: userId });
|
||||
await this.stateService.setCryptoMasterKeyAuto(null, { userId: userId });
|
||||
|
||||
await this.cryptoService.clearKey(false, userId);
|
||||
|
Loading…
Reference in New Issue
Block a user