mirror of
https://github.com/bitwarden/browser.git
synced 2024-09-18 02:41:15 +02:00
[PM-6426] Implementing abortTimeout for Fido2ClientService using TaskSchedulerService
This commit is contained in:
parent
2f517336db
commit
f60a37fe2c
@ -830,6 +830,7 @@ export default class MainBackground {
|
|||||||
this.authService,
|
this.authService,
|
||||||
this.vaultSettingsService,
|
this.vaultSettingsService,
|
||||||
this.domainSettingsService,
|
this.domainSettingsService,
|
||||||
|
this.taskSchedulerService,
|
||||||
this.logService,
|
this.logService,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { AuthService } from "../../../auth/abstractions/auth.service";
|
|||||||
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
||||||
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
||||||
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
||||||
|
import { TaskSchedulerService } from "../../../platform/abstractions/task-scheduler.service";
|
||||||
import { Utils } from "../../../platform/misc/utils";
|
import { Utils } from "../../../platform/misc/utils";
|
||||||
import {
|
import {
|
||||||
Fido2AuthenticatorError,
|
Fido2AuthenticatorError,
|
||||||
@ -34,6 +35,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
let authService!: MockProxy<AuthService>;
|
let authService!: MockProxy<AuthService>;
|
||||||
let vaultSettingsService: MockProxy<VaultSettingsService>;
|
let vaultSettingsService: MockProxy<VaultSettingsService>;
|
||||||
let domainSettingsService: MockProxy<DomainSettingsService>;
|
let domainSettingsService: MockProxy<DomainSettingsService>;
|
||||||
|
let taskSchedulerService: MockProxy<TaskSchedulerService>;
|
||||||
let client!: Fido2ClientService;
|
let client!: Fido2ClientService;
|
||||||
let tab!: chrome.tabs.Tab;
|
let tab!: chrome.tabs.Tab;
|
||||||
|
|
||||||
@ -43,6 +45,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
authService = mock<AuthService>();
|
authService = mock<AuthService>();
|
||||||
vaultSettingsService = mock<VaultSettingsService>();
|
vaultSettingsService = mock<VaultSettingsService>();
|
||||||
domainSettingsService = mock<DomainSettingsService>();
|
domainSettingsService = mock<DomainSettingsService>();
|
||||||
|
taskSchedulerService = mock<TaskSchedulerService>();
|
||||||
|
|
||||||
client = new Fido2ClientService(
|
client = new Fido2ClientService(
|
||||||
authenticator,
|
authenticator,
|
||||||
@ -50,6 +53,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
authService,
|
authService,
|
||||||
vaultSettingsService,
|
vaultSettingsService,
|
||||||
domainSettingsService,
|
domainSettingsService,
|
||||||
|
taskSchedulerService,
|
||||||
);
|
);
|
||||||
configService.serverConfig$ = of({ environment: { vault: VaultUrl } } as any);
|
configService.serverConfig$ = of({ environment: { vault: VaultUrl } } as any);
|
||||||
vaultSettingsService.enablePasskeys$ = of(true);
|
vaultSettingsService.enablePasskeys$ = of(true);
|
||||||
|
@ -6,6 +6,8 @@ import { AuthenticationStatus } from "../../../auth/enums/authentication-status"
|
|||||||
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
||||||
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
||||||
import { LogService } from "../../../platform/abstractions/log.service";
|
import { LogService } from "../../../platform/abstractions/log.service";
|
||||||
|
import { TaskSchedulerService } from "../../../platform/abstractions/task-scheduler.service";
|
||||||
|
import { ScheduledTaskNames } from "../../../platform/enums/scheduled-task-name.enum";
|
||||||
import { Utils } from "../../../platform/misc/utils";
|
import { Utils } from "../../../platform/misc/utils";
|
||||||
import {
|
import {
|
||||||
Fido2AuthenticatorError,
|
Fido2AuthenticatorError,
|
||||||
@ -38,12 +40,26 @@ import { Fido2Utils } from "./fido2-utils";
|
|||||||
* It is highly recommended that the W3C specification is used a reference when reading this code.
|
* It is highly recommended that the W3C specification is used a reference when reading this code.
|
||||||
*/
|
*/
|
||||||
export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
||||||
|
private readonly TIMEOUTS = {
|
||||||
|
NO_VERIFICATION: {
|
||||||
|
DEFAULT: 120000,
|
||||||
|
MIN: 30000,
|
||||||
|
MAX: 180000,
|
||||||
|
},
|
||||||
|
WITH_VERIFICATION: {
|
||||||
|
DEFAULT: 300000,
|
||||||
|
MIN: 30000,
|
||||||
|
MAX: 600000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authenticator: Fido2AuthenticatorService,
|
private authenticator: Fido2AuthenticatorService,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private vaultSettingsService: VaultSettingsService,
|
private vaultSettingsService: VaultSettingsService,
|
||||||
private domainSettingsService: DomainSettingsService,
|
private domainSettingsService: DomainSettingsService,
|
||||||
|
private taskSchedulerService: TaskSchedulerService,
|
||||||
private logService?: LogService,
|
private logService?: LogService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -151,7 +167,7 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
|||||||
this.logService?.info(`[Fido2Client] Aborted with AbortController`);
|
this.logService?.info(`[Fido2Client] Aborted with AbortController`);
|
||||||
throw new DOMException("The operation either timed out or was not allowed.", "AbortError");
|
throw new DOMException("The operation either timed out or was not allowed.", "AbortError");
|
||||||
}
|
}
|
||||||
const timeout = setAbortTimeout(
|
const timeout = await this.setAbortTimeout(
|
||||||
abortController,
|
abortController,
|
||||||
params.authenticatorSelection?.userVerification,
|
params.authenticatorSelection?.userVerification,
|
||||||
params.timeout,
|
params.timeout,
|
||||||
@ -200,7 +216,11 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTimeout(timeout);
|
await this.taskSchedulerService.clearScheduledTask({
|
||||||
|
taskName: ScheduledTaskNames.fido2ClientAbortTimeout,
|
||||||
|
timeoutId: timeout,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
credentialId: Fido2Utils.bufferToString(makeCredentialResult.credentialId),
|
credentialId: Fido2Utils.bufferToString(makeCredentialResult.credentialId),
|
||||||
attestationObject: Fido2Utils.bufferToString(makeCredentialResult.attestationObject),
|
attestationObject: Fido2Utils.bufferToString(makeCredentialResult.attestationObject),
|
||||||
@ -260,7 +280,11 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
|||||||
throw new DOMException("The operation either timed out or was not allowed.", "AbortError");
|
throw new DOMException("The operation either timed out or was not allowed.", "AbortError");
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeout = setAbortTimeout(abortController, params.userVerification, params.timeout);
|
const timeout = await this.setAbortTimeout(
|
||||||
|
abortController,
|
||||||
|
params.userVerification,
|
||||||
|
params.timeout,
|
||||||
|
);
|
||||||
|
|
||||||
let getAssertionResult;
|
let getAssertionResult;
|
||||||
try {
|
try {
|
||||||
@ -297,7 +321,10 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
|||||||
this.logService?.info(`[Fido2Client] Aborted with AbortController`);
|
this.logService?.info(`[Fido2Client] Aborted with AbortController`);
|
||||||
throw new DOMException("The operation either timed out or was not allowed.", "AbortError");
|
throw new DOMException("The operation either timed out or was not allowed.", "AbortError");
|
||||||
}
|
}
|
||||||
clearTimeout(timeout);
|
await this.taskSchedulerService.clearScheduledTask({
|
||||||
|
taskName: ScheduledTaskNames.fido2ClientAbortTimeout,
|
||||||
|
timeoutId: timeout,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
authenticatorData: Fido2Utils.bufferToString(getAssertionResult.authenticatorData),
|
authenticatorData: Fido2Utils.bufferToString(getAssertionResult.authenticatorData),
|
||||||
@ -310,43 +337,29 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
|||||||
signature: Fido2Utils.bufferToString(getAssertionResult.signature),
|
signature: Fido2Utils.bufferToString(getAssertionResult.signature),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const TIMEOUTS = {
|
private setAbortTimeout = async (
|
||||||
NO_VERIFICATION: {
|
|
||||||
DEFAULT: 120000,
|
|
||||||
MIN: 30000,
|
|
||||||
MAX: 180000,
|
|
||||||
},
|
|
||||||
WITH_VERIFICATION: {
|
|
||||||
DEFAULT: 300000,
|
|
||||||
MIN: 30000,
|
|
||||||
MAX: 600000,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function setAbortTimeout(
|
|
||||||
abortController: AbortController,
|
abortController: AbortController,
|
||||||
userVerification?: UserVerification,
|
userVerification?: UserVerification,
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
): number {
|
): Promise<number | NodeJS.Timeout> => {
|
||||||
let clampedTimeout: number;
|
let clampedTimeout: number;
|
||||||
|
|
||||||
|
const { WITH_VERIFICATION, NO_VERIFICATION } = this.TIMEOUTS;
|
||||||
if (userVerification === "required") {
|
if (userVerification === "required") {
|
||||||
timeout = timeout ?? TIMEOUTS.WITH_VERIFICATION.DEFAULT;
|
timeout = timeout ?? WITH_VERIFICATION.DEFAULT;
|
||||||
clampedTimeout = Math.max(
|
clampedTimeout = Math.max(WITH_VERIFICATION.MIN, Math.min(timeout, WITH_VERIFICATION.MAX));
|
||||||
TIMEOUTS.WITH_VERIFICATION.MIN,
|
|
||||||
Math.min(timeout, TIMEOUTS.WITH_VERIFICATION.MAX),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
timeout = timeout ?? TIMEOUTS.NO_VERIFICATION.DEFAULT;
|
timeout = timeout ?? NO_VERIFICATION.DEFAULT;
|
||||||
clampedTimeout = Math.max(
|
clampedTimeout = Math.max(NO_VERIFICATION.MIN, Math.min(timeout, NO_VERIFICATION.MAX));
|
||||||
TIMEOUTS.NO_VERIFICATION.MIN,
|
|
||||||
Math.min(timeout, TIMEOUTS.NO_VERIFICATION.MAX),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return window.setTimeout(() => abortController.abort(), clampedTimeout);
|
return await this.taskSchedulerService.setTimeout(
|
||||||
|
() => abortController.abort(),
|
||||||
|
clampedTimeout,
|
||||||
|
ScheduledTaskNames.fido2ClientAbortTimeout,
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user