summaryrefslogtreecommitdiffhomepage
path: root/packages/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src')
-rw-r--r--packages/server/src/helpers/generateChallenge.ts7
-rw-r--r--packages/server/src/registration/generateRegistrationOptions.test.ts228
2 files changed, 134 insertions, 101 deletions
diff --git a/packages/server/src/helpers/generateChallenge.ts b/packages/server/src/helpers/generateChallenge.ts
index 8d804eb..496f527 100644
--- a/packages/server/src/helpers/generateChallenge.ts
+++ b/packages/server/src/helpers/generateChallenge.ts
@@ -16,5 +16,10 @@ export async function generateChallenge(): Promise<Uint8Array> {
await isoCrypto.getRandomValues(challenge);
- return challenge;
+ return _generateChallengeInternals.stubThis(challenge);
}
+
+// Make it possible to stub the return value during testing
+export const _generateChallengeInternals = {
+ stubThis: (value: Uint8Array) => value,
+};
diff --git a/packages/server/src/registration/generateRegistrationOptions.test.ts b/packages/server/src/registration/generateRegistrationOptions.test.ts
index f1b34c4..2f80f9d 100644
--- a/packages/server/src/registration/generateRegistrationOptions.test.ts
+++ b/packages/server/src/registration/generateRegistrationOptions.test.ts
@@ -1,8 +1,14 @@
-jest.mock("../helpers/generateChallenge");
+import { assertEquals } from "https://deno.land/std@0.198.0/assert/mod.ts";
+import {
+ returnsNext,
+ stub,
+} from "https://deno.land/std@0.198.0/testing/mock.ts";
import { generateRegistrationOptions } from "./generateRegistrationOptions.ts";
+import { _generateChallengeInternals } from "../helpers/generateChallenge.ts";
+import { isoUint8Array } from "../helpers/iso/index.ts";
-test("should generate credential request options suitable for sending via JSON", () => {
+Deno.test("should generate credential request options suitable for sending via JSON", async () => {
const rpName = "SimpleWebAuthn";
const rpID = "not.real";
const challenge = "totallyrandomvalue";
@@ -11,7 +17,7 @@ test("should generate credential request options suitable for sending via JSON",
const timeout = 1;
const attestationType = "indirect";
- const options = generateRegistrationOptions({
+ const options = await generateRegistrationOptions({
rpName,
rpID,
challenge,
@@ -21,39 +27,42 @@ test("should generate credential request options suitable for sending via JSON",
attestationType,
});
- expect(options).toEqual({
- // Challenge, base64url-encoded
- challenge: "dG90YWxseXJhbmRvbXZhbHVl",
- rp: {
- name: rpName,
- id: rpID,
- },
- user: {
- id: userID,
- name: userName,
- displayName: userName,
- },
- pubKeyCredParams: [
- { alg: -8, type: "public-key" },
- { alg: -7, type: "public-key" },
- { alg: -257, type: "public-key" },
- ],
- timeout,
- attestation: attestationType,
- excludeCredentials: [],
- authenticatorSelection: {
- requireResidentKey: false,
- residentKey: "preferred",
- userVerification: "preferred",
- },
- extensions: {
- credProps: true,
+ assertEquals(
+ options,
+ {
+ // Challenge, base64url-encoded
+ challenge: "dG90YWxseXJhbmRvbXZhbHVl",
+ rp: {
+ name: rpName,
+ id: rpID,
+ },
+ user: {
+ id: userID,
+ name: userName,
+ displayName: userName,
+ },
+ pubKeyCredParams: [
+ { alg: -8, type: "public-key" },
+ { alg: -7, type: "public-key" },
+ { alg: -257, type: "public-key" },
+ ],
+ timeout,
+ attestation: attestationType,
+ excludeCredentials: [],
+ authenticatorSelection: {
+ requireResidentKey: false,
+ residentKey: "preferred",
+ userVerification: "preferred",
+ },
+ extensions: {
+ credProps: true,
+ },
},
- });
+ );
});
-test("should map excluded credential IDs if specified", () => {
- const options = generateRegistrationOptions({
+Deno.test("should map excluded credential IDs if specified", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
challenge: "totallyrandomvalue",
@@ -61,24 +70,27 @@ test("should map excluded credential IDs if specified", () => {
userName: "usernameHere",
excludeCredentials: [
{
- id: Buffer.from("someIDhere", "ascii"),
+ id: isoUint8Array.fromASCIIString("someIDhere"),
type: "public-key",
transports: ["usb", "ble", "nfc", "internal"],
},
],
});
- expect(options.excludeCredentials).toEqual([
- {
- id: "c29tZUlEaGVyZQ",
- type: "public-key",
- transports: ["usb", "ble", "nfc", "internal"],
- },
- ]);
+ assertEquals(
+ options.excludeCredentials,
+ [
+ {
+ id: "c29tZUlEaGVyZQ",
+ type: "public-key",
+ transports: ["usb", "ble", "nfc", "internal"],
+ },
+ ],
+ );
});
-test("defaults to 60 seconds if no timeout is specified", () => {
- const options = generateRegistrationOptions({
+Deno.test("defaults to 60 seconds if no timeout is specified", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
challenge: "totallyrandomvalue",
@@ -86,11 +98,11 @@ test("defaults to 60 seconds if no timeout is specified", () => {
userName: "usernameHere",
});
- expect(options.timeout).toEqual(60000);
+ assertEquals(options.timeout, 60000);
});
-test("defaults to none attestation if no attestation type is specified", () => {
- const options = generateRegistrationOptions({
+Deno.test("defaults to none attestation if no attestation type is specified", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
challenge: "totallyrandomvalue",
@@ -98,11 +110,11 @@ test("defaults to none attestation if no attestation type is specified", () => {
userName: "usernameHere",
});
- expect(options.attestation).toEqual("none");
+ assertEquals(options.attestation, "none");
});
-test("should set authenticatorSelection if specified", () => {
- const options = generateRegistrationOptions({
+Deno.test("should set authenticatorSelection if specified", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
challenge: "totallyrandomvalue",
@@ -115,15 +127,18 @@ test("should set authenticatorSelection if specified", () => {
},
});
- expect(options.authenticatorSelection).toEqual({
- authenticatorAttachment: "cross-platform",
- requireResidentKey: false,
- userVerification: "preferred",
- });
+ assertEquals(
+ options.authenticatorSelection,
+ {
+ authenticatorAttachment: "cross-platform",
+ requireResidentKey: false,
+ userVerification: "preferred",
+ },
+ );
});
-test("should set extensions if specified", () => {
- const options = generateRegistrationOptions({
+Deno.test("should set extensions if specified", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
challenge: "totallyrandomvalue",
@@ -132,22 +147,22 @@ test("should set extensions if specified", () => {
extensions: { appid: "simplewebauthn" },
});
- expect(options.extensions?.appid).toEqual("simplewebauthn");
+ assertEquals(options.extensions?.appid, "simplewebauthn");
});
-test("should include credProps if extensions are not provided", () => {
- const options = generateRegistrationOptions({
+Deno.test("should include credProps if extensions are not provided", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
userID: "1234",
userName: "usernameHere",
});
- expect(options.extensions?.credProps).toEqual(true);
+ assertEquals(options.extensions?.credProps, true);
});
-test("should include credProps if extensions are provided", () => {
- const options = generateRegistrationOptions({
+Deno.test("should include credProps if extensions are provided", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
userID: "1234",
@@ -155,11 +170,19 @@ test("should include credProps if extensions are provided", () => {
extensions: { appid: "simplewebauthn" },
});
- expect(options.extensions?.credProps).toEqual(true);
+ assertEquals(options.extensions?.credProps, true);
});
-test("should generate a challenge if one is not provided", () => {
- const options = generateRegistrationOptions({
+Deno.test("should generate a challenge if one is not provided", async () => {
+ const mockGenerateChallenge = stub(
+ _generateChallengeInternals,
+ "stubThis",
+ returnsNext([
+ new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
+ ]),
+ );
+
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -167,11 +190,13 @@ test("should generate a challenge if one is not provided", () => {
});
// base64url-encoded 16-byte buffer from mocked `generateChallenge()`
- expect(options.challenge).toEqual("AQIDBAUGBwgJCgsMDQ4PEA");
+ assertEquals(options.challenge, "AQIDBAUGBwgJCgsMDQ4PEA");
+
+ mockGenerateChallenge.restore();
});
-test("should use custom supported algorithm IDs as-is when provided", () => {
- const options = generateRegistrationOptions({
+Deno.test("should use custom supported algorithm IDs as-is when provided", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -179,15 +204,18 @@ test("should use custom supported algorithm IDs as-is when provided", () => {
supportedAlgorithmIDs: [-7, -8, -65535],
});
- expect(options.pubKeyCredParams).toEqual([
- { alg: -7, type: "public-key" },
- { alg: -8, type: "public-key" },
- { alg: -65535, type: "public-key" },
- ]);
+ assertEquals(
+ options.pubKeyCredParams,
+ [
+ { alg: -7, type: "public-key" },
+ { alg: -8, type: "public-key" },
+ { alg: -65535, type: "public-key" },
+ ],
+ );
});
-test("should require resident key if residentKey option is absent but requireResidentKey is set to true", () => {
- const options = generateRegistrationOptions({
+Deno.test("should require resident key if residentKey option is absent but requireResidentKey is set to true", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -197,12 +225,12 @@ test("should require resident key if residentKey option is absent but requireRes
},
});
- expect(options.authenticatorSelection?.requireResidentKey).toEqual(true);
- expect(options.authenticatorSelection?.residentKey).toEqual("required");
+ assertEquals(options.authenticatorSelection?.requireResidentKey, true);
+ assertEquals(options.authenticatorSelection?.residentKey, "required");
});
-test("should discourage resident key if residentKey option is absent but requireResidentKey is set to false", () => {
- const options = generateRegistrationOptions({
+Deno.test("should discourage resident key if residentKey option is absent but requireResidentKey is set to false", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -212,24 +240,24 @@ test("should discourage resident key if residentKey option is absent but require
},
});
- expect(options.authenticatorSelection?.requireResidentKey).toEqual(false);
- expect(options.authenticatorSelection?.residentKey).toBeUndefined();
+ assertEquals(options.authenticatorSelection?.requireResidentKey, false);
+ assertEquals(options.authenticatorSelection?.residentKey, undefined);
});
-test("should prefer resident key if both residentKey and requireResidentKey options are absent", () => {
- const options = generateRegistrationOptions({
+Deno.test("should prefer resident key if both residentKey and requireResidentKey options are absent", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
userName: "usernameHere",
});
- expect(options.authenticatorSelection?.requireResidentKey).toEqual(false);
- expect(options.authenticatorSelection?.residentKey).toEqual("preferred");
+ assertEquals(options.authenticatorSelection?.requireResidentKey, false);
+ assertEquals(options.authenticatorSelection?.residentKey, "preferred");
});
-test("should set requireResidentKey to true if residentKey if set to required", () => {
- const options = generateRegistrationOptions({
+Deno.test("should set requireResidentKey to true if residentKey if set to required", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -239,12 +267,12 @@ test("should set requireResidentKey to true if residentKey if set to required",
},
});
- expect(options.authenticatorSelection?.requireResidentKey).toEqual(true);
- expect(options.authenticatorSelection?.residentKey).toEqual("required");
+ assertEquals(options.authenticatorSelection?.requireResidentKey, true);
+ assertEquals(options.authenticatorSelection?.residentKey, "required");
});
-test("should set requireResidentKey to false if residentKey if set to preferred", () => {
- const options = generateRegistrationOptions({
+Deno.test("should set requireResidentKey to false if residentKey if set to preferred", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -254,12 +282,12 @@ test("should set requireResidentKey to false if residentKey if set to preferred"
},
});
- expect(options.authenticatorSelection?.requireResidentKey).toEqual(false);
- expect(options.authenticatorSelection?.residentKey).toEqual("preferred");
+ assertEquals(options.authenticatorSelection?.requireResidentKey, false);
+ assertEquals(options.authenticatorSelection?.residentKey, "preferred");
});
-test("should set requireResidentKey to false if residentKey if set to discouraged", () => {
- const options = generateRegistrationOptions({
+Deno.test("should set requireResidentKey to false if residentKey if set to discouraged", async () => {
+ const options = await generateRegistrationOptions({
rpID: "not.real",
rpName: "SimpleWebAuthn",
userID: "1234",
@@ -269,12 +297,12 @@ test("should set requireResidentKey to false if residentKey if set to discourage
},
});
- expect(options.authenticatorSelection?.requireResidentKey).toEqual(false);
- expect(options.authenticatorSelection?.residentKey).toEqual("discouraged");
+ assertEquals(options.authenticatorSelection?.requireResidentKey, false);
+ assertEquals(options.authenticatorSelection?.residentKey, "discouraged");
});
-test("should prefer Ed25519 in pubKeyCredParams", () => {
- const options = generateRegistrationOptions({
+Deno.test("should prefer Ed25519 in pubKeyCredParams", async () => {
+ const options = await generateRegistrationOptions({
rpName: "SimpleWebAuthn",
rpID: "not.real",
challenge: "totallyrandomvalue",
@@ -282,5 +310,5 @@ test("should prefer Ed25519 in pubKeyCredParams", () => {
userName: "usernameHere",
});
- expect(options.pubKeyCredParams[0].alg).toEqual(-8);
+ assertEquals(options.pubKeyCredParams[0].alg, -8);
});