Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server/require-user-verification #181

Merged
merged 1 commit into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ test('should throw an error if user verification is required but user was not ve
expectedOrigin: assertionOrigin,
expectedRPID: 'dev.dontneeda.pw',
authenticator: authenticator,
fidoUserVerification: 'required',
requireUserVerification: true,
});
}).toThrow(/user could not be verified/i);
});
Expand Down
30 changes: 11 additions & 19 deletions packages/server/src/authentication/verifyAuthenticationResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type VerifyAuthenticationResponseOpts = {
expectedOrigin: string | string[];
expectedRPID: string | string[];
authenticator: AuthenticatorDevice;
fidoUserVerification?: UserVerificationRequirement;
requireUserVerification?: boolean;
};

/**
Expand All @@ -32,9 +32,8 @@ export type VerifyAuthenticationResponseOpts = {
* @param expectedOrigin Website URL (or array of URLs) that the registration should have occurred on
* @param expectedRPID RP ID (or array of IDs) that was specified in the registration options
* @param authenticator An internal {@link AuthenticatorDevice} matching the credential's ID
* @param fidoUserVerification (Optional) The value specified for `userVerification` when calling
* `generateAssertionOptions()`. Activates FIDO-specific user presence and verification checks.
* Omitting this value defaults verification to a WebAuthn-specific user presence requirement.
* @param requireUserVerification (Optional) Enforce user verification by the authenticator
* (via PIN, fingerprint, etc...)
*/
export default function verifyAuthenticationResponse(
options: VerifyAuthenticationResponseOpts,
Expand All @@ -45,7 +44,7 @@ export default function verifyAuthenticationResponse(
expectedOrigin,
expectedRPID,
authenticator,
fidoUserVerification,
requireUserVerification,
} = options;
const { id, rawId, type: credentialType, response } = credential;

Expand Down Expand Up @@ -154,21 +153,14 @@ export default function verifyAuthenticationResponse(
}
}

// WebAuthn only requires the user presence flag be true
if (!flags.up) {
throw new Error('User not present during authentication');
}

// Enforce user verification if required
if (fidoUserVerification) {
if (fidoUserVerification === 'required') {
// Require `flags.uv` be true (implies `flags.up` is true)
if (!flags.uv) {
throw new Error('User verification required, but user could not be verified');
}
} else if (fidoUserVerification === 'preferred' || fidoUserVerification === 'discouraged') {
// Ignore `flags.uv`
}
} else {
// WebAuthn only requires the user presence flag be true
if (!flags.up) {
throw new Error('User not present during authentication');
}
if (requireUserVerification && !flags.uv) {
throw new Error('User verification required, but user could not be verified');
}

const clientDataHash = toHash(base64url.toBuffer(response.clientDataJSON));
Expand Down