-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Berend Sliedrecht <[email protected]>
- Loading branch information
1 parent
c15e2f4
commit a86e90b
Showing
28 changed files
with
728 additions
and
65 deletions.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
packages/core/__tests__/createEntityConfiguration.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import assert from 'node:assert' | ||
import { describe, it } from 'node:test' | ||
import { createEntityConfiguration } from '../src/entityConfiguration' | ||
import type { SignCallback } from '../src/utils' | ||
|
||
describe('create entity configuration', () => { | ||
const signCallback: SignCallback = () => Promise.resolve(new Uint8Array(42).fill(8)) | ||
|
||
it('should create a basic entity configuration', async () => { | ||
const entityConfiguration = await createEntityConfiguration({ | ||
signCallback, | ||
claims: { | ||
exp: 1, | ||
iat: 1, | ||
iss: 'https://example.org', | ||
sub: 'https://example.org', | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
}, | ||
header: { kid: 'a', typ: 'entity-statement+jwt' }, | ||
}) | ||
|
||
assert( | ||
entityConfiguration, | ||
'eyJraWQiOiJhIiwidHlwIjoiZW50aXR5LXN0YXRlbWVudCtqd3QifQ.eyJpc3MiOiJodHRwczovL2V4YW1wbGUub3JnIiwic3ViIjoiaHR0cHM6Ly9leGFtcGxlLm9yZyIsImlhdCI6IjE5NzAtMDEtMDFUMDA6MDA6MDEuMDAwWiIsImV4cCI6IjE5NzAtMDEtMDFUMDA6MDA6MDEuMDAwWiIsImp3a3MiOnsia2V5cyI6W3sia3R5IjoiRUMiLCJraWQiOiJhIn1dfX0.CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI' | ||
) | ||
}) | ||
|
||
it('should create a more complex entity configuration', async () => { | ||
const entityConfiguration = await createEntityConfiguration({ | ||
signCallback, | ||
claims: { | ||
exp: 1, | ||
iat: 1, | ||
iss: 'https://example.org', | ||
sub: 'https://example.org', | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
authority_hints: ['https://foo.com'], | ||
}, | ||
header: { kid: 'a', typ: 'entity-statement+jwt' }, | ||
}) | ||
|
||
assert( | ||
entityConfiguration, | ||
'eyJraWQiOiJhIiwidHlwIjoiZW50aXR5LXN0YXRlbWVudCtqd3QifQ.eyJpc3MiOiJodHRwczovL2V4YW1wbGUub3JnIiwic3ViIjoiaHR0cHM6Ly9leGFtcGxlLm9yZyIsImlhdCI6IjE5NzAtMDEtMDFUMDA6MDA6MDEuMDAwWiIsImV4cCI6IjE5NzAtMDEtMDFUMDA6MDA6MDEuMDAwWiIsImp3a3MiOnsia2V5cyI6W3sia3R5IjoiRUMiLCJraWQiOiJhIn1dfSwiYXV0aG9yaXR5X2hpbnRzIjpbImh0dHBzOi8vZm9vLmNvbSJdfQ.CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI' | ||
) | ||
}) | ||
|
||
it('should not create a entity configuration when iss and sub are not equal', async () => { | ||
await assert.rejects( | ||
createEntityConfiguration({ | ||
signCallback, | ||
claims: { | ||
exp: 1, | ||
iat: 1, | ||
iss: 'https://some-other.url', | ||
sub: 'https://example.org', | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
}, | ||
header: { kid: 'a', typ: 'entity-statement+jwt' }, | ||
}), | ||
{ | ||
name: 'ZodError', | ||
} | ||
) | ||
}) | ||
|
||
it('should not create a entity configuration when kid is not found in jwks.keys', async () => { | ||
await assert.rejects( | ||
createEntityConfiguration({ | ||
signCallback, | ||
claims: { | ||
exp: 1, | ||
iat: 1, | ||
iss: 'https://example.org', | ||
sub: 'https://example.org', | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
}, | ||
header: { kid: 'invalid_id', typ: 'entity-statement+jwt' }, | ||
}), | ||
{ | ||
name: 'Error', | ||
message: "key with id: 'invalid_id' could not be found in the claims", | ||
} | ||
) | ||
}) | ||
|
||
it("should not create a entity configuration when typ is not 'entity-statement+jwt'", async () => { | ||
await assert.rejects( | ||
createEntityConfiguration({ | ||
signCallback, | ||
claims: { | ||
exp: 1, | ||
iat: 1, | ||
iss: 'https://example.org', | ||
sub: 'https://example.org', | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
}, | ||
// @ts-ignore | ||
header: { kid: 'a', typ: 'invalid_typ' }, | ||
}), | ||
{ | ||
name: 'ZodError', | ||
} | ||
) | ||
}) | ||
|
||
it('should not create a entity configuration when jwks.keys include keys with the same kid', async () => { | ||
await assert.rejects( | ||
createEntityConfiguration({ | ||
signCallback, | ||
claims: { | ||
exp: 1, | ||
iat: 1, | ||
iss: 'https://example.org', | ||
sub: 'https://example.org', | ||
jwks: { | ||
keys: [ | ||
{ kid: 'a', kty: 'EC' }, | ||
{ kid: 'a', kty: 'EC' }, | ||
], | ||
}, | ||
}, | ||
header: { kid: 'a', typ: 'entity-statement+jwt' }, | ||
}), | ||
{ | ||
name: 'ZodError', | ||
} | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { describe, it } from 'node:test' | ||
import { createEntityConfiguration, fetchEntityConfiguration } from '../src/entityConfiguration' | ||
import type { SignCallback, VerifyCallback } from '../src/utils' | ||
|
||
import assert from 'node:assert/strict' | ||
import nock from 'nock' | ||
|
||
describe('fetch entity configuration', () => { | ||
const verifyJwtCallback: VerifyCallback = () => Promise.resolve(true) | ||
|
||
const signCallback: SignCallback = () => Promise.resolve(new Uint8Array(10).fill(42)) | ||
|
||
it('should fetch a simple entity configuration', async () => { | ||
const entityId = 'https://example.org' | ||
|
||
const claims = { | ||
iss: entityId, | ||
sub: entityId, | ||
iat: new Date(), | ||
exp: new Date(), | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
} | ||
|
||
const entityConfiguration = await createEntityConfiguration({ | ||
header: { kid: 'a', typ: 'entity-statement+jwt' }, | ||
claims, | ||
signCallback, | ||
}) | ||
|
||
const scope = nock(entityId).get('/.well-known/openid-federation').reply(200, entityConfiguration, { | ||
'content-type': 'application/entity-statement+jwt', | ||
}) | ||
|
||
const fetchedEntityConfiguration = await fetchEntityConfiguration({ | ||
entityId, | ||
verifyJwtCallback, | ||
}) | ||
|
||
assert.deepStrictEqual(fetchedEntityConfiguration, claims) | ||
|
||
scope.done() | ||
}) | ||
|
||
it('should not fetch an entity configuration when the content-type is invalid', async () => { | ||
const entityId = 'https://exampletwo.org' | ||
|
||
const claims = { | ||
iss: entityId, | ||
sub: entityId, | ||
iat: new Date(), | ||
exp: new Date(), | ||
jwks: { keys: [{ kid: 'a', kty: 'EC' }] }, | ||
} | ||
|
||
const entityConfiguration = await createEntityConfiguration({ | ||
header: { kid: 'a', typ: 'entity-statement+jwt' }, | ||
claims, | ||
signCallback, | ||
}) | ||
|
||
const scope = nock(entityId).get('/.well-known/openid-federation').reply(200, entityConfiguration, { | ||
'content-type': 'invalid-type', | ||
}) | ||
|
||
await assert.rejects(fetchEntityConfiguration({ entityId, verifyJwtCallback }), { name: 'Error' }) | ||
|
||
scope.done() | ||
}) | ||
|
||
it('should not fetch an entity configuration when there is no entity configuration', async () => { | ||
const entityId = 'https://examplethree.org' | ||
|
||
await assert.rejects(fetchEntityConfiguration({ entityId, verifyJwtCallback }), { name: 'TypeError' }) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import assert from 'node:assert/strict' | ||
import { describe, it } from 'node:test' | ||
import { addPaths, addSearchParams } from '../src/utils' | ||
|
||
const addUrlFixtures = [ | ||
{ | ||
baseUrl: 'https://example.org', | ||
paths: ['one', 'two'], | ||
expected: 'https://example.org/one/two', | ||
}, | ||
{ | ||
baseUrl: 'https://example.org/', | ||
paths: ['one', 'two'], | ||
expected: 'https://example.org/one/two', | ||
}, | ||
{ | ||
baseUrl: 'https://example.org/////', | ||
paths: ['one', 'two///'], | ||
expected: 'https://example.org/one/two', | ||
}, | ||
{ | ||
baseUrl: 'https://example.org/zero', | ||
paths: ['one', 'two/'], | ||
expected: 'https://example.org/zero/one/two', | ||
}, | ||
{ | ||
baseUrl: 'https://example.org/zero', | ||
paths: ['/one/', 'two/'], | ||
expected: 'https://example.org/zero/one/two', | ||
}, | ||
] | ||
|
||
const addSearchParamsFixtures: Array<{ | ||
baseUrl: string | ||
searchParams: Record<string, string> | ||
expected: string | ||
}> = [ | ||
{ | ||
baseUrl: 'https://example.org', | ||
searchParams: { one: 'two' }, | ||
expected: 'https://example.org?one=two', | ||
}, | ||
{ | ||
baseUrl: 'https://example.org?', | ||
searchParams: { one: 'two' }, | ||
expected: 'https://example.org?one=two', | ||
}, | ||
{ | ||
baseUrl: 'https://example.org', | ||
searchParams: { foo: 'bar', baz: 'foo' }, | ||
expected: 'https://example.org?foo=bar&baz=foo', | ||
}, | ||
] | ||
|
||
describe('url parsing', () => { | ||
describe('append path to url', () => { | ||
addUrlFixtures.map(({ paths, expected, baseUrl }) => { | ||
it(`should correctly correctly turn '${baseUrl}' into ${expected}`, () => { | ||
assert.strictEqual(addPaths(baseUrl, ...paths), expected) | ||
}) | ||
}) | ||
}) | ||
|
||
describe('append search params to url', () => { | ||
addSearchParamsFixtures.map(({ searchParams, expected, baseUrl }) => { | ||
it(`should correctly correctly turn '${baseUrl}' into ${expected}`, () => { | ||
assert.strictEqual(addSearchParams(baseUrl, searchParams), expected) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.