mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 16:23:44 +00:00
[EC-598] feat: add automatic default timeouts
This commit is contained in:
@@ -188,4 +188,8 @@ export class BrowserFido2UserInterfaceService implements Fido2UserInterfaceServi
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setAbortTimeout(abortController: AbortController) {
|
||||||
|
return setTimeout(() => abortController.abort());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ import { joseToDer } from "./ecdsa-utils";
|
|||||||
// We support self-signing, but Google won't accept it.
|
// We support self-signing, but Google won't accept it.
|
||||||
// TODO: Look into supporting self-signed packed format.
|
// TODO: Look into supporting self-signed packed format.
|
||||||
const STANDARD_ATTESTATION_FORMAT: "none" | "packed" = "none";
|
const STANDARD_ATTESTATION_FORMAT: "none" | "packed" = "none";
|
||||||
|
const DEFAULT_TIMEOUT = 120000;
|
||||||
|
const MIN_TIMEOUT = 30000;
|
||||||
|
const MAX_TIMEOUT = 600000;
|
||||||
|
|
||||||
interface BitCredential {
|
interface BitCredential {
|
||||||
credentialId: CredentialId;
|
credentialId: CredentialId;
|
||||||
@@ -46,8 +49,13 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
|||||||
|
|
||||||
async createCredential(
|
async createCredential(
|
||||||
params: CredentialRegistrationParams,
|
params: CredentialRegistrationParams,
|
||||||
abortController?: AbortController
|
abortController = new AbortController()
|
||||||
): Promise<CredentialRegistrationResult> {
|
): Promise<CredentialRegistrationResult> {
|
||||||
|
// Comment: Timeouts could potentially be implemented using decorators.
|
||||||
|
// But since I try to use decorators a little as possible and only
|
||||||
|
// for the most generic solutions, I'm gonne leave this as is untill peer review.
|
||||||
|
const timeout = setAbortTimeout(abortController);
|
||||||
|
|
||||||
const presence = await this.fido2UserInterfaceService.confirmNewCredential(
|
const presence = await this.fido2UserInterfaceService.confirmNewCredential(
|
||||||
{
|
{
|
||||||
credentialName: params.rp.name,
|
credentialName: params.rp.name,
|
||||||
@@ -115,6 +123,8 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
clearTimeout(timeout);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
credentialId: Fido2Utils.bufferToString(credentialId.raw),
|
credentialId: Fido2Utils.bufferToString(credentialId.raw),
|
||||||
clientDataJSON: Fido2Utils.bufferToString(clientData),
|
clientDataJSON: Fido2Utils.bufferToString(clientData),
|
||||||
@@ -127,8 +137,9 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
|||||||
|
|
||||||
async assertCredential(
|
async assertCredential(
|
||||||
params: CredentialAssertParams,
|
params: CredentialAssertParams,
|
||||||
abortController?: AbortController
|
abortController = new AbortController()
|
||||||
): Promise<CredentialAssertResult> {
|
): Promise<CredentialAssertResult> {
|
||||||
|
const timeout = setAbortTimeout(abortController);
|
||||||
let credential: BitCredential | undefined;
|
let credential: BitCredential | undefined;
|
||||||
|
|
||||||
if (params.allowedCredentialIds && params.allowedCredentialIds.length > 0) {
|
if (params.allowedCredentialIds && params.allowedCredentialIds.length > 0) {
|
||||||
@@ -185,6 +196,8 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
|||||||
privateKey: credential.keyValue,
|
privateKey: credential.keyValue,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
clearTimeout(timeout);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
credentialId: credential.credentialId.encoded,
|
credentialId: credential.credentialId.encoded,
|
||||||
clientDataJSON: Fido2Utils.bufferToString(clientData),
|
clientDataJSON: Fido2Utils.bufferToString(clientData),
|
||||||
@@ -194,10 +207,7 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getCredential(
|
private async getCredential(allowedCredentialIds: string[]): Promise<BitCredential | undefined> {
|
||||||
allowedCredentialIds: string[],
|
|
||||||
abortController?: AbortController
|
|
||||||
): Promise<BitCredential | undefined> {
|
|
||||||
let cipher: Cipher | undefined;
|
let cipher: Cipher | undefined;
|
||||||
for (const allowedCredential of allowedCredentialIds) {
|
for (const allowedCredential of allowedCredentialIds) {
|
||||||
cipher = await this.cipherService.get(allowedCredential);
|
cipher = await this.cipherService.get(allowedCredential);
|
||||||
@@ -414,3 +424,9 @@ function authDataFlags(options: Flags): number {
|
|||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAbortTimeout(abortController: AbortController, timeout = DEFAULT_TIMEOUT): number {
|
||||||
|
// TODO: Set different timeouts depending on `userVerification` value
|
||||||
|
const clampedTimeout = Math.max(MIN_TIMEOUT, Math.min(timeout, MAX_TIMEOUT));
|
||||||
|
return window.setTimeout(() => abortController.abort(), clampedTimeout);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user