UNPKG

fido2-lib

Version:

A library for performing FIDO 2.0 / WebAuthn functionality

558 lines (494 loc) 15 kB
// Testing lib import * as chai from "chai"; // Helpers import { Stub } from "./helpers/stub.js"; import { Fido2Lib } from "../lib/main.js"; const assert = chai.assert; describe("Fido2Lib extensions", function() { afterEach(function() { Fido2Lib.deleteAllExtensions(); }); it("exist", function() { assert.isFunction(Fido2Lib.addExtension); assert.isFunction(Fido2Lib.deleteAllExtensions); assert.isFunction(Fido2Lib.parseExtensionResult); assert.isFunction(Fido2Lib.validateExtensionResult); const mc = new Fido2Lib(); assert.isFunction(mc.generateExtensionOptions); assert.isFunction(mc.enableExtension); assert.isFunction(mc.disableExtension); assert.isFunction(mc.setExtensionOptions); }); describe("addExtension", function() { function fn() {} it("throws if extName is not a string", function() { assert.throws(function() { Fido2Lib.addExtension(undefined, fn, fn, fn); }, Error, "expected 'extName' to be String, got: undefined"); }); it("throws if optionGeneratorFn isn't a function", function() { assert.throws(function() { Fido2Lib.addExtension("test", undefined, fn, fn); }, Error, "expected 'optionGeneratorFn' to be a Function, got: undefined"); }); it("throws if resultParserFn isn't a function", function() { assert.throws(function() { Fido2Lib.addExtension("test", fn, undefined, fn); }, Error, "expected 'resultParserFn' to be a Function, got: undefined"); }); it("throws if resultValidatorFn isn't a function", function() { assert.throws(function() { Fido2Lib.addExtension("test", fn, fn, undefined); }, Error, "expected 'resultValidatorFn' to be a Function, got: undefined"); }); it("adds the new extension", function() { Fido2Lib.addExtension("test", fn, fn, fn); }); it("throws if name is already set", function() { Fido2Lib.addExtension("test", fn, fn, fn); assert.throws(function() { Fido2Lib.addExtension("test", fn, fn, fn); }, Error, "the extension 'test' has already been added"); }); }); describe("generateExtensionOptions", function() { let mc; function fn() {} beforeEach(function() { mc = new Fido2Lib(); }); it("throws if extName isn't a string", function() { assert.throws( function() { mc.generateExtensionOptions(undefined, "attestation"); }, Error, "expected 'extName' to be String, got: undefined", ); }); it("throws if extName isn't found", function() { assert.throws( function() { mc.generateExtensionOptions("test", "attestation"); }, Error, "valid extension for 'test' not found", ); }); it("throws if type isn't 'attestation' or 'assertion'", function() { assert.throws( function() { mc.generateExtensionOptions("test", "foo"); }, Error, "expected 'type' to be 'attestation' or 'assertion', got: foo", ); }); it("can generate for attestation", function(done) { function generateFn(name, type, options) { assert.strictEqual(name, "test"); assert.strictEqual(type, "attestation"); assert.isUndefined(options); done(); } Fido2Lib.addExtension("test", generateFn, fn, fn); mc.generateExtensionOptions("test", "attestation"); }); it("can generate for assertion", function(done) { function generateFn(name, type, options) { assert.strictEqual(name, "test"); assert.strictEqual(type, "assertion"); assert.isUndefined(options); done(); } Fido2Lib.addExtension("test", generateFn, fn, fn); mc.generateExtensionOptions("test", "assertion"); }); it("passes through options", function(done) { const opts = { foo: "bar", }; function generateFn(name, type, options) { assert.strictEqual(name, "test"); assert.strictEqual(type, "assertion"); assert.strictEqual(options, opts); done(); } Fido2Lib.addExtension("test", generateFn, fn, fn); mc.generateExtensionOptions("test", "assertion", opts); }); }); describe("parseExtensionResult", function() { it("throws if extName isn't a string"); it("throws if extName isn't found"); it("throws if return value isn't valid"); it("returns parsed value"); }); describe("validateExtensionResult", function() { it("throws if extName isn't a string"); it("throws if extName isn't found"); it("throws if return value isn't true"); it("sets audit info"); }); describe("enableExtension", function() { let mc; function fn() {} beforeEach(function() { mc = new Fido2Lib(); }); it("throws if extName isn't a string", function() { assert.throws( function() { mc.enableExtension(undefined); }, Error, "expected 'extName' to be String, got: undefined", ); }); it("throws if extName isn't found", function() { assert.throws( function() { mc.enableExtension("test"); }, Error, "valid extension for 'test' not found", ); }); it("is disabled by default", function() { assert.isFalse(mc.extSet.has("test")); assert.isFalse(mc.extSet.has("test2")); Fido2Lib.addExtension("test", fn, fn, fn); Fido2Lib.addExtension("test2", fn, fn, fn); assert.isFalse(mc.extSet.has("test")); assert.isFalse(mc.extSet.has("test2")); mc = new Fido2Lib(); assert.isFalse(mc.extSet.has("test")); assert.isFalse(mc.extSet.has("test2")); }); it("sets extension to true", function() { Fido2Lib.addExtension("test", fn, fn, fn); mc = new Fido2Lib(); assert.isFalse(mc.extSet.has("test")); mc.enableExtension("test"); assert.isTrue(mc.extSet.has("test")); }); }); describe("disableExtension", function() { let mc; function fn() {} beforeEach(function() { mc = new Fido2Lib(); }); it("throws if extName isn't a string", function() { assert.throws( function() { mc.disableExtension(undefined); }, Error, "expected 'extName' to be String, got: undefined", ); }); it("throws if extName isn't found", function() { assert.throws( function() { mc.disableExtension("test"); }, Error, "valid extension for 'test' not found", ); }); it("sets extension to false", function() { Fido2Lib.addExtension("test", fn, fn, fn); mc = new Fido2Lib(); assert.isFalse(mc.extSet.has("test")); mc.enableExtension("test"); assert.isTrue(mc.extSet.has("test")); mc.disableExtension("test"); assert.isFalse(mc.extSet.has("test")); }); }); describe("setExtensionOptions", function() { let mc; function fn() {} beforeEach(function() { mc = new Fido2Lib(); }); it("throws if extName isn't a string", function() { assert.throws( function() { mc.setExtensionOptions(undefined); }, Error, "expected 'extName' to be String, got: undefined", ); }); it("throws if extName isn't found", function() { assert.throws( function() { mc.setExtensionOptions("test"); }, Error, "valid extension for 'test' not found", ); }); it("sets options", function() { const opts = { foo: "bar", }; Fido2Lib.addExtension("test", fn, fn, fn); mc.setExtensionOptions("test", opts); assert.isTrue(mc.extOptMap.has("test")); assert.strictEqual(mc.extOptMap.get("test"), opts); }); }); describe("attestationOptions", function() { let mc; function fn() {} beforeEach(function() { mc = new Fido2Lib(); }); it("calls generator", function() { const genSpy = new Stub(); const extVal = { beer: "good", }; genSpy.return(extVal); Fido2Lib.addExtension("test", genSpy.stub(),fn, fn); mc.enableExtension("test"); return mc.attestationOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test); assert.strictEqual(opts.extensions.test, extVal); }); }); it("calls all generators", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.enableExtension("test2"); return mc.attestationOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isFalse(opts.extensions.test2); }); }); it("calls all enabled generators", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.disableExtension("test2"); return mc.attestationOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isUndefined(opts.extensions.test2); }); }); it("passes through default options", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; const extOpt1 = { foo: "bar", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; const extOpt2 = null; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.setExtensionOptions("test1", extOpt1); mc.enableExtension("test2"); mc.setExtensionOptions("test2", extOpt2); return mc.attestationOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isFalse(opts.extensions.test2); assert.isTrue(genSpy1.calledWithExactly("test1", "attestation", extOpt1)); assert.isTrue(genSpy2.calledWithExactly("test2", "attestation", extOpt2)); }); }); it("passes through passed-in options", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; const extOpt1 = { foo: "bar", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; const extOpt2 = null; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.enableExtension("test2"); return mc.attestationOptions({ extensionOptions: { test1: extOpt1, test2: extOpt2, }, }) .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isFalse(opts.extensions.test2); assert.isTrue(genSpy1.calledWithExactly("test1", "attestation", extOpt1)); assert.isTrue(genSpy2.calledWithExactly("test2", "attestation", extOpt2)); }); }); }); describe("assertionOptions", function() { let mc; function fn() {} beforeEach(function() { mc = new Fido2Lib(); }); it("calls generator", function() { const genSpy = new Stub(); const extVal = { beer: "good", }; genSpy.return(extVal); Fido2Lib.addExtension("test", genSpy.stub(),fn, fn); mc.enableExtension("test"); return mc.assertionOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test); assert.strictEqual(opts.extensions.test, extVal); }); }); it("calls all generators", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.enableExtension("test2"); return mc.assertionOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isFalse(opts.extensions.test2); }); }); it("calls all enabled generators", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.disableExtension("test2"); return mc.assertionOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isUndefined(opts.extensions.test2); }); }); it("passes through default options", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; const extOpt1 = { foo: "bar", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; const extOpt2 = null; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.setExtensionOptions("test1", extOpt1); mc.enableExtension("test2"); mc.setExtensionOptions("test2", extOpt2); return mc.assertionOptions() .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isFalse(opts.extensions.test2); assert.isTrue(genSpy1.calledWithExactly("test1", "assertion", extOpt1)); assert.isTrue(genSpy2.calledWithExactly("test2", "assertion", extOpt2)); }); }); it("passes through passed-in options", function() { const genSpy1 = new Stub(); const extVal1 = { beer: "good", }; const extOpt1 = { foo: "bar", }; genSpy1.return(extVal1); const genSpy2 = new Stub(); const extVal2 = false; const extOpt2 = null; genSpy2.return(extVal2); Fido2Lib.addExtension("test1", genSpy1.stub(),fn, fn); Fido2Lib.addExtension("test2", genSpy2.stub(),fn, fn); mc.enableExtension("test1"); mc.enableExtension("test2"); return mc.assertionOptions({ extensionOptions: { test1: extOpt1, test2: extOpt2, }, }) .then((opts) => { assert.isObject(opts.extensions); assert.isObject(opts.extensions.test1); assert.strictEqual(opts.extensions.test1, extVal1); assert.isFalse(opts.extensions.test2); assert.isTrue(genSpy1.calledWithExactly("test1", "assertion", extOpt1)); assert.isTrue(genSpy2.calledWithExactly("test2", "assertion", extOpt2)); }); }); }); });