186 lines
6.1 KiB
TypeScript
186 lines
6.1 KiB
TypeScript
/**
|
|
* Cognito identity provider configuration compatibility tests.
|
|
*
|
|
* The response shapes asserted here were measured against the live Cognito API:
|
|
* `IdpIdentifiers` is echoed by CreateIdentityProvider and UpdateIdentityProvider
|
|
* only when the request supplied the member, whatever the stored value, while
|
|
* DescribeIdentityProvider always returns it. Members a request omits are
|
|
* preserved rather than cleared.
|
|
*/
|
|
|
|
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
import {
|
|
CognitoIdentityProviderClient,
|
|
CreateUserPoolCommand,
|
|
DeleteUserPoolCommand,
|
|
CreateIdentityProviderCommand,
|
|
DescribeIdentityProviderCommand,
|
|
ListIdentityProvidersCommand,
|
|
UpdateIdentityProviderCommand,
|
|
DeleteIdentityProviderCommand,
|
|
IdentityProviderTypeType,
|
|
} from '@aws-sdk/client-cognito-identity-provider';
|
|
import { makeClient, uniqueName } from './setup';
|
|
|
|
const OIDC_DETAILS = {
|
|
client_id: 'node-compat-client',
|
|
client_secret: 'node-compat-secret',
|
|
attributes_request_method: 'GET',
|
|
oidc_issuer: 'https://issuer.example.com',
|
|
authorize_scopes: 'openid',
|
|
};
|
|
|
|
describe('Cognito identity providers', () => {
|
|
let cognito: CognitoIdentityProviderClient;
|
|
let poolId: string;
|
|
|
|
beforeAll(async () => {
|
|
cognito = makeClient(CognitoIdentityProviderClient);
|
|
const pool = await cognito.send(
|
|
new CreateUserPoolCommand({ PoolName: uniqueName('idp-pool') })
|
|
);
|
|
poolId = pool.UserPool!.Id!;
|
|
});
|
|
|
|
afterAll(async () => {
|
|
if (poolId) {
|
|
await cognito.send(new DeleteUserPoolCommand({ UserPoolId: poolId }));
|
|
}
|
|
});
|
|
|
|
it('defaults AttributeMapping and omits IdpIdentifiers on create', async () => {
|
|
const created = await cognito.send(
|
|
new CreateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidc',
|
|
ProviderType: IdentityProviderTypeType.OIDC,
|
|
ProviderDetails: { ...OIDC_DETAILS },
|
|
})
|
|
);
|
|
|
|
expect(created.IdentityProvider!.AttributeMapping).toEqual({ username: 'sub' });
|
|
expect(created.IdentityProvider!.IdpIdentifiers).toBeUndefined();
|
|
|
|
const described = await cognito.send(
|
|
new DescribeIdentityProviderCommand({ UserPoolId: poolId, ProviderName: 'NodeOidc' })
|
|
);
|
|
expect(described.IdentityProvider!.IdpIdentifiers).toEqual([]);
|
|
expect(described.IdentityProvider!.ProviderDetails!.client_id).toBe('node-compat-client');
|
|
|
|
await cognito.send(
|
|
new DeleteIdentityProviderCommand({ UserPoolId: poolId, ProviderName: 'NodeOidc' })
|
|
);
|
|
});
|
|
|
|
it('preserves members the update request omits', async () => {
|
|
await cognito.send(
|
|
new CreateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcAliased',
|
|
ProviderType: IdentityProviderTypeType.OIDC,
|
|
ProviderDetails: { ...OIDC_DETAILS },
|
|
AttributeMapping: { email: 'email', username: 'sub' },
|
|
IdpIdentifiers: ['node-alias'],
|
|
})
|
|
);
|
|
|
|
const updated = await cognito.send(
|
|
new UpdateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcAliased',
|
|
ProviderDetails: { ...OIDC_DETAILS },
|
|
})
|
|
);
|
|
expect(updated.IdentityProvider!.IdpIdentifiers).toBeUndefined();
|
|
|
|
const described = await cognito.send(
|
|
new DescribeIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcAliased',
|
|
})
|
|
);
|
|
expect(described.IdentityProvider!.IdpIdentifiers).toEqual(['node-alias']);
|
|
expect(described.IdentityProvider!.AttributeMapping).toEqual({
|
|
email: 'email',
|
|
username: 'sub',
|
|
});
|
|
|
|
await cognito.send(
|
|
new DeleteIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcAliased',
|
|
})
|
|
);
|
|
});
|
|
|
|
it('lists providers as summaries without provider details', async () => {
|
|
await cognito.send(
|
|
new CreateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcListed',
|
|
ProviderType: IdentityProviderTypeType.OIDC,
|
|
ProviderDetails: { ...OIDC_DETAILS },
|
|
})
|
|
);
|
|
|
|
const listed = await cognito.send(new ListIdentityProvidersCommand({ UserPoolId: poolId }));
|
|
|
|
expect(listed.Providers).toHaveLength(1);
|
|
expect(listed.Providers![0].ProviderName).toBe('NodeOidcListed');
|
|
expect(listed.Providers![0].ProviderType).toBe('OIDC');
|
|
expect(listed.Providers![0].CreationDate).toBeInstanceOf(Date);
|
|
expect(listed.Providers![0]).not.toHaveProperty('ProviderDetails');
|
|
|
|
await cognito.send(
|
|
new DeleteIdentityProviderCommand({ UserPoolId: poolId, ProviderName: 'NodeOidcListed' })
|
|
);
|
|
const empty = await cognito.send(new ListIdentityProvidersCommand({ UserPoolId: poolId }));
|
|
expect(empty.Providers).toEqual([]);
|
|
});
|
|
|
|
it('rejects a duplicate provider name and an unknown provider type', async () => {
|
|
await cognito.send(
|
|
new CreateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcDuplicate',
|
|
ProviderType: IdentityProviderTypeType.OIDC,
|
|
ProviderDetails: { ...OIDC_DETAILS },
|
|
})
|
|
);
|
|
|
|
// The SDK maps the wire `__type` onto `error.name` and puts the AWS text in
|
|
// `message`, so the exception has to be matched on the name.
|
|
await expect(
|
|
cognito.send(
|
|
new CreateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcDuplicate',
|
|
ProviderType: IdentityProviderTypeType.OIDC,
|
|
ProviderDetails: { ...OIDC_DETAILS },
|
|
})
|
|
)
|
|
).rejects.toMatchObject({ name: 'DuplicateProviderException' });
|
|
|
|
await expect(
|
|
cognito.send(
|
|
new CreateIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeBogus',
|
|
ProviderType: 'NotARealType' as IdentityProviderTypeType,
|
|
ProviderDetails: { client_id: 'x' },
|
|
})
|
|
)
|
|
).rejects.toMatchObject({
|
|
name: 'InvalidParameterException',
|
|
message: expect.stringContaining('Member must satisfy enum value set'),
|
|
});
|
|
|
|
await cognito.send(
|
|
new DeleteIdentityProviderCommand({
|
|
UserPoolId: poolId,
|
|
ProviderName: 'NodeOidcDuplicate',
|
|
})
|
|
);
|
|
});
|
|
});
|