diff --git a/test/backchannel_logout/backchannel_logout.test.js b/test/backchannel_logout/backchannel_logout.test.js index a1406f648..c775809fa 100644 --- a/test/backchannel_logout/backchannel_logout.test.js +++ b/test/backchannel_logout/backchannel_logout.test.js @@ -1,3 +1,4 @@ +const { strict: assert } = require('assert'); const { parse: parseUrl } = require('url'); const sinon = require('sinon').createSandbox(); @@ -7,8 +8,6 @@ const nock = require('nock'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; - describe('Back-Channel Logout 1.0', () => { before(bootstrap(__dirname)); @@ -61,8 +60,8 @@ describe('Back-Channel Logout 1.0', () => { .post('/backchannel_logout') .reply(500); - return client.backchannelLogout('subject', 'foo').then(fail, (err) => { - expect(err.message).to.eql('expected 200 OK from https://no-sid.example.com/backchannel_logout, got: 500 Internal Server Error'); + return assert.rejects(client.backchannelLogout('subject', 'foo'), { + message: 'expected 200 OK from https://no-sid.example.com/backchannel_logout, got: 500 Internal Server Error', }); }); }); diff --git a/test/base_token/base_token.test.js b/test/base_token/base_token.test.js index db5e1be1b..6079d4421 100644 --- a/test/base_token/base_token.test.js +++ b/test/base_token/base_token.test.js @@ -1,11 +1,11 @@ +const { strict: assert } = require('assert'); + const sinon = require('sinon').createSandbox(); const { expect } = require('chai'); const timekeeper = require('timekeeper'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; - describe('BaseToken', () => { before(bootstrap(__dirname)); @@ -136,9 +136,10 @@ describe('BaseToken', () => { const value = await token.save(); const adapterThrow = new Error('adapter throw!'); sinon.stub(this.TestAdapter.for('Session'), 'findByUid').callsFake(async () => { throw adapterThrow; }); - await this.provider.RefreshToken.find(value).then(fail, (err) => { + return assert.rejects(this.provider.RefreshToken.find(value), (err) => { this.TestAdapter.for('Session').findByUid.restore(); expect(err).to.equal(adapterThrow); + return true; }); }); @@ -156,12 +157,12 @@ describe('BaseToken', () => { it('rethrows adapter#findByUserCode errors (Device Code)', async function () { const adapterThrow = new Error('adapter throw!'); sinon.stub(this.TestAdapter.for('DeviceCode'), 'findByUserCode').callsFake(async () => { throw adapterThrow; }); - await this.provider.DeviceCode.findByUserCode('123-456-789').then(() => { + return assert.rejects(this.provider.DeviceCode.findByUserCode('123-456-789').then(() => { this.TestAdapter.for('DeviceCode').findByUserCode.restore(); - fail(); - }, (err) => { + }), (err) => { this.TestAdapter.for('DeviceCode').findByUserCode.restore(); expect(err).to.equal(adapterThrow); + return true; }); }); }); diff --git a/test/configuration/client_keystore.test.js b/test/configuration/client_keystore.test.js index d74b8c060..b042d7b0a 100644 --- a/test/configuration/client_keystore.test.js +++ b/test/configuration/client_keystore.test.js @@ -10,8 +10,6 @@ const JWT = require('../../lib/helpers/jwt'); const epochTime = require('../../lib/helpers/epoch_time'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; - const endpoint = nock('https://client.example.com/'); const keystore = new jose.JWKS.KeyStore(); @@ -63,15 +61,17 @@ describe('client keystore refresh', () => { const client = await this.provider.Client.find('client'); sinon.stub(client.asymmetricKeyStore, 'fresh').returns(false); return Promise.all([ - client.asymmetricKeyStore.refresh().then(fail, (err) => { + assert.rejects(client.asymmetricKeyStore.refresh(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.eql('client JSON Web Key Set failed to be refreshed'); + return true; }), - client.asymmetricKeyStore.refresh().then(fail, (err) => { + assert.rejects(client.asymmetricKeyStore.refresh(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.eql('client JSON Web Key Set failed to be refreshed'); + return true; }), ]); }); @@ -101,10 +101,11 @@ describe('client keystore refresh', () => { const client = await this.provider.Client.find('client'); sinon.stub(client.asymmetricKeyStore, 'fresh').returns(false); - await client.asymmetricKeyStore.refresh().then(fail, (err) => { + return assert.rejects(client.asymmetricKeyStore.refresh(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.eql('client JSON Web Key Set failed to be refreshed'); + return true; }); }); @@ -113,10 +114,11 @@ describe('client keystore refresh', () => { const client = await this.provider.Client.find('client'); sinon.stub(client.asymmetricKeyStore, 'fresh').returns(false); - await client.asymmetricKeyStore.refresh().then(fail, (err) => { + return assert.rejects(client.asymmetricKeyStore.refresh(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.eql('client JSON Web Key Set failed to be refreshed'); + return true; }); }); @@ -125,10 +127,11 @@ describe('client keystore refresh', () => { const client = await this.provider.Client.find('client'); sinon.stub(client.asymmetricKeyStore, 'fresh').returns(false); - await client.asymmetricKeyStore.refresh().then(fail, (err) => { + return assert.rejects(client.asymmetricKeyStore.refresh(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.eql('client JSON Web Key Set failed to be refreshed'); + return true; }); }); @@ -225,10 +228,10 @@ describe('client keystore refresh', () => { const client = await this.provider.Client.find('client'); client.asymmetricKeyStore.freshUntil = epochTime() - 1; - await JWT.verify( + return assert.rejects(JWT.verify( 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgA', client.asymmetricKeyStore, - ).then(fail, () => {}); + )); }); it('refreshes stale keystores before id_token encryption', async function () { diff --git a/test/configuration/client_metadata.test.js b/test/configuration/client_metadata.test.js index f6c7ecb8e..1c1f9688f 100644 --- a/test/configuration/client_metadata.test.js +++ b/test/configuration/client_metadata.test.js @@ -1,3 +1,4 @@ +const { strict: assert } = require('assert'); const util = require('util'); const { expect } = require('chai'); @@ -43,29 +44,29 @@ describe('Client metadata validation', () => { }); } - const fail = () => { throw new Error('expected promise to be rejected'); }; - const mustBeString = (prop, values = [[], 123, true, null, false, {}, ''], metadata, configuration) => { values.forEach((value) => { let msg = util.format('must be a string, %j provided', value); if (metadata) msg = util.format(`${msg}, [client %j]`, omit(metadata, ['jwks.keys'])); if (configuration) msg = util.format(`${msg}, [provider %j]`, configuration); - it(msg, () => addClient({ ...metadata, [prop]: value }, configuration).then(fail, (err) => { + // eslint-disable-next-line max-len + it(msg, () => assert.rejects(addClient({ ...metadata, [prop]: value }, configuration), (err) => { if (prop === 'redirect_uris') { expect(err.message).to.equal('invalid_redirect_uri'); } else { expect(err.message).to.equal('invalid_client_metadata'); } expect(err.error_description).to.equal(`${prop} must be a non-empty string if provided`); + return true; })); }); }; const mustBeUri = (prop, protocols, configuration, metadata) => { - it('must be a uri', () => addClient({ + it('must be a uri', () => assert.rejects(addClient({ ...metadata, [prop]: 'whatever://not but not a uri', - }, configuration).then(fail, (err) => { + }, configuration), (err) => { if (prop === 'redirect_uris') { expect(err.message).to.equal('invalid_redirect_uri'); } else { @@ -76,6 +77,7 @@ describe('Client metadata validation', () => { } else { expect(err.error_description).to.equal(`${prop} must be a web uri`); } + return true; })); protocols.forEach((protocol) => { @@ -89,15 +91,16 @@ describe('Client metadata validation', () => { values.forEach((value) => { let msg = util.format('must be a array, %j provided', value); if (configuration) msg = util.format(`${msg}, [provider %j]`, configuration); - it(msg, () => addClient({ + it(msg, () => assert.rejects(addClient({ [prop]: value, - }, configuration).then(fail, (err) => { + }, configuration), (err) => { if (prop === 'redirect_uris') { expect(err.message).to.equal('invalid_redirect_uri'); } else { expect(err.message).to.equal('invalid_client_metadata'); } expect(err.error_description).to.equal(`${prop} must be an array`); + return true; })); }); }; @@ -107,15 +110,16 @@ describe('Client metadata validation', () => { let msg = util.format('must be a boolean, %j provided', value); if (metadata) msg = util.format(`${msg}, [client %j]`, omit(metadata, ['jwks.keys'])); if (configuration) msg = util.format(`${msg}, [provider %j]`, configuration); - it(msg, () => addClient({ + it(msg, () => assert.rejects(addClient({ [prop]: value, - }, configuration).then(fail, (err) => { + }, configuration), (err) => { if (prop === 'redirect_uris') { expect(err.message).to.equal('invalid_redirect_uri'); } else { expect(err.message).to.equal('invalid_client_metadata'); } expect(err.error_description).to.equal(`${prop} must be a boolean`); + return true; })); }); }; @@ -138,16 +142,17 @@ describe('Client metadata validation', () => { (values || [null, undefined, '']).forEach((value) => { let msg = util.format('is required, %j provided', value); if (configuration) msg = util.format(`${msg}, [provider %j]`, configuration); - it(msg, () => addClient({ + it(msg, () => assert.rejects(addClient({ [prop]: value, ...metadata, - }, configuration).then(fail, (err) => { + }, configuration), (err) => { if (prop === 'redirect_uris') { expect(err.message).to.equal('invalid_redirect_uri'); } else { expect(err.message).to.equal('invalid_client_metadata'); } expect(err.error_description).to.equal(`${prop} is mandatory property`); + return true; })); }); }; @@ -171,16 +176,17 @@ describe('Client metadata validation', () => { let msg = util.format('rejects %j', value); if (metadata) msg = util.format(`${msg}, [client %j]`, omit(metadata, ['jwks.keys'])); if (configuration) msg = util.format(`${msg}, [provider %j]`, configuration); - it(msg, () => addClient({ ...metadata, [prop]: value }, configuration).then(fail, (err) => { + // eslint-disable-next-line max-len + it(msg, () => assert.rejects(addClient({ ...metadata, [prop]: value }, configuration), (err) => { if (prop === 'redirect_uris') { expect(err.message).to.equal('invalid_redirect_uri'); } else { expect(err.message).to.equal('invalid_client_metadata'); } if (description) { - const assert = description.exec ? 'match' : 'equal'; - expect(err.error_description).to[assert](description); + expect(err.error_description).to[description.exec ? 'match' : 'equal'](description); } + return true; })); }; @@ -636,11 +642,12 @@ describe('Client metadata validation', () => { mustBeString(this.title, undefined, { jwks: { keys: [sigKey] }, }, configuration); - it('is required when id_token_encrypted_response_enc is also provided', () => addClient({ + it('is required when id_token_encrypted_response_enc is also provided', () => assert.rejects(addClient({ id_token_encrypted_response_enc: 'whatever', - }, configuration).then(fail, (err) => { + }, configuration), (err) => { expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.equal('id_token_encrypted_response_alg is mandatory property when id_token_encrypted_response_enc is provided'); + return true; })); allows(this.title, 'dir', undefined, configuration); [ @@ -688,11 +695,12 @@ describe('Client metadata validation', () => { mustBeString(this.title, undefined, { jwks: { keys: [sigKey] }, }, configuration); - it('is required when userinfo_encrypted_response_enc is also provided', () => addClient({ + it('is required when userinfo_encrypted_response_enc is also provided', () => assert.rejects(addClient({ userinfo_encrypted_response_enc: 'whatever', - }, configuration).then(fail, (err) => { + }, configuration), (err) => { expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.equal('userinfo_encrypted_response_alg is mandatory property when userinfo_encrypted_response_enc is provided'); + return true; })); allows(this.title, 'dir', undefined, configuration); [ @@ -741,11 +749,12 @@ describe('Client metadata validation', () => { mustBeString(this.title, undefined, { jwks: { keys: [sigKey] }, }, configuration); - it('is required when introspection_encrypted_response_enc is also provided', () => addClient({ + it('is required when introspection_encrypted_response_enc is also provided', () => assert.rejects(addClient({ introspection_encrypted_response_enc: 'whatever', - }, configuration).then(fail, (err) => { + }, configuration), (err) => { expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.equal('introspection_encrypted_response_alg is mandatory property when introspection_encrypted_response_enc is provided'); + return true; })); allows(this.title, 'dir', undefined, configuration); [ @@ -794,11 +803,12 @@ describe('Client metadata validation', () => { mustBeString(this.title, undefined, { jwks: { keys: [sigKey] }, }, configuration); - it('is required when authorization_encrypted_response_enc is also provided', () => addClient({ + it('is required when authorization_encrypted_response_enc is also provided', () => assert.rejects(addClient({ authorization_encrypted_response_enc: 'whatever', - }, configuration).then(fail, (err) => { + }, configuration), (err) => { expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.equal('authorization_encrypted_response_alg is mandatory property when authorization_encrypted_response_enc is provided'); + return true; })); allows(this.title, 'dir', undefined, configuration); [ @@ -853,11 +863,12 @@ describe('Client metadata validation', () => { defaultsTo(this.title, undefined); defaultsTo(this.title, undefined, undefined, configuration); mustBeString(this.title, undefined, undefined, configuration); - it('is required when request_object_encryption_enc is also provided', () => addClient({ + it('is required when request_object_encryption_enc is also provided', () => assert.rejects(addClient({ request_object_encryption_enc: 'whatever', - }, configuration).then(fail, (err) => { + }, configuration), (err) => { expect(err.message).to.equal('invalid_client_metadata'); expect(err.error_description).to.equal('request_object_encryption_alg is mandatory property when request_object_encryption_enc is provided'); + return true; })); allows(this.title, 'dir', undefined, configuration); [ diff --git a/test/formats/jwt.test.js b/test/formats/jwt.test.js index f7b791894..63d29d783 100644 --- a/test/formats/jwt.test.js +++ b/test/formats/jwt.test.js @@ -1,5 +1,6 @@ /* eslint-disable no-shadow */ /* eslint-disable no-param-reassign */ +const { strict: assert } = require('assert'); const crypto = require('crypto'); const util = require('util'); @@ -10,7 +11,6 @@ const base64url = require('base64url'); const epochTime = require('../../lib/helpers/epoch_time'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; const generateKeyPair = util.promisify(crypto.generateKeyPair); function decode(b64urljson) { return JSON.parse(base64url.decode(b64urljson)); @@ -142,9 +142,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('jwt.sign.kid must be a string when provided'); + return true; }); }); @@ -164,9 +165,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('jwt.encrypt.kid must be a string when provided'); + return true; }); }); @@ -348,9 +350,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('JWT Access Tokens may not use JWS algorithm "none"'); + return true; }); }); @@ -367,9 +370,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('missing jwt.sign.key Resource Server configuration'); + return true; }); }); @@ -387,9 +391,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('jwt.sign.key Resource Server configuration must be a secret (symmetric) key'); + return true; }); }); @@ -407,9 +412,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('jwt.sign.key Resource Server configuration must be a secret (symmetric) key'); + return true; }); }); @@ -426,9 +432,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('resolved Resource Server jwt configuration has no corresponding key in the provider\'s keystore'); + return true; }); }); @@ -447,9 +454,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('jwt.encrypt.key Resource Server configuration must be a secret (symmetric) or a public key'); + return true; }); }); @@ -468,14 +476,16 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('missing jwt.sign Resource Server configuration'); + return true; }); }); // eslint-disable-next-line no-restricted-syntax for (const prop of ['alg', 'enc', 'key']) { + // eslint-disable-next-line no-loop-func it(`ensures JWE Configuration has ${prop}`, async function () { const resourceServer = { accessTokenFormat: 'jwt', @@ -493,9 +503,10 @@ describe('jwt format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal(`missing jwt.encrypt.${prop} Resource Server configuration`); + return true; }); }); } diff --git a/test/formats/paseto.test.js b/test/formats/paseto.test.js index c1eef9619..4137a1805 100644 --- a/test/formats/paseto.test.js +++ b/test/formats/paseto.test.js @@ -1,5 +1,6 @@ /* eslint-disable no-shadow */ /* eslint-disable no-param-reassign */ +const { strict: assert } = require('assert'); const crypto = require('crypto'); const util = require('util'); @@ -10,7 +11,6 @@ const paseto = require('paseto'); const epochTime = require('../../lib/helpers/epoch_time'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; const generateKeyPair = util.promisify(crypto.generateKeyPair); describe('paseto format', () => { @@ -141,9 +141,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('unsupported PASETO version and purpose'); + return true; }); }); @@ -160,9 +161,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('resolved Resource Server paseto configuration has no corresponding key in the provider\'s keystore'); + return true; }); }); @@ -180,9 +182,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('paseto.kid must be a string when provided'); + return true; }); }); @@ -198,9 +201,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('unsupported PASETO version and purpose'); + return true; }); }); @@ -216,9 +220,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('unsupported "paseto.version"'); + return true; }); }); @@ -234,9 +239,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('local purpose PASETO Resource Server requires a "paseto.key"'); + return true; }); }); @@ -253,9 +259,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('local purpose PASETO Resource Server "paseto.key" must be 256 bits long secret key'); + return true; }); }); @@ -272,9 +279,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('local purpose PASETO Resource Server "paseto.key" must be 256 bits long secret key'); + return true; }); }); @@ -291,9 +299,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('local purpose PASETO Resource Server "paseto.key" must be 256 bits long secret key'); + return true; }); }); @@ -305,9 +314,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('missing "paseto" Resource Server configuration'); + return true; }); }); @@ -320,9 +330,10 @@ describe('paseto format', () => { const client = await this.provider.Client.find(clientId); const token = new this.provider.AccessToken({ client, ...fullPayload, resourceServer }); - await token.save().then(fail, (err) => { + return assert.rejects(token.save(), (err) => { expect(err).to.be.an('error'); expect(err.message).to.equal('missing "paseto" Resource Server configuration'); + return true; }); }); }); diff --git a/test/interaction/interaction.test.js b/test/interaction/interaction.test.js index a8fa44cad..44cc46d2d 100644 --- a/test/interaction/interaction.test.js +++ b/test/interaction/interaction.test.js @@ -1,5 +1,7 @@ /* eslint-disable no-underscore-dangle */ +const { strict: assert } = require('assert'); + const { expect } = require('chai'); const KeyGrip = require('keygrip'); // eslint-disable-line import/no-extraneous-dependencies const sinon = require('sinon').createSandbox(); @@ -11,7 +13,6 @@ const epochTime = require('../../lib/helpers/epoch_time'); const expire = new Date(); expire.setDate(expire.getDate() + 1); const expired = new Date(0); -const fail = () => { throw new Error('expected promise to be rejected'); }; function handlesInteractionSessionErrors() { it('"handles" not found interaction session id cookie', async function () { @@ -24,9 +25,10 @@ function handlesInteractionSessionErrors() { sinon.spy(this.provider, 'interactionDetails'); await this.agent.get(this.url).expect(400); - await this.provider.interactionDetails.getCall(0).returnValue.then(fail, (err) => { + return assert.rejects(this.provider.interactionDetails.getCall(0).returnValue, (err) => { expect(err.name).to.eql('SessionNotFound'); expect(err.error_description).to.eql('interaction session id cookie not found'); + return true; }); }); @@ -36,9 +38,10 @@ function handlesInteractionSessionErrors() { sinon.spy(this.provider, 'interactionDetails'); await this.agent.get(this.url).expect(400); - await this.provider.interactionDetails.getCall(0).returnValue.then(fail, (err) => { + return assert.rejects(this.provider.interactionDetails.getCall(0).returnValue, (err) => { expect(err.name).to.eql('SessionNotFound'); expect(err.error_description).to.eql('interaction session not found'); + return true; }); }); } diff --git a/test/oauth_native_apps/oauth_native_apps.test.js b/test/oauth_native_apps/oauth_native_apps.test.js index 68b2ae2d4..961d276c8 100644 --- a/test/oauth_native_apps/oauth_native_apps.test.js +++ b/test/oauth_native_apps/oauth_native_apps.test.js @@ -1,9 +1,9 @@ +const { strict: assert } = require('assert'); + const { expect } = require('chai'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; - describe('OAuth 2.0 for Native Apps Best Current Practice features', () => { before(bootstrap(__dirname)); @@ -21,16 +21,17 @@ describe('OAuth 2.0 for Native Apps Best Current Practice features', () => { }); it('rejects custom schemes without dots with reverse domain name scheme recommendation', function () { - return i(this.provider).clientAdd({ + return assert.rejects(i(this.provider).clientAdd({ application_type: 'native', client_id: 'native-custom', grant_types: ['implicit'], response_types: ['id_token'], token_endpoint_auth_method: 'none', redirect_uris: ['myapp:/op/callback'], - }).then(fail, (err) => { + }), (err) => { expect(err).to.have.property('message', 'invalid_redirect_uri'); expect(err).to.have.property('error_description', 'redirect_uris for native clients using Custom URI scheme should use reverse domain name based scheme'); + return true; }); }); }); @@ -48,16 +49,17 @@ describe('OAuth 2.0 for Native Apps Best Current Practice features', () => { }); it('rejects https if using loopback uris', function () { - return i(this.provider).clientAdd({ + return assert.rejects(i(this.provider).clientAdd({ application_type: 'native', client_id: 'native-custom', grant_types: ['implicit'], response_types: ['id_token'], token_endpoint_auth_method: 'none', redirect_uris: ['https://localhost/op/callback'], - }).then(fail, (err) => { + }), (err) => { expect(err).to.have.property('message', 'invalid_redirect_uri'); expect(err).to.have.property('error_description', 'redirect_uris for native clients using claimed HTTPS URIs must not be using localhost as hostname'); + return true; }); }); }); @@ -187,16 +189,17 @@ describe('OAuth 2.0 for Native Apps Best Current Practice features', () => { }); it('rejects http protocol uris not using loopback uris', function () { - return i(this.provider).clientAdd({ + return assert.rejects(i(this.provider).clientAdd({ application_type: 'native', client_id: 'native-custom', grant_types: ['implicit'], response_types: ['id_token'], token_endpoint_auth_method: 'none', redirect_uris: ['http://rp.example.com/op/callback'], - }).then(fail, (err) => { + }), (err) => { expect(err).to.have.property('message', 'invalid_redirect_uri'); expect(err).to.have.property('error_description', 'redirect_uris for native clients using http as a protocol can only use loopback addresses as hostnames'); + return true; }); }); }); diff --git a/test/pairwise/pairwise_clients.test.js b/test/pairwise/pairwise_clients.test.js index f6bd6ecec..73c243048 100644 --- a/test/pairwise/pairwise_clients.test.js +++ b/test/pairwise/pairwise_clients.test.js @@ -5,8 +5,6 @@ const nock = require('nock'); const bootstrap = require('../test_helper'); -const j = JSON.stringify; - describe('pairwise features', () => { before(bootstrap(__dirname)); @@ -58,7 +56,7 @@ describe('pairwise features', () => { it('is not ignored even without subject_type=pairwise', function () { nock('https://foobar.example.com') .get('/sector') - .reply(200, j(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); + .reply(200, JSON.stringify(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); return i(this.provider).clientAdd({ client_id: 'client', @@ -75,7 +73,7 @@ describe('pairwise features', () => { it('validates the sector from the provided uri', function () { nock('https://foobar.example.com') .get('/sector') - .reply(200, j(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); + .reply(200, JSON.stringify(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); return i(this.provider).clientAdd({ client_id: 'client', @@ -92,7 +90,7 @@ describe('pairwise features', () => { it('validates the sector from the provided uri for static clients too', function () { nock('https://foobar.example.com') .get('/sector') - .reply(200, j(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); + .reply(200, JSON.stringify(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); return this.provider.Client.find('client-static-with-sector').then((client) => { expect(client).to.be.ok; @@ -118,7 +116,7 @@ describe('pairwise features', () => { it('validates all redirect_uris are in the uri', function () { nock('https://client.example.com') .get('/sector') - .reply(200, j(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); + .reply(200, JSON.stringify(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); return i(this.provider).clientAdd({ client_id: 'client', @@ -139,7 +137,7 @@ describe('pairwise features', () => { it('validates jwks_uri is in the response', function () { nock('https://client.example.com') .get('/sector') - .reply(200, j(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); + .reply(200, JSON.stringify(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); return i(this.provider).clientAdd({ client_id: 'client', @@ -164,7 +162,7 @@ describe('pairwise features', () => { it('validates jwks_uri is in the response', function () { nock('https://client.example.com') .get('/sector') - .reply(200, j(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); + .reply(200, JSON.stringify(['https://client.example.com/cb', 'https://another.example.com/forum/cb'])); return i(this.provider).clientAdd({ client_id: 'client', @@ -207,7 +205,7 @@ describe('pairwise features', () => { it('validates only accepts json array responses', function () { nock('https://client.example.com') .get('/sector') - .reply(200, j('https://client.example.com/cb')); + .reply(200, JSON.stringify('https://client.example.com/cb')); return i(this.provider).clientAdd({ client_id: 'client', @@ -247,7 +245,7 @@ describe('pairwise features', () => { it('doesnt accepts 200s, rejects even on redirect', function () { nock('https://client.example.com') .get('/sector') - .reply(201, j('https://client.example.com/cb')); + .reply(201, JSON.stringify('https://client.example.com/cb')); return i(this.provider).clientAdd({ client_id: 'client', diff --git a/test/refresh/refresh.grant.test.js b/test/refresh/refresh.grant.test.js index 536595c92..b30b8ce48 100644 --- a/test/refresh/refresh.grant.test.js +++ b/test/refresh/refresh.grant.test.js @@ -1,3 +1,4 @@ +const { strict: assert } = require('assert'); const { parse: parseUrl } = require('url'); const sinon = require('sinon'); @@ -7,8 +8,6 @@ const timekeeper = require('timekeeper'); const bootstrap = require('../test_helper'); -const fail = () => { throw new Error('expected promise to be rejected'); }; -const j = JSON.parse; const route = '/token'; function errorDetail(spy) { @@ -84,7 +83,7 @@ describe('grant_type=refresh_token', () => { }) .expect(({ body }) => { expect(body).to.have.keys('access_token', 'id_token', 'expires_in', 'token_type', 'refresh_token', 'scope'); - const refreshIdToken = j(base64url.decode(body.id_token.split('.')[1])); + const refreshIdToken = JSON.parse(base64url.decode(body.id_token.split('.')[1])); expect(refreshIdToken).to.have.property('nonce', 'foobarnonce'); expect(body).to.have.property('refresh_token').that.is.a('string'); }); @@ -365,7 +364,7 @@ describe('grant_type=refresh_token', () => { }) .expect((response) => { expect(response.body).to.have.keys('access_token', 'id_token', 'expires_in', 'token_type', 'refresh_token', 'scope'); - const refreshIdToken = j(base64url.decode(response.body.id_token.split('.')[1])); + const refreshIdToken = JSON.parse(base64url.decode(response.body.id_token.split('.')[1])); expect(refreshIdToken).to.have.property('nonce', 'foobarnonce'); expect(response.body).to.have.property('refresh_token').not.equal(rt); }); @@ -431,7 +430,7 @@ describe('grant_type=refresh_token', () => { this.provider.on('grant.revoked', grantRevokeSpy); this.provider.on('refresh_token.destroyed', tokenDestroySpy); - return Promise.all([ + return assert.rejects(Promise.all([ this.agent.post(route) .auth('client', 'secret') .send({ @@ -448,9 +447,10 @@ describe('grant_type=refresh_token', () => { }) .type('form') .expect(200), // one of them will fail. - ]).then(fail, () => { + ]), () => { expect(grantRevokeSpy.calledOnce).to.be.true; expect(tokenDestroySpy.calledOnce).to.be.true; + return true; }); }); }); @@ -506,7 +506,7 @@ describe('grant_type=refresh_token', () => { }) .expect((response) => { expect(response.body).to.have.keys('access_token', 'id_token', 'expires_in', 'token_type', 'refresh_token', 'scope'); - const refreshIdToken = j(base64url.decode(response.body.id_token.split('.')[1])); + const refreshIdToken = JSON.parse(base64url.decode(response.body.id_token.split('.')[1])); expect(refreshIdToken).to.have.property('nonce', 'foobarnonce'); expect(response.body).to.have.property('refresh_token').not.equal(rt); }); @@ -570,7 +570,7 @@ describe('grant_type=refresh_token', () => { this.provider.on('grant.revoked', grantRevokeSpy); this.provider.on('refresh_token.destroyed', tokenDestroySpy); - return Promise.all([ + return assert.rejects(Promise.all([ this.agent.post(route) .auth('client', 'secret') .send({ @@ -587,9 +587,10 @@ describe('grant_type=refresh_token', () => { }) .type('form') .expect(200), // one of them will fail. - ]).then(fail, () => { + ]), () => { expect(grantRevokeSpy.calledOnce).to.be.true; expect(tokenDestroySpy.calledOnce).to.be.true; + return true; }); }); }); @@ -622,7 +623,7 @@ describe('grant_type=refresh_token', () => { .expect(200) .expect(({ body }) => { expect(body).to.have.keys('access_token', 'id_token', 'expires_in', 'token_type', 'refresh_token', 'scope'); - const refreshIdToken = j(base64url.decode(body.id_token.split('.')[1])); + const refreshIdToken = JSON.parse(base64url.decode(body.id_token.split('.')[1])); expect(refreshIdToken).to.have.property('nonce', 'foobarnonce'); expect(body).to.have.property('refresh_token').that.is.a('string'); }) diff --git a/test/registration_policies/registration_policies.test.js b/test/registration_policies/registration_policies.test.js index d8fd776c5..339ab5632 100644 --- a/test/registration_policies/registration_policies.test.js +++ b/test/registration_policies/registration_policies.test.js @@ -1,5 +1,6 @@ -/* eslint-disable no-param-reassign */ +/* eslint-disable no-param-reassign, max-len */ +const { strict: assert } = require('assert'); const url = require('url'); const sinon = require('sinon').createSandbox(); @@ -8,8 +9,6 @@ const { expect } = require('chai'); const bootstrap = require('../test_helper'); const { Provider } = require('../../lib'); -const fail = () => { throw new Error('expected promise to be rejected'); }; - describe('client registration policies', () => { before(bootstrap(__dirname)); beforeEach(sinon.restore); @@ -147,58 +146,66 @@ describe('client registration policies', () => { }); it('policies must be an array', async function () { - await new this.provider.InitialAccessToken({ policies: null }).save().then(fail, (err) => { + await assert.rejects(new this.provider.InitialAccessToken({ policies: null }).save(), (err) => { expect(err).to.have.property('message', 'policies must be an array'); + return true; }); const saved = await new this.provider.InitialAccessToken({ policies: undefined }).save(); this.TestAdapter.for('InitialAccessToken').syncUpdate(this.getTokenJti(saved), { policies: null, }); - await this.provider.InitialAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.InitialAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policies must be an array'); + return true; }); }); it('policies array must have members', async function () { - await new this.provider.InitialAccessToken({ policies: [] }).save().then(fail, (err) => { + await assert.rejects(new this.provider.InitialAccessToken({ policies: [] }).save(), (err) => { expect(err).to.have.property('message', 'policies must not be empty'); + return true; }); const saved = await new this.provider.InitialAccessToken({ policies: undefined }).save(); this.TestAdapter.for('InitialAccessToken').syncUpdate(this.getTokenJti(saved), { policies: [], }); - await this.provider.InitialAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.InitialAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policies must not be empty'); + return true; }); }); it('policies members must be strings', async function () { - await new this.provider.InitialAccessToken({ policies: [null] }).save().then(fail, (err) => { + await assert.rejects(new this.provider.InitialAccessToken({ policies: [null] }).save(), (err) => { expect(err).to.have.property('message', 'policies must be strings'); + return true; }); const saved = await new this.provider.InitialAccessToken({ policies: undefined }).save(); this.TestAdapter.for('InitialAccessToken').syncUpdate(this.getTokenJti(saved), { policies: [null], }); - await this.provider.InitialAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.InitialAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policies must be strings'); + return true; }); }); it('policies members must be present in the provider configuration', async function () { - await new this.provider.InitialAccessToken({ policies: ['foo-bar'] }).save().then(fail, (err) => { + await assert.rejects(new this.provider.InitialAccessToken({ policies: ['foo-bar'] }).save(), (err) => { expect(err).to.have.property('message', 'policy foo-bar not configured'); + return true; }); const saved = await new this.provider.InitialAccessToken({ policies: undefined }).save(); this.TestAdapter.for('InitialAccessToken').syncUpdate(this.getTokenJti(saved), { policies: ['foo-bar'], }); - await this.provider.InitialAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.InitialAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policy foo-bar not configured'); + return true; }); }); }); @@ -354,8 +361,9 @@ describe('client registration policies', () => { policies: null, }); - await this.provider.RegistrationAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.RegistrationAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policies must be an array'); + return true; }); }); @@ -365,8 +373,9 @@ describe('client registration policies', () => { policies: [], }); - await this.provider.RegistrationAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.RegistrationAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policies must not be empty'); + return true; }); }); @@ -376,8 +385,9 @@ describe('client registration policies', () => { policies: [null], }); - await this.provider.RegistrationAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.RegistrationAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policies must be strings'); + return true; }); }); @@ -387,8 +397,9 @@ describe('client registration policies', () => { policies: ['foo-bar'], }); - await this.provider.RegistrationAccessToken.find(saved).then(fail, (err) => { + return assert.rejects(this.provider.RegistrationAccessToken.find(saved), (err) => { expect(err).to.have.property('message', 'policy foo-bar not configured'); + return true; }); }); }); diff --git a/test/resource_indicators/resource_indicators.test.js b/test/resource_indicators/resource_indicators.test.js index 64861500a..fc67045a7 100644 --- a/test/resource_indicators/resource_indicators.test.js +++ b/test/resource_indicators/resource_indicators.test.js @@ -1,22 +1,23 @@ /* eslint-disable prefer-destructuring */ +const { strict: assert } = require('assert'); + const sinon = require('sinon'); const { expect } = require('chai'); const bootstrap = require('../test_helper'); const { features: { resourceIndicators: defaults } } = require('../../lib/helpers/defaults')(); -const fail = () => { throw new Error('expected promise to be rejected'); }; - describe('features.resourceIndicators defaults', () => { it('defaultResource', async () => { expect(await defaults.defaultResource()).to.be.undefined; expect(await defaults.defaultResource(undefined, undefined, ['urn:example:rs'])).to.deep.equal(['urn:example:rs']); }); - it('getResourceServerInfo', async () => defaults.getResourceServerInfo().then(fail, (err) => { + it('getResourceServerInfo', () => assert.rejects(defaults.getResourceServerInfo(), (err) => { expect(err.message).to.equal('invalid_target'); expect(err.error_description).to.equal('resource indicator is missing, or unknown'); + return true; })); });