feat(api): Cognito user actions, groups and test sign-in
Adds enable, disable, confirm, sign-out, password reset and set-password for one user; user group membership; group list, create and delete; and a test sign-in that returns decoded token claims. A refused test sign-in is an outcome rather than a 401, which would end the console session. Also adds a generic GET for one flat item and a schema deleteImpact so delete confirmations can say what else goes with a resource.
This commit is contained in:
@@ -16,6 +16,7 @@ import {awsEksSchema} from '../cloud-spi/eksSchema'
|
||||
import {awsKmsSchema} from '../cloud-spi/kmsSchema'
|
||||
import {awsStorageSchema, azureStorageSchema, gcpStorageSchema} from '../cloud-spi/storageSchema'
|
||||
import {awsSesEmailSchema} from '../cloud-spi/emailSchema'
|
||||
import {awsUserPoolsSchema} from '../cloud-spi/userPoolsSchema'
|
||||
import {awsAppConfigSchema} from '../cloud-spi/appConfigSchema'
|
||||
import {awsEventBridgeSchema} from '../cloud-spi/eventbridgeSchema'
|
||||
import {awsNotificationsSchema} from '../cloud-spi/notificationsSchema'
|
||||
@@ -694,6 +695,58 @@ describe('cloud schema routes', () => {
|
||||
])
|
||||
})
|
||||
|
||||
test('reads one flat item, answering 404 when it is gone', async () => {
|
||||
const app = appWithRoutes([mockAdapter('aws', {
|
||||
service: 'userpools',
|
||||
schema: awsUserPoolsSchema,
|
||||
items: {
|
||||
listItems: async () => ({items: [], nextCursor: null}),
|
||||
getItem: async (_poolId, username) => username === 'bob@example.com'
|
||||
? {id: 'u-1', collectionId: null, timestamp: null, body: {email: username, groups: ['admins']}, metadata: {}}
|
||||
: null,
|
||||
},
|
||||
})])
|
||||
|
||||
const found = await app.request('/api/clouds/aws/services/userpools/resources/us-east-1_x/items/bob%40example.com')
|
||||
const missing = await app.request('/api/clouds/aws/services/userpools/resources/us-east-1_x/items/nobody')
|
||||
|
||||
expect(found.status).toBe(200)
|
||||
expect((await found.json()).body.groups).toEqual(['admins'])
|
||||
expect(missing.status).toBe(404)
|
||||
})
|
||||
|
||||
test('routes Cognito user actions, groups and test sign-in to the adapter', async () => {
|
||||
const calls: unknown[] = []
|
||||
const app = appWithRoutes([mockAdapter('aws', {
|
||||
service: 'userpools',
|
||||
schema: awsUserPoolsSchema,
|
||||
updateUserPoolUser: async (poolId, username, input) => { calls.push(['action', poolId, username, input]) },
|
||||
setUserPoolUserGroups: async (poolId, username, groups) => { calls.push(['groups', poolId, username, groups]) },
|
||||
listUserPoolGroups: async () => [{name: 'admins', description: null, precedence: 0, createdAt: null}],
|
||||
createUserPoolGroup: async (_poolId, input) => ({name: input.name, description: null, precedence: null, createdAt: null}),
|
||||
deleteUserPoolGroup: async (poolId, groupName) => { calls.push(['deleteGroup', poolId, groupName]) },
|
||||
testUserPoolSignIn: async () => ({outcome: 'rejected', code: 'NotAuthorizedException', message: 'Incorrect username or password.'}),
|
||||
})])
|
||||
const json = (method: string, body: unknown) => ({method, headers: {'content-type': 'application/json'}, body: JSON.stringify(body)})
|
||||
const base = '/api/clouds/aws/services/userpools/resources/us-east-1_x'
|
||||
|
||||
expect((await app.request(`${base}/users/bob%40example.com/actions`, json('POST', {action: 'disable'}))).status).toBe(200)
|
||||
expect((await app.request(`${base}/users/bob%40example.com/groups`, json('PUT', {groups: ['admins']}))).status).toBe(200)
|
||||
expect(await (await app.request(`${base}/groups`)).json()).toEqual([{name: 'admins', description: null, precedence: 0, createdAt: null}])
|
||||
expect((await app.request(`${base}/groups`, json('POST', {name: 'editors'}))).status).toBe(201)
|
||||
expect((await app.request(`${base}/groups/editors`, {method: 'DELETE'})).status).toBe(200)
|
||||
|
||||
const signIn = await app.request(`${base}/sign-in-test`, json('POST', {clientId: 'c', username: 'bob', password: 'x'}))
|
||||
expect(signIn.status).toBe(200)
|
||||
expect((await signIn.json()).outcome).toBe('rejected')
|
||||
|
||||
expect(calls).toEqual([
|
||||
['action', 'us-east-1_x', 'bob@example.com', {action: 'disable'}],
|
||||
['groups', 'us-east-1_x', 'bob@example.com', ['admins']],
|
||||
['deleteGroup', 'us-east-1_x', 'editors'],
|
||||
])
|
||||
})
|
||||
|
||||
test('clears the SES mailbox through the email adapter', async () => {
|
||||
let cleared = false
|
||||
const app = appWithRoutes([mockAdapter('aws', {
|
||||
|
||||
Reference in New Issue
Block a user