+ it('covers option defaults', function () {
+ delete options.authenticator.secureAuthOnly;
+ delete options.dingus?.proxyPrefix;
+ delete options.authenticator.forbiddenPAMIdentifiers;
+ options.authenticator.authnEnabled.push('flarpyauth');
+ authenticator = new Authenticator(stubLogger, stubDb, options);
+ });
+
+ it('covers invalid sameSite', function () {
+ options.authenticator.sessionCookieSameSite = 'Sometimes';
+ assert.throws(() => new Authenticator(stubLogger, stubDb, options), RangeError);
+ });
+
+ describe('createIdentifier', function () {
+ let dbCtx;
+ beforeEach(function () {
+ dbCtx = {};
+ credential = 'badpassword';
+ });
+ it('covers success', async function () {
+ const otpKey = '1234567890123456789012';
+ await authenticator.createIdentifier(dbCtx, identifier, credential, otpKey);
+ assert(authenticator.db.authenticationUpsert.called);
+ });
+ it('covers failure', async function () {
+ const expected = new Error('blah');
+ await authenticator.db.authenticationUpsert.rejects(expected);
+ // assert.rejects was not happy to handle this for some reason
+ try {
+ await authenticator.createIdentifier(dbCtx, identifier, credential);
+ assert.fail('no expecte exception');
+ } catch (e) {
+ assert.deepStrictEqual(e, expected);
+ assert(authenticator.db.authenticationUpsert.called);
+ assert(authenticator.logger.error.called);
+ }
+ });
+ }); // createIdentifier
+
+ describe('updateCredential', function () {
+ let dbCtx, newCredential;
+ beforeEach(function () {
+ dbCtx = {};
+ newCredential = 'newpassword';
+ });
+ it('covers success', async function () {
+ await authenticator.updateCredential(dbCtx, identifier, newCredential);
+ assert(authenticator.db.authenticationUpdateCredential.called);
+ assert(authenticator.logger.info.called);
+ });
+ it('covers failure', async function () {
+ const expected = new Error('foo');
+ authenticator.db.authenticationUpdateCredential.rejects(expected);
+ try {
+ await authenticator.updateCredential(dbCtx, identifier, newCredential);
+ assert.fail('no expected exception');
+ } catch (e) {
+ assert.deepStrictEqual(e, expected);
+ assert(authenticator.logger.error.called);
+ }
+ // assert.rejects was not happy to handle this for some reason
+ });
+ }); // updateCredential
+
+ describe('_secureCredential', function () {
+ beforeEach(function () {
+ credential = 'badpassword';
+ });
+ it('covers plain', async function () {
+ const result = await authenticator._secureCredential(credential, 'plain');
+ assert.strictEqual(result, '$plain$' + credential);
+ });
+ it('covers default (argon2)', async function () {
+ const result = await authenticator._secureCredential(credential);
+ assert(result.startsWith('$argon2'));
+ });
+ it('covers invalid authn', async function () {
+ const authn = 'bogus';
+ assert.rejects(async () => await authenticator._secureCredential(credential, authn), RangeError);
+ });
+ }); // _secureCredential
+
+ describe('_validateAuthDataCredential', function () {
+ let authData;
+ beforeEach(function () {
+ credential = 'badpassword';
+ authData = {};
+ });
+ it('fails if not provided a credential', async function () {
+ const result = await authenticator._validateAuthDataCredential(authData, credential);
+ assert.strictEqual(result, false);
+ });
+ it('covers plain', async function () {
+ authData.credential = '$plain$badpassword';
+ const result = await authenticator._validateAuthDataCredential(authData, credential);
+ assert.strictEqual(result, true);
+ });
+ }); // _validateAuthDataCredential
+