Files
Filip Skokan f0d95390e9 feat: experimental Bun support
This attempts to work around:

- missing Node.js APIs in Bun
- Bun's bugs in url.parse(..., true)
- Bun loading `jose`'s bun target instead of the require one

It is not possible to run openid-client's test suite due to other Bun
Node.js compatibility bugs which is why this is "experimental"

Refs #622
Refs #623
2023-10-03 16:58:50 +02:00

95 lines
3.2 KiB
JavaScript

const { expect } = require('chai');
const nock = require('nock');
const timekeeper = require('timekeeper');
const jose = require('jose');
const { Issuer } = require('../../lib');
const fail = () => {
throw new Error('expected promise to be rejected');
};
describe('Validating Self-Issued OP responses', () => {
afterEach(timekeeper.reset);
afterEach(nock.cleanAll);
before(function () {
const issuer = new Issuer({
authorization_endpoint: 'openid:',
issuer: 'https://self-issued.me',
scopes_supported: ['openid', 'profile', 'email', 'address', 'phone'],
response_types_supported: ['id_token'],
subject_types_supported: ['pairwise'],
id_token_signing_alg_values_supported: ['RS256'],
request_object_signing_alg_values_supported: ['none', 'RS256'],
registration_endpoint: 'https://self-issued.me/registration/1.0/',
});
const client = new issuer.Client({
client_id: 'https://rp.example.com/cb',
response_types: ['id_token'],
token_endpoint_auth_method: 'none',
id_token_signed_response_alg: 'ES256',
});
Object.assign(this, { issuer, client });
});
async function idToken(claims = {}) {
const kp = await jose.generateKeyPair('ES256', { extractable: true });
const jwk = await jose.exportJWK(kp.publicKey);
const sub = await jose.calculateJwkThumbprint(jwk);
return await new jose.SignJWT({
sub_jwk: jwk,
sub,
...claims,
})
.setIssuedAt()
.setProtectedHeader({ alg: 'ES256' })
.setIssuer('https://self-issued.me')
.setAudience('https://rp.example.com/cb')
.setExpirationTime('2h')
.sign(kp.privateKey);
}
describe('consuming an ID Token response', () => {
it('consumes a self-issued response', async function () {
const { client } = this;
return client.callback(undefined, { id_token: await idToken() });
});
it('expects sub_jwk to be in the ID Token claims', async function () {
const { client } = this;
return client
.callback(undefined, { id_token: await idToken({ sub_jwk: undefined }) })
.then(fail, (err) => {
expect(err.name).to.equal('RPError');
expect(err.message).to.equal('missing required JWT property sub_jwk');
expect(err).to.have.property('jwt');
});
});
it('expects sub_jwk to be a public JWK', async function () {
const { client } = this;
return client
.callback(undefined, { id_token: await idToken({ sub_jwk: 'foobar' }) })
.then(fail, (err) => {
expect(err.name).to.equal('RPError');
expect(err.message).to.equal('failed to use sub_jwk claim as an asymmetric JSON Web Key');
expect(err).to.have.property('jwt');
});
});
it('expects sub to be the thumbprint of the sub_jwk', async function () {
const { client } = this;
return client
.callback(undefined, { id_token: await idToken({ sub: 'foo' }) })
.then(fail, (err) => {
expect(err.name).to.equal('RPError');
expect(err.message).to.equal('failed to match the subject with sub_jwk');
expect(err).to.have.property('jwt');
});
});
});
});