Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Organization Name #1113

Merged
merged 5 commits into from Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions EXAMPLES.md
Expand Up @@ -165,7 +165,7 @@ await createAuth0Client({
clientId: '<AUTH0_CLIENT_ID>',
authorizationParams: {
redirect_uri: '<MY_CALLBACK_URL>',
organization: '<MY_ORG_ID>'
organization: '<MY_ORG_ID_OR_NAME>'
}
});
```
Expand All @@ -176,14 +176,14 @@ You can also specify the organization when logging in:
// Using a redirect
await client.loginWithRedirect({
authorizationParams: {
organization: '<MY_ORG_ID>'
organization: '<MY_ORG_ID_OR_NAME>'
}
});

// Using a popup window
await client.loginWithPopup({
authorizationParams: {
organization: '<MY_ORG_ID>'
organization: '<MY_ORG_ID_OR_NAME>'
}
});
```
Expand Down
7 changes: 5 additions & 2 deletions __tests__/Auth0Client/getTokenSilently.test.ts
Expand Up @@ -1954,7 +1954,10 @@ describe('Auth0Client', () => {
});

it('stores the org_id in a hint cookie if returned in the ID token claims', async () => {
const auth0 = setup({}, { org_id: TEST_ORG_ID });
const auth0 = setup(
{ authorizationParams: { organization: TEST_ORG_ID } },
{ org_id: TEST_ORG_ID }
);

jest.spyOn(<any>utils, 'runIframe').mockResolvedValue({
access_token: TEST_ACCESS_TOKEN,
Expand All @@ -1980,7 +1983,7 @@ describe('Auth0Client', () => {
);
});

it('removes organization hint cookie if no org claim was returned in the ID token', async () => {
it('removes organization hint cookie if no organization was specified', async () => {
const auth0 = setup({});

jest.spyOn(<any>utils, 'runIframe').mockResolvedValue({
Expand Down
17 changes: 10 additions & 7 deletions __tests__/Auth0Client/loginWithPopup.test.ts
Expand Up @@ -559,29 +559,29 @@ describe('Auth0Client', () => {
);
});

it('calls `tokenVerifier.verify` with the organization id', async () => {
it('calls `tokenVerifier.verify` with the organization', async () => {
const auth0 = setup({
authorizationParams: { organization: 'test_org_123' }
authorizationParams: { organization: 'org_123' }
});

await loginWithPopup(auth0);

expect(tokenVerifier).toHaveBeenCalledWith(
expect.objectContaining({
organizationId: 'test_org_123'
organization: 'org_123'
})
);
});

it('calls `tokenVerifier.verify` with the organization id given in the login method', async () => {
it('calls `tokenVerifier.verify` with the organization given in the login method', async () => {
const auth0 = setup();
await loginWithPopup(auth0, {
authorizationParams: { organization: 'test_org_123' }
authorizationParams: { organization: 'org_123' }
});

expect(tokenVerifier).toHaveBeenCalledWith(
expect.objectContaining({
organizationId: 'test_org_123'
organization: 'org_123'
})
);
});
Expand Down Expand Up @@ -682,7 +682,10 @@ describe('Auth0Client', () => {

it('saves organization hint cookie in storage', async () => {
const auth0 = setup(
{ cookieDomain: TEST_DOMAIN },
{
cookieDomain: TEST_DOMAIN,
authorizationParams: { organization: TEST_ORG_ID }
},
{ org_id: TEST_ORG_ID }
);

Expand Down
22 changes: 13 additions & 9 deletions __tests__/Auth0Client/loginWithRedirect.test.ts
Expand Up @@ -452,22 +452,25 @@ describe('Auth0Client', () => {
);
});

it('calls `tokenVerifier.verify` with the global organization id', async () => {
it('calls `tokenVerifier.verify` with the global organization', async () => {
const auth0 = setup({
authorizationParams: { organization: 'test_org_123' }
authorizationParams: { organization: 'org_123' }
});

await loginWithRedirect(auth0);

expect(tokenVerifier).toHaveBeenCalledWith(
expect.objectContaining({
organizationId: 'test_org_123'
organization: 'org_123'
})
);
});

it('stores the organization ID in a hint cookie', async () => {
const auth0 = setup({}, { org_id: TEST_ORG_ID });
it('stores the organization in a hint cookie', async () => {
const auth0 = setup(
{ authorizationParams: { organization: TEST_ORG_ID } },
{ org_id: TEST_ORG_ID }
);

await loginWithRedirect(auth0);

Expand All @@ -488,7 +491,8 @@ describe('Auth0Client', () => {
);
});

it('removes the org hint cookie if no org_id claim in the ID token', async () => {
it('removes the organization hint cookie if no organization specified', async () => {
// TODO: WHAT IS ORG_NAME ?
const auth0 = setup({});

await loginWithRedirect(auth0);
Expand All @@ -504,17 +508,17 @@ describe('Auth0Client', () => {
);
});

it('calls `tokenVerifier.verify` with the specific organization id', async () => {
it('calls `tokenVerifier.verify` with the specific organization', async () => {
const auth0 = setup({
authorizationParams: { organization: 'test_org_123' }
authorizationParams: { organization: 'org_123' }
});

await loginWithRedirect(auth0, {
authorizationParams: { organization: 'test_org_456' }
});
expect(tokenVerifier).toHaveBeenCalledWith(
expect.objectContaining({
organizationId: 'test_org_456'
organization: 'test_org_456'
})
);
});
Expand Down
85 changes: 78 additions & 7 deletions __tests__/jwt.test.ts
Expand Up @@ -153,14 +153,62 @@ describe('jwt', () => {
});

it('verifies correctly with an organization ID', async () => {
const org_id = 'test_org_123';
const org_id = 'org_123';

const id_token = await createJWT({ ...DEFAULT_PAYLOAD, org_id });

const { encoded, header, claims } = verify({
...verifyOptions,
id_token,
organizationId: org_id
organization: org_id
});

expect({ encoded, header, payload: claims }).toMatchObject(
verifier.decode(id_token)
);
});

it('verifies correctly with an organization Name', async () => {
const org_name = 'my-org';

const id_token = await createJWT({ ...DEFAULT_PAYLOAD, org_name });

const { encoded, header, claims } = verify({
...verifyOptions,
id_token,
organization: org_name
});

expect({ encoded, header, payload: claims }).toMatchObject(
verifier.decode(id_token)
);
});

it('verifies correctly with an organization Name in wrong case', async () => {
const org_name = 'my-org';

const id_token = await createJWT({ ...DEFAULT_PAYLOAD, org_name });

const { encoded, header, claims } = verify({
...verifyOptions,
id_token,
organization: 'My-org'
});

expect({ encoded, header, payload: claims }).toMatchObject(
verifier.decode(id_token)
);
});

it('verifies correctly with an organization Name surrounded by whitespace', async () => {
const org_name = 'my-org';

const id_token = await createJWT({ ...DEFAULT_PAYLOAD, org_name });

const { encoded, header, claims } = verify({
...verifyOptions,
id_token,
organization: ' my-org '
});

expect({ encoded, header, payload: claims }).toMatchObject(
Expand Down Expand Up @@ -369,26 +417,49 @@ describe('jwt', () => {
).not.toThrow();
});

it('validate org_id is present when organizationId is provided', async () => {
it('validate org_id is present when organization id is provided', async () => {
const id_token = await createJWT({ ...DEFAULT_PAYLOAD });

expect(() =>
verify({ ...verifyOptions, id_token, organizationId: 'test_org_123' })
verify({ ...verifyOptions, id_token, organization: 'org_123' })
).toThrow(
'Organization ID (org_id) claim must be a string present in the ID token'
);
});

it('validate org_id matches the claim when organizationId is provided', async () => {
it('validate org_id matches the claim when organization id is provided', async () => {
const id_token = await createJWT({
...DEFAULT_PAYLOAD,
org_id: 'test_org_456'
});

expect(() =>
verify({ ...verifyOptions, id_token, organizationId: 'test_org_123' })
verify({ ...verifyOptions, id_token, organization: 'org_123' })
).toThrow(
'Organization ID (org_id) claim mismatch in the ID token; expected "org_123", found "test_org_456"'
);
});

it('validate org_name is present when organization name is provided', async () => {
const id_token = await createJWT({ ...DEFAULT_PAYLOAD });

expect(() =>
verify({ ...verifyOptions, id_token, organization: 'my-org' })
).toThrow(
'Organization Name (org_name) claim must be a string present in the ID token'
);
});

it('validate org_id matches the claim when organization id is provided', async () => {
const id_token = await createJWT({
...DEFAULT_PAYLOAD,
org_name: 'my-other-org'
});

expect(() =>
verify({ ...verifyOptions, id_token, organization: 'my-org' })
).toThrow(
'Organization ID (org_id) claim mismatch in the ID token; expected "test_org_123", found "test_org_456"'
'Organization Name (org_name) claim mismatch in the ID token; expected "my-org", found "my-other-org"'
);
});
});