diff --git a/integration-tests/aws-sdk/addCustomAttributes.test.ts b/integration-tests/aws-sdk/addCustomAttributes.test.ts index 3fa7b842..ca52c9df 100644 --- a/integration-tests/aws-sdk/addCustomAttributes.test.ts +++ b/integration-tests/aws-sdk/addCustomAttributes.test.ts @@ -8,35 +8,31 @@ describe( const client = Cognito(); // create the user pool client - const up = await client - .createUserPool({ - PoolName: "pool", - }); + const up = await client.createUserPool({ + PoolName: "pool", + }); - const describeResponse = await client - .describeUserPool({ - UserPoolId: up.UserPool?.Id!, - }); + const describeResponse = await client.describeUserPool({ + UserPoolId: up.UserPool?.Id, + }); expect(describeResponse.UserPool).toMatchObject({ SchemaAttributes: USER_POOL_AWS_DEFAULTS.SchemaAttributes, }); - await client - .addCustomAttributes({ - UserPoolId: up.UserPool?.Id!, - CustomAttributes: [ - { - AttributeDataType: "String", - Name: "test", - }, - ], - }); + await client.addCustomAttributes({ + UserPoolId: up.UserPool?.Id, + CustomAttributes: [ + { + AttributeDataType: "String", + Name: "test", + }, + ], + }); - const describeResponseAfterUpdate = await client - .describeUserPool({ - UserPoolId: up.UserPool?.Id!, - }); + const describeResponseAfterUpdate = await client.describeUserPool({ + UserPoolId: up.UserPool?.Id, + }); expect(describeResponseAfterUpdate.UserPool).toMatchObject({ SchemaAttributes: [ @@ -52,5 +48,5 @@ describe( ], }); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/adminConfirmSignUp.test.ts b/integration-tests/aws-sdk/adminConfirmSignUp.test.ts index 9664f24a..08a63960 100644 --- a/integration-tests/aws-sdk/adminConfirmSignUp.test.ts +++ b/integration-tests/aws-sdk/adminConfirmSignUp.test.ts @@ -6,41 +6,36 @@ describe( it("confirms a user", async () => { const client = Cognito(); - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); - - await client - .signUp({ - UserAttributes: [{ Name: "phone_number", Value: "0400000000" }], - Username: "abc", - ClientId: upc.UserPoolClient?.ClientId!, - Password: "def", - }); - - let user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); + + await client.signUp({ + UserAttributes: [{ Name: "phone_number", Value: "0400000000" }], + Username: "abc", + ClientId: upc.UserPoolClient?.ClientId, + Password: "def", + }); + + let user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.UserStatus).toEqual("UNCONFIRMED"); - await client - .adminConfirmSignUp({ - UserPoolId: "test", - Username: "abc", - }); + await client.adminConfirmSignUp({ + UserPoolId: "test", + Username: "abc", + }); - user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.UserStatus).toEqual("CONFIRMED"); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/adminDeleteUserAttributes.test.ts b/integration-tests/aws-sdk/adminDeleteUserAttributes.test.ts index 3138ff3d..71386b3e 100644 --- a/integration-tests/aws-sdk/adminDeleteUserAttributes.test.ts +++ b/integration-tests/aws-sdk/adminDeleteUserAttributes.test.ts @@ -7,22 +7,20 @@ describe( it("updates a user's attributes", async () => { const client = Cognito(); - await client - .adminCreateUser({ - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "custom:example", Value: "1" }, - ], - Username: "abc", - UserPoolId: "test", - DesiredDeliveryMediums: ["EMAIL"], - }); + await client.adminCreateUser({ + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "custom:example", Value: "1" }, + ], + Username: "abc", + UserPoolId: "test", + DesiredDeliveryMediums: ["EMAIL"], + }); - let user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + let user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -30,23 +28,21 @@ describe( { Name: "custom:example", Value: "1" }, ]); - await client - .adminDeleteUserAttributes({ - UserPoolId: "test", - Username: "abc", - UserAttributeNames: ["custom:example"], - }); + await client.adminDeleteUserAttributes({ + UserPoolId: "test", + Username: "abc", + UserAttributeNames: ["custom:example"], + }); - user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, { Name: "email", Value: "example@example.com" }, ]); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/adminDisableUser.test.ts b/integration-tests/aws-sdk/adminDisableUser.test.ts index 73624080..e8a7e828 100644 --- a/integration-tests/aws-sdk/adminDisableUser.test.ts +++ b/integration-tests/aws-sdk/adminDisableUser.test.ts @@ -6,30 +6,27 @@ describe( it("updates a user's attributes", async () => { const client = Cognito(); - await client - .adminCreateUser({ - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "custom:example", Value: "1" }, - ], - Username: "abc", - UserPoolId: "test", - DesiredDeliveryMediums: ["EMAIL"], - }); + await client.adminCreateUser({ + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "custom:example", Value: "1" }, + ], + Username: "abc", + UserPoolId: "test", + DesiredDeliveryMediums: ["EMAIL"], + }); - await client - .adminDisableUser({ - UserPoolId: "test", - Username: "abc", - }); + await client.adminDisableUser({ + UserPoolId: "test", + Username: "abc", + }); - const user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + const user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.Enabled).toEqual(false); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/adminEnableUser.test.ts b/integration-tests/aws-sdk/adminEnableUser.test.ts index 26b9a765..28883329 100644 --- a/integration-tests/aws-sdk/adminEnableUser.test.ts +++ b/integration-tests/aws-sdk/adminEnableUser.test.ts @@ -6,44 +6,39 @@ describe( it("updates a user's attributes", async () => { const client = Cognito(); - await client - .adminCreateUser({ - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "custom:example", Value: "1" }, - ], - Username: "abc", - UserPoolId: "test", - DesiredDeliveryMediums: ["EMAIL"], - }); - - await client - .adminDisableUser({ - UserPoolId: "test", - Username: "abc", - }); - - let user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + await client.adminCreateUser({ + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "custom:example", Value: "1" }, + ], + Username: "abc", + UserPoolId: "test", + DesiredDeliveryMediums: ["EMAIL"], + }); + + await client.adminDisableUser({ + UserPoolId: "test", + Username: "abc", + }); + + let user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.Enabled).toEqual(false); - await client - .adminEnableUser({ - UserPoolId: "test", - Username: "abc", - }); + await client.adminEnableUser({ + UserPoolId: "test", + Username: "abc", + }); - user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.Enabled).toEqual(true); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/adminInitiateAuth.test.ts b/integration-tests/aws-sdk/adminInitiateAuth.test.ts index abb6936c..8dc9c4aa 100644 --- a/integration-tests/aws-sdk/adminInitiateAuth.test.ts +++ b/integration-tests/aws-sdk/adminInitiateAuth.test.ts @@ -10,23 +10,21 @@ describe( it("throws for missing user", async () => { const client = Cognito(); - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); await expect( - client - .adminInitiateAuth({ - UserPoolId: "test", - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "ADMIN_USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "example@example.com", - PASSWORD: "def", - }, - }) + client.adminInitiateAuth({ + UserPoolId: "test", + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "ADMIN_USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "example@example.com", + PASSWORD: "def", + }, + }), ).rejects.toMatchObject({ message: "User not authorized", }); @@ -35,72 +33,66 @@ describe( it("handles users with UNCONFIRMED status", async () => { const client = Cognito(); - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); - await client - .signUp({ - ClientId: upc.UserPoolClient?.ClientId!, - Password: "def", - UserAttributes: [{ Name: "email", Value: "example@example.com" }], - Username: "abc", - }); + await client.signUp({ + ClientId: upc.UserPoolClient?.ClientId, + Password: "def", + UserAttributes: [{ Name: "email", Value: "example@example.com" }], + Username: "abc", + }); await expect( - client - .adminInitiateAuth({ - UserPoolId: "test", - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "ADMIN_USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - }) + client.adminInitiateAuth({ + UserPoolId: "test", + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "ADMIN_USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + }), ).rejects.toEqual(new UserNotConfirmedException()); }); it("can authenticate users with ADMIN_USER_PASSWORD_AUTH auth flow", async () => { const client = Cognito(); - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); - - const createUserResponse = await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "email_verified", Value: "true" }, - ], - Username: "abc", - UserPoolId: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); + + const createUserResponse = await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "email_verified", Value: "true" }, + ], + Username: "abc", + UserPoolId: "test", + }); const userSub = attributeValue( "sub", - createUserResponse.User?.Attributes + createUserResponse.User?.Attributes, ); - const response = await client - .adminInitiateAuth({ - UserPoolId: "test", - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "ADMIN_USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - }); + const response = await client.adminInitiateAuth({ + UserPoolId: "test", + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "ADMIN_USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + }); expect( - jwt.decode(response.AuthenticationResult?.AccessToken as string) + jwt.decode(response.AuthenticationResult?.AccessToken as string), ).toEqual({ auth_time: expect.any(Number), client_id: upc.UserPoolClient?.ClientId, @@ -116,7 +108,7 @@ describe( }); expect( - jwt.decode(response.AuthenticationResult?.IdToken as string) + jwt.decode(response.AuthenticationResult?.IdToken as string), ).toEqual({ "cognito:username": "abc", aud: upc.UserPoolClient?.ClientId, @@ -133,7 +125,7 @@ describe( }); expect( - jwt.decode(response.AuthenticationResult?.RefreshToken as string) + jwt.decode(response.AuthenticationResult?.RefreshToken as string), ).toEqual({ "cognito:username": "abc", email: "example@example.com", @@ -147,54 +139,50 @@ describe( it("can authenticate users with REFRESH_TOKEN_AUTH auth flow", async () => { const client = Cognito(); - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); - - const createUserResponse = await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "email_verified", Value: "true" }, - ], - Username: "abc", - UserPoolId: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); + + const createUserResponse = await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "email_verified", Value: "true" }, + ], + Username: "abc", + UserPoolId: "test", + }); const userSub = attributeValue( "sub", - createUserResponse.User?.Attributes + createUserResponse.User?.Attributes, ); - const initialLoginResponse = await client - .adminInitiateAuth({ - UserPoolId: "test", - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "ADMIN_USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - }); + const initialLoginResponse = await client.adminInitiateAuth({ + UserPoolId: "test", + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "ADMIN_USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + }); - const refreshTokenLoginResponse = await client - .adminInitiateAuth({ - UserPoolId: "test", - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "REFRESH_TOKEN_AUTH", - AuthParameters: { - REFRESH_TOKEN: initialLoginResponse.AuthenticationResult - ?.RefreshToken as string, - }, - }); + const refreshTokenLoginResponse = await client.adminInitiateAuth({ + UserPoolId: "test", + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "REFRESH_TOKEN_AUTH", + AuthParameters: { + REFRESH_TOKEN: initialLoginResponse.AuthenticationResult + ?.RefreshToken as string, + }, + }); expect( jwt.decode( - refreshTokenLoginResponse.AuthenticationResult?.AccessToken as string - ) + refreshTokenLoginResponse.AuthenticationResult?.AccessToken as string, + ), ).toEqual({ auth_time: expect.any(Number), client_id: upc.UserPoolClient?.ClientId, @@ -211,8 +199,8 @@ describe( expect( jwt.decode( - refreshTokenLoginResponse.AuthenticationResult?.IdToken as string - ) + refreshTokenLoginResponse.AuthenticationResult?.IdToken as string, + ), ).toEqual({ "cognito:username": "abc", aud: upc.UserPoolClient?.ClientId, @@ -229,8 +217,8 @@ describe( }); expect( - refreshTokenLoginResponse.AuthenticationResult?.RefreshToken + refreshTokenLoginResponse.AuthenticationResult?.RefreshToken, ).not.toBeDefined(); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/adminListGroupsForUser.test.ts b/integration-tests/aws-sdk/adminListGroupsForUser.test.ts index d491738a..6e9de179 100644 --- a/integration-tests/aws-sdk/adminListGroupsForUser.test.ts +++ b/integration-tests/aws-sdk/adminListGroupsForUser.test.ts @@ -14,33 +14,29 @@ describe( it("lists groups for a user", async () => { const client = Cognito(); - const createGroupResponse = await client - .createGroup({ - GroupName: "group-1", - UserPoolId: "test", - }); + const createGroupResponse = await client.createGroup({ + GroupName: "group-1", + UserPoolId: "test", + }); - await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], - Username: "user-1", - UserPoolId: "test", - }); + await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], + Username: "user-1", + UserPoolId: "test", + }); - await client - .adminAddUserToGroup({ - Username: "user-1", - GroupName: "group-1", - UserPoolId: "test", - }); + await client.adminAddUserToGroup({ + Username: "user-1", + GroupName: "group-1", + UserPoolId: "test", + }); - const result = await client - .adminListGroupsForUser({ - UserPoolId: "test", - Username: "user-1", - }); + const result = await client.adminListGroupsForUser({ + UserPoolId: "test", + Username: "user-1", + }); expect(result.Groups).toEqual([createGroupResponse.Group]); }); @@ -48,32 +44,29 @@ describe( it("lists groups for an unassigned user", async () => { const client = Cognito(); - await client - .createGroup({ - GroupName: "group-2", - UserPoolId: "test", - }); + await client.createGroup({ + GroupName: "group-2", + UserPoolId: "test", + }); - await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], - Username: "user-1", - UserPoolId: "test", - }); + await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], + Username: "user-1", + UserPoolId: "test", + }); - const result = await client - .adminListGroupsForUser({ - UserPoolId: "test", - Username: "user-1", - }); + const result = await client.adminListGroupsForUser({ + UserPoolId: "test", + Username: "user-1", + }); expect(result.Groups).toHaveLength(0); }); }, { clock, - } - ) + }, + ), ); diff --git a/integration-tests/aws-sdk/adminRemoveUserFromGroup.test.ts b/integration-tests/aws-sdk/adminRemoveUserFromGroup.test.ts index 7c3c6cb3..91a26441 100644 --- a/integration-tests/aws-sdk/adminRemoveUserFromGroup.test.ts +++ b/integration-tests/aws-sdk/adminRemoveUserFromGroup.test.ts @@ -14,54 +14,48 @@ describe( it("lists groups for a user", async () => { const client = Cognito(); - const createGroupResponse = await client - .createGroup({ - GroupName: "group-1", - UserPoolId: "test", - }); - - await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], - Username: "user-1", - UserPoolId: "test", - }); - - await client - .adminAddUserToGroup({ - Username: "user-1", - GroupName: "group-1", - UserPoolId: "test", - }); - - const result = await client - .adminListGroupsForUser({ - UserPoolId: "test", - Username: "user-1", - }); + const createGroupResponse = await client.createGroup({ + GroupName: "group-1", + UserPoolId: "test", + }); + + await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], + Username: "user-1", + UserPoolId: "test", + }); + + await client.adminAddUserToGroup({ + Username: "user-1", + GroupName: "group-1", + UserPoolId: "test", + }); + + const result = await client.adminListGroupsForUser({ + UserPoolId: "test", + Username: "user-1", + }); expect(result.Groups).toEqual([createGroupResponse.Group]); - await client - .adminRemoveUserFromGroup({ - Username: "user-1", - GroupName: "group-1", - UserPoolId: "test", - }); + await client.adminRemoveUserFromGroup({ + Username: "user-1", + GroupName: "group-1", + UserPoolId: "test", + }); - const resultAfterRemove = await client - .adminListGroupsForUser({ - UserPoolId: "test", - Username: "user-1", - }); + const resultAfterRemove = await client.adminListGroupsForUser({ + UserPoolId: "test", + Username: "user-1", + }); expect(resultAfterRemove.Groups).toHaveLength(0); }); }, { clock, - } - ) + }, + ), ); diff --git a/integration-tests/aws-sdk/adminUpdateUserAttributes.test.ts b/integration-tests/aws-sdk/adminUpdateUserAttributes.test.ts index 82b824b2..6aa55387 100644 --- a/integration-tests/aws-sdk/adminUpdateUserAttributes.test.ts +++ b/integration-tests/aws-sdk/adminUpdateUserAttributes.test.ts @@ -7,21 +7,19 @@ describe( it("updates a user's attributes", async () => { const client = Cognito(); - await client - .adminCreateUser({ - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "phone_number", Value: "0400000000" }, - ], - Username: "abc", - UserPoolId: "test", - }); + await client.adminCreateUser({ + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "phone_number", Value: "0400000000" }, + ], + Username: "abc", + UserPoolId: "test", + }); - let user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + let user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -29,18 +27,16 @@ describe( { Name: "phone_number", Value: "0400000000" }, ]); - await client - .adminUpdateUserAttributes({ - UserPoolId: "test", - Username: "abc", - UserAttributes: [{ Name: "email", Value: "example2@example.com" }], - }); + await client.adminUpdateUserAttributes({ + UserPoolId: "test", + Username: "abc", + UserAttributes: [{ Name: "email", Value: "example2@example.com" }], + }); - user = await client - .adminGetUser({ - UserPoolId: "test", - Username: "abc", - }); + user = await client.adminGetUser({ + UserPoolId: "test", + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -49,5 +45,5 @@ describe( { Name: "email_verified", Value: "false" }, ]); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/changePassword.test.ts b/integration-tests/aws-sdk/changePassword.test.ts index 04c6e279..f9158733 100644 --- a/integration-tests/aws-sdk/changePassword.test.ts +++ b/integration-tests/aws-sdk/changePassword.test.ts @@ -7,74 +7,67 @@ describe( const client = Cognito(); // create the user pool client - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); // create a user - await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [{ Name: "email", Value: "example@example.com" }], - Username: "abc", - UserPoolId: "test", - }); + await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [{ Name: "email", Value: "example@example.com" }], + Username: "abc", + UserPoolId: "test", + }); - await client - .adminSetUserPassword({ - Password: "firstPassword", - Permanent: true, - Username: "abc", - UserPoolId: "test", - }); + await client.adminSetUserPassword({ + Password: "firstPassword", + Permanent: true, + Username: "abc", + UserPoolId: "test", + }); // login - const initAuthResponse = await client - .initiateAuth({ - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "firstPassword", - }, - }); + const initAuthResponse = await client.initiateAuth({ + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "firstPassword", + }, + }); // delete the user with their token - await client - .changePassword({ - AccessToken: initAuthResponse.AuthenticationResult?.AccessToken!, - PreviousPassword: "firstPassword", - ProposedPassword: "secondPassword", - }); + await client.changePassword({ + AccessToken: initAuthResponse.AuthenticationResult?.AccessToken, + PreviousPassword: "firstPassword", + ProposedPassword: "secondPassword", + }); // (fail to) login with the old password await expect( - client - .initiateAuth({ - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "firstPassword", - }, - }) - ).rejects.toBeDefined(); - - // login with the new password - const initAuthResponse2nd = await client - .initiateAuth({ - ClientId: upc.UserPoolClient?.ClientId!, + client.initiateAuth({ + ClientId: upc.UserPoolClient?.ClientId, AuthFlow: "USER_PASSWORD_AUTH", AuthParameters: { USERNAME: "abc", - PASSWORD: "secondPassword", + PASSWORD: "firstPassword", }, - }); + }), + ).rejects.toBeDefined(); + + // login with the new password + const initAuthResponse2nd = await client.initiateAuth({ + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "secondPassword", + }, + }); expect(initAuthResponse2nd).toBeDefined(); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/deleteUser.test.ts b/integration-tests/aws-sdk/deleteUser.test.ts index 0e7ed712..d8223fb3 100644 --- a/integration-tests/aws-sdk/deleteUser.test.ts +++ b/integration-tests/aws-sdk/deleteUser.test.ts @@ -8,55 +8,49 @@ describe( const client = Cognito(); // create the user pool client - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); // create a user - await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [{ Name: "email", Value: "example@example.com" }], - Username: "abc", - UserPoolId: "test", - }); + await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [{ Name: "email", Value: "example@example.com" }], + Username: "abc", + UserPoolId: "test", + }); - await client - .adminSetUserPassword({ - Password: "newPassword", - Permanent: true, - Username: "abc", - UserPoolId: "test", - }); + await client.adminSetUserPassword({ + Password: "newPassword", + Permanent: true, + Username: "abc", + UserPoolId: "test", + }); // attempt to login - const initAuthResponse = await client - .initiateAuth({ - ClientId: upc.UserPoolClient?.ClientId!, - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "newPassword", - }, - }); + const initAuthResponse = await client.initiateAuth({ + ClientId: upc.UserPoolClient?.ClientId, + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "newPassword", + }, + }); // delete the user with their token - await client - .deleteUser({ - AccessToken: initAuthResponse.AuthenticationResult?.AccessToken!, - }); + await client.deleteUser({ + AccessToken: initAuthResponse.AuthenticationResult?.AccessToken, + }); // verify they don't exist anymore await expect( - client - .adminGetUser({ - Username: "abc", - UserPoolId: "test", - }) + client.adminGetUser({ + Username: "abc", + UserPoolId: "test", + }), ).rejects.toEqual(new UserNotFoundError("User does not exist.")); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/deleteUserAttributes.test.ts b/integration-tests/aws-sdk/deleteUserAttributes.test.ts index 688cc66f..4b3ed75c 100644 --- a/integration-tests/aws-sdk/deleteUserAttributes.test.ts +++ b/integration-tests/aws-sdk/deleteUserAttributes.test.ts @@ -7,55 +7,49 @@ describe( it("updates a user's attributes", async () => { const client = Cognito(); - const pool = await client - .createUserPool({ - PoolName: "test", - AutoVerifiedAttributes: ["email"], - }); + const pool = await client.createUserPool({ + PoolName: "test", + AutoVerifiedAttributes: ["email"], + }); const userPoolId = pool.UserPool?.Id as string; - const upc = await client - .createUserPoolClient({ - UserPoolId: userPoolId, - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: userPoolId, + ClientName: "test", + }); - await client - .adminCreateUser({ - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "custom:example", Value: "1" }, - ], - Username: "abc", - UserPoolId: userPoolId, - TemporaryPassword: "def", - DesiredDeliveryMediums: ["EMAIL"], - }); + await client.adminCreateUser({ + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "custom:example", Value: "1" }, + ], + Username: "abc", + UserPoolId: userPoolId, + TemporaryPassword: "def", + DesiredDeliveryMediums: ["EMAIL"], + }); - await client - .adminSetUserPassword({ - UserPoolId: userPoolId, - Username: "abc", - Password: "def", - Permanent: true, - }); + await client.adminSetUserPassword({ + UserPoolId: userPoolId, + Username: "abc", + Password: "def", + Permanent: true, + }); // login as the user - const initiateAuthResponse = await client - .initiateAuth({ - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - ClientId: upc.UserPoolClient?.ClientId as string, - }); + const initiateAuthResponse = await client.initiateAuth({ + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + ClientId: upc.UserPoolClient?.ClientId as string, + }); - let user = await client - .adminGetUser({ - UserPoolId: userPoolId, - Username: "abc", - }); + let user = await client.adminGetUser({ + UserPoolId: userPoolId, + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -63,23 +57,21 @@ describe( { Name: "custom:example", Value: "1" }, ]); - await client - .deleteUserAttributes({ - AccessToken: initiateAuthResponse.AuthenticationResult - ?.AccessToken as string, - UserAttributeNames: ["custom:example"], - }); + await client.deleteUserAttributes({ + AccessToken: initiateAuthResponse.AuthenticationResult + ?.AccessToken as string, + UserAttributeNames: ["custom:example"], + }); - user = await client - .adminGetUser({ - UserPoolId: userPoolId, - Username: "abc", - }); + user = await client.adminGetUser({ + UserPoolId: userPoolId, + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, { Name: "email", Value: "example@example.com" }, ]); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/getGroup.test.ts b/integration-tests/aws-sdk/getGroup.test.ts index 35a23ff7..0a41dd2e 100644 --- a/integration-tests/aws-sdk/getGroup.test.ts +++ b/integration-tests/aws-sdk/getGroup.test.ts @@ -14,20 +14,18 @@ describe( it("get a group", async () => { const client = Cognito(); - await client - .createGroup({ - Description: "Description", - GroupName: "abc", - Precedence: 1, - RoleArn: "arn", - UserPoolId: "test", - }); + await client.createGroup({ + Description: "Description", + GroupName: "abc", + Precedence: 1, + RoleArn: "arn", + UserPoolId: "test", + }); - const getGroupResponse = await client - .getGroup({ - GroupName: "abc", - UserPoolId: "test", - }); + const getGroupResponse = await client.getGroup({ + GroupName: "abc", + UserPoolId: "test", + }); expect(getGroupResponse.Group).toEqual({ CreationDate: roundedDate, @@ -42,6 +40,6 @@ describe( }, { clock, - } - ) + }, + ), ); diff --git a/integration-tests/aws-sdk/getUserAttributeVerificationCode.test.ts b/integration-tests/aws-sdk/getUserAttributeVerificationCode.test.ts index b6fd489c..5d860477 100644 --- a/integration-tests/aws-sdk/getUserAttributeVerificationCode.test.ts +++ b/integration-tests/aws-sdk/getUserAttributeVerificationCode.test.ts @@ -1,4 +1,3 @@ -import { UUID } from "../../src/__tests__/patterns"; import { TestContext } from "../../src/__tests__/testContext"; import { withCognitoSdk } from "./setup"; import { User } from "../../src/services/userPoolService"; @@ -9,53 +8,47 @@ describe( it("sends a verification code for a user's attribute", async () => { const client = Cognito(); - const pool = await client - .createUserPool({ - PoolName: "test", - AutoVerifiedAttributes: ["email"], - }); + const pool = await client.createUserPool({ + PoolName: "test", + AutoVerifiedAttributes: ["email"], + }); const userPoolId = pool.UserPool?.Id as string; - const upc = await client - .createUserPoolClient({ - UserPoolId: userPoolId, - ClientName: "test", - }); - - await client - .adminCreateUser({ - UserAttributes: [{ Name: "email", Value: "example@example.com" }], - Username: "abc", - UserPoolId: userPoolId, - TemporaryPassword: "def", - DesiredDeliveryMediums: ["EMAIL"], - }); - - await client - .adminSetUserPassword({ - UserPoolId: userPoolId, - Username: "abc", - Password: "def", - Permanent: true, - }); + const upc = await client.createUserPoolClient({ + UserPoolId: userPoolId, + ClientName: "test", + }); + + await client.adminCreateUser({ + UserAttributes: [{ Name: "email", Value: "example@example.com" }], + Username: "abc", + UserPoolId: userPoolId, + TemporaryPassword: "def", + DesiredDeliveryMediums: ["EMAIL"], + }); + + await client.adminSetUserPassword({ + UserPoolId: userPoolId, + Username: "abc", + Password: "def", + Permanent: true, + }); // login as the user - const initiateAuthResponse = await client - .initiateAuth({ - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - ClientId: upc.UserPoolClient?.ClientId as string, - }); - - await client - .getUserAttributeVerificationCode({ - AccessToken: initiateAuthResponse.AuthenticationResult - ?.AccessToken as string, - AttributeName: "email", - }); + const initiateAuthResponse = await client.initiateAuth({ + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + ClientId: upc.UserPoolClient?.ClientId as string, + }); + + await client.getUserAttributeVerificationCode({ + AccessToken: initiateAuthResponse.AuthenticationResult + ?.AccessToken as string, + AttributeName: "email", + }); // get the user's code -- this is very nasty const ds = await dataStoreFactory().create(TestContext, userPoolId, {}); @@ -63,5 +56,5 @@ describe( expect(storedUser.AttributeVerificationCode).toMatch(/^\d{6}$/); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/listUserPools.test.ts b/integration-tests/aws-sdk/listUserPools.test.ts index 223b592c..8fc41f1c 100644 --- a/integration-tests/aws-sdk/listUserPools.test.ts +++ b/integration-tests/aws-sdk/listUserPools.test.ts @@ -6,31 +6,27 @@ describe( it("lists user pools", async () => { const client = Cognito(); - await client - .createUserPool({ - PoolName: "test-1", - }); - await client - .createUserPool({ - PoolName: "test-2", - }); - await client - .createUserPool({ - PoolName: "test-3", - }); + await client.createUserPool({ + PoolName: "test-1", + }); + await client.createUserPool({ + PoolName: "test-2", + }); + await client.createUserPool({ + PoolName: "test-3", + }); - const result = await client - .listUserPools({ - MaxResults: 10, - }); + const result = await client.listUserPools({ + MaxResults: 10, + }); expect(result.UserPools).toEqual( expect.arrayContaining([ expect.objectContaining({ Name: "test-1" }), expect.objectContaining({ Name: "test-2" }), expect.objectContaining({ Name: "test-3" }), - ]) + ]), ); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/listUsersInGroup.test.ts b/integration-tests/aws-sdk/listUsersInGroup.test.ts index 0a4a3494..581c2d23 100644 --- a/integration-tests/aws-sdk/listUsersInGroup.test.ts +++ b/integration-tests/aws-sdk/listUsersInGroup.test.ts @@ -14,33 +14,29 @@ describe( it("lists users in a group", async () => { const client = Cognito(); - await client - .createGroup({ - GroupName: "group-1", - UserPoolId: "test", - }); + await client.createGroup({ + GroupName: "group-1", + UserPoolId: "test", + }); - const createUserResponse = await client - .adminCreateUser({ - DesiredDeliveryMediums: ["EMAIL"], - TemporaryPassword: "def", - UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], - Username: "user-1", - UserPoolId: "test", - }); + const createUserResponse = await client.adminCreateUser({ + DesiredDeliveryMediums: ["EMAIL"], + TemporaryPassword: "def", + UserAttributes: [{ Name: "email", Value: "example+1@example.com" }], + Username: "user-1", + UserPoolId: "test", + }); - await client - .adminAddUserToGroup({ - Username: "user-1", - GroupName: "group-1", - UserPoolId: "test", - }); + await client.adminAddUserToGroup({ + Username: "user-1", + GroupName: "group-1", + UserPoolId: "test", + }); - const result = await client - .listUsersInGroup({ - UserPoolId: "test", - GroupName: "group-1", - }); + const result = await client.listUsersInGroup({ + UserPoolId: "test", + GroupName: "group-1", + }); expect(result.Users).toEqual([createUserResponse.User]); }); @@ -48,23 +44,21 @@ describe( it("lists no users in an empty group", async () => { const client = Cognito(); - await client - .createGroup({ - GroupName: "group-2", - UserPoolId: "test", - }); + await client.createGroup({ + GroupName: "group-2", + UserPoolId: "test", + }); - const result = await client - .listUsersInGroup({ - UserPoolId: "test", - GroupName: "group-2", - }); + const result = await client.listUsersInGroup({ + UserPoolId: "test", + GroupName: "group-2", + }); expect(result.Users).toHaveLength(0); }); }, { clock, - } - ) + }, + ), ); diff --git a/integration-tests/aws-sdk/updateGroup.test.ts b/integration-tests/aws-sdk/updateGroup.test.ts index 3cc4434d..252058c3 100644 --- a/integration-tests/aws-sdk/updateGroup.test.ts +++ b/integration-tests/aws-sdk/updateGroup.test.ts @@ -6,41 +6,37 @@ describe( it("updates a group", async () => { const client = Cognito(); - await client - .createGroup({ - GroupName: "abc", - UserPoolId: "test", - Description: "original description", - }); + await client.createGroup({ + GroupName: "abc", + UserPoolId: "test", + Description: "original description", + }); - const getGroupResponse = await client - .getGroup({ - GroupName: "abc", - UserPoolId: "test", - }); + const getGroupResponse = await client.getGroup({ + GroupName: "abc", + UserPoolId: "test", + }); expect(getGroupResponse.Group).toMatchObject({ GroupName: "abc", Description: "original description", }); - await client - .updateGroup({ - GroupName: "abc", - UserPoolId: "test", - Description: "new description", - }); + await client.updateGroup({ + GroupName: "abc", + UserPoolId: "test", + Description: "new description", + }); - const getGroupResponseAfterUpdate = await client - .getGroup({ - GroupName: "abc", - UserPoolId: "test", - }); + const getGroupResponseAfterUpdate = await client.getGroup({ + GroupName: "abc", + UserPoolId: "test", + }); expect(getGroupResponseAfterUpdate.Group).toMatchObject({ GroupName: "abc", Description: "new description", }); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/updateUserAttributes.test.ts b/integration-tests/aws-sdk/updateUserAttributes.test.ts index fa20f381..c6b20bd4 100644 --- a/integration-tests/aws-sdk/updateUserAttributes.test.ts +++ b/integration-tests/aws-sdk/updateUserAttributes.test.ts @@ -7,54 +7,48 @@ describe( it("updates a user's attributes", async () => { const client = Cognito(); - const pool = await client - .createUserPool({ - PoolName: "test", - AutoVerifiedAttributes: ["email"], - }); + const pool = await client.createUserPool({ + PoolName: "test", + AutoVerifiedAttributes: ["email"], + }); const userPoolId = pool.UserPool?.Id as string; - const upc = await client - .createUserPoolClient({ - UserPoolId: userPoolId, - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: userPoolId, + ClientName: "test", + }); - await client - .adminCreateUser({ - UserAttributes: [ - { Name: "email", Value: "example@example.com" }, - { Name: "phone_number", Value: "0400000000" }, - ], - Username: "abc", - UserPoolId: userPoolId, - TemporaryPassword: "def", - }); + await client.adminCreateUser({ + UserAttributes: [ + { Name: "email", Value: "example@example.com" }, + { Name: "phone_number", Value: "0400000000" }, + ], + Username: "abc", + UserPoolId: userPoolId, + TemporaryPassword: "def", + }); - await client - .adminSetUserPassword({ - UserPoolId: userPoolId, - Username: "abc", - Password: "def", - Permanent: true, - }); + await client.adminSetUserPassword({ + UserPoolId: userPoolId, + Username: "abc", + Password: "def", + Permanent: true, + }); // login as the user - const initiateAuthResponse = await client - .initiateAuth({ - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - ClientId: upc.UserPoolClient?.ClientId as string, - }); + const initiateAuthResponse = await client.initiateAuth({ + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + ClientId: upc.UserPoolClient?.ClientId as string, + }); - let user = await client - .adminGetUser({ - UserPoolId: userPoolId, - Username: "abc", - }); + let user = await client.adminGetUser({ + UserPoolId: userPoolId, + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -62,18 +56,16 @@ describe( { Name: "phone_number", Value: "0400000000" }, ]); - await client - .updateUserAttributes({ - AccessToken: initiateAuthResponse.AuthenticationResult - ?.AccessToken as string, - UserAttributes: [{ Name: "email", Value: "example2@example.com" }], - }); + await client.updateUserAttributes({ + AccessToken: initiateAuthResponse.AuthenticationResult + ?.AccessToken as string, + UserAttributes: [{ Name: "email", Value: "example2@example.com" }], + }); - user = await client - .adminGetUser({ - UserPoolId: userPoolId, - Username: "abc", - }); + user = await client.adminGetUser({ + UserPoolId: userPoolId, + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -82,5 +74,5 @@ describe( { Name: "email_verified", Value: "false" }, ]); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/updateUserPool.test.ts b/integration-tests/aws-sdk/updateUserPool.test.ts index 12941f0e..2ebea75f 100644 --- a/integration-tests/aws-sdk/updateUserPool.test.ts +++ b/integration-tests/aws-sdk/updateUserPool.test.ts @@ -7,37 +7,33 @@ describe( const client = Cognito(); // create the user pool client - const up = await client - .createUserPool({ - PoolName: "pool", - MfaConfiguration: "OFF", - }); + const up = await client.createUserPool({ + PoolName: "pool", + MfaConfiguration: "OFF", + }); - const describeResponse = await client - .describeUserPool({ - UserPoolId: up.UserPool?.Id!, - }); + const describeResponse = await client.describeUserPool({ + UserPoolId: up.UserPool?.Id, + }); expect(describeResponse.UserPool).toMatchObject({ Name: "pool", MfaConfiguration: "OFF", }); - await client - .updateUserPool({ - UserPoolId: up.UserPool?.Id!, - MfaConfiguration: "OPTIONAL", - }); + await client.updateUserPool({ + UserPoolId: up.UserPool?.Id, + MfaConfiguration: "OPTIONAL", + }); - const describeResponseAfterUpdate = await client - .describeUserPool({ - UserPoolId: up.UserPool?.Id!, - }); + const describeResponseAfterUpdate = await client.describeUserPool({ + UserPoolId: up.UserPool?.Id, + }); expect(describeResponseAfterUpdate.UserPool).toMatchObject({ Name: "pool", MfaConfiguration: "OPTIONAL", }); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/updateUserPoolClient.test.ts b/integration-tests/aws-sdk/updateUserPoolClient.test.ts index 897d5285..2aa74dd9 100644 --- a/integration-tests/aws-sdk/updateUserPoolClient.test.ts +++ b/integration-tests/aws-sdk/updateUserPoolClient.test.ts @@ -7,38 +7,34 @@ describe( const client = Cognito(); // create the user pool client - const upc = await client - .createUserPoolClient({ - UserPoolId: "test", - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: "test", + ClientName: "test", + }); - const describeResponse = await client - .describeUserPoolClient({ - ClientId: upc.UserPoolClient?.ClientId!, - UserPoolId: "test", - }); + const describeResponse = await client.describeUserPoolClient({ + ClientId: upc.UserPoolClient?.ClientId, + UserPoolId: "test", + }); expect(describeResponse.UserPoolClient).toMatchObject({ ClientName: "test", }); - await client - .updateUserPoolClient({ - ClientId: upc.UserPoolClient?.ClientId!, - UserPoolId: "test", - ClientName: "new client name", - }); + await client.updateUserPoolClient({ + ClientId: upc.UserPoolClient?.ClientId, + UserPoolId: "test", + ClientName: "new client name", + }); - const describeResponseAfterUpdate = await client - .describeUserPoolClient({ - ClientId: upc.UserPoolClient?.ClientId!, - UserPoolId: "test", - }); + const describeResponseAfterUpdate = await client.describeUserPoolClient({ + ClientId: upc.UserPoolClient?.ClientId, + UserPoolId: "test", + }); expect(describeResponseAfterUpdate.UserPoolClient).toMatchObject({ ClientName: "new client name", }); }); - }) + }), ); diff --git a/integration-tests/aws-sdk/verifyUserAttribute.test.ts b/integration-tests/aws-sdk/verifyUserAttribute.test.ts index dbfc8276..794465e7 100644 --- a/integration-tests/aws-sdk/verifyUserAttribute.test.ts +++ b/integration-tests/aws-sdk/verifyUserAttribute.test.ts @@ -9,71 +9,63 @@ describe( it("verifies a user's attribute", async () => { const client = Cognito(); - const pool = await client - .createUserPool({ - PoolName: "test", - AutoVerifiedAttributes: ["email"], - }); + const pool = await client.createUserPool({ + PoolName: "test", + AutoVerifiedAttributes: ["email"], + }); const userPoolId = pool.UserPool?.Id as string; - const upc = await client - .createUserPoolClient({ - UserPoolId: userPoolId, - ClientName: "test", - }); + const upc = await client.createUserPoolClient({ + UserPoolId: userPoolId, + ClientName: "test", + }); - await client - .adminCreateUser({ - UserAttributes: [{ Name: "email", Value: "example@example.com" }], - Username: "abc", - UserPoolId: userPoolId, - TemporaryPassword: "def", - DesiredDeliveryMediums: ["EMAIL"], - }); + await client.adminCreateUser({ + UserAttributes: [{ Name: "email", Value: "example@example.com" }], + Username: "abc", + UserPoolId: userPoolId, + TemporaryPassword: "def", + DesiredDeliveryMediums: ["EMAIL"], + }); - await client - .adminSetUserPassword({ - Username: "abc", - UserPoolId: userPoolId, - Password: "def", - Permanent: true, - }); + await client.adminSetUserPassword({ + Username: "abc", + UserPoolId: userPoolId, + Password: "def", + Permanent: true, + }); - await client - .adminUpdateUserAttributes({ - UserPoolId: userPoolId, - Username: "abc", - UserAttributes: [{ Name: "email", Value: "example2@example.com" }], - }); + await client.adminUpdateUserAttributes({ + UserPoolId: userPoolId, + Username: "abc", + UserAttributes: [{ Name: "email", Value: "example2@example.com" }], + }); // get the user's code -- this is very nasty const ds = await dataStoreFactory().create(TestContext, userPoolId, {}); const storedUser = (await ds.get(TestContext, ["Users", "abc"])) as User; // login as the user - const initiateAuthResponse = await client - .initiateAuth({ - AuthFlow: "USER_PASSWORD_AUTH", - AuthParameters: { - USERNAME: "abc", - PASSWORD: "def", - }, - ClientId: upc.UserPoolClient?.ClientId as string, - }); + const initiateAuthResponse = await client.initiateAuth({ + AuthFlow: "USER_PASSWORD_AUTH", + AuthParameters: { + USERNAME: "abc", + PASSWORD: "def", + }, + ClientId: upc.UserPoolClient?.ClientId as string, + }); - await client - .verifyUserAttribute({ - AttributeName: "email", - AccessToken: initiateAuthResponse.AuthenticationResult - ?.AccessToken as string, - Code: storedUser.AttributeVerificationCode as string, - }); + await client.verifyUserAttribute({ + AttributeName: "email", + AccessToken: initiateAuthResponse.AuthenticationResult + ?.AccessToken as string, + Code: storedUser.AttributeVerificationCode as string, + }); - const user = await client - .adminGetUser({ - UserPoolId: userPoolId, - Username: "abc", - }); + const user = await client.adminGetUser({ + UserPoolId: userPoolId, + Username: "abc", + }); expect(user.UserAttributes).toEqual([ { Name: "sub", Value: expect.stringMatching(UUID) }, @@ -81,5 +73,5 @@ describe( { Name: "email_verified", Value: "true" }, ]); }); - }) + }), ); diff --git a/src/__tests__/FakeMessageDeliveryService.ts b/src/__tests__/FakeMessageDeliveryService.ts index ddf4d3f8..cddee3a1 100644 --- a/src/__tests__/FakeMessageDeliveryService.ts +++ b/src/__tests__/FakeMessageDeliveryService.ts @@ -22,7 +22,7 @@ export class FakeMessageDeliveryService implements MessageDelivery { ctx: Context, user: User, deliveryDetails: DeliveryDetails, - message: Message + message: Message, ): Promise { this.messages.push({ deliveryDetails, diff --git a/src/__tests__/mockCognitoService.ts b/src/__tests__/mockCognitoService.ts index 0a1dd2ed..07722181 100644 --- a/src/__tests__/mockCognitoService.ts +++ b/src/__tests__/mockCognitoService.ts @@ -3,7 +3,7 @@ import { CognitoServiceFactory } from "../services/cognitoService"; import { newMockUserPoolService } from "./mockUserPoolService"; export const newMockCognitoService = ( - userPoolClient: UserPoolService = newMockUserPoolService() + userPoolClient: UserPoolService = newMockUserPoolService(), ): jest.Mocked => ({ createUserPool: jest.fn(), deleteUserPool: jest.fn(), @@ -15,7 +15,7 @@ export const newMockCognitoService = ( }); export const newMockCognitoServiceFactory = ( - cognitoService: jest.Mocked = newMockCognitoService() + cognitoService: jest.Mocked = newMockCognitoService(), ): jest.Mocked => ({ create: jest.fn().mockResolvedValue(cognitoService), }); diff --git a/src/__tests__/mockDataStore.ts b/src/__tests__/mockDataStore.ts index bc3f6c74..41a8dd50 100644 --- a/src/__tests__/mockDataStore.ts +++ b/src/__tests__/mockDataStore.ts @@ -9,7 +9,7 @@ export const newMockDataStore = (): jest.Mocked => ({ }); export const newMockDataStoreFactory = ( - dataStore: jest.Mocked = newMockDataStore() + dataStore: jest.Mocked = newMockDataStore(), ): jest.Mocked => ({ create: jest.fn().mockResolvedValue(dataStore), }); diff --git a/src/__tests__/mockUserPoolService.ts b/src/__tests__/mockUserPoolService.ts index 92c78206..be103809 100644 --- a/src/__tests__/mockUserPoolService.ts +++ b/src/__tests__/mockUserPoolService.ts @@ -4,7 +4,7 @@ import { UserPool, UserPoolServiceFactory } from "../services/userPoolService"; export const newMockUserPoolService = ( config: UserPool = { Id: "test", - } + }, ): jest.Mocked => ({ addUserToGroup: jest.fn(), deleteAppClient: jest.fn(), @@ -31,7 +31,7 @@ export const newMockUserPoolService = ( }); export const newMockUserPoolServiceFactory = ( - cognitoService: jest.Mocked = newMockUserPoolService() + cognitoService: jest.Mocked = newMockUserPoolService(), ): jest.Mocked => ({ create: jest.fn().mockResolvedValue(cognitoService), }); diff --git a/src/__tests__/testDataBuilder.ts b/src/__tests__/testDataBuilder.ts index f55ef8d3..81ab062c 100644 --- a/src/__tests__/testDataBuilder.ts +++ b/src/__tests__/testDataBuilder.ts @@ -48,7 +48,7 @@ export const group = (partial?: Partial): Group => ({ }); export const identityProvider = ( - partial?: Partial + partial?: Partial, ): IdentityProvider => ({ ProviderName: partial?.ProviderName ?? id("IdentityProvider"), ProviderType: partial?.ProviderType ?? undefined, diff --git a/src/bin/start.ts b/src/bin/start.ts index 9a2900e7..91e6b6ce 100644 --- a/src/bin/start.ts +++ b/src/bin/start.ts @@ -13,9 +13,8 @@ const logger = Pino( ignore: "pid,name,hostname", singleLine: true, messageFormat: (log, messageKey) => - - `${log["reqId"] as string ?? "NONE"} ${log["target"] as string ?? "NONE"} ${log[messageKey] as string}`, - }) + `${(log["reqId"] as string) ?? "NONE"} ${(log["target"] as string) ?? "NONE"} ${log[messageKey] as string}`, + }), ); createDefaultServer(logger) diff --git a/src/server/Router.test.ts b/src/server/Router.test.ts index 943dc36e..c5aef021 100644 --- a/src/server/Router.test.ts +++ b/src/server/Router.test.ts @@ -10,7 +10,7 @@ describe("Router", () => { const route = Router(services)("invalid"); await expect(route(TestContext, null as any)).rejects.toEqual( - new UnsupportedError('Unsupported x-amz-target header "invalid"') + new UnsupportedError('Unsupported x-amz-target header "invalid"'), ); }); diff --git a/src/server/Router.ts b/src/server/Router.ts index e4f64305..7aa4fce8 100644 --- a/src/server/Router.ts +++ b/src/server/Router.ts @@ -14,7 +14,7 @@ export const Router = if (!isSupportedTarget(target)) { return () => Promise.reject( - new UnsupportedError(`Unsupported x-amz-target header "${target}"`) + new UnsupportedError(`Unsupported x-amz-target header "${target}"`), ); } @@ -32,7 +32,7 @@ export const Router = logger: targetLogger, }, // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - req + req, ); targetLogger.debug("end"); return res; diff --git a/src/server/config.ts b/src/server/config.ts index f346ea8a..030b1a70 100644 --- a/src/server/config.ts +++ b/src/server/config.ts @@ -48,7 +48,7 @@ export const DefaultConfig: Config = { export const loadConfig = async ( ctx: Context, - dataStoreFactory: DataStoreFactory + dataStoreFactory: DataStoreFactory, ): Promise => { ctx.logger.debug("loadConfig"); const dataStore = await dataStoreFactory.create(ctx, "config", {}); @@ -64,6 +64,6 @@ export const loadConfig = async ( // eslint-disable-next-line @typescript-eslint/no-unsafe-return return srcValue; } - } + }, ); }; diff --git a/src/server/defaults.ts b/src/server/defaults.ts index 43fd83a0..85381ee3 100644 --- a/src/server/defaults.ts +++ b/src/server/defaults.ts @@ -20,7 +20,7 @@ import { CryptoService } from "../services/crypto"; import { Lambda } from "@aws-sdk/client-lambda"; export const createDefaultServer = async ( - logger: pino.Logger + logger: pino.Logger, ): Promise => { const configDirectory = ".cognito"; const dataDirectory = `${configDirectory}/db`; @@ -31,7 +31,7 @@ export const createDefaultServer = async ( const config = await loadConfig( ctx, // the config gets a separate factory because it's stored in a different directory - new StormDBDataStoreFactory(configDirectory, new InMemoryCache()) + new StormDBDataStoreFactory(configDirectory, new InMemoryCache()), ); logger.debug({ config }, "Loaded config"); @@ -40,27 +40,24 @@ export const createDefaultServer = async ( const dataStoreFactory = new StormDBDataStoreFactory( dataDirectory, - new InMemoryCache() + new InMemoryCache(), ); const cognitoServiceFactory = new CognitoServiceFactoryImpl( dataDirectory, clock, dataStoreFactory, - new UserPoolServiceFactoryImpl(clock, dataStoreFactory) + new UserPoolServiceFactoryImpl(clock, dataStoreFactory), ); const cognitoClient = await cognitoServiceFactory.create( ctx, - config.UserPoolDefaults + config.UserPoolDefaults, ); const triggers = new TriggersService( clock, cognitoClient, - new LambdaService( - config.TriggerFunctions, - new Lambda(config.LambdaClient) - ), - new CryptoService(config.KMSConfig) + new LambdaService(config.TriggerFunctions, new Lambda(config.LambdaClient)), + new CryptoService(config.KMSConfig), ); return createServer( @@ -70,19 +67,19 @@ export const createDefaultServer = async ( config, messages: new MessagesService( triggers, - new MessageDeliveryService(new ConsoleMessageSender()) + new MessageDeliveryService(new ConsoleMessageSender()), ), otp, tokenGenerator: new JwtTokenGenerator( clock, triggers, - config.TokenConfig + config.TokenConfig, ), triggers, }), logger, { development: !!process.env.COGNITO_LOCAL_DEVMODE, - } + }, ); }; diff --git a/src/server/server.ts b/src/server/server.ts index b2b922e9..e096ccc9 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -23,7 +23,7 @@ export interface Server { export const createServer = ( router: Router, logger: Logger, - options: Partial = {} + options: Partial = {}, ): Server => { const pino = Pino({ logger, @@ -41,12 +41,12 @@ export const createServer = ( app.use( cors({ origin: "*", - }) + }), ); app.use( bodyParser.json({ type: "application/x-amz-json-1.1", - }) + }), ); app.get("/:userPoolId/.well-known/jwks.json", (req, res) => { @@ -88,7 +88,7 @@ export const createServer = ( // eslint-disable-next-line @typescript-eslint/no-explicit-any const replacer: (this: any, key: string, value: any) => any = function ( key, - value + value, ) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access if (this[key] instanceof Date) { @@ -134,7 +134,7 @@ export const createServer = ( res.status(500).json(ex); return; } - } + }, ); }); @@ -153,7 +153,7 @@ export const createServer = ( const httpServer = app.listen( actualOptions.port, actualOptions.hostname, - () => resolve(httpServer) + () => resolve(httpServer), ); httpServer.on("error", reject); }); diff --git a/src/services/cognitoService.test.ts b/src/services/cognitoService.test.ts index b8283dc1..a0b7359b 100644 --- a/src/services/cognitoService.test.ts +++ b/src/services/cognitoService.test.ts @@ -20,7 +20,7 @@ describe("CognitoServiceFactory", () => { "data-directory", new ClockFake(new Date()), mockDataStoreFactory, - newMockUserPoolServiceFactory() + newMockUserPoolServiceFactory(), ); await factory.create(TestContext, {}); @@ -30,7 +30,7 @@ describe("CognitoServiceFactory", () => { "clients", { Clients: {}, - } + }, ); }); }); @@ -57,7 +57,7 @@ describe("Cognito Service", () => { clientsDataStore, new ClockFake(new Date()), { UsernameAttributes: [] }, - mockUserPoolServiceFactory + mockUserPoolServiceFactory, ); const userPool = await cognitoClient.getUserPool(TestContext, "testing"); @@ -65,7 +65,7 @@ describe("Cognito Service", () => { expect(mockUserPoolServiceFactory.create).toHaveBeenCalledWith( TestContext, clientsDataStore, - { ...USER_POOL_AWS_DEFAULTS, Id: "testing", UsernameAttributes: [] } + { ...USER_POOL_AWS_DEFAULTS, Id: "testing", UsernameAttributes: [] }, ); expect(userPool).toEqual(mockUserPool); }); @@ -83,11 +83,11 @@ describe("Cognito Service", () => { clientsDataStore, new ClockFake(new Date()), { UsernameAttributes: [] }, - mockUserPoolServiceFactory + mockUserPoolServiceFactory, ); await expect( - cognitoClient.getUserPoolForClientId(TestContext, "testing") + cognitoClient.getUserPoolForClientId(TestContext, "testing"), ).rejects.toBeInstanceOf(ResourceNotFoundError); expect(mockUserPoolServiceFactory.create).not.toHaveBeenCalled(); @@ -106,12 +106,12 @@ describe("Cognito Service", () => { clientsDataStore, new ClockFake(new Date()), { UsernameAttributes: [] }, - mockUserPoolServiceFactory + mockUserPoolServiceFactory, ); const userPool = await cognitoClient.getUserPoolForClientId( TestContext, - "testing" + "testing", ); expect(clientsDataStore.get).toHaveBeenCalledWith(TestContext, [ @@ -121,7 +121,7 @@ describe("Cognito Service", () => { expect(mockUserPoolServiceFactory.create).toHaveBeenCalledWith( TestContext, clientsDataStore, - { ...USER_POOL_AWS_DEFAULTS, Id: "userPoolId", UsernameAttributes: [] } + { ...USER_POOL_AWS_DEFAULTS, Id: "userPoolId", UsernameAttributes: [] }, ); expect(userPool).toEqual(mockUserPool); }); diff --git a/src/services/cognitoService.ts b/src/services/cognitoService.ts index 09eb0f73..c300c83d 100644 --- a/src/services/cognitoService.ts +++ b/src/services/cognitoService.ts @@ -267,11 +267,11 @@ export interface CognitoService { getUserPool(ctx: Context, userPoolId: string): Promise; getUserPoolForClientId( ctx: Context, - clientId: string + clientId: string, ): Promise; listAppClients( ctx: Context, - userPoolId: string + userPoolId: string, ): Promise; listUserPools(ctx: Context): Promise; } @@ -279,7 +279,7 @@ export interface CognitoService { export interface CognitoServiceFactory { create( ctx: Context, - userPoolDefaultConfig: UserPoolDefaults + userPoolDefaultConfig: UserPoolDefaults, ): Promise; } @@ -295,7 +295,7 @@ export class CognitoServiceImpl implements CognitoService { clients: DataStore, clock: Clock, userPoolDefaultConfig: UserPoolDefaults, - userPoolServiceFactory: UserPoolServiceFactory + userPoolServiceFactory: UserPoolServiceFactory, ) { this.clients = clients; this.clock = clock; @@ -306,7 +306,7 @@ export class CognitoServiceImpl implements CognitoService { public async createUserPool( ctx: Context, - userPool: UserPool + userPool: UserPool, ): Promise { ctx.logger.debug("CognitoServiceImpl.createUserPool"); const service = await this.userPoolServiceFactory.create( @@ -317,8 +317,8 @@ export class CognitoServiceImpl implements CognitoService { {}, USER_POOL_AWS_DEFAULTS, this.userPoolDefaultConfig, - userPool - ) + userPool, + ), ); return service.options; @@ -327,14 +327,14 @@ export class CognitoServiceImpl implements CognitoService { public async deleteUserPool(ctx: Context, userPool: UserPool): Promise { ctx.logger.debug( { userPoolId: userPool.Id }, - "CognitoServiceImpl.deleteUserPool" + "CognitoServiceImpl.deleteUserPool", ); await fs.rm(path.join(this.dataDirectory, `${userPool.Id}.json`)); } public async getUserPool( ctx: Context, - userPoolId: string + userPoolId: string, ): Promise { ctx.logger.debug({ userPoolId }, "CognitoServiceImpl.getUserPool"); return this.userPoolServiceFactory.create(ctx, this.clients, { @@ -346,7 +346,7 @@ export class CognitoServiceImpl implements CognitoService { public async getUserPoolForClientId( ctx: Context, - clientId: string + clientId: string, ): Promise { ctx.logger.debug({ clientId }, "CognitoServiceImpl.getUserPoolForClientId"); const appClient = await this.getAppClient(ctx, clientId); @@ -363,7 +363,7 @@ export class CognitoServiceImpl implements CognitoService { public async getAppClient( ctx: Context, - clientId: string + clientId: string, ): Promise { ctx.logger.debug({ clientId }, "CognitoServiceImpl.getAppClient"); return this.clients.get(ctx, ["Clients", clientId]); @@ -371,13 +371,13 @@ export class CognitoServiceImpl implements CognitoService { public async listAppClients( ctx: Context, - userPoolId: string + userPoolId: string, ): Promise { ctx.logger.debug({ userPoolId }, "CognitoServiceImpl.listAppClients"); const clients = await this.clients.get>( ctx, "Clients", - {} + {}, ); return Object.values(clients).filter((x) => x.UserPoolId === userPoolId); @@ -396,16 +396,16 @@ export class CognitoServiceImpl implements CognitoService { x.isFile() && path.extname(x.name) === ".json" && path.basename(x.name, path.extname(x.name)) !== - CLIENTS_DATABASE_NAME + CLIENTS_DATABASE_NAME, ) .map(async (x) => { const userPool = await this.getUserPool( ctx, - path.basename(x.name, path.extname(x.name)) + path.basename(x.name, path.extname(x.name)), ); return userPool.options; - }) + }), ); } } @@ -420,7 +420,7 @@ export class CognitoServiceFactoryImpl implements CognitoServiceFactory { dataDirectory: string, clock: Clock, dataStoreFactory: DataStoreFactory, - userPoolServiceFactory: UserPoolServiceFactory + userPoolServiceFactory: UserPoolServiceFactory, ) { this.dataDirectory = dataDirectory; this.clock = clock; @@ -430,12 +430,12 @@ export class CognitoServiceFactoryImpl implements CognitoServiceFactory { public async create( ctx: Context, - userPoolDefaultConfig: UserPoolDefaults + userPoolDefaultConfig: UserPoolDefaults, ): Promise { const clients = await this.dataStoreFactory.create( ctx, CLIENTS_DATABASE_NAME, - { Clients: {} } + { Clients: {} }, ); return new CognitoServiceImpl( @@ -443,7 +443,7 @@ export class CognitoServiceFactoryImpl implements CognitoServiceFactory { clients, this.clock, userPoolDefaultConfig, - this.userPoolServiceFactory + this.userPoolServiceFactory, ); } } diff --git a/src/services/crypto.ts b/src/services/crypto.ts index f9f832b6..ab73722c 100644 --- a/src/services/crypto.ts +++ b/src/services/crypto.ts @@ -28,7 +28,7 @@ export class CryptoService { if (!this.config || !this.config.KMSKeyAlias || !this.config.KMSKeyId) { throw new Error( - "KMSConfig.KMSKeyAlias and KMSConfig.KMSKeyId is required when using a CustomEmailSender trigger." + "KMSConfig.KMSKeyAlias and KMSConfig.KMSKeyId is required when using a CustomEmailSender trigger.", ); } diff --git a/src/services/filter.test.ts b/src/services/filter.test.ts index e4ac4fd8..2f97c9e7 100644 --- a/src/services/filter.test.ts +++ b/src/services/filter.test.ts @@ -6,18 +6,18 @@ describe("FilterConfig", () => { "throws if an invalid filter is used: %s", (input) => { expect(() => new FilterConfig({}).parse(input)).toThrowError( - new InvalidParameterError("Error while parsing filter") + new InvalidParameterError("Error while parsing filter"), ); - } + }, ); it("throws if an unsupported attributeName is used", () => { expect(() => new FilterConfig<{ FirstName: string }>({ first_name: FilterConfig.caseSensitive((x) => x.FirstName), - }).parse('invalid = "value"') + }).parse('invalid = "value"'), ).toThrowError( - new InvalidParameterError("Invalid search attribute: invalid") + new InvalidParameterError("Invalid search attribute: invalid"), ); }); @@ -43,7 +43,7 @@ describe("FilterConfig", () => { }).parse(`first_name = "${input}"`); expect(expr({ FirstName: value })).toBe(result); - } + }, ); it.each` @@ -66,7 +66,7 @@ describe("FilterConfig", () => { }).parse(`status = "${input}"`); expect(expr({ Enabled: value })).toBe(result); - } + }, ); }); @@ -85,7 +85,7 @@ describe("FilterConfig", () => { }).parse(`first_name = "${input}"`); expect(expr({ FirstName: value })).toBe(result); - } + }, ); }); }); @@ -109,7 +109,7 @@ describe("FilterConfig", () => { }).parse(`first_name ^= "${input}"`); expect(expr({ FirstName: value })).toBe(result); - } + }, ); }); @@ -131,7 +131,7 @@ describe("FilterConfig", () => { }).parse(`first_name ^= "${input}"`); expect(expr({ FirstName: value })).toBe(result); - } + }, ); }); }); diff --git a/src/services/filter.ts b/src/services/filter.ts index 0249c593..7af1597c 100644 --- a/src/services/filter.ts +++ b/src/services/filter.ts @@ -1,7 +1,7 @@ import { InvalidParameterError } from "../errors"; const FilterExpression = new RegExp( - /^\s*(?.*)\s+(?\^?=)\s+"(?.*)"\s*$/ + /^\s*(?.*)\s+(?\^?=)\s+"(?.*)"\s*$/, ); type Matcher = (obj: T, filterType: "=" | "^=", value: string) => boolean; @@ -10,11 +10,11 @@ type FieldLookup = (obj: T) => string | boolean | undefined; function compare( fieldValue: string | undefined, type: "=" | "^=", - value: string + value: string, ) { return type === "=" ? fieldValue === value - : fieldValue?.startsWith(value) ?? false; + : (fieldValue?.startsWith(value) ?? false); } export class FilterConfig { @@ -27,7 +27,7 @@ export class FilterConfig { compare( field(obj)?.toString()?.toLocaleLowerCase(), type, - value.toLocaleLowerCase() + value.toLocaleLowerCase(), ); } diff --git a/src/services/lambda.ts b/src/services/lambda.ts index 57700589..febbfe21 100644 --- a/src/services/lambda.ts +++ b/src/services/lambda.ts @@ -18,7 +18,11 @@ import { UserLambdaValidationError, } from "../errors"; import { Context } from "./context"; -import { InvocationResponse, InvocationType, Lambda as LambdaClient } from "@aws-sdk/client-lambda"; +import { + InvocationResponse, + InvocationType, + Lambda as LambdaClient, +} from "@aws-sdk/client-lambda"; type CognitoUserPoolEvent = | CreateAuthChallengeTriggerEvent @@ -54,7 +58,8 @@ interface CustomEmailSenderEvent | "CustomEmailSender_VerifyUserAttribute"; } -export interface CustomMessageEvent extends Omit { +export interface CustomMessageEvent + extends Omit { clientId: string | undefined; clientMetadata: Record | undefined; codeParameter: string; @@ -165,37 +170,37 @@ export interface Lambda { invoke( ctx: Context, lambda: "CustomMessage", - event: CustomMessageEvent + event: CustomMessageEvent, ): Promise; invoke( ctx: Context, lambda: "UserMigration", - event: UserMigrationEvent + event: UserMigrationEvent, ): Promise; invoke( ctx: Context, lambda: "PreSignUp", - event: PreSignUpEvent + event: PreSignUpEvent, ): Promise; invoke( ctx: Context, lambda: "PreTokenGeneration", - event: PreTokenGenerationEvent + event: PreTokenGenerationEvent, ): Promise; invoke( ctx: Context, lambda: "PostAuthentication", - event: PostAuthenticationEvent + event: PostAuthenticationEvent, ): Promise; invoke( ctx: Context, lambda: "PostConfirmation", - event: PostConfirmationEvent + event: PostConfirmationEvent, ): Promise; invoke( ctx: Context, lambda: "CustomEmailSender", - event: CustomEmailSenderEvent + event: CustomEmailSenderEvent, ): Promise; } @@ -223,7 +228,7 @@ export class LambdaService implements Lambda { | PostConfirmationEvent | PreSignUpEvent | PreTokenGenerationEvent - | UserMigrationEvent + | UserMigrationEvent, ): Promise { const functionName = this.config[trigger]; if (!functionName) { @@ -237,27 +242,28 @@ export class LambdaService implements Lambda { functionName, event: JSON.stringify(lambdaEvent, undefined, 2), }, - `Invoking "${functionName}" with event` + `Invoking "${functionName}" with event`, ); let result: InvocationResponse; try { - result = await this.lambdaClient - .invoke({ - FunctionName: functionName, - InvocationType: InvocationType.RequestResponse, - Payload: JSON.stringify(lambdaEvent), - }); + result = await this.lambdaClient.invoke({ + FunctionName: functionName, + InvocationType: InvocationType.RequestResponse, + Payload: JSON.stringify(lambdaEvent), + }); } catch (ex) { ctx.logger.error(ex); throw new UnexpectedLambdaExceptionError(); } ctx.logger.debug( - `Lambda completed with StatusCode=${result.StatusCode} and FunctionError=${result.FunctionError}` + `Lambda completed with StatusCode=${result.StatusCode} and FunctionError=${result.FunctionError}`, ); if (!result.FunctionError) { try { - const parsedPayload = JSON.parse(this.decoder.decode(result.Payload)) as { response: T }; + const parsedPayload = JSON.parse( + this.decoder.decode(result.Payload), + ) as { response: T }; return parsedPayload.response; } catch (err) { @@ -268,11 +274,13 @@ export class LambdaService implements Lambda { ctx.logger.error({ result }, result.FunctionError); if (result.FunctionError === "Unhandled" && result.Payload) { - const parsedPayload = JSON.parse(this.decoder.decode(result.Payload)) as { errorMessage: string }; + const parsedPayload = JSON.parse( + this.decoder.decode(result.Payload), + ) as { errorMessage: string }; if (parsedPayload.errorMessage) { throw new UserLambdaValidationError( - `${functionName} failed with error ${parsedPayload.errorMessage}.` + `${functionName} failed with error ${parsedPayload.errorMessage}.`, ); } } @@ -289,7 +297,7 @@ export class LambdaService implements Lambda { | PostConfirmationEvent | PreSignUpEvent | PreTokenGenerationEvent - | UserMigrationEvent + | UserMigrationEvent, ): CognitoUserPoolEvent { const version = "0"; // TODO: how do we know what this is? const callerContext = { diff --git a/src/services/messages.test.ts b/src/services/messages.test.ts index 1a5d67d6..8ebba3c7 100644 --- a/src/services/messages.test.ts +++ b/src/services/messages.test.ts @@ -45,7 +45,7 @@ describe("messages service", () => { const messages = new MessagesService( mockTriggers, - mockMessageDelivery + mockMessageDelivery, ); await messages.deliver( TestContext, @@ -57,7 +57,7 @@ describe("messages service", () => { { client: "metadata", }, - deliveryDetails + deliveryDetails, ); expect(mockTriggers.customMessage).toHaveBeenCalledWith(TestContext, { @@ -81,7 +81,7 @@ describe("messages service", () => { emailMessage: "email", emailSubject: "email subject", smsMessage: "sms", - } + }, ); }); }); @@ -95,7 +95,7 @@ describe("messages service", () => { const messages = new MessagesService( mockTriggers, - mockMessageDelivery + mockMessageDelivery, ); await messages.deliver( TestContext, @@ -107,7 +107,7 @@ describe("messages service", () => { { client: "metadata", }, - deliveryDetails + deliveryDetails, ); expect(mockTriggers.customMessage).toHaveBeenCalledWith(TestContext, { @@ -128,7 +128,7 @@ describe("messages service", () => { deliveryDetails, { __code: "123456", - } + }, ); }); }); @@ -149,7 +149,7 @@ describe("messages service", () => { { client: "metadata", }, - deliveryDetails + deliveryDetails, ); expect(mockTriggers.customMessage).not.toHaveBeenCalled(); @@ -159,7 +159,7 @@ describe("messages service", () => { deliveryDetails, { __code: "123456", - } + }, ); }); }); diff --git a/src/services/messages.ts b/src/services/messages.ts index 25e22834..99a65745 100644 --- a/src/services/messages.ts +++ b/src/services/messages.ts @@ -33,7 +33,7 @@ export interface Messages { user: User, code: string, clientMetadata: Record | undefined, - deliveryDetails: DeliveryDetails + deliveryDetails: DeliveryDetails, ): Promise; } @@ -54,7 +54,7 @@ export class MessagesService implements Messages { user: User, code: string, clientMetadata: Record | undefined, - deliveryDetails: DeliveryDetails + deliveryDetails: DeliveryDetails, ): Promise { if ( this.triggers.enabled("CustomEmailSender") && @@ -67,7 +67,7 @@ export class MessagesService implements Messages { userPoolId, user, code, - clientMetadata + clientMetadata, ); } @@ -78,7 +78,7 @@ export class MessagesService implements Messages { userPoolId, user, code, - clientMetadata + clientMetadata, ); await this.messageDelivery.deliver(ctx, user, deliveryDetails, message); @@ -91,7 +91,7 @@ export class MessagesService implements Messages { userPoolId: string, user: User, code: string, - clientMetadata: Record | undefined + clientMetadata: Record | undefined, ): Promise { if (this.triggers.enabled("CustomMessage")) { const message = await this.triggers.customMessage(ctx, { @@ -123,7 +123,7 @@ export class MessagesService implements Messages { userPoolId: string, user: User, code: string, - clientMetadata: Record | undefined + clientMetadata: Record | undefined, ): Promise { await this.triggers.customEmailSender(ctx, { clientId: clientId ?? AWS_ADMIN_CLIENT_ID, diff --git a/src/services/tokenGenerator.test.ts b/src/services/tokenGenerator.test.ts index 45acf161..3be9b881 100644 --- a/src/services/tokenGenerator.test.ts +++ b/src/services/tokenGenerator.test.ts @@ -48,7 +48,7 @@ describe("JwtTokenGenerator", () => { [], TDB.appClient(), { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); // id token has new claim added @@ -84,7 +84,7 @@ describe("JwtTokenGenerator", () => { [], TDB.appClient(), { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); // id token has new claim added @@ -94,7 +94,7 @@ describe("JwtTokenGenerator", () => { expect(jwt.decode(tokens.AccessToken)).not.toHaveProperty("email"); expect(jwt.decode(tokens.RefreshToken)).toHaveProperty( "email", - attributeValue("email", user.Attributes) + attributeValue("email", user.Attributes), ); }); @@ -117,7 +117,7 @@ describe("JwtTokenGenerator", () => { [], TDB.appClient(), { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); // id token has new claim added @@ -127,7 +127,7 @@ describe("JwtTokenGenerator", () => { expect(jwt.decode(tokens.AccessToken)).not.toHaveProperty("email"); expect(jwt.decode(tokens.RefreshToken)).toHaveProperty( "email", - attributeValue("email", user.Attributes) + attributeValue("email", user.Attributes), ); }); @@ -168,7 +168,7 @@ describe("JwtTokenGenerator", () => { [], TDB.appClient(), { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect(jwt.decode(tokens.IdToken)).not.toMatchObject({ @@ -190,7 +190,7 @@ describe("JwtTokenGenerator", () => { [], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect(jwt.decode(tokens.AccessToken)).toEqual({ @@ -251,17 +251,17 @@ describe("JwtTokenGenerator", () => { [], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect((jwt.decode(tokens.AccessToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + ONE_DAY + Math.floor(originalDate.getTime() / 1000) + ONE_DAY, ); expect((jwt.decode(tokens.IdToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + ONE_DAY + Math.floor(originalDate.getTime() / 1000) + ONE_DAY, ); expect((jwt.decode(tokens.RefreshToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + SEVEN_DAYS + Math.floor(originalDate.getTime() / 1000) + SEVEN_DAYS, ); }); }); @@ -287,17 +287,17 @@ describe("JwtTokenGenerator", () => { [], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect((jwt.decode(tokens.AccessToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + ONE_DAY + Math.floor(originalDate.getTime() / 1000) + ONE_DAY, ); expect((jwt.decode(tokens.IdToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + ONE_DAY + Math.floor(originalDate.getTime() / 1000) + ONE_DAY, ); expect((jwt.decode(tokens.RefreshToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + SEVEN_DAYS + Math.floor(originalDate.getTime() / 1000) + SEVEN_DAYS, ); }); }); @@ -319,17 +319,17 @@ describe("JwtTokenGenerator", () => { [], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect((jwt.decode(tokens.AccessToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + 10 * ONE_HOUR + Math.floor(originalDate.getTime() / 1000) + 10 * ONE_HOUR, ); expect((jwt.decode(tokens.IdToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + 20 * ONE_HOUR + Math.floor(originalDate.getTime() / 1000) + 20 * ONE_HOUR, ); expect((jwt.decode(tokens.RefreshToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + 30 * ONE_DAY + Math.floor(originalDate.getTime() / 1000) + 30 * ONE_DAY, ); }); }); @@ -355,17 +355,17 @@ describe("JwtTokenGenerator", () => { [], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect((jwt.decode(tokens.AccessToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + 10 + Math.floor(originalDate.getTime() / 1000) + 10, ); expect((jwt.decode(tokens.IdToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + 20 * ONE_MINUTE + Math.floor(originalDate.getTime() / 1000) + 20 * ONE_MINUTE, ); expect((jwt.decode(tokens.RefreshToken) as JwtPayload).exp).toEqual( - Math.floor(originalDate.getTime() / 1000) + 30 * ONE_HOUR + Math.floor(originalDate.getTime() / 1000) + 30 * ONE_HOUR, ); }); }); @@ -392,14 +392,14 @@ describe("JwtTokenGenerator", () => { [], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); expect( - (jwt.decode(tokens.AccessToken) as JwtPayload)["cognito:groups"] + (jwt.decode(tokens.AccessToken) as JwtPayload)["cognito:groups"], ).toBeUndefined(); expect( - (jwt.decode(tokens.IdToken) as JwtPayload)["cognito:groups"] + (jwt.decode(tokens.IdToken) as JwtPayload)["cognito:groups"], ).toBeUndefined(); }); @@ -423,16 +423,15 @@ describe("JwtTokenGenerator", () => { ["group1", "group2"], userPoolClient, { client: "metadata" }, - "RefreshTokens" + "RefreshTokens", ); - expect((jwt.decode(tokens.AccessToken) as JwtPayload)["cognito:groups"]).toEqual( - ["group1", "group2"] - ); - expect((jwt.decode(tokens.IdToken) as JwtPayload)["cognito:groups"]).toEqual([ - "group1", - "group2", - ]); + expect( + (jwt.decode(tokens.AccessToken) as JwtPayload)["cognito:groups"], + ).toEqual(["group1", "group2"]); + expect( + (jwt.decode(tokens.IdToken) as JwtPayload)["cognito:groups"], + ).toEqual(["group1", "group2"]); }); }); }); diff --git a/src/services/tokenGenerator.ts b/src/services/tokenGenerator.ts index 1ab48152..90ec993d 100644 --- a/src/services/tokenGenerator.ts +++ b/src/services/tokenGenerator.ts @@ -65,22 +65,22 @@ type RawToken = Record< const applyTokenOverrides = ( token: RawToken, - overrides: TokenOverrides + overrides: TokenOverrides, ): RawToken => { // TODO: support group overrides const claimsToSuppress = (overrides?.claimsToSuppress ?? []).filter( - (claim) => !RESERVED_CLAIMS.includes(claim) + (claim) => !RESERVED_CLAIMS.includes(claim), ); const claimsToOverride = Object.entries( - overrides?.claimsToAddOrOverride ?? [] + overrides?.claimsToAddOrOverride ?? [], ).filter(([claim]) => !RESERVED_CLAIMS.includes(claim)); return Object.fromEntries( [...Object.entries(token), ...claimsToOverride].filter( - ([claim]) => !claimsToSuppress.includes(claim) - ) + ([claim]) => !claimsToSuppress.includes(claim), + ), ); }; @@ -102,14 +102,14 @@ export interface TokenGenerator { | "Authentication" | "HostedAuth" | "NewPasswordChallenge" - | "RefreshTokens" + | "RefreshTokens", ): Promise; } const formatExpiration = ( duration: number | undefined, unit: ValidityUnit, - fallback: string + fallback: string, ): string => (duration ? `${duration}${unit}` : fallback); export class JwtTokenGenerator implements TokenGenerator { @@ -120,7 +120,7 @@ export class JwtTokenGenerator implements TokenGenerator { public constructor( clock: Clock, triggers: Triggers, - tokenConfig: TokenConfig + tokenConfig: TokenConfig, ) { this.clock = clock; this.triggers = triggers; @@ -138,7 +138,7 @@ export class JwtTokenGenerator implements TokenGenerator { | "Authentication" | "HostedAuth" | "NewPasswordChallenge" - | "RefreshTokens" + | "RefreshTokens", ): Promise { const eventId = uuid.v4(); const authTime = Math.floor(this.clock.get().getTime() / 1000); @@ -160,7 +160,7 @@ export class JwtTokenGenerator implements TokenGenerator { auth_time: authTime, email: attributeValue("email", user.Attributes), email_verified: Boolean( - attributeValue("email_verified", user.Attributes) ?? false + attributeValue("email_verified", user.Attributes) ?? false, ), event_id: eventId, iat: authTime, @@ -203,7 +203,7 @@ export class JwtTokenGenerator implements TokenGenerator { expiresIn: formatExpiration( userPoolClient.AccessTokenValidity, userPoolClient.TokenValidityUnits?.AccessToken ?? "hours", - "24h" + "24h", ), keyid: "CognitoLocal", }), @@ -213,7 +213,7 @@ export class JwtTokenGenerator implements TokenGenerator { expiresIn: formatExpiration( userPoolClient.IdTokenValidity, userPoolClient.TokenValidityUnits?.IdToken ?? "hours", - "24h" + "24h", ), audience: userPoolClient.ClientId, keyid: "CognitoLocal", @@ -234,9 +234,9 @@ export class JwtTokenGenerator implements TokenGenerator { expiresIn: formatExpiration( userPoolClient.RefreshTokenValidity, userPoolClient.TokenValidityUnits?.RefreshToken ?? "days", - "7d" + "7d", ), - } + }, ), }; } diff --git a/src/services/userPoolService.test.ts b/src/services/userPoolService.test.ts index 814d0e43..00a33cd8 100644 --- a/src/services/userPoolService.test.ts +++ b/src/services/userPoolService.test.ts @@ -1,5 +1,8 @@ import { ClockFake } from "../__tests__/clockFake"; -import { AttributeType, UsernameAttributeType } from "@aws-sdk/client-cognito-identity-provider"; +import { + AttributeType, + UsernameAttributeType, +} from "@aws-sdk/client-cognito-identity-provider"; import { newMockDataStore, newMockDataStoreFactory, @@ -28,7 +31,7 @@ describe("UserPoolServiceFactory", () => { const clientsDataStore = newMockDataStore(); const factory = new UserPoolServiceFactoryImpl( new ClockFake(new Date()), - mockDataStoreFactory + mockDataStoreFactory, ); await factory.create(TestContext, clientsDataStore, { @@ -42,7 +45,7 @@ describe("UserPoolServiceFactory", () => { { Options: { Id: "local", UsernameAttributes: [] }, Users: {}, - } + }, ); }); }); @@ -63,7 +66,7 @@ describe("User Pool Service", () => { it("saves an app client", async () => { const ds = newMockDataStore(); ds.get.mockImplementation((ctx, key, defaults) => - Promise.resolve(defaults) + Promise.resolve(defaults), ); const userPool = new UserPoolServiceImpl( @@ -73,7 +76,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); const appClient: AppClient = { @@ -90,7 +93,7 @@ describe("User Pool Service", () => { expect(mockClientsDataStore.set).toHaveBeenCalledWith( TestContext, ["Clients", "clientId"], - appClient + appClient, ); }); }); @@ -108,7 +111,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); await userPool.saveGroup(TestContext, group); @@ -116,7 +119,7 @@ describe("User Pool Service", () => { expect(ds.set).toHaveBeenCalledWith( TestContext, ["Groups", group.GroupName], - group + group, ); }); }); @@ -134,7 +137,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); await userPool.saveUser(TestContext, user); @@ -142,7 +145,7 @@ describe("User Pool Service", () => { expect(ds.set).toHaveBeenCalledWith( TestContext, ["Users", user.Username], - user + user, ); }); }); @@ -160,7 +163,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); await userPool.deleteAppClient(TestContext, appClient); @@ -185,7 +188,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); await userPool.deleteGroup(TestContext, group); @@ -218,7 +221,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); await userPool.deleteUser(TestContext, user); @@ -261,7 +264,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); const newDate = new Date(); @@ -276,7 +279,7 @@ describe("User Pool Service", () => { ...group1, LastModifiedDate: newDate, members: [], - } + }, ); expect(ds.set).toHaveBeenCalledWith( TestContext, @@ -285,7 +288,7 @@ describe("User Pool Service", () => { ...group2, LastModifiedDate: newDate, members: [], - } + }, ); expect(ds.set).not.toHaveBeenCalledWith(TestContext, [ "Groups", @@ -326,14 +329,14 @@ describe("User Pool Service", () => { mockClientsDataStore, clock, ds, - options + options, ); }); it("returns null if group doesn't exist", async () => { const foundGroup = await userPool.getGroupByGroupName( TestContext, - "invalid" + "invalid", ); expect(foundGroup).toBeNull(); @@ -342,7 +345,7 @@ describe("User Pool Service", () => { it("returns existing group by their group name", async () => { const foundGroup = await userPool.getGroupByGroupName( TestContext, - group.GroupName + group.GroupName, ); expect(foundGroup).toEqual(group); @@ -404,7 +407,7 @@ describe("User Pool Service", () => { mockClientsDataStore, clock, ds, - options + options, ); }); @@ -417,7 +420,7 @@ describe("User Pool Service", () => { it("returns existing user by their username", async () => { const foundUser = await userPool.getUserByUsername( TestContext, - user.Username + user.Username, ); expect(foundUser).toEqual(user); @@ -426,7 +429,7 @@ describe("User Pool Service", () => { it("returns existing user by their sub", async () => { const foundUser = await userPool.getUserByUsername( TestContext, - "uuid-1234" + "uuid-1234", ); expect(foundUser).toEqual(user); @@ -436,7 +439,7 @@ describe("User Pool Service", () => { it("returns existing user by their email", async () => { const foundUser = await userPool.getUserByUsername( TestContext, - "example@example.com" + "example@example.com", ); expect(foundUser).toEqual(foundUser); @@ -445,7 +448,7 @@ describe("User Pool Service", () => { it("does not return the user by their email", async () => { const foundUser = await userPool.getUserByUsername( TestContext, - "example@example.com" + "example@example.com", ); expect(foundUser).toBeNull(); @@ -456,7 +459,7 @@ describe("User Pool Service", () => { it("returns existing user by their phone number", async () => { const foundUser = await userPool.getUserByUsername( TestContext, - "0411000111" + "0411000111", ); expect(foundUser).toEqual(user); @@ -465,13 +468,13 @@ describe("User Pool Service", () => { it("does not return the user by their phone number", async () => { const foundUser = await userPool.getUserByUsername( TestContext, - "0411000111" + "0411000111", ); expect(foundUser).toBeNull(); }); } - } + }, ); }); @@ -535,19 +538,19 @@ describe("User Pool Service", () => { describe("attributesIncludeMatch", () => { it("returns true if attribute exists in collection with matching name and value", () => { expect( - attributesIncludeMatch("email", "example@example.com", attributes) + attributesIncludeMatch("email", "example@example.com", attributes), ).toBe(true); }); it("returns false if attribute exists in collection with matching name but not matching value", () => { expect(attributesIncludeMatch("email", "invalid", attributes)).toBe( - false + false, ); }); it("returns false if attribute does not exist in collection", () => { expect(attributesIncludeMatch("invalid", "invalid", attributes)).toBe( - false + false, ); }); }); @@ -577,7 +580,7 @@ describe("User Pool Service", () => { attributesFromRecord({ sub: "uuid", email: "example@example.com", - }) + }), ).toEqual(attributes); }); }); @@ -595,7 +598,7 @@ describe("User Pool Service", () => { { Id: "local", UsernameAttributes: [], - } + }, ); await userPool.saveGroup(TestContext, { @@ -617,7 +620,7 @@ describe("User Pool Service", () => { LastModifiedDate: now, Precedence: 1, RoleArn: "ARN", - } + }, ); }); }); @@ -654,7 +657,7 @@ describe("User Pool Service", () => { mockClientsDataStore, clock, ds, - options + options, ); }); @@ -676,7 +679,7 @@ describe("User Pool Service", () => { ds, { Id: "test", - } + }, ); await userPool.updateOptions(TestContext, { @@ -698,7 +701,7 @@ describe("User Pool Service", () => { ds, { Id: "test", - } + }, ); await userPool.updateOptions(TestContext, { @@ -719,7 +722,7 @@ describe("User Pool Service", () => { ds, { Id: "test", - } + }, ); const user = TDB.user(); @@ -734,7 +737,7 @@ describe("User Pool Service", () => { ...group, LastModifiedDate: clock.get(), members: [user.Username], - } + }, ); }); @@ -746,7 +749,7 @@ describe("User Pool Service", () => { ds, { Id: "test", - } + }, ); const user = TDB.user(); @@ -769,7 +772,7 @@ describe("User Pool Service", () => { ds, { Id: "test", - } + }, ); const user = TDB.user(); @@ -786,7 +789,7 @@ describe("User Pool Service", () => { ...group, LastModifiedDate: clock.get(), members: [], - } + }, ); }); }); @@ -800,7 +803,7 @@ describe("User Pool Service", () => { ds, { Id: "test", - } + }, ); const user = TDB.user(); @@ -832,7 +835,7 @@ describe("User Pool Service", () => { const groupMembership = await userPool.listUserGroupMembership( TestContext, - user + user, ); expect(groupMembership).toEqual([group1.GroupName, group2.GroupName]); diff --git a/src/services/userPoolService.ts b/src/services/userPoolService.ts index 5f50bf90..51294822 100644 --- a/src/services/userPoolService.ts +++ b/src/services/userPoolService.ts @@ -21,32 +21,32 @@ export interface MFAOption { export const attribute = ( name: string, - value: string | undefined + value: string | undefined, ): AttributeType => ({ Name: name, Value: value }); export const attributesIncludeMatch = ( attributeName: string, attributeValue: string, - attributes: AttributeType[] | undefined + attributes: AttributeType[] | undefined, ) => !!(attributes ?? []).find( - (x) => x.Name === attributeName && x.Value === attributeValue + (x) => x.Name === attributeName && x.Value === attributeValue, ); export const attributesInclude = ( attributeName: string, - attributes: AttributeType[] | undefined + attributes: AttributeType[] | undefined, ) => !!(attributes ?? []).find((x) => x.Name === attributeName); export const attributeValue = ( attributeName: string | undefined, - attributes: AttributeType[] | undefined + attributes: AttributeType[] | undefined, ) => (attributes ?? []).find((x) => x.Name === attributeName)?.Value; export const attributesToRecord = ( - attributes: AttributeType[] | undefined + attributes: AttributeType[] | undefined, ): Record => (attributes ?? []) .filter((attr) => attr.Name) .reduce((acc, attr) => ({ ...acc, [attr.Name!]: attr.Value }), {}); export const attributesFromRecord = ( - attributes: Record + attributes: Record, ): AttributeType[] => Object.entries(attributes).map(([Name, Value]) => ({ Name, Value })); export const attributesAppend = ( @@ -73,10 +73,10 @@ export const attributesRemove = ( attributes?.filter((x) => x.Name && !toRemove.includes(x.Name)) ?? []; export const customAttributes = ( - attributes: AttributeType[] | undefined + attributes: AttributeType[] | undefined, ): AttributeType[] => (attributes ?? []).filter( - (attr) => attr.Name && attr.Name.startsWith("custom:") + (attr) => attr.Name && attr.Name.startsWith("custom:"), ); export interface User { @@ -149,22 +149,22 @@ export interface UserPoolService { deleteGroup(ctx: Context, group: Group): Promise; deleteIdentityProvider( ctx: Context, - identityProvider: IdentityProvider + identityProvider: IdentityProvider, ): Promise; deleteUser(ctx: Context, user: User): Promise; getGroupByGroupName(ctx: Context, groupName: string): Promise; getIdentityProviderByIdentifier( ctx: Context, - identifier: string + identifier: string, ): Promise; getIdentityProviderByProviderName( ctx: Context, - providerName: string + providerName: string, ): Promise; getUserByUsername(ctx: Context, username: string): Promise; getUserByRefreshToken( ctx: Context, - refreshToken: string + refreshToken: string, ): Promise; listGroups(ctx: Context): Promise; listIdentityProviders(ctx: Context): Promise; @@ -175,13 +175,13 @@ export interface UserPoolService { saveGroup(ctx: Context, group: Group): Promise; saveIdentityProvider( ctx: Context, - identityProvider: IdentityProvider + identityProvider: IdentityProvider, ): Promise; saveUser(ctx: Context, user: User): Promise; storeRefreshToken( ctx: Context, refreshToken: string, - user: User + user: User, ): Promise; } @@ -189,7 +189,7 @@ export interface UserPoolServiceFactory { create( ctx: Context, clientsDataStore: DataStore, - defaultOptions: UserPool + defaultOptions: UserPool, ): Promise; } @@ -208,7 +208,7 @@ export class UserPoolServiceImpl implements UserPoolService { clientsDataStore: DataStore, clock: Clock, dataStore: DataStore, - config: UserPool + config: UserPool, ) { this.clientsDataStore = clientsDataStore; this._options = config; @@ -218,23 +218,23 @@ export class UserPoolServiceImpl implements UserPoolService { public async saveAppClient( ctx: Context, - appClient: AppClient + appClient: AppClient, ): Promise { ctx.logger.debug("UserPoolServiceImpl.saveAppClient"); await this.clientsDataStore.set( ctx, ["Clients", appClient.ClientId], - appClient + appClient, ); } public async deleteAppClient( ctx: Context, - appClient: AppClient + appClient: AppClient, ): Promise { ctx.logger.debug( { clientId: appClient.ClientId }, - "UserPoolServiceImpl.deleteAppClient" + "UserPoolServiceImpl.deleteAppClient", ); await this.clientsDataStore.delete(ctx, ["Clients", appClient.ClientId]); } @@ -242,21 +242,21 @@ export class UserPoolServiceImpl implements UserPoolService { public async deleteGroup(ctx: Context, group: Group): Promise { ctx.logger.debug( { groupName: group.GroupName }, - "UserPoolServiceImpl.deleteGroup" + "UserPoolServiceImpl.deleteGroup", ); await this.dataStore.delete(ctx, ["Groups", group.GroupName]); } public async deleteIdentityProvider( ctx: Context, - identityProvider: IdentityProvider + identityProvider: IdentityProvider, ): Promise { ctx.logger.debug( { userPoolId: identityProvider.UserPoolId, idendityProviderName: identityProvider.ProviderName, }, - "UserPoolServiceImpl.deleteIdentityProvider" + "UserPoolServiceImpl.deleteIdentityProvider", ); await this.dataStore.delete(ctx, [ "IdentityProviders", @@ -267,7 +267,7 @@ export class UserPoolServiceImpl implements UserPoolService { public async deleteUser(ctx: Context, user: User): Promise { ctx.logger.debug( { username: user.Username }, - "UserPoolServiceImpl.deleteUser" + "UserPoolServiceImpl.deleteUser", ); await this.dataStore.delete(ctx, ["Users", user.Username]); @@ -276,7 +276,7 @@ export class UserPoolServiceImpl implements UserPoolService { public async getGroupByGroupName( ctx: Context, - groupName: string + groupName: string, ): Promise { ctx.logger.debug("UserPoolServiceImpl.getGroupByGroupName"); const result = await this.dataStore.get(ctx, ["Groups", groupName]); @@ -286,17 +286,17 @@ export class UserPoolServiceImpl implements UserPoolService { public async getIdentityProviderByIdentifier( ctx: Context, - identifier: string + identifier: string, ): Promise { ctx.logger.debug( { identifier }, - "UserPoolServiceImpl.getIdentityProviderByIdentifier" + "UserPoolServiceImpl.getIdentityProviderByIdentifier", ); const identityProviders = await this.listIdentityProviders(ctx); const identityProvider = identityProviders.find( (identityProvider) => Array.isArray(identityProvider.IdpIdentifiers) && - identityProvider.IdpIdentifiers.includes(identifier) + identityProvider.IdpIdentifiers.includes(identifier), ); return identityProvider ?? null; @@ -304,7 +304,7 @@ export class UserPoolServiceImpl implements UserPoolService { public async getIdentityProviderByProviderName( ctx: Context, - providerName: string + providerName: string, ): Promise { ctx.logger.debug("UserPoolServiceImpl.getIdentityProviderByProviderName"); const result = await this.dataStore.get(ctx, [ @@ -317,7 +317,7 @@ export class UserPoolServiceImpl implements UserPoolService { public async getUserByUsername( ctx: Context, - username: string + username: string, ): Promise { ctx.logger.debug({ username }, "UserPoolServiceImpl.getUserByUsername"); @@ -337,7 +337,7 @@ export class UserPoolServiceImpl implements UserPoolService { const users = await this.dataStore.get>( ctx, "Users", - {} + {}, ); for (const user of Object.values(users)) { @@ -365,17 +365,17 @@ export class UserPoolServiceImpl implements UserPoolService { public async getUserByRefreshToken( ctx: Context, - refreshToken: string + refreshToken: string, ): Promise { ctx.logger.debug( { refreshToken }, - "UserPoolServiceImpl.getUserByRefreshToken" + "UserPoolServiceImpl.getUserByRefreshToken", ); const users = await this.listUsers(ctx); const user = users.find( (user) => Array.isArray(user.RefreshTokens) && - user.RefreshTokens.includes(refreshToken) + user.RefreshTokens.includes(refreshToken), ); return user ?? null; @@ -383,41 +383,41 @@ export class UserPoolServiceImpl implements UserPoolService { public async listUsers( ctx: Context, - filter?: string + filter?: string, ): Promise { ctx.logger.debug("UserPoolServiceImpl.listUsers"); const filterConfig = new FilterConfig({ username: FilterConfig.caseSensitive((x) => x.Username), email: FilterConfig.caseSensitive((x) => - attributeValue("email", x.Attributes) + attributeValue("email", x.Attributes), ), phone_number: FilterConfig.caseSensitive((x) => - attributeValue("phone_number", x.Attributes) + attributeValue("phone_number", x.Attributes), ), name: FilterConfig.caseSensitive((x) => - attributeValue("name", x.Attributes) + attributeValue("name", x.Attributes), ), given_name: FilterConfig.caseSensitive((x) => - attributeValue("given_name", x.Attributes) + attributeValue("given_name", x.Attributes), ), family_name: FilterConfig.caseSensitive((x) => - attributeValue("family_name", x.Attributes) + attributeValue("family_name", x.Attributes), ), preferred_username: FilterConfig.caseSensitive((x) => - attributeValue("preferred_username", x.Attributes) + attributeValue("preferred_username", x.Attributes), ), "cognito:user_status": FilterConfig.caseInsensitive((x) => x.UserStatus), status: FilterConfig.caseSensitive((x) => x.Enabled), sub: FilterConfig.caseSensitive((x) => - attributeValue("sub", x.Attributes) + attributeValue("sub", x.Attributes), ), }); const users = await this.dataStore.get>( ctx, "Users", - {} + {}, ); return Object.values(users).filter(filterConfig.parse(filter)); @@ -426,7 +426,7 @@ export class UserPoolServiceImpl implements UserPoolService { public async updateOptions(ctx: Context, userPool: UserPool): Promise { ctx.logger.debug( { userPoolId: userPool.Id }, - "UserPoolServiceImpl.updateOptions" + "UserPoolServiceImpl.updateOptions", ); await this.dataStore.set(ctx, "Options", userPool); this._options = userPool; @@ -443,20 +443,20 @@ export class UserPoolServiceImpl implements UserPoolService { const groups = await this.dataStore.get>( ctx, "Groups", - {} + {}, ); return Object.values(groups); } async listIdentityProviders( - ctx: Context + ctx: Context, ): Promise { ctx.logger.debug("UserPoolServiceImpl.listIdentityProviders"); const groups = await this.dataStore.get>( ctx, "IdentityProviders", - {} + {}, ); return Object.values(groups); @@ -465,11 +465,11 @@ export class UserPoolServiceImpl implements UserPoolService { public async addUserToGroup( ctx: Context, group: Group, - user: User + user: User, ): Promise { ctx.logger.debug( { username: user.Username, groupName: group.GroupName }, - "UserPoolServiceImpl.addUserToFromGroup" + "UserPoolServiceImpl.addUserToFromGroup", ); const groupMembers = new Set(group.members ?? []); @@ -486,11 +486,11 @@ export class UserPoolServiceImpl implements UserPoolService { public async removeUserFromGroup( ctx: Context, group: Group, - user: User + user: User, ): Promise { ctx.logger.debug( { username: user.Username, groupName: group.GroupName }, - "UserPoolServiceImpl.removeUserFromGroup" + "UserPoolServiceImpl.removeUserFromGroup", ); const groupMembers = new Set(group.members ?? []); @@ -506,16 +506,16 @@ export class UserPoolServiceImpl implements UserPoolService { private async removeUserFromAllGroups( ctx: Context, - user: User + user: User, ): Promise { ctx.logger.debug( { username: user.Username }, - "UserPoolServiceImpl.removeUserFromAllGroups" + "UserPoolServiceImpl.removeUserFromAllGroups", ); const groups = await this.listGroups(ctx); await Promise.all( - groups.map((group) => this.removeUserFromGroup(ctx, group, user)) + groups.map((group) => this.removeUserFromGroup(ctx, group, user)), ); } @@ -527,27 +527,27 @@ export class UserPoolServiceImpl implements UserPoolService { async saveIdentityProvider( ctx: Context, - identityProvider: IdentityProvider + identityProvider: IdentityProvider, ): Promise { ctx.logger.debug( { identityProvider }, - "UserPoolServiceImpl.saveIdentityProvider" + "UserPoolServiceImpl.saveIdentityProvider", ); await this.dataStore.set( ctx, ["IdentityProviders", identityProvider.ProviderName], - identityProvider + identityProvider, ); } async listUserGroupMembership( ctx: Context, - user: User + user: User, ): Promise { ctx.logger.debug( { username: user.Username }, - "UserPoolServiceImpl.listUserGroupMembership" + "UserPoolServiceImpl.listUserGroupMembership", ); // could optimise this by dual-writing group membership to both the group and @@ -564,12 +564,12 @@ export class UserPoolServiceImpl implements UserPoolService { async storeRefreshToken( ctx: Context, refreshToken: string, - user: User + user: User, ): Promise { ctx.logger.debug( { refreshToken, username: user.Username }, "UserPoolServiceImpl.storeRefreshToken", - refreshToken + refreshToken, ); const refreshTokens = Array.isArray(user.RefreshTokens) ? user.RefreshTokens @@ -595,7 +595,7 @@ export class UserPoolServiceFactoryImpl implements UserPoolServiceFactory { public async create( ctx: Context, clientsDataStore: DataStore, - defaultOptions: UserPool + defaultOptions: UserPool, ): Promise { const id = defaultOptions.Id; @@ -608,32 +608,32 @@ export class UserPoolServiceFactoryImpl implements UserPoolServiceFactory { const config = await dataStore.get( ctx, "Options", - defaultOptions + defaultOptions, ); return new UserPoolServiceImpl( clientsDataStore, this.clock, dataStore, - config + config, ); } } export const validatePermittedAttributeChanges = ( requestAttributes: AttributeType[], - schemaAttributes: SchemaAttributeType[] + schemaAttributes: SchemaAttributeType[], ): AttributeType[] => { for (const attr of requestAttributes) { const attrSchema = schemaAttributes.find((x) => x.Name === attr.Name); if (!attrSchema) { throw new InvalidParameterError( - `user.${attr.Name}: Attribute does not exist in the schema.` + `user.${attr.Name}: Attribute does not exist in the schema.`, ); } if (!attrSchema.Mutable) { throw new InvalidParameterError( - `user.${attr.Name}: Attribute cannot be updated. (changing an immutable attribute)` + `user.${attr.Name}: Attribute cannot be updated. (changing an immutable attribute)`, ); } } @@ -643,7 +643,7 @@ export const validatePermittedAttributeChanges = ( !attributesInclude("email", requestAttributes) ) { throw new InvalidParameterError( - "Email is required to verify/un-verify an email" + "Email is required to verify/un-verify an email", ); } @@ -652,7 +652,7 @@ export const validatePermittedAttributeChanges = ( !attributesInclude("phone_number", requestAttributes) ) { throw new InvalidParameterError( - "Phone Number is required to verify/un-verify a phone number" + "Phone Number is required to verify/un-verify a phone number", ); } @@ -660,7 +660,7 @@ export const validatePermittedAttributeChanges = ( }; export const defaultVerifiedAttributesIfModified = ( - attributes: AttributeType[] + attributes: AttributeType[], ): AttributeType[] => { const attributesToSet = [...attributes]; if ( @@ -679,7 +679,7 @@ export const defaultVerifiedAttributesIfModified = ( }; export const hasUnverifiedContactAttributes = ( - userAttributesToSet: AttributeType[] + userAttributesToSet: AttributeType[], ): boolean => attributeValue("email_verified", userAttributesToSet) === "false" || attributeValue("phone_number_verified", userAttributesToSet) === "false"; diff --git a/src/targets/Target.ts b/src/targets/Target.ts index 507dfcbc..84988329 100644 --- a/src/targets/Target.ts +++ b/src/targets/Target.ts @@ -5,7 +5,7 @@ export type TargetName = keyof typeof Targets; export type Target = ( ctx: Context, - req: Req + req: Req, ) => Promise; export const isSupportedTarget = (name: string): name is TargetName => diff --git a/src/targets/addCustomAttributes.test.ts b/src/targets/addCustomAttributes.test.ts index 09293443..7db2265c 100644 --- a/src/targets/addCustomAttributes.test.ts +++ b/src/targets/addCustomAttributes.test.ts @@ -62,7 +62,7 @@ describe("AddCustomAttributes target", () => { }, ], LastModifiedDate: newDate, - } + }, ); }); @@ -100,7 +100,7 @@ describe("AddCustomAttributes target", () => { }, ], LastModifiedDate: newDate, - } + }, ); }); @@ -130,11 +130,11 @@ describe("AddCustomAttributes target", () => { Name: "test", }, ], - }) + }), ).rejects.toEqual( new InvalidParameterError( - "custom:test: Existing attribute already has name custom:test." - ) + "custom:test: Existing attribute already has name custom:test.", + ), ); expect(mockUserPoolService.updateOptions).not.toHaveBeenCalled(); diff --git a/src/targets/addCustomAttributes.ts b/src/targets/addCustomAttributes.ts index ad1c8e53..854250b0 100644 --- a/src/targets/addCustomAttributes.ts +++ b/src/targets/addCustomAttributes.ts @@ -22,7 +22,8 @@ export const AddCustomAttributes = }: AddCustomAttributesServices): AddCustomAttributesTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - if (!req.CustomAttributes) throw new MissingParameterError("CustomAttributes"); + if (!req.CustomAttributes) + throw new MissingParameterError("CustomAttributes"); assertParameterLength("CustomAttributes", 1, 25, req.CustomAttributes); @@ -37,7 +38,7 @@ export const AddCustomAttributes = if (userPool.options.SchemaAttributes?.find((x) => x.Name === name)) { throw new InvalidParameterError( - `${name}: Existing attribute already has name ${name}.` + `${name}: Existing attribute already has name ${name}.`, ); } diff --git a/src/targets/adminAddUserToGroup.test.ts b/src/targets/adminAddUserToGroup.test.ts index c323d171..4bafac9f 100644 --- a/src/targets/adminAddUserToGroup.test.ts +++ b/src/targets/adminAddUserToGroup.test.ts @@ -45,7 +45,7 @@ describe("AdminAddUserToGroup target", () => { expect(mockUserPoolService.addUserToGroup).toHaveBeenCalledWith( TestContext, existingGroup, - existingUser + existingUser, ); }); @@ -60,7 +60,7 @@ describe("AdminAddUserToGroup target", () => { GroupName: "group", Username: existingUser.Username, UserPoolId: "test", - }) + }), ).rejects.toEqual(new GroupNotFoundError()); }); @@ -75,7 +75,7 @@ describe("AdminAddUserToGroup target", () => { GroupName: existingGroup.GroupName, Username: "user", UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/adminAddUserToGroup.ts b/src/targets/adminAddUserToGroup.ts index 1b31ae1b..f196f74f 100644 --- a/src/targets/adminAddUserToGroup.ts +++ b/src/targets/adminAddUserToGroup.ts @@ -1,9 +1,16 @@ import { AdminAddUserToGroupRequest } from "@aws-sdk/client-cognito-identity-provider"; -import { GroupNotFoundError, MissingParameterError, UserNotFoundError } from "../errors"; +import { + GroupNotFoundError, + MissingParameterError, + UserNotFoundError, +} from "../errors"; import { Services } from "../services"; import { Target } from "./Target"; -export type AdminAddUserToGroupTarget = Target; +export type AdminAddUserToGroupTarget = Target< + AdminAddUserToGroupRequest, + object +>; type AdminAddUserToGroupServices = Pick; @@ -13,7 +20,7 @@ export const AdminAddUserToGroup = if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.GroupName) throw new MissingParameterError("GroupName"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const group = await userPool.getGroupByGroupName(ctx, req.GroupName); diff --git a/src/targets/adminConfirmSignUp.ts b/src/targets/adminConfirmSignUp.ts index f64f37bd..99a5d471 100644 --- a/src/targets/adminConfirmSignUp.ts +++ b/src/targets/adminConfirmSignUp.ts @@ -27,7 +27,7 @@ export const AdminConfirmSignUp = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { @@ -36,7 +36,7 @@ export const AdminConfirmSignUp = if (user.UserStatus !== UserStatusType.UNCONFIRMED) { throw new NotAuthorizedError( - `User cannot be confirmed. Current status is ${user.UserStatus}` + `User cannot be confirmed. Current status is ${user.UserStatus}`, ); } @@ -60,7 +60,7 @@ export const AdminConfirmSignUp = // into every place we send attributes to lambdas userAttributes: attributesAppend( updatedUser.Attributes, - attribute("cognito:user_status", updatedUser.UserStatus) + attribute("cognito:user_status", updatedUser.UserStatus), ), }); } diff --git a/src/targets/adminCreateUser.test.ts b/src/targets/adminCreateUser.test.ts index f3f93d95..b07e254a 100644 --- a/src/targets/adminCreateUser.test.ts +++ b/src/targets/adminCreateUser.test.ts @@ -117,7 +117,7 @@ describe("AdminCreateUser target", () => { AttributeName: "email", DeliveryMedium: "EMAIL", Destination: "example@example.com", - } + }, ); }); @@ -131,11 +131,11 @@ describe("AdminCreateUser target", () => { UserAttributes: [], Username: "user-supplied", UserPoolId: "test", - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired delivery mediums" - ) + "User has no attribute matching desired delivery mediums", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); @@ -169,7 +169,7 @@ describe("AdminCreateUser target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0400000000", - } + }, ); }); @@ -181,11 +181,11 @@ describe("AdminCreateUser target", () => { UserAttributes: [], Username: "user-supplied", UserPoolId: "test", - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired delivery mediums" - ) + "User has no attribute matching desired delivery mediums", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); @@ -218,7 +218,7 @@ describe("AdminCreateUser target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0400000000", - } + }, ); }); @@ -232,11 +232,11 @@ describe("AdminCreateUser target", () => { UserAttributes: [], Username: "user-supplied", UserPoolId: "test", - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired delivery mediums" - ) + "User has no attribute matching desired delivery mediums", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); @@ -273,7 +273,7 @@ describe("AdminCreateUser target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0400000000", - } + }, ); }); @@ -303,7 +303,7 @@ describe("AdminCreateUser target", () => { AttributeName: "email", DeliveryMedium: "EMAIL", Destination: "example@example.com", - } + }, ); }); @@ -317,11 +317,11 @@ describe("AdminCreateUser target", () => { UserAttributes: [], Username: "user-supplied", UserPoolId: "test", - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired delivery mediums" - ) + "User has no attribute matching desired delivery mediums", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); @@ -374,7 +374,7 @@ describe("AdminCreateUser target", () => { UserAttributes: existingUser.Attributes, Username: existingUser.Username, UserPoolId: "test", - }) + }), ).rejects.toEqual(new UsernameExistsError()); }); diff --git a/src/targets/adminCreateUser.ts b/src/targets/adminCreateUser.ts index e6594387..18679130 100644 --- a/src/targets/adminCreateUser.ts +++ b/src/targets/adminCreateUser.ts @@ -23,7 +23,7 @@ import { userToResponseObject } from "./responses"; import { Target } from "./Target"; const generator = shortUUID( - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!" + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!", ); export type AdminCreateUserTarget = Target< @@ -38,7 +38,7 @@ type AdminCreateUserServices = Pick< const selectAppropriateDeliveryMethod = ( desiredDeliveryMediums: DeliveryMediumType[], - user: User + user: User, ): DeliveryDetails | null => { if (desiredDeliveryMediums.includes("SMS")) { const phoneNumber = attributeValue("phone_number", user.Attributes); @@ -71,16 +71,16 @@ const deliverWelcomeMessage = async ( temporaryPassword: string, user: User, messages: Messages, - userPool: UserPoolService + userPool: UserPoolService, ) => { const deliveryDetails = selectAppropriateDeliveryMethod( req.DesiredDeliveryMediums ?? ["SMS"], - user + user, ); if (!deliveryDetails) { // TODO: I don't know what the real error message should be for this throw new InvalidParameterError( - "User has no attribute matching desired delivery mediums" + "User has no attribute matching desired delivery mediums", ); } @@ -92,7 +92,7 @@ const deliverWelcomeMessage = async ( user, temporaryPassword, req.ClientMetadata, - deliveryDetails + deliveryDetails, ); }; @@ -106,7 +106,7 @@ export const AdminCreateUser = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const existingUser = await userPool.getUserByUsername(ctx, req.Username); const supressWelcomeMessage = req.MessageAction === "SUPPRESS"; @@ -118,7 +118,7 @@ export const AdminCreateUser = } const attributes = attributesInclude("sub", req.UserAttributes) - ? req.UserAttributes ?? [] + ? (req.UserAttributes ?? []) : [{ Name: "sub", Value: uuid.v4() }, ...(req.UserAttributes ?? [])]; const now = clock.get(); @@ -160,7 +160,7 @@ export const AdminCreateUser = temporaryPassword, user, messages, - userPool + userPool, ); } diff --git a/src/targets/adminDeleteUser.test.ts b/src/targets/adminDeleteUser.test.ts index d6e9c4dd..c0a5e26f 100644 --- a/src/targets/adminDeleteUser.test.ts +++ b/src/targets/adminDeleteUser.test.ts @@ -29,7 +29,7 @@ describe("AdminDeleteUser target", () => { expect(mockUserPoolService.deleteUser).toHaveBeenCalledWith( TestContext, - existingUser + existingUser, ); }); @@ -42,7 +42,7 @@ describe("AdminDeleteUser target", () => { adminDeleteUser(TestContext, { Username: existingUser.Username, UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError("User does not exist")); }); }); diff --git a/src/targets/adminDeleteUser.ts b/src/targets/adminDeleteUser.ts index 46627d70..a9574b3c 100644 --- a/src/targets/adminDeleteUser.ts +++ b/src/targets/adminDeleteUser.ts @@ -12,7 +12,7 @@ export const AdminDeleteUser = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { diff --git a/src/targets/adminDeleteUserAttributes.test.ts b/src/targets/adminDeleteUserAttributes.test.ts index 69d5a56b..b696ce69 100644 --- a/src/targets/adminDeleteUserAttributes.test.ts +++ b/src/targets/adminDeleteUserAttributes.test.ts @@ -31,7 +31,7 @@ describe("AdminDeleteUserAttributes target", () => { UserPoolId: "test", Username: "abc", UserAttributeNames: ["custom:example"], - }) + }), ).rejects.toEqual(new NotAuthorizedError()); }); diff --git a/src/targets/adminDeleteUserAttributes.ts b/src/targets/adminDeleteUserAttributes.ts index c784866f..7e4f7315 100644 --- a/src/targets/adminDeleteUserAttributes.ts +++ b/src/targets/adminDeleteUserAttributes.ts @@ -22,8 +22,9 @@ export const AdminDeleteUserAttributes = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - if (!req.UserAttributeNames) throw new MissingParameterError("UserAttributeNames"); - + if (!req.UserAttributeNames) + throw new MissingParameterError("UserAttributeNames"); + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { diff --git a/src/targets/adminDisableUser.test.ts b/src/targets/adminDisableUser.test.ts index 99429a68..399740be 100644 --- a/src/targets/adminDisableUser.test.ts +++ b/src/targets/adminDisableUser.test.ts @@ -49,7 +49,7 @@ describe("AdminDisableUser target", () => { adminDisableUser(TestContext, { Username: "user", UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/adminDisableUser.ts b/src/targets/adminDisableUser.ts index 56006527..bce7c66c 100644 --- a/src/targets/adminDisableUser.ts +++ b/src/targets/adminDisableUser.ts @@ -18,7 +18,7 @@ export const AdminDisableUser = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { diff --git a/src/targets/adminEnableUser.test.ts b/src/targets/adminEnableUser.test.ts index 019aa30e..acb7514d 100644 --- a/src/targets/adminEnableUser.test.ts +++ b/src/targets/adminEnableUser.test.ts @@ -49,7 +49,7 @@ describe("AdminEnableUser target", () => { adminEnableUser(TestContext, { Username: "user", UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/adminEnableUser.ts b/src/targets/adminEnableUser.ts index 0f0e4a14..2bb6fbdd 100644 --- a/src/targets/adminEnableUser.ts +++ b/src/targets/adminEnableUser.ts @@ -18,7 +18,7 @@ export const AdminEnableUser = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { diff --git a/src/targets/adminGetUser.test.ts b/src/targets/adminGetUser.test.ts index 57b183d9..e1c9e26c 100644 --- a/src/targets/adminGetUser.test.ts +++ b/src/targets/adminGetUser.test.ts @@ -46,7 +46,7 @@ describe("AdminGetUser target", () => { adminGetUser(TestContext, { Username: existingUser.Username, UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError("User does not exist.")); }); }); diff --git a/src/targets/adminInitiateAuth.test.ts b/src/targets/adminInitiateAuth.test.ts index 6164d103..bf9ef187 100644 --- a/src/targets/adminInitiateAuth.test.ts +++ b/src/targets/adminInitiateAuth.test.ts @@ -63,7 +63,7 @@ describe("AdminInitiateAuth target", () => { expect(mockUserPoolService.storeRefreshToken).toHaveBeenCalledWith( TestContext, response.AuthenticationResult?.RefreshToken, - existingUser + existingUser, ); expect(response.AuthenticationResult?.AccessToken).toEqual("access"); @@ -78,7 +78,7 @@ describe("AdminInitiateAuth target", () => { { client: "metadata", }, - "Authentication" + "Authentication", ); }); @@ -110,7 +110,7 @@ describe("AdminInitiateAuth target", () => { expect(mockUserPoolService.getUserByRefreshToken).toHaveBeenCalledWith( TestContext, - "refresh token" + "refresh token", ); expect(mockUserPoolService.storeRefreshToken).not.toHaveBeenCalled(); @@ -128,7 +128,7 @@ describe("AdminInitiateAuth target", () => { { client: "metadata", }, - "RefreshTokens" + "RefreshTokens", ); }); }); diff --git a/src/targets/adminInitiateAuth.ts b/src/targets/adminInitiateAuth.ts index 23f1f10f..ed5cee54 100644 --- a/src/targets/adminInitiateAuth.ts +++ b/src/targets/adminInitiateAuth.ts @@ -27,24 +27,24 @@ type AdminInitiateAuthServices = Pick< const adminUserPasswordAuthFlow = async ( ctx: Context, services: AdminInitiateAuthServices, - req: AdminInitiateAuthRequest + req: AdminInitiateAuthRequest, ): Promise => { if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.AuthParameters) { throw new InvalidParameterError( - "Missing required parameter authParameters" + "Missing required parameter authParameters", ); } if (!req.AuthParameters.USERNAME || !req.AuthParameters.PASSWORD) { throw new InvalidParameterError( - "AuthParameters USERNAME and PASSWORD are required" + "AuthParameters USERNAME and PASSWORD are required", ); } const userPool = await services.cognito.getUserPoolForClientId( ctx, - req.ClientId + req.ClientId, ); const userPoolClient = await services.cognito.getAppClient(ctx, req.ClientId); let user = await userPool.getUserByUsername(ctx, req.AuthParameters.USERNAME); @@ -86,7 +86,7 @@ const adminUserPasswordAuthFlow = async ( userGroups, userPoolClient, req.ClientMetadata, - "Authentication" + "Authentication", ); await userPool.storeRefreshToken(ctx, tokens.RefreshToken, user); @@ -109,12 +109,12 @@ const adminUserPasswordAuthFlow = async ( const refreshTokenAuthFlow = async ( ctx: Context, services: AdminInitiateAuthServices, - req: AdminInitiateAuthRequest + req: AdminInitiateAuthRequest, ): Promise => { if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.AuthParameters) { throw new InvalidParameterError( - "Missing required parameter authParameters" + "Missing required parameter authParameters", ); } @@ -124,12 +124,12 @@ const refreshTokenAuthFlow = async ( const userPool = await services.cognito.getUserPoolForClientId( ctx, - req.ClientId + req.ClientId, ); const userPoolClient = await services.cognito.getAppClient(ctx, req.ClientId); const user = await userPool.getUserByRefreshToken( ctx, - req.AuthParameters.REFRESH_TOKEN + req.AuthParameters.REFRESH_TOKEN, ); if (!user || !userPoolClient) { throw new NotAuthorizedError(); @@ -143,7 +143,7 @@ const refreshTokenAuthFlow = async ( userGroups, userPoolClient, req.ClientMetadata, - "RefreshTokens" + "RefreshTokens", ); return { diff --git a/src/targets/adminLinkProviderForUser.ts b/src/targets/adminLinkProviderForUser.ts index 1ed5fceb..ecb3d9ab 100644 --- a/src/targets/adminLinkProviderForUser.ts +++ b/src/targets/adminLinkProviderForUser.ts @@ -4,7 +4,10 @@ import { } from "@aws-sdk/client-cognito-identity-provider"; import { Services } from "../services"; import { Target } from "./Target"; -import { IdentityProviderNotFoundError, MissingParameterError } from "../errors"; +import { + IdentityProviderNotFoundError, + MissingParameterError, +} from "../errors"; export type AdminLinkProviderForUserTarget = Target< AdminLinkProviderForUserRequest, @@ -27,7 +30,7 @@ export const AdminLinkProviderForUser = } const identityProvider = await userPool.getIdentityProviderByProviderName( ctx, - req.SourceUser.ProviderName + req.SourceUser.ProviderName, ); if (!identityProvider) { throw new IdentityProviderNotFoundError(); diff --git a/src/targets/adminListGroupsForUser.test.ts b/src/targets/adminListGroupsForUser.test.ts index 8f2f91b2..ba2a83d2 100644 --- a/src/targets/adminListGroupsForUser.test.ts +++ b/src/targets/adminListGroupsForUser.test.ts @@ -82,7 +82,7 @@ describe("AdminListGroupsForUser target", () => { adminListGroupsForUser(TestContext, { Username: "user", UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/adminListGroupsForUser.ts b/src/targets/adminListGroupsForUser.ts index 1982b3e4..678419d2 100644 --- a/src/targets/adminListGroupsForUser.ts +++ b/src/targets/adminListGroupsForUser.ts @@ -19,7 +19,7 @@ export const AdminListGroupsForUser = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { @@ -27,7 +27,9 @@ export const AdminListGroupsForUser = } const groups = await userPool.listGroups(ctx); - const usersGroups = groups.filter((x) => x.members?.includes(req.Username!)); + const usersGroups = groups.filter((x) => + x.members?.includes(req.Username!), + ); return { Groups: usersGroups.map(groupToResponseObject(req.UserPoolId)), diff --git a/src/targets/adminRemoveUserFromGroup.test.ts b/src/targets/adminRemoveUserFromGroup.test.ts index 186a6108..ca6fd891 100644 --- a/src/targets/adminRemoveUserFromGroup.test.ts +++ b/src/targets/adminRemoveUserFromGroup.test.ts @@ -39,7 +39,7 @@ describe("AdminRemoveUserFromGroup target", () => { expect(mockUserPoolService.removeUserFromGroup).toHaveBeenCalledWith( TestContext, existingGroup, - existingUser + existingUser, ); }); @@ -54,7 +54,7 @@ describe("AdminRemoveUserFromGroup target", () => { GroupName: "group", Username: existingUser.Username, UserPoolId: "test", - }) + }), ).rejects.toEqual(new GroupNotFoundError()); }); @@ -69,7 +69,7 @@ describe("AdminRemoveUserFromGroup target", () => { GroupName: existingGroup.GroupName, Username: "user", UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/adminRemoveUserFromGroup.ts b/src/targets/adminRemoveUserFromGroup.ts index 2f9c778d..05bff076 100644 --- a/src/targets/adminRemoveUserFromGroup.ts +++ b/src/targets/adminRemoveUserFromGroup.ts @@ -1,5 +1,9 @@ import { AdminRemoveUserFromGroupRequest } from "@aws-sdk/client-cognito-identity-provider"; -import { GroupNotFoundError, MissingParameterError, UserNotFoundError } from "../errors"; +import { + GroupNotFoundError, + MissingParameterError, + UserNotFoundError, +} from "../errors"; import { Services } from "../services"; import { Target } from "./Target"; diff --git a/src/targets/adminSetUserPassword.test.ts b/src/targets/adminSetUserPassword.test.ts index dfbce5a0..8d1e57a7 100644 --- a/src/targets/adminSetUserPassword.test.ts +++ b/src/targets/adminSetUserPassword.test.ts @@ -97,7 +97,7 @@ describe("AdminSetUser target", () => { Password: "Password", Username: "Username", UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError("User does not exist")); }); }); diff --git a/src/targets/adminUpdateUserAttributes.test.ts b/src/targets/adminUpdateUserAttributes.test.ts index 5c687a6e..d46a8521 100644 --- a/src/targets/adminUpdateUserAttributes.test.ts +++ b/src/targets/adminUpdateUserAttributes.test.ts @@ -43,7 +43,7 @@ describe("AdminUpdateUserAttributes target", () => { UserPoolId: "test", UserAttributes: [{ Name: "custom:example", Value: "1" }], Username: "abc", - }) + }), ).rejects.toEqual(new NotAuthorizedError()); }); @@ -71,7 +71,7 @@ describe("AdminUpdateUserAttributes target", () => { ...user, Attributes: attributesAppend( user.Attributes, - attribute("custom:example", "1") + attribute("custom:example", "1"), ), UserLastModifiedDate: clock.get(), }); @@ -83,39 +83,48 @@ describe("AdminUpdateUserAttributes target", () => { ${"an attribute which isn't mutable in the schema"} | ${"custom:immutable"} | ${"user.custom:immutable: Attribute cannot be updated. (changing an immutable attribute)"} ${"email_verified without an email attribute"} | ${"email_verified"} | ${"Email is required to verify/un-verify an email"} ${"phone_number_verified without an phone_number attribute"} | ${"phone_number_verified"} | ${"Phone Number is required to verify/un-verify a phone number"} - `("req.UserAttributes contains $desc", ({ attribute, expectedError }: { attribute: string, expectedError: string }) => { - beforeEach(() => { - mockUserPoolService.options.SchemaAttributes = [ - { - Name: "email_verified", - Mutable: true, - }, - { - Name: "phone_number_verified", - Mutable: true, - }, - { - Name: "custom:immutable", - Mutable: false, - }, - ]; - }); + `( + "req.UserAttributes contains $desc", + ({ + attribute, + expectedError, + }: { + attribute: string; + expectedError: string; + }) => { + beforeEach(() => { + mockUserPoolService.options.SchemaAttributes = [ + { + Name: "email_verified", + Mutable: true, + }, + { + Name: "phone_number_verified", + Mutable: true, + }, + { + Name: "custom:immutable", + Mutable: false, + }, + ]; + }); - it("throws an invalid parameter error", async () => { - mockUserPoolService.getUserByUsername.mockResolvedValue(TDB.user()); + it("throws an invalid parameter error", async () => { + mockUserPoolService.getUserByUsername.mockResolvedValue(TDB.user()); - await expect( - adminUpdateUserAttributes(TestContext, { - ClientMetadata: { - client: "metadata", - }, - UserPoolId: "test", - UserAttributes: [{ Name: attribute, Value: "1" }], - Username: "abc", - }) - ).rejects.toEqual(new InvalidParameterError(expectedError)); - }); - }); + await expect( + adminUpdateUserAttributes(TestContext, { + ClientMetadata: { + client: "metadata", + }, + UserPoolId: "test", + UserAttributes: [{ Name: attribute, Value: "1" }], + Username: "abc", + }), + ).rejects.toEqual(new InvalidParameterError(expectedError)); + }); + }, + ); describe.each(["email", "phone_number"])( "%s is in req.UserAttributes without the relevant verified attribute", @@ -139,12 +148,12 @@ describe("AdminUpdateUserAttributes target", () => { Attributes: attributesAppend( user.Attributes, attribute(attr, "new value"), - attribute(`${attr}_verified`, "false") + attribute(`${attr}_verified`, "false"), ), UserLastModifiedDate: clock.get(), }); }); - } + }, ); describe("user pool has auto verified attributes enabled", () => { @@ -157,99 +166,102 @@ describe("AdminUpdateUserAttributes target", () => { ${["email"]} ${["phone_number"]} ${["email", "phone_number"]} - `("when $attributes is unverified", ({ attributes }: { attributes: string[] }) => { - describe("the verification status was not affected by the update", () => { - it("does not deliver a OTP code to the user", async () => { - const user = TDB.user({ - Attributes: attributes.map((attr: string) => - attribute(`${attr}_verified`, "false") - ), - }); + `( + "when $attributes is unverified", + ({ attributes }: { attributes: string[] }) => { + describe("the verification status was not affected by the update", () => { + it("does not deliver a OTP code to the user", async () => { + const user = TDB.user({ + Attributes: attributes.map((attr: string) => + attribute(`${attr}_verified`, "false"), + ), + }); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); - mockUserPoolService.options.SchemaAttributes = [ - { Name: "example", Mutable: true }, - ]; + mockUserPoolService.getUserByUsername.mockResolvedValue(user); + mockUserPoolService.options.SchemaAttributes = [ + { Name: "example", Mutable: true }, + ]; - await adminUpdateUserAttributes(TestContext, { - ClientMetadata: { - client: "metadata", - }, - UserPoolId: "test", - UserAttributes: [attribute("example", "1")], - Username: "abc", - }); + await adminUpdateUserAttributes(TestContext, { + ClientMetadata: { + client: "metadata", + }, + UserPoolId: "test", + UserAttributes: [attribute("example", "1")], + Username: "abc", + }); - expect(mockMessages.deliver).not.toHaveBeenCalled(); + expect(mockMessages.deliver).not.toHaveBeenCalled(); + }); }); - }); - describe("the verification status changed because of the update", () => { - it("throws if the user doesn't have a valid way to contact them", async () => { - const user = TDB.user({ - Attributes: [], + describe("the verification status changed because of the update", () => { + it("throws if the user doesn't have a valid way to contact them", async () => { + const user = TDB.user({ + Attributes: [], + }); + + mockUserPoolService.getUserByUsername.mockResolvedValue(user); + + await expect( + adminUpdateUserAttributes(TestContext, { + ClientMetadata: { + client: "metadata", + }, + UserPoolId: "test", + UserAttributes: attributes.map((attr: string) => + attribute(attr, "new value"), + ), + Username: "abc", + }), + ).rejects.toEqual( + new InvalidParameterError( + "User has no attribute matching desired auto verified attributes", + ), + ); }); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); + it("delivers a OTP code to the user", async () => { + const user = TDB.user(); + + mockUserPoolService.getUserByUsername.mockResolvedValue(user); - await expect( - adminUpdateUserAttributes(TestContext, { + await adminUpdateUserAttributes(TestContext, { ClientMetadata: { client: "metadata", }, UserPoolId: "test", UserAttributes: attributes.map((attr: string) => - attribute(attr, "new value") + attribute(attr, "new value"), ), Username: "abc", - }) - ).rejects.toEqual( - new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" - ) - ); - }); - - it("delivers a OTP code to the user", async () => { - const user = TDB.user(); - - mockUserPoolService.getUserByUsername.mockResolvedValue(user); - - await adminUpdateUserAttributes(TestContext, { - ClientMetadata: { - client: "metadata", - }, - UserPoolId: "test", - UserAttributes: attributes.map((attr: string) => - attribute(attr, "new value") - ), - Username: "abc", + }); + + expect(mockMessages.deliver).toHaveBeenCalledWith( + TestContext, + "UpdateUserAttribute", + null, + "test", + user, + "123456", + { client: "metadata" }, + { + AttributeName: "email", + DeliveryMedium: "EMAIL", + Destination: attributeValue("email", user.Attributes), + }, + ); + + expect(mockUserPoolService.saveUser).toHaveBeenCalledWith( + TestContext, + expect.objectContaining({ + AttributeVerificationCode: "123456", + }), + ); }); - - expect(mockMessages.deliver).toHaveBeenCalledWith( - TestContext, - "UpdateUserAttribute", - null, - "test", - user, - "123456", - { client: "metadata" }, - { - AttributeName: "email", - DeliveryMedium: "EMAIL", - Destination: attributeValue("email", user.Attributes), - } - ); - - expect(mockUserPoolService.saveUser).toHaveBeenCalledWith( - TestContext, - expect.objectContaining({ - AttributeVerificationCode: "123456", - }) - ); }); - }); - }); + }, + ); }); describe("user pool does not have auto verified attributes", () => { @@ -262,53 +274,56 @@ describe("AdminUpdateUserAttributes target", () => { ${["email"]} ${["phone_number"]} ${["email", "phone_number"]} - `("when $attributes is unverified", ({ attributes }: { attributes: string[] }) => { - describe("the verification status was not affected by the update", () => { - it("does not deliver a OTP code to the user", async () => { - const user = TDB.user({ - Attributes: attributes.map((attr: string) => - attribute(`${attr}_verified`, "false") - ), - }); + `( + "when $attributes is unverified", + ({ attributes }: { attributes: string[] }) => { + describe("the verification status was not affected by the update", () => { + it("does not deliver a OTP code to the user", async () => { + const user = TDB.user({ + Attributes: attributes.map((attr: string) => + attribute(`${attr}_verified`, "false"), + ), + }); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); - mockUserPoolService.options.SchemaAttributes = [ - { Name: "example", Mutable: true }, - ]; + mockUserPoolService.getUserByUsername.mockResolvedValue(user); + mockUserPoolService.options.SchemaAttributes = [ + { Name: "example", Mutable: true }, + ]; - await adminUpdateUserAttributes(TestContext, { - ClientMetadata: { - client: "metadata", - }, - UserPoolId: "test", - UserAttributes: [attribute("example", "1")], - Username: "abc", - }); + await adminUpdateUserAttributes(TestContext, { + ClientMetadata: { + client: "metadata", + }, + UserPoolId: "test", + UserAttributes: [attribute("example", "1")], + Username: "abc", + }); - expect(mockMessages.deliver).not.toHaveBeenCalled(); + expect(mockMessages.deliver).not.toHaveBeenCalled(); + }); }); - }); - describe("the verification status changed because of the update", () => { - it("does not deliver a OTP code to the user", async () => { - const user = TDB.user(); + describe("the verification status changed because of the update", () => { + it("does not deliver a OTP code to the user", async () => { + const user = TDB.user(); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); + mockUserPoolService.getUserByUsername.mockResolvedValue(user); - await adminUpdateUserAttributes(TestContext, { - ClientMetadata: { - client: "metadata", - }, - UserPoolId: "test", - UserAttributes: attributes.map((attr: string) => - attribute(attr, "new value") - ), - Username: "abc", - }); + await adminUpdateUserAttributes(TestContext, { + ClientMetadata: { + client: "metadata", + }, + UserPoolId: "test", + UserAttributes: attributes.map((attr: string) => + attribute(attr, "new value"), + ), + Username: "abc", + }); - expect(mockMessages.deliver).not.toHaveBeenCalled(); + expect(mockMessages.deliver).not.toHaveBeenCalled(); + }); }); - }); - }); + }, + ); }); }); diff --git a/src/targets/adminUpdateUserAttributes.ts b/src/targets/adminUpdateUserAttributes.ts index e2e491d0..4bc1c8d3 100644 --- a/src/targets/adminUpdateUserAttributes.ts +++ b/src/targets/adminUpdateUserAttributes.ts @@ -2,7 +2,11 @@ import { AdminUpdateUserAttributesRequest, AdminUpdateUserAttributesResponse, } from "@aws-sdk/client-cognito-identity-provider"; -import { InvalidParameterError, MissingParameterError, NotAuthorizedError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + NotAuthorizedError, +} from "../errors"; import { Messages, Services, UserPoolService } from "../services"; import { USER_POOL_AWS_DEFAULTS } from "../services/cognitoService"; import { selectAppropriateDeliveryMethod } from "../services/messageDelivery/deliveryMethod"; @@ -22,16 +26,16 @@ const sendAttributeVerificationCode = async ( user: User, messages: Messages, req: AdminUpdateUserAttributesRequest, - code: string + code: string, ) => { const deliveryDetails = selectAppropriateDeliveryMethod( userPool.options.AutoVerifiedAttributes ?? [], - user + user, ); if (!deliveryDetails) { // TODO: I don't know what the real error message should be for this throw new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" + "User has no attribute matching desired auto verified attributes", ); } @@ -43,7 +47,7 @@ const sendAttributeVerificationCode = async ( user, code, req.ClientMetadata, - deliveryDetails + deliveryDetails, ); }; @@ -84,8 +88,8 @@ export const AdminUpdateUserAttributes = // fail. userPool.options.SchemaAttributes ?? USER_POOL_AWS_DEFAULTS.SchemaAttributes ?? - [] - ) + [], + ), ); const updatedUser = { @@ -115,7 +119,7 @@ export const AdminUpdateUserAttributes = user, messages, req, - code + code, ); } diff --git a/src/targets/changePassword.test.ts b/src/targets/changePassword.test.ts index 6ba8456d..761d3e5f 100644 --- a/src/targets/changePassword.test.ts +++ b/src/targets/changePassword.test.ts @@ -34,7 +34,7 @@ describe("ChangePassword target", () => { AccessToken: "blah", PreviousPassword: "abc", ProposedPassword: "def", - }) + }), ).rejects.toBeInstanceOf(InvalidParameterError); expect(mockUserPoolService.saveUser).not.toHaveBeenCalled(); @@ -62,11 +62,11 @@ describe("ChangePassword target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), PreviousPassword: "abc", ProposedPassword: "def", - }) + }), ).rejects.toEqual(new NotAuthorizedError()); expect(mockUserPoolService.saveUser).not.toHaveBeenCalled(); @@ -98,11 +98,11 @@ describe("ChangePassword target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), PreviousPassword: "abc", ProposedPassword: "def", - }) + }), ).rejects.toEqual(new InvalidPasswordError()); expect(mockUserPoolService.saveUser).not.toHaveBeenCalled(); @@ -133,7 +133,7 @@ describe("ChangePassword target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), PreviousPassword: "previous-password", ProposedPassword: "new-password", diff --git a/src/targets/changePassword.ts b/src/targets/changePassword.ts index 2c4114b4..98546b63 100644 --- a/src/targets/changePassword.ts +++ b/src/targets/changePassword.ts @@ -24,8 +24,9 @@ export const ChangePassword = ({ cognito, clock }: ChangePasswordServices): ChangePasswordTarget => async (ctx, req) => { if (!req.AccessToken) throw new MissingParameterError("AccessToken"); - if (!req.ProposedPassword) throw new MissingParameterError("ProposedPassword"); - + if (!req.ProposedPassword) + throw new MissingParameterError("ProposedPassword"); + const decodedToken = jwt.decode(req.AccessToken) as Token | null; if (!decodedToken) { ctx.logger.info("Unable to decode token"); @@ -34,7 +35,7 @@ export const ChangePassword = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.username); if (!user) { diff --git a/src/targets/confirmForgotPassword.test.ts b/src/targets/confirmForgotPassword.test.ts index f5fd7e01..ab86736a 100644 --- a/src/targets/confirmForgotPassword.test.ts +++ b/src/targets/confirmForgotPassword.test.ts @@ -42,7 +42,7 @@ describe("ConfirmForgotPassword target", () => { Username: "janice", ConfirmationCode: "123456", Password: "newPassword", - }) + }), ).rejects.toBeInstanceOf(UserNotFoundError); }); @@ -60,7 +60,7 @@ describe("ConfirmForgotPassword target", () => { Username: "janice", ConfirmationCode: "123456", Password: "newPassword", - }) + }), ).rejects.toBeInstanceOf(CodeMismatchError); }); @@ -123,11 +123,11 @@ describe("ConfirmForgotPassword target", () => { source: "PostConfirmation_ConfirmForgotPassword", userAttributes: attributesAppend( user.Attributes, - attribute("cognito:user_status", "CONFIRMED") + attribute("cognito:user_status", "CONFIRMED"), ), userPoolId: "test", username: user.Username, - } + }, ); }); }); diff --git a/src/targets/confirmForgotPassword.ts b/src/targets/confirmForgotPassword.ts index 26615586..4551cdf0 100644 --- a/src/targets/confirmForgotPassword.ts +++ b/src/targets/confirmForgotPassword.ts @@ -3,7 +3,11 @@ import { ConfirmForgotPasswordResponse, UserStatusType, } from "@aws-sdk/client-cognito-identity-provider"; -import { CodeMismatchError, MissingParameterError, UserNotFoundError } from "../errors"; +import { + CodeMismatchError, + MissingParameterError, + UserNotFoundError, +} from "../errors"; import { Services } from "../services"; import { attribute, attributesAppend } from "../services/userPoolService"; import { Target } from "./Target"; @@ -28,7 +32,7 @@ export const ConfirmForgotPassword = if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.Username) throw new MissingParameterError("Username"); if (!req.Password) throw new MissingParameterError("Password"); - + const userPool = await cognito.getUserPoolForClientId(ctx, req.ClientId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { @@ -61,7 +65,7 @@ export const ConfirmForgotPassword = // into every place we send attributes to lambdas userAttributes: attributesAppend( updatedUser.Attributes, - attribute("cognito:user_status", updatedUser.UserStatus) + attribute("cognito:user_status", updatedUser.UserStatus), ), }); } diff --git a/src/targets/confirmSignUp.test.ts b/src/targets/confirmSignUp.test.ts index e8d29bcb..eabcd611 100644 --- a/src/targets/confirmSignUp.test.ts +++ b/src/targets/confirmSignUp.test.ts @@ -38,7 +38,7 @@ describe("ConfirmSignUp target", () => { Username: "janice", ConfirmationCode: "123456", ForceAliasCreation: false, - }) + }), ).rejects.toBeInstanceOf(NotAuthorizedError); }); @@ -55,7 +55,7 @@ describe("ConfirmSignUp target", () => { ClientId: "clientId", Username: user.Username, ConfirmationCode: "123456", - }) + }), ).rejects.toBeInstanceOf(CodeMismatchError); }); @@ -116,11 +116,11 @@ describe("ConfirmSignUp target", () => { source: "PostConfirmation_ConfirmSignUp", userAttributes: attributesAppend( user.Attributes, - attribute("cognito:user_status", "CONFIRMED") + attribute("cognito:user_status", "CONFIRMED"), ), userPoolId: "test", username: user.Username, - } + }, ); }); }); diff --git a/src/targets/confirmSignUp.ts b/src/targets/confirmSignUp.ts index 43973a53..2674163a 100644 --- a/src/targets/confirmSignUp.ts +++ b/src/targets/confirmSignUp.ts @@ -27,7 +27,7 @@ export const ConfirmSignUp = async (ctx, req) => { if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.Username) throw new MissingParameterError("Username"); - + const userPool = await cognito.getUserPoolForClientId(ctx, req.ClientId); const user = await userPool.getUserByUsername(ctx, req.Username); if (!user) { @@ -63,7 +63,7 @@ export const ConfirmSignUp = // into every place we send attributes to lambdas userAttributes: attributesAppend( updatedUser.Attributes, - attribute("cognito:user_status", updatedUser.UserStatus) + attribute("cognito:user_status", updatedUser.UserStatus), ), }); } diff --git a/src/targets/createGroup.ts b/src/targets/createGroup.ts index f813ff97..9b802c4f 100644 --- a/src/targets/createGroup.ts +++ b/src/targets/createGroup.ts @@ -17,7 +17,7 @@ export const CreateGroup = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.GroupName) throw new MissingParameterError("GroupName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const now = clock.get(); diff --git a/src/targets/createIdentityProvider.ts b/src/targets/createIdentityProvider.ts index cef586f9..7e10dffc 100644 --- a/src/targets/createIdentityProvider.ts +++ b/src/targets/createIdentityProvider.ts @@ -23,7 +23,7 @@ export const CreateIdentityProvider = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.ProviderName) throw new MissingParameterError("ProviderName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const now = clock.get(); @@ -42,7 +42,7 @@ export const CreateIdentityProvider = return { IdentityProvider: identityProviderToResponseObject(req.UserPoolId)( - identityProvider + identityProvider, ), }; }; diff --git a/src/targets/createUserPool.test.ts b/src/targets/createUserPool.test.ts index 33249140..c51fb44c 100644 --- a/src/targets/createUserPool.test.ts +++ b/src/targets/createUserPool.test.ts @@ -33,14 +33,14 @@ describe("CreateUserPool target", () => { TestContext, { Arn: expect.stringMatching( - /^arn:aws:cognito-idp:local:local:userpool\/local_[\w\d]{8}$/ + /^arn:aws:cognito-idp:local:local:userpool\/local_[\w\d]{8}$/, ), CreationDate: originalDate, Id: expect.stringMatching(/^local_[\w\d]{8}$/), LastModifiedDate: originalDate, Name: "test-pool", SchemaAttributes: USER_POOL_AWS_DEFAULTS.SchemaAttributes, - } + }, ); expect(result).toEqual({ @@ -66,7 +66,7 @@ describe("CreateUserPool target", () => { TestContext, { Arn: expect.stringMatching( - /^arn:aws:cognito-idp:local:local:userpool\/local_[\w\d]{8}$/ + /^arn:aws:cognito-idp:local:local:userpool\/local_[\w\d]{8}$/, ), CreationDate: originalDate, Id: expect.stringMatching(/^local_[\w\d]{8}$/), @@ -83,7 +83,7 @@ describe("CreateUserPool target", () => { StringAttributeConstraints: {}, }, ], - } + }, ); expect(result).toEqual({ @@ -110,7 +110,7 @@ describe("CreateUserPool target", () => { TestContext, { Arn: expect.stringMatching( - /^arn:aws:cognito-idp:local:local:userpool\/local_[\w\d]{8}$/ + /^arn:aws:cognito-idp:local:local:userpool\/local_[\w\d]{8}$/, ), CreationDate: originalDate, Id: expect.stringMatching(/^local_[\w\d]{8}$/), @@ -329,7 +329,7 @@ describe("CreateUserPool target", () => { }, }, ], - } + }, ); expect(result).toEqual({ diff --git a/src/targets/createUserPool.ts b/src/targets/createUserPool.ts index 618ff0c2..a97599fc 100644 --- a/src/targets/createUserPool.ts +++ b/src/targets/createUserPool.ts @@ -13,7 +13,7 @@ const REGION = "local"; const ACCOUNT_ID = "local"; const generator = shortUUID( - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", ); export type CreateUserPoolTarget = Target< @@ -33,10 +33,10 @@ type CreateUserPoolServices = Pick; */ const createSchemaAttributes = ( defaultAttributes: SchemaAttributeType[], - requestSchema: SchemaAttributeType[] + requestSchema: SchemaAttributeType[], ): SchemaAttributeType[] => { const overrides = Object.fromEntries( - requestSchema.map((x) => [x.Name as string, x]) + requestSchema.map((x) => [x.Name as string, x]), ); const defaultAttributeNames = defaultAttributes.map((x) => x.Name); const overriddenAttributes = defaultAttributes.map((attr) => { @@ -62,9 +62,13 @@ const createSchemaAttributes = ( Mutable: attr.Mutable ?? true, Required: attr.Required ?? false, StringAttributeConstraints: - type === "String" ? attr.StringAttributeConstraints ?? {} : undefined, + type === "String" + ? (attr.StringAttributeConstraints ?? {}) + : undefined, NumberAttributeConstraints: - type === "Number" ? attr.NumberAttributeConstraints ?? {} : undefined, + type === "Number" + ? (attr.NumberAttributeConstraints ?? {}) + : undefined, }; }); @@ -95,7 +99,7 @@ export const CreateUserPool = Policies: req.Policies, SchemaAttributes: createSchemaAttributes( USER_POOL_AWS_DEFAULTS.SchemaAttributes ?? [], - req.Schema ?? [] + req.Schema ?? [], ), SmsAuthenticationMessage: req.SmsAuthenticationMessage, SmsConfiguration: req.SmsConfiguration, diff --git a/src/targets/createUserPoolClient.test.ts b/src/targets/createUserPoolClient.test.ts index 759a689f..6dc2ad1d 100644 --- a/src/targets/createUserPoolClient.test.ts +++ b/src/targets/createUserPoolClient.test.ts @@ -41,7 +41,7 @@ describe("CreateUserPoolClient target", () => { IdToken: "minutes", RefreshToken: "days", }, - } + }, ); expect(result).toEqual({ diff --git a/src/targets/createUserPoolClient.ts b/src/targets/createUserPoolClient.ts index 424fc79a..87f1245b 100644 --- a/src/targets/createUserPoolClient.ts +++ b/src/targets/createUserPoolClient.ts @@ -23,7 +23,7 @@ export const CreateUserPoolClient = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.ClientName) throw new MissingParameterError("ClientName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const appClient: AppClient = { diff --git a/src/targets/deleteGroup.test.ts b/src/targets/deleteGroup.test.ts index c8ea22e6..3d12747d 100644 --- a/src/targets/deleteGroup.test.ts +++ b/src/targets/deleteGroup.test.ts @@ -30,7 +30,7 @@ describe("DeleteGroup target", () => { expect(mockUserPoolService.deleteGroup).toHaveBeenCalledWith( TestContext, - existingGroup + existingGroup, ); }); @@ -41,7 +41,7 @@ describe("DeleteGroup target", () => { deleteGroup(TestContext, { GroupName: "group", UserPoolId: "test", - }) + }), ).rejects.toEqual(new GroupNotFoundError()); }); }); diff --git a/src/targets/deleteGroup.ts b/src/targets/deleteGroup.ts index 184e08ee..2311e52c 100644 --- a/src/targets/deleteGroup.ts +++ b/src/targets/deleteGroup.ts @@ -3,8 +3,7 @@ import { GroupNotFoundError, MissingParameterError } from "../errors"; import { Services } from "../services"; import { Target } from "./Target"; -export type DeleteGroupTarget = Target< - DeleteGroupRequest, object>; +export type DeleteGroupTarget = Target; type DeleteGroupServices = Pick; @@ -13,7 +12,7 @@ export const DeleteGroup = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.GroupName) throw new MissingParameterError("GroupName"); - + // TODO: from the docs "Calling this action requires developer credentials.", can we enforce this? const userPool = await cognito.getUserPool(ctx, req.UserPoolId); diff --git a/src/targets/deleteIdentityProvider.test.ts b/src/targets/deleteIdentityProvider.test.ts index 298e89d0..39853200 100644 --- a/src/targets/deleteIdentityProvider.test.ts +++ b/src/targets/deleteIdentityProvider.test.ts @@ -25,7 +25,7 @@ describe("DeleteIdentityProvider target", () => { const existingIdentityProvider = TDB.identityProvider(); mockUserPoolService.getIdentityProviderByProviderName.mockResolvedValue( - existingIdentityProvider + existingIdentityProvider, ); await deleteIdentityProvider(TestContext, { @@ -35,7 +35,7 @@ describe("DeleteIdentityProvider target", () => { expect(mockUserPoolService.deleteIdentityProvider).toHaveBeenCalledWith( TestContext, - existingIdentityProvider + existingIdentityProvider, ); }); @@ -46,7 +46,7 @@ describe("DeleteIdentityProvider target", () => { deleteIdentityProvider(TestContext, { ProviderName: "identityProvider", UserPoolId: "test", - }) + }), ).rejects.toEqual(new IdentityProviderNotFoundError()); }); }); diff --git a/src/targets/deleteIdentityProvider.ts b/src/targets/deleteIdentityProvider.ts index 523c6ffd..a3ef2bf2 100644 --- a/src/targets/deleteIdentityProvider.ts +++ b/src/targets/deleteIdentityProvider.ts @@ -1,5 +1,8 @@ import { DeleteIdentityProviderRequest } from "@aws-sdk/client-cognito-identity-provider"; -import { IdentityProviderNotFoundError, MissingParameterError } from "../errors"; +import { + IdentityProviderNotFoundError, + MissingParameterError, +} from "../errors"; import { Services } from "../services"; import { Target } from "./Target"; @@ -15,11 +18,11 @@ export const DeleteIdentityProvider = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.ProviderName) throw new MissingParameterError("ProviderName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const group = await userPool.getIdentityProviderByProviderName( ctx, - req.ProviderName + req.ProviderName, ); if (!group) { throw new IdentityProviderNotFoundError(); diff --git a/src/targets/deleteUser.test.ts b/src/targets/deleteUser.test.ts index 929d042c..88006317 100644 --- a/src/targets/deleteUser.test.ts +++ b/src/targets/deleteUser.test.ts @@ -43,13 +43,13 @@ describe("DeleteUser target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), }); expect(mockUserPoolService.deleteUser).toHaveBeenCalledWith( TestContext, - user + user, ); }); @@ -57,7 +57,7 @@ describe("DeleteUser target", () => { await expect( deleteUser(TestContext, { AccessToken: "blah", - }) + }), ).rejects.toBeInstanceOf(InvalidParameterError); }); @@ -83,9 +83,9 @@ describe("DeleteUser target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), - }) + }), ).rejects.toEqual(new NotAuthorizedError()); }); }); diff --git a/src/targets/deleteUser.ts b/src/targets/deleteUser.ts index 32270543..b5f7a3e5 100644 --- a/src/targets/deleteUser.ts +++ b/src/targets/deleteUser.ts @@ -1,6 +1,10 @@ import { DeleteUserRequest } from "@aws-sdk/client-cognito-identity-provider"; import jwt from "jsonwebtoken"; -import { InvalidParameterError, MissingParameterError, NotAuthorizedError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + NotAuthorizedError, +} from "../errors"; import { Services } from "../services"; import { Token } from "../services/tokenGenerator"; import { Target } from "./Target"; @@ -13,7 +17,7 @@ export const DeleteUser = ({ cognito }: DeleteUserServices): DeleteUserTarget => async (ctx, req) => { if (!req.AccessToken) throw new MissingParameterError("AccessToken"); - + const decodedToken = jwt.decode(req.AccessToken) as Token | null; if (!decodedToken) { ctx.logger.info("Unable to decode token"); @@ -22,7 +26,7 @@ export const DeleteUser = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.sub); if (!user) { diff --git a/src/targets/deleteUserAttributes.test.ts b/src/targets/deleteUserAttributes.test.ts index c0255416..825f592a 100644 --- a/src/targets/deleteUserAttributes.test.ts +++ b/src/targets/deleteUserAttributes.test.ts @@ -33,7 +33,7 @@ const validToken = jwt.sign( issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ); describe("DeleteUserAttributes target", () => { @@ -55,7 +55,7 @@ describe("DeleteUserAttributes target", () => { deleteUserAttributes(TestContext, { AccessToken: validToken, UserAttributeNames: ["custom:example"], - }) + }), ).rejects.toEqual(new NotAuthorizedError()); }); @@ -64,7 +64,7 @@ describe("DeleteUserAttributes target", () => { deleteUserAttributes(TestContext, { AccessToken: "invalid token", UserAttributeNames: ["custom:example"], - }) + }), ).rejects.toEqual(new InvalidParameterError()); }); diff --git a/src/targets/deleteUserAttributes.ts b/src/targets/deleteUserAttributes.ts index 6f2b8a8a..8e931f25 100644 --- a/src/targets/deleteUserAttributes.ts +++ b/src/targets/deleteUserAttributes.ts @@ -3,7 +3,11 @@ import { DeleteUserAttributesResponse, } from "@aws-sdk/client-cognito-identity-provider"; import jwt from "jsonwebtoken"; -import { InvalidParameterError, MissingParameterError, NotAuthorizedError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + NotAuthorizedError, +} from "../errors"; import { Services } from "../services"; import { Token } from "../services/tokenGenerator"; import { attributesRemove } from "../services/userPoolService"; @@ -23,8 +27,9 @@ export const DeleteUserAttributes = }: DeleteUserAttributesServices): DeleteUserAttributesTarget => async (ctx, req) => { if (!req.AccessToken) throw new MissingParameterError("AccessToken"); - if (!req.UserAttributeNames) throw new MissingParameterError("UserAttributeNames"); - + if (!req.UserAttributeNames) + throw new MissingParameterError("UserAttributeNames"); + const decodedToken = jwt.decode(req.AccessToken) as Token | null; if (!decodedToken) { ctx.logger.info("Unable to decode token"); @@ -33,7 +38,7 @@ export const DeleteUserAttributes = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.sub); if (!user) { diff --git a/src/targets/deleteUserPool.test.ts b/src/targets/deleteUserPool.test.ts index 059a74ec..c65798a8 100644 --- a/src/targets/deleteUserPool.test.ts +++ b/src/targets/deleteUserPool.test.ts @@ -21,7 +21,7 @@ describe("DeleteUserPool target", () => { const userPool = TDB.userPool(); mockCognitoService.getUserPool.mockResolvedValue( - newMockUserPoolService(userPool) + newMockUserPoolService(userPool), ); await deleteUserPool(TestContext, { @@ -30,7 +30,7 @@ describe("DeleteUserPool target", () => { expect(mockCognitoService.deleteUserPool).toHaveBeenCalledWith( TestContext, - userPool + userPool, ); }); diff --git a/src/targets/deleteUserPool.ts b/src/targets/deleteUserPool.ts index 6f50fa9b..85c830b7 100644 --- a/src/targets/deleteUserPool.ts +++ b/src/targets/deleteUserPool.ts @@ -3,10 +3,7 @@ import { MissingParameterError, ResourceNotFoundError } from "../errors"; import { Services } from "../services"; import { Target } from "./Target"; -export type DeleteUserPoolTarget = Target< - DeleteUserPoolRequest, - object ->; +export type DeleteUserPoolTarget = Target; type DeleteUserPoolServices = Pick; @@ -14,7 +11,7 @@ export const DeleteUserPool = ({ cognito }: DeleteUserPoolServices): DeleteUserPoolTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + // TODO: from the docs "Calling this action requires developer credentials.", can we enforce this? const userPool = await cognito.getUserPool(ctx, req.UserPoolId); if (!userPool) { diff --git a/src/targets/deleteUserPoolClient.test.ts b/src/targets/deleteUserPoolClient.test.ts index b55abfb7..23ca2472 100644 --- a/src/targets/deleteUserPoolClient.test.ts +++ b/src/targets/deleteUserPoolClient.test.ts @@ -37,7 +37,7 @@ describe("DeleteUserPoolClient target", () => { expect(mockUserPoolService.deleteAppClient).toHaveBeenCalledWith( TestContext, - existingAppClient + existingAppClient, ); }); @@ -48,7 +48,7 @@ describe("DeleteUserPoolClient target", () => { deleteUserPoolClient(TestContext, { ClientId: "clientId", UserPoolId: "test", - }) + }), ).rejects.toEqual(new ResourceNotFoundError()); }); @@ -64,7 +64,7 @@ describe("DeleteUserPoolClient target", () => { deleteUserPoolClient(TestContext, { ClientId: "clientId", UserPoolId: "pool-two", - }) + }), ).rejects.toEqual(new ResourceNotFoundError()); }); }); diff --git a/src/targets/deleteUserPoolClient.ts b/src/targets/deleteUserPoolClient.ts index ab1d79d0..b0efa7a0 100644 --- a/src/targets/deleteUserPoolClient.ts +++ b/src/targets/deleteUserPoolClient.ts @@ -15,7 +15,7 @@ export const DeleteUserPoolClient = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.ClientId) throw new MissingParameterError("ClientId"); - + // TODO: from the docs "Calling this action requires developer credentials.", can we enforce this? const userPool = await cognito.getUserPool(ctx, req.UserPoolId); diff --git a/src/targets/describeIdentityProvider.test.ts b/src/targets/describeIdentityProvider.test.ts index de982456..c8d425bb 100644 --- a/src/targets/describeIdentityProvider.test.ts +++ b/src/targets/describeIdentityProvider.test.ts @@ -25,7 +25,7 @@ describe("DescribeIdentityProvider target", () => { const existingGroup = TDB.identityProvider(); mockUserPoolService.getIdentityProviderByProviderName.mockResolvedValue( - existingGroup + existingGroup, ); const result = await describeIdentityProvider(TestContext, { @@ -34,7 +34,7 @@ describe("DescribeIdentityProvider target", () => { }); expect( - mockUserPoolService.getIdentityProviderByProviderName + mockUserPoolService.getIdentityProviderByProviderName, ).toHaveBeenCalledWith(TestContext, existingGroup.ProviderName); expect(result.IdentityProvider).toEqual({ @@ -51,14 +51,14 @@ describe("DescribeIdentityProvider target", () => { it("throws if the identity provider doesn't exist", async () => { mockUserPoolService.getIdentityProviderByProviderName.mockResolvedValue( - null + null, ); await expect( describeIdentityProvider(TestContext, { ProviderName: "identityProvider", UserPoolId: "test", - }) + }), ).rejects.toEqual(new IdentityProviderNotFoundError()); }); }); diff --git a/src/targets/describeIdentityProvider.ts b/src/targets/describeIdentityProvider.ts index 9c41a43c..cb90b2a4 100644 --- a/src/targets/describeIdentityProvider.ts +++ b/src/targets/describeIdentityProvider.ts @@ -2,7 +2,10 @@ import { DescribeIdentityProviderRequest, DescribeIdentityProviderResponse, } from "@aws-sdk/client-cognito-identity-provider"; -import { IdentityProviderNotFoundError, MissingParameterError } from "../errors"; +import { + IdentityProviderNotFoundError, + MissingParameterError, +} from "../errors"; import { Services } from "../services"; import { identityProviderToResponseObject } from "./responses"; import { Target } from "./Target"; @@ -17,11 +20,11 @@ export const DescribeIdentityProvider = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.ProviderName) throw new MissingParameterError("ProviderName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const identityProvider = await userPool.getIdentityProviderByProviderName( ctx, - req.ProviderName + req.ProviderName, ); if (!identityProvider) { throw new IdentityProviderNotFoundError(); @@ -29,7 +32,7 @@ export const DescribeIdentityProvider = return { IdentityProvider: identityProviderToResponseObject(req.UserPoolId)( - identityProvider + identityProvider, ), }; }; diff --git a/src/targets/describeUserPool.test.ts b/src/targets/describeUserPool.test.ts index 9e34c07f..3fba8d2f 100644 --- a/src/targets/describeUserPool.test.ts +++ b/src/targets/describeUserPool.test.ts @@ -19,7 +19,7 @@ describe("DescribeUserPool target", () => { it("returns an existing user pool", async () => { const existingUserPool = TDB.userPool(); mockCognitoService.getUserPool.mockResolvedValue( - newMockUserPoolService(existingUserPool) + newMockUserPoolService(existingUserPool), ); const result = await describeUserPool(TestContext, { diff --git a/src/targets/describeUserPool.ts b/src/targets/describeUserPool.ts index dfa5d5fd..508d2387 100644 --- a/src/targets/describeUserPool.ts +++ b/src/targets/describeUserPool.ts @@ -16,7 +16,7 @@ export const DescribeUserPool = ({ cognito }: Pick): DescribeUserPoolTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); if (!userPool) { throw new ResourceNotFoundError(); diff --git a/src/targets/describeUserPoolClient.test.ts b/src/targets/describeUserPoolClient.test.ts index f8206362..9555af4e 100644 --- a/src/targets/describeUserPoolClient.test.ts +++ b/src/targets/describeUserPoolClient.test.ts @@ -53,7 +53,7 @@ describe("DescribeUserPoolClient target", () => { describeUserPoolClient(TestContext, { ClientId: "abc", UserPoolId: "userPoolId", - }) + }), ).rejects.toEqual(new ResourceNotFoundError()); }); }); diff --git a/src/targets/forgotPassword.test.ts b/src/targets/forgotPassword.test.ts index 523c1f54..1cb1af95 100644 --- a/src/targets/forgotPassword.test.ts +++ b/src/targets/forgotPassword.test.ts @@ -36,7 +36,7 @@ describe("ForgotPassword target", () => { forgotPassword(TestContext, { ClientId: "clientId", Username: "0000-0000", - }) + }), ).rejects.toBeInstanceOf(UserNotFoundError); }); @@ -63,7 +63,7 @@ describe("ForgotPassword target", () => { AttributeName: "email", DeliveryMedium: "EMAIL", Destination: attributeValue("email", user.Attributes), - } + }, ); expect(result).toEqual({ diff --git a/src/targets/forgotPassword.ts b/src/targets/forgotPassword.ts index 1da89341..04a9d7c7 100644 --- a/src/targets/forgotPassword.ts +++ b/src/targets/forgotPassword.ts @@ -2,7 +2,11 @@ import { ForgotPasswordRequest, ForgotPasswordResponse, } from "@aws-sdk/client-cognito-identity-provider"; -import { MissingParameterError, UnsupportedError, UserNotFoundError } from "../errors"; +import { + MissingParameterError, + UnsupportedError, + UserNotFoundError, +} from "../errors"; import { Services } from "../services"; import { DeliveryDetails } from "../services/messageDelivery/messageDelivery"; import { attributeValue } from "../services/userPoolService"; @@ -57,7 +61,7 @@ export const ForgotPassword = user, code, req.ClientMetadata, - deliveryDetails + deliveryDetails, ); await userPool.saveUser(ctx, { diff --git a/src/targets/getGroup.test.ts b/src/targets/getGroup.test.ts index c791dcaa..a180df3c 100644 --- a/src/targets/getGroup.test.ts +++ b/src/targets/getGroup.test.ts @@ -30,7 +30,7 @@ describe("GetGroup target", () => { expect(mockUserPoolService.getGroupByGroupName).toHaveBeenCalledWith( TestContext, - existingGroup.GroupName + existingGroup.GroupName, ); expect(result.Group).toEqual({ @@ -50,7 +50,7 @@ describe("GetGroup target", () => { getGroup(TestContext, { GroupName: "group", UserPoolId: "test", - }) + }), ).rejects.toEqual(new GroupNotFoundError()); }); }); diff --git a/src/targets/getGroup.ts b/src/targets/getGroup.ts index 81c899c9..532e6f9d 100644 --- a/src/targets/getGroup.ts +++ b/src/targets/getGroup.ts @@ -14,7 +14,7 @@ export const GetGroup = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.GroupName) throw new MissingParameterError("GroupName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const group = await userPool.getGroupByGroupName(ctx, req.GroupName); if (!group) { diff --git a/src/targets/getIdentityProviderByIdentifier.test.ts b/src/targets/getIdentityProviderByIdentifier.test.ts index 7208d289..ab2e1c75 100644 --- a/src/targets/getIdentityProviderByIdentifier.test.ts +++ b/src/targets/getIdentityProviderByIdentifier.test.ts @@ -28,7 +28,7 @@ describe("GetIdentityProviderByIdentifier target", () => { }); mockUserPoolService.getIdentityProviderByIdentifier.mockResolvedValue( - existingIdentityProvider + existingIdentityProvider, ); const result = await getIdentityProviderByIdentifier(TestContext, { @@ -37,7 +37,7 @@ describe("GetIdentityProviderByIdentifier target", () => { }); expect( - mockUserPoolService.getIdentityProviderByIdentifier + mockUserPoolService.getIdentityProviderByIdentifier, ).toHaveBeenCalledWith(TestContext, IdpIdentifier); expect(result.IdentityProvider).toEqual({ @@ -59,7 +59,7 @@ describe("GetIdentityProviderByIdentifier target", () => { getIdentityProviderByIdentifier(TestContext, { IdpIdentifier: "identifier", UserPoolId: "test", - }) + }), ).rejects.toEqual(new IdentityProviderNotFoundError()); }); }); diff --git a/src/targets/getIdentityProviderByIdentifier.ts b/src/targets/getIdentityProviderByIdentifier.ts index 85ee4628..406c2fc5 100644 --- a/src/targets/getIdentityProviderByIdentifier.ts +++ b/src/targets/getIdentityProviderByIdentifier.ts @@ -2,7 +2,10 @@ import { GetIdentityProviderByIdentifierRequest, GetIdentityProviderByIdentifierResponse, } from "@aws-sdk/client-cognito-identity-provider"; -import { IdentityProviderNotFoundError, MissingParameterError } from "../errors"; +import { + IdentityProviderNotFoundError, + MissingParameterError, +} from "../errors"; import { Services } from "../services"; import { identityProviderToResponseObject } from "./responses"; import { Target } from "./Target"; @@ -19,11 +22,11 @@ export const GetIdentityProviderByIdentifier = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.IdpIdentifier) throw new MissingParameterError("IdpIdentifier"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const identityProvider = await userPool.getIdentityProviderByIdentifier( ctx, - req.IdpIdentifier + req.IdpIdentifier, ); if (!identityProvider) { throw new IdentityProviderNotFoundError(); @@ -31,7 +34,7 @@ export const GetIdentityProviderByIdentifier = return { IdentityProvider: identityProviderToResponseObject(req.UserPoolId)( - identityProvider + identityProvider, ), }; }; diff --git a/src/targets/getUser.test.ts b/src/targets/getUser.test.ts index b423715a..3eae96b3 100644 --- a/src/targets/getUser.test.ts +++ b/src/targets/getUser.test.ts @@ -44,7 +44,7 @@ describe("GetUser target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), }); @@ -59,7 +59,7 @@ describe("GetUser target", () => { await expect( getUser(TestContext, { AccessToken: "blah", - }) + }), ).rejects.toBeInstanceOf(InvalidParameterError); }); @@ -85,9 +85,9 @@ describe("GetUser target", () => { issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ), - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/getUser.ts b/src/targets/getUser.ts index dba5a718..44712b1c 100644 --- a/src/targets/getUser.ts +++ b/src/targets/getUser.ts @@ -3,7 +3,11 @@ import { GetUserResponse, } from "@aws-sdk/client-cognito-identity-provider"; import jwt from "jsonwebtoken"; -import { InvalidParameterError, MissingParameterError, UserNotFoundError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + UserNotFoundError, +} from "../errors"; import { Services } from "../services"; import { Token } from "../services/tokenGenerator"; import { Target } from "./Target"; @@ -23,7 +27,7 @@ export const GetUser = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.sub); if (!user) { diff --git a/src/targets/getUserAttributeVerificationCode.test.ts b/src/targets/getUserAttributeVerificationCode.test.ts index 148e1946..5d554d4b 100644 --- a/src/targets/getUserAttributeVerificationCode.test.ts +++ b/src/targets/getUserAttributeVerificationCode.test.ts @@ -31,7 +31,7 @@ const validToken = jwt.sign( issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ); describe("GetUserAttributeVerificationCode target", () => { @@ -57,7 +57,7 @@ describe("GetUserAttributeVerificationCode target", () => { getUserAttributeVerificationCode(TestContext, { AccessToken: "blah", AttributeName: "email", - }) + }), ).rejects.toBeInstanceOf(InvalidParameterError); }); @@ -68,7 +68,7 @@ describe("GetUserAttributeVerificationCode target", () => { getUserAttributeVerificationCode(TestContext, { AccessToken: validToken, AttributeName: "email", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); @@ -86,11 +86,11 @@ describe("GetUserAttributeVerificationCode target", () => { }, AccessToken: validToken, AttributeName: "email", - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" - ) + "User has no attribute matching desired auto verified attributes", + ), ); }); @@ -121,14 +121,14 @@ describe("GetUserAttributeVerificationCode target", () => { AttributeName: "email", DeliveryMedium: "EMAIL", Destination: attributeValue("email", user.Attributes), - } + }, ); expect(mockUserPoolService.saveUser).toHaveBeenCalledWith( TestContext, expect.objectContaining({ AttributeVerificationCode: "123456", - }) + }), ); }); }); diff --git a/src/targets/getUserAttributeVerificationCode.ts b/src/targets/getUserAttributeVerificationCode.ts index 2d72143e..54b393d5 100644 --- a/src/targets/getUserAttributeVerificationCode.ts +++ b/src/targets/getUserAttributeVerificationCode.ts @@ -4,7 +4,11 @@ import { } from "@aws-sdk/client-cognito-identity-provider"; import jwt from "jsonwebtoken"; import { Messages, Services, UserPoolService } from "../services"; -import { InvalidParameterError, MissingParameterError, UserNotFoundError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + UserNotFoundError, +} from "../errors"; import { selectAppropriateDeliveryMethod } from "../services/messageDelivery/deliveryMethod"; import { Token } from "../services/tokenGenerator"; import { User } from "../services/userPoolService"; @@ -17,16 +21,16 @@ const sendAttributeVerificationCode = async ( user: User, messages: Messages, req: GetUserAttributeVerificationCodeRequest, - code: string + code: string, ) => { const deliveryDetails = selectAppropriateDeliveryMethod( userPool.options.AutoVerifiedAttributes ?? [], - user + user, ); if (!deliveryDetails) { // TODO: I don't know what the real error message should be for this throw new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" + "User has no attribute matching desired auto verified attributes", ); } @@ -38,7 +42,7 @@ const sendAttributeVerificationCode = async ( user, code, req.ClientMetadata, - deliveryDetails + deliveryDetails, ); }; @@ -69,7 +73,7 @@ export const GetUserAttributeVerificationCode = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.sub); if (!user) { @@ -89,7 +93,7 @@ export const GetUserAttributeVerificationCode = user, messages, req, - code + code, ); return {}; diff --git a/src/targets/getUserPoolMfaConfig.ts b/src/targets/getUserPoolMfaConfig.ts index c1b557fc..25d5e552 100644 --- a/src/targets/getUserPoolMfaConfig.ts +++ b/src/targets/getUserPoolMfaConfig.ts @@ -17,7 +17,7 @@ export const GetUserPoolMfaConfig = ({ cognito }: GetUserPoolMfaConfigServices): GetUserPoolMfaConfigTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); return { diff --git a/src/targets/initiateAuth.test.ts b/src/targets/initiateAuth.test.ts index cdd3f6a7..5987930c 100644 --- a/src/targets/initiateAuth.test.ts +++ b/src/targets/initiateAuth.test.ts @@ -53,9 +53,9 @@ describe("InitiateAuth target", () => { initiateAuth(TestContext, { ClientId: userPoolClient.ClientId, AuthFlow: "USER_PASSWORD_AUTH", - }) + }), ).rejects.toEqual( - new InvalidParameterError("Missing required parameter authParameters") + new InvalidParameterError("Missing required parameter authParameters"), ); }); @@ -72,7 +72,7 @@ describe("InitiateAuth target", () => { USERNAME: user.Username, PASSWORD: "bad-password", }, - }) + }), ).rejects.toBeInstanceOf(InvalidPasswordError); }); @@ -91,7 +91,7 @@ describe("InitiateAuth target", () => { USERNAME: user.Username, PASSWORD: "bad-password", }, - }) + }), ).rejects.toBeInstanceOf(PasswordResetRequiredError); }); @@ -150,7 +150,7 @@ describe("InitiateAuth target", () => { USERNAME: "username", PASSWORD: "password", }, - }) + }), ).rejects.toBeInstanceOf(NotAuthorizedError); }); }); @@ -207,7 +207,7 @@ describe("InitiateAuth target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0411000111", - } + }, ); // also saves the code on the user for comparison later @@ -216,14 +216,14 @@ describe("InitiateAuth target", () => { { ...user, MFACode: "123456", - } + }, ); }); describe("when Post Authentication trigger is enabled", () => { it("does not invoke the trigger", async () => { mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PostAuthentication" + (trigger) => trigger === "PostAuthentication", ); await initiateAuth(TestContext, { @@ -256,7 +256,7 @@ describe("InitiateAuth target", () => { USERNAME: user.Username, PASSWORD: user.Password, }, - }) + }), ).rejects.toBeInstanceOf(NotAuthorizedError); }); }); @@ -317,7 +317,7 @@ describe("InitiateAuth target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0411000111", - } + }, ); // also saves the code on the user for comparison later @@ -326,14 +326,14 @@ describe("InitiateAuth target", () => { { ...user, MFACode: "123456", - } + }, ); }); describe("when Post Authentication trigger is enabled", () => { it("does not invoke the trigger", async () => { mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PostAuthentication" + (trigger) => trigger === "PostAuthentication", ); await initiateAuth(TestContext, { @@ -384,7 +384,7 @@ describe("InitiateAuth target", () => { expect(output.AuthenticationResult?.AccessToken).toEqual("access"); expect(output.AuthenticationResult?.IdToken).toEqual("id"); expect(output.AuthenticationResult?.RefreshToken).toEqual( - "refresh" + "refresh", ); expect(mockTokenGenerator.generate).toHaveBeenCalledWith( @@ -393,7 +393,7 @@ describe("InitiateAuth target", () => { [], userPoolClient, undefined, - "Authentication" + "Authentication", ); }); }); @@ -439,7 +439,7 @@ describe("InitiateAuth target", () => { [], userPoolClient, undefined, - "Authentication" + "Authentication", ); }); @@ -452,7 +452,7 @@ describe("InitiateAuth target", () => { }); mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PostAuthentication" + (trigger) => trigger === "PostAuthentication", ); await initiateAuth(TestContext, { @@ -472,11 +472,11 @@ describe("InitiateAuth target", () => { userAttributes: user.Attributes, username: user.Username, userPoolId: userPoolClient.UserPoolId, - } + }, ); expect( - mockTriggers.postAuthentication as jest.Mock + mockTriggers.postAuthentication as jest.Mock, ).toHaveBeenCalledBefore(mockTokenGenerator.generate as jest.Mock); }); }); @@ -516,7 +516,7 @@ describe("InitiateAuth target", () => { describe("when Post Authentication trigger is enabled", () => { it("does not invoke the trigger", async () => { mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PostAuthentication" + (trigger) => trigger === "PostAuthentication", ); await initiateAuth(TestContext, { @@ -572,7 +572,7 @@ describe("InitiateAuth target", () => { [], userPoolClient, undefined, - "RefreshTokens" + "RefreshTokens", ); }); }); diff --git a/src/targets/initiateAuth.ts b/src/targets/initiateAuth.ts index 5f8ed583..d9b62014 100644 --- a/src/targets/initiateAuth.ts +++ b/src/targets/initiateAuth.ts @@ -39,7 +39,7 @@ const verifyMfaChallenge = async ( user: User, req: InitiateAuthRequest, userPool: UserPoolService, - services: InitiateAuthServices + services: InitiateAuthServices, ): Promise => { if (!req.ClientId) throw new MissingParameterError("ClientId"); @@ -48,7 +48,7 @@ const verifyMfaChallenge = async ( } const smsMfaOption = user.MFAOptions?.find( (x): x is MFAOption & { DeliveryMedium: DeliveryMediumType } => - x.DeliveryMedium === "SMS" + x.DeliveryMedium === "SMS", ); if (!smsMfaOption) { throw new UnsupportedError("MFA challenge without SMS"); @@ -56,7 +56,7 @@ const verifyMfaChallenge = async ( const deliveryDestination = attributeValue( smsMfaOption.AttributeName, - user.Attributes + user.Attributes, ); if (!deliveryDestination) { throw new UnsupportedError(`SMS_MFA without ${smsMfaOption.AttributeName}`); @@ -75,7 +75,7 @@ const verifyMfaChallenge = async ( DeliveryMedium: smsMfaOption.DeliveryMedium, AttributeName: smsMfaOption.AttributeName, Destination: deliveryDestination, - } + }, ); await userPool.saveUser(ctx, { @@ -99,7 +99,7 @@ const verifyPasswordChallenge = async ( req: InitiateAuthRequest, userPool: UserPoolService, userPoolClient: AppClient, - services: InitiateAuthServices + services: InitiateAuthServices, ): Promise => { const userGroups = await userPool.listUserGroupMembership(ctx, user); @@ -113,7 +113,7 @@ const verifyPasswordChallenge = async ( // // source: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html undefined, - "Authentication" + "Authentication", ); await userPool.storeRefreshToken(ctx, tokens.RefreshToken, user); @@ -140,13 +140,13 @@ const userPasswordAuthFlow = async ( req: InitiateAuthRequest, userPool: UserPoolService, userPoolClient: AppClient, - services: InitiateAuthServices + services: InitiateAuthServices, ): Promise => { if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.AuthParameters) { throw new InvalidParameterError( - "Missing required parameter authParameters" + "Missing required parameter authParameters", ); } @@ -217,7 +217,7 @@ const userPasswordAuthFlow = async ( req, userPool, userPoolClient, - services + services, ); }; @@ -226,11 +226,11 @@ const refreshTokenAuthFlow = async ( req: InitiateAuthRequest, userPool: UserPoolService, userPoolClient: AppClient, - services: InitiateAuthServices + services: InitiateAuthServices, ): Promise => { if (!req.AuthParameters) { throw new InvalidParameterError( - "Missing required parameter authParameters" + "Missing required parameter authParameters", ); } @@ -240,7 +240,7 @@ const refreshTokenAuthFlow = async ( const user = await userPool.getUserByRefreshToken( ctx, - req.AuthParameters.REFRESH_TOKEN + req.AuthParameters.REFRESH_TOKEN, ); if (!user) { throw new NotAuthorizedError(); @@ -258,7 +258,7 @@ const refreshTokenAuthFlow = async ( // // source: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html undefined, - "RefreshTokens" + "RefreshTokens", ); return { @@ -280,14 +280,14 @@ export const InitiateAuth = (services: InitiateAuthServices): InitiateAuthTarget => async (ctx, req) => { if (!req.ClientId) throw new MissingParameterError("ClientId"); - + const userPool = await services.cognito.getUserPoolForClientId( ctx, - req.ClientId + req.ClientId, ); const userPoolClient = await services.cognito.getAppClient( ctx, - req.ClientId + req.ClientId, ); if (!userPoolClient) { throw new NotAuthorizedError(); diff --git a/src/targets/listGroups.ts b/src/targets/listGroups.ts index 684795c0..c19539e8 100644 --- a/src/targets/listGroups.ts +++ b/src/targets/listGroups.ts @@ -15,7 +15,7 @@ export const ListGroups = ({ cognito }: ListGroupServices): ListGroupsTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + // TODO: Limit support // TODO: PaginationToken support diff --git a/src/targets/listIdentityProviders.ts b/src/targets/listIdentityProviders.ts index 03ef9f30..521f6bf0 100644 --- a/src/targets/listIdentityProviders.ts +++ b/src/targets/listIdentityProviders.ts @@ -18,13 +18,13 @@ export const ListIdentityProviders = ({ cognito }: ListIdentityProviderservices): ListIdentityProvidersTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const identityProviders = await userPool.listIdentityProviders(ctx); return { Providers: identityProviders.map( - identityProviderToResponseObject(req.UserPoolId) + identityProviderToResponseObject(req.UserPoolId), ), }; }; diff --git a/src/targets/listUsers.test.ts b/src/targets/listUsers.test.ts index 2443cfda..4fb4c420 100644 --- a/src/targets/listUsers.test.ts +++ b/src/targets/listUsers.test.ts @@ -62,7 +62,7 @@ describe("ListUsers target", () => { expect(mockUserPoolService.listUsers).toHaveBeenCalledWith( TestContext, - 'username = "abc"' + 'username = "abc"', ); }); diff --git a/src/targets/listUsers.ts b/src/targets/listUsers.ts index 2a3c97bb..53385b32 100644 --- a/src/targets/listUsers.ts +++ b/src/targets/listUsers.ts @@ -13,7 +13,7 @@ export const ListUsers = ({ cognito }: Pick): ListUsersTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const users = await userPool.listUsers(ctx, req.Filter); diff --git a/src/targets/listUsersInGroup.test.ts b/src/targets/listUsersInGroup.test.ts index e1ef43a0..fda953f2 100644 --- a/src/targets/listUsersInGroup.test.ts +++ b/src/targets/listUsersInGroup.test.ts @@ -34,7 +34,7 @@ describe("ListUsersInGroup target", () => { return Promise.resolve(existingUser2); } return Promise.resolve(null); - } + }, ); const result = await listUsersInGroup(TestContext, { @@ -44,7 +44,7 @@ describe("ListUsersInGroup target", () => { expect(mockUserPoolService.getGroupByGroupName).toHaveBeenCalledWith( TestContext, - existingGroup.GroupName + existingGroup.GroupName, ); expect(result.Users).toEqual([ @@ -81,7 +81,7 @@ describe("ListUsersInGroup target", () => { expect(mockUserPoolService.getGroupByGroupName).toHaveBeenCalledWith( TestContext, - existingGroup.GroupName + existingGroup.GroupName, ); expect(result.Users).toHaveLength(0); @@ -94,7 +94,7 @@ describe("ListUsersInGroup target", () => { listUsersInGroup(TestContext, { GroupName: "group", UserPoolId: "test", - }) + }), ).rejects.toEqual(new GroupNotFoundError()); }); @@ -113,14 +113,14 @@ describe("ListUsersInGroup target", () => { } // don't ever return a value for existingUser2 return Promise.resolve(null); - } + }, ); await expect( listUsersInGroup(TestContext, { GroupName: existingGroup.GroupName, UserPoolId: "test", - }) + }), ).rejects.toEqual(new UserNotFoundError()); }); }); diff --git a/src/targets/listUsersInGroup.ts b/src/targets/listUsersInGroup.ts index cc493587..345f6be4 100644 --- a/src/targets/listUsersInGroup.ts +++ b/src/targets/listUsersInGroup.ts @@ -2,7 +2,11 @@ import { ListUsersInGroupRequest, ListUsersInGroupResponse, } from "@aws-sdk/client-cognito-identity-provider"; -import { GroupNotFoundError, MissingParameterError, UserNotFoundError } from "../errors"; +import { + GroupNotFoundError, + MissingParameterError, + UserNotFoundError, +} from "../errors"; import { Services } from "../services"; import { userToResponseObject } from "./responses"; import { Target } from "./Target"; @@ -17,7 +21,7 @@ export const ListUsersInGroup = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.GroupName) throw new MissingParameterError("GroupName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const group = await userPool.getGroupByGroupName(ctx, req.GroupName); if (!group) { @@ -33,7 +37,7 @@ export const ListUsersInGroup = } return userToResponseObject(user); - }) ?? [] + }) ?? [], ), }; }; diff --git a/src/targets/respondToAuthChallenge.test.ts b/src/targets/respondToAuthChallenge.test.ts index 274b22b0..d984f4af 100644 --- a/src/targets/respondToAuthChallenge.test.ts +++ b/src/targets/respondToAuthChallenge.test.ts @@ -58,7 +58,7 @@ describe("RespondToAuthChallenge target", () => { SMS_MFA_CODE: "123456", }, Session: "Session", - }) + }), ).rejects.toBeInstanceOf(NotAuthorizedError); }); @@ -67,11 +67,11 @@ describe("RespondToAuthChallenge target", () => { respondToAuthChallenge(TestContext, { ClientId: "clientId", ChallengeName: "SMS_MFA", - }) + }), ).rejects.toEqual( new InvalidParameterError( - "Missing required parameter challenge responses" - ) + "Missing required parameter challenge responses", + ), ); }); @@ -81,9 +81,9 @@ describe("RespondToAuthChallenge target", () => { ClientId: "clientId", ChallengeName: "SMS_MFA", ChallengeResponses: {}, - }) + }), ).rejects.toEqual( - new InvalidParameterError("Missing required parameter USERNAME") + new InvalidParameterError("Missing required parameter USERNAME"), ); }); @@ -97,9 +97,9 @@ describe("RespondToAuthChallenge target", () => { ChallengeResponses: { USERNAME: "abc", }, - }) + }), ).rejects.toEqual( - new InvalidParameterError("Missing required parameter Session") + new InvalidParameterError("Missing required parameter Session"), ); }); @@ -168,14 +168,14 @@ describe("RespondToAuthChallenge target", () => { { client: "metadata", }, - "Authentication" + "Authentication", ); }); describe("when Post Authentication trigger is enabled", () => { it("does invokes the trigger", async () => { mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PostAuthentication" + (trigger) => trigger === "PostAuthentication", ); await respondToAuthChallenge(TestContext, { @@ -202,7 +202,7 @@ describe("RespondToAuthChallenge target", () => { userAttributes: user.Attributes, username: user.Username, userPoolId: userPoolClient.UserPoolId, - } + }, ); }); }); @@ -221,7 +221,7 @@ describe("RespondToAuthChallenge target", () => { SMS_MFA_CODE: "4321", }, Session: "Session", - }) + }), ).rejects.toBeInstanceOf(CodeMismatchError); }); }); @@ -243,9 +243,9 @@ describe("RespondToAuthChallenge target", () => { USERNAME: user.Username, }, Session: "session", - }) + }), ).rejects.toEqual( - new InvalidParameterError("Missing required parameter NEW_PASSWORD") + new InvalidParameterError("Missing required parameter NEW_PASSWORD"), ); }); @@ -303,14 +303,14 @@ describe("RespondToAuthChallenge target", () => { [], userPoolClient, { client: "metadata" }, - "Authentication" + "Authentication", ); }); describe("when Post Authentication trigger is enabled", () => { it("does invokes the trigger", async () => { mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PostAuthentication" + (trigger) => trigger === "PostAuthentication", ); await respondToAuthChallenge(TestContext, { @@ -331,7 +331,7 @@ describe("RespondToAuthChallenge target", () => { userAttributes: user.Attributes, username: user.Username, userPoolId: userPoolClient.UserPoolId, - } + }, ); }); }); diff --git a/src/targets/respondToAuthChallenge.ts b/src/targets/respondToAuthChallenge.ts index 85e7eaec..13b413b7 100644 --- a/src/targets/respondToAuthChallenge.ts +++ b/src/targets/respondToAuthChallenge.ts @@ -31,10 +31,10 @@ export const RespondToAuthChallenge = }: RespondToAuthChallengeService): RespondToAuthChallengeTarget => async (ctx, req) => { if (!req.ClientId) throw new MissingParameterError("ClientId"); - + if (!req.ChallengeResponses) { throw new InvalidParameterError( - "Missing required parameter challenge responses" + "Missing required parameter challenge responses", ); } if (!req.ChallengeResponses.USERNAME) { @@ -49,7 +49,7 @@ export const RespondToAuthChallenge = const user = await userPool.getUserByUsername( ctx, - req.ChallengeResponses.USERNAME + req.ChallengeResponses.USERNAME, ); if (!user || !userPoolClient) { throw new NotAuthorizedError(); @@ -68,7 +68,7 @@ export const RespondToAuthChallenge = } else if (req.ChallengeName === "NEW_PASSWORD_REQUIRED") { if (!req.ChallengeResponses.NEW_PASSWORD) { throw new InvalidParameterError( - "Missing required parameter NEW_PASSWORD" + "Missing required parameter NEW_PASSWORD", ); } @@ -81,7 +81,7 @@ export const RespondToAuthChallenge = }); } else { throw new UnsupportedError( - `respondToAuthChallenge with ChallengeName=${req.ChallengeName}` + `respondToAuthChallenge with ChallengeName=${req.ChallengeName}`, ); } @@ -106,7 +106,7 @@ export const RespondToAuthChallenge = userGroups, userPoolClient, req.ClientMetadata, - "Authentication" + "Authentication", ), }; }; diff --git a/src/targets/revokeToken.test.ts b/src/targets/revokeToken.test.ts index a5691086..a61b9054 100644 --- a/src/targets/revokeToken.test.ts +++ b/src/targets/revokeToken.test.ts @@ -35,7 +35,7 @@ describe("AdminInitiateAuth target", () => { TestContext, expect.objectContaining({ RefreshTokens: [], - }) + }), ); }); }); diff --git a/src/targets/revokeToken.ts b/src/targets/revokeToken.ts index cf2a34a2..f092c703 100644 --- a/src/targets/revokeToken.ts +++ b/src/targets/revokeToken.ts @@ -15,14 +15,14 @@ export const RevokeToken = async (ctx, req) => { if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.Token) throw new MissingParameterError("Token"); - + const userPool = await cognito.getUserPoolForClientId(ctx, req.ClientId); const users = await userPool.listUsers(ctx); const user = users.find( (user) => Array.isArray(user.RefreshTokens) && - user.RefreshTokens.includes(req.Token!) + user.RefreshTokens.includes(req.Token!), ); if (!user) { diff --git a/src/targets/signUp.test.ts b/src/targets/signUp.test.ts index 4d79cc5a..103e6867 100644 --- a/src/targets/signUp.test.ts +++ b/src/targets/signUp.test.ts @@ -53,7 +53,7 @@ describe("SignUp target", () => { Password: "pwd", Username: user.Username, UserAttributes: [], - }) + }), ).rejects.toBeInstanceOf(UsernameExistsError); }); @@ -88,7 +88,7 @@ describe("SignUp target", () => { describe("when PreSignUp trigger is enabled", () => { beforeEach(() => { mockTriggers.enabled.mockImplementation( - (trigger) => trigger === "PreSignUp" + (trigger) => trigger === "PreSignUp", ); }); @@ -141,7 +141,7 @@ describe("SignUp target", () => { Username: "user-supplied", UserAttributes: [{ Name: "email", Value: "example@example.com" }], ValidationData: [{ Name: "another", Value: "attribute" }], - }) + }), ).rejects.toBeInstanceOf(UserLambdaValidationError); }); @@ -171,7 +171,7 @@ describe("SignUp target", () => { TestContext, expect.objectContaining({ UserStatus: "CONFIRMED", - }) + }), ); }); @@ -179,7 +179,7 @@ describe("SignUp target", () => { beforeEach(() => { mockTriggers.enabled.mockImplementation( (trigger) => - trigger === "PreSignUp" || trigger === "PostConfirmation" + trigger === "PreSignUp" || trigger === "PostConfirmation", ); }); @@ -211,14 +211,14 @@ describe("SignUp target", () => { userPoolId: "test", username: "user-supplied", validationData: undefined, - } + }, ); }); it("throws if the PostConfirmation lambda fails", async () => { mockUserPoolService.getUserByUsername.mockResolvedValue(null); mockTriggers.postConfirmation.mockRejectedValue( - new UserLambdaValidationError() + new UserLambdaValidationError(), ); await expect( @@ -231,7 +231,7 @@ describe("SignUp target", () => { Username: "user-supplied", UserAttributes: [{ Name: "email", Value: "example@example.com" }], ValidationData: [{ Name: "another", Value: "attribute" }], - }) + }), ).rejects.toBeInstanceOf(UserLambdaValidationError); }); }); @@ -263,7 +263,7 @@ describe("SignUp target", () => { TestContext, expect.objectContaining({ UserStatus: "UNCONFIRMED", - }) + }), ); }); @@ -308,7 +308,7 @@ describe("SignUp target", () => { { Name: "email", Value: "example@example.com" }, { Name: "email_verified", Value: "true" }, ], - }) + }), ); }); @@ -337,7 +337,7 @@ describe("SignUp target", () => { TestContext, expect.objectContaining({ Attributes: [{ Name: "sub", Value: expect.stringMatching(UUID) }], - }) + }), ); }); @@ -370,7 +370,7 @@ describe("SignUp target", () => { { Name: "phone_number", Value: "0400000000" }, { Name: "phone_number_verified", Value: "true" }, ], - }) + }), ); }); @@ -399,7 +399,7 @@ describe("SignUp target", () => { TestContext, expect.objectContaining({ Attributes: [{ Name: "sub", Value: expect.stringMatching(UUID) }], - }) + }), ); }); }); @@ -490,7 +490,7 @@ describe("SignUp target", () => { AttributeName: "email", DeliveryMedium: "EMAIL", Destination: "example@example.com", - } + }, ); }); @@ -501,11 +501,11 @@ describe("SignUp target", () => { Password: "pwd", Username: "user-supplied", UserAttributes: [], - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" - ) + "User has no attribute matching desired auto verified attributes", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); @@ -559,7 +559,7 @@ describe("SignUp target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0400000000", - } + }, ); }); @@ -570,11 +570,11 @@ describe("SignUp target", () => { Password: "pwd", Username: "user-supplied", UserAttributes: [], - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" - ) + "User has no attribute matching desired auto verified attributes", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); @@ -635,7 +635,7 @@ describe("SignUp target", () => { AttributeName: "phone_number", DeliveryMedium: "SMS", Destination: "0400000000", - } + }, ); }); @@ -681,7 +681,7 @@ describe("SignUp target", () => { AttributeName: "email", DeliveryMedium: "EMAIL", Destination: "example@example.com", - } + }, ); }); @@ -692,11 +692,11 @@ describe("SignUp target", () => { Password: "pwd", Username: "user-supplied", UserAttributes: [], - }) + }), ).rejects.toEqual( new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" - ) + "User has no attribute matching desired auto verified attributes", + ), ); expect(mockMessages.deliver).not.toHaveBeenCalled(); diff --git a/src/targets/signUp.ts b/src/targets/signUp.ts index b26eb2b9..34d209ed 100644 --- a/src/targets/signUp.ts +++ b/src/targets/signUp.ts @@ -4,7 +4,11 @@ import { UserStatusType, } from "@aws-sdk/client-cognito-identity-provider"; import * as uuid from "uuid"; -import { InvalidParameterError, MissingParameterError, UsernameExistsError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + UsernameExistsError, +} from "../errors"; import { Messages, Services, UserPoolService } from "../services"; import { selectAppropriateDeliveryMethod } from "../services/messageDelivery/deliveryMethod"; import { DeliveryDetails } from "../services/messageDelivery/messageDelivery"; @@ -32,11 +36,11 @@ const deliverWelcomeMessage = async ( user: User, userPool: UserPoolService, messages: Messages, - clientMetadata: Record | undefined + clientMetadata: Record | undefined, ): Promise => { const deliveryDetails = selectAppropriateDeliveryMethod( userPool.options.AutoVerifiedAttributes ?? [], - user + user, ); if (!deliveryDetails && !userPool.options.AutoVerifiedAttributes) { // From the console: When Cognito's default verification method is not enabled, you must use APIs or Lambda triggers @@ -45,7 +49,7 @@ const deliverWelcomeMessage = async ( } else if (!deliveryDetails) { // TODO: I don't know what the real error message should be for this throw new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" + "User has no attribute matching desired auto verified attributes", ); } @@ -57,7 +61,7 @@ const deliverWelcomeMessage = async ( user, code, clientMetadata, - deliveryDetails + deliveryDetails, ); return deliveryDetails; @@ -76,7 +80,7 @@ export const SignUp = if (!req.ClientId) throw new MissingParameterError("ClientId"); if (!req.Username) throw new MissingParameterError("Username"); if (!req.Password) throw new MissingParameterError("Password"); - + // TODO: This should behave differently depending on if PreventUserExistenceErrors // is enabled on the updatedUser pool. This will be the default after Feb 2020. // See: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-managing-errors.html @@ -87,7 +91,7 @@ export const SignUp = } const attributes = attributesInclude("sub", req.UserAttributes) - ? req.UserAttributes ?? [] + ? (req.UserAttributes ?? []) : [{ Name: "sub", Value: uuid.v4() }, ...(req.UserAttributes ?? [])]; let userStatus: UserStatusType = "UNCONFIRMED"; @@ -143,7 +147,7 @@ export const SignUp = updatedUser, userPool, messages, - req.ClientMetadata + req.ClientMetadata, ); await userPool.saveUser(ctx, { @@ -166,7 +170,7 @@ export const SignUp = // into every place we send attributes to lambdas userAttributes: attributesAppend( updatedUser.Attributes, - attribute("cognito:user_status", updatedUser.UserStatus) + attribute("cognito:user_status", updatedUser.UserStatus), ), }); } diff --git a/src/targets/updateGroup.test.ts b/src/targets/updateGroup.test.ts index 89c70928..8aeddc54 100644 --- a/src/targets/updateGroup.test.ts +++ b/src/targets/updateGroup.test.ts @@ -42,7 +42,7 @@ describe("UpdateGroup target", () => { expect(mockUserPoolService.getGroupByGroupName).toHaveBeenCalledWith( TestContext, - existingGroup.GroupName + existingGroup.GroupName, ); expect(mockUserPoolService.saveGroup).toHaveBeenCalledWith(TestContext, { @@ -84,7 +84,7 @@ describe("UpdateGroup target", () => { expect(mockUserPoolService.getGroupByGroupName).toHaveBeenCalledWith( TestContext, - existingGroup.GroupName + existingGroup.GroupName, ); expect(mockUserPoolService.saveGroup).toHaveBeenCalledWith(TestContext, { @@ -111,7 +111,7 @@ describe("UpdateGroup target", () => { updateGroup(TestContext, { GroupName: "group", UserPoolId: "test", - }) + }), ).rejects.toEqual(new GroupNotFoundError()); }); }); diff --git a/src/targets/updateGroup.ts b/src/targets/updateGroup.ts index de09b382..01090310 100644 --- a/src/targets/updateGroup.ts +++ b/src/targets/updateGroup.ts @@ -16,7 +16,7 @@ export const UpdateGroup = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.GroupName) throw new MissingParameterError("GroupName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const group = await userPool.getGroupByGroupName(ctx, req.GroupName); if (!group) { diff --git a/src/targets/updateIdentityProvider.test.ts b/src/targets/updateIdentityProvider.test.ts index 0e1779a1..939304ec 100644 --- a/src/targets/updateIdentityProvider.test.ts +++ b/src/targets/updateIdentityProvider.test.ts @@ -31,7 +31,7 @@ describe("UpdateGroup target", () => { const existingIdentityProvider = TDB.identityProvider(); mockUserPoolService.getIdentityProviderByProviderName.mockResolvedValue( - existingIdentityProvider + existingIdentityProvider, ); const newDate = new Date(); @@ -46,7 +46,7 @@ describe("UpdateGroup target", () => { }); expect( - mockUserPoolService.getIdentityProviderByProviderName + mockUserPoolService.getIdentityProviderByProviderName, ).toHaveBeenCalledWith(TestContext, existingIdentityProvider.ProviderName); expect(mockUserPoolService.saveIdentityProvider).toHaveBeenCalledWith( @@ -57,7 +57,7 @@ describe("UpdateGroup target", () => { AttributeMapping: { newAttributeKey: "new attribute value" }, IdpIdentifiers: ["newIdentifier"], ProviderDetails: { newProviderDetailKey: "new provider detail" }, - } + }, ); expect(result.IdentityProvider).toEqual({ @@ -78,7 +78,7 @@ describe("UpdateGroup target", () => { }); mockUserPoolService.getIdentityProviderByProviderName.mockResolvedValue( - existingIdentityProvider + existingIdentityProvider, ); const newDate = new Date(); @@ -91,7 +91,7 @@ describe("UpdateGroup target", () => { }); expect( - mockUserPoolService.getIdentityProviderByProviderName + mockUserPoolService.getIdentityProviderByProviderName, ).toHaveBeenCalledWith(TestContext, existingIdentityProvider.ProviderName); expect(mockUserPoolService.saveIdentityProvider).toHaveBeenCalledWith( @@ -100,7 +100,7 @@ describe("UpdateGroup target", () => { ...existingIdentityProvider, LastModifiedDate: newDate, IdpIdentifiers: ["newIdentifier"], - } + }, ); expect(result.IdentityProvider).toEqual({ @@ -117,14 +117,14 @@ describe("UpdateGroup target", () => { it("throws if the identity provider doesn't exist", async () => { mockUserPoolService.getIdentityProviderByProviderName.mockResolvedValue( - null + null, ); await expect( updateIdentityProvider(TestContext, { ProviderName: "identityProvider", UserPoolId: "test", - }) + }), ).rejects.toEqual(new IdentityProviderNotFoundError()); }); }); diff --git a/src/targets/updateIdentityProvider.ts b/src/targets/updateIdentityProvider.ts index 86cd3b17..7ae4ee8e 100644 --- a/src/targets/updateIdentityProvider.ts +++ b/src/targets/updateIdentityProvider.ts @@ -3,7 +3,10 @@ import { UpdateIdentityProviderResponse, } from "@aws-sdk/client-cognito-identity-provider"; import { Services } from "../services"; -import { IdentityProviderNotFoundError, MissingParameterError } from "../errors"; +import { + IdentityProviderNotFoundError, + MissingParameterError, +} from "../errors"; import { identityProviderToResponseObject } from "./responses"; import { Target } from "./Target"; @@ -22,11 +25,11 @@ export const UpdateIdentityProvider = async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); if (!req.ProviderName) throw new MissingParameterError("ProviderName"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const identityProvider = await userPool.getIdentityProviderByProviderName( ctx, - req.ProviderName + req.ProviderName, ); if (!identityProvider) { throw new IdentityProviderNotFoundError(); @@ -45,7 +48,7 @@ export const UpdateIdentityProvider = return { IdentityProvider: identityProviderToResponseObject(req.UserPoolId)( - updatedIdentityProvider + updatedIdentityProvider, ), }; }; diff --git a/src/targets/updateUserAttributes.test.ts b/src/targets/updateUserAttributes.test.ts index 9dde8b98..74bb5d44 100644 --- a/src/targets/updateUserAttributes.test.ts +++ b/src/targets/updateUserAttributes.test.ts @@ -38,7 +38,7 @@ const validToken = jwt.sign( issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ); describe("UpdateUserAttributes target", () => { @@ -65,7 +65,7 @@ describe("UpdateUserAttributes target", () => { client: "metadata", }, UserAttributes: [{ Name: "custom:example", Value: "1" }], - }) + }), ).rejects.toBeInstanceOf(InvalidParameterError); }); @@ -79,7 +79,7 @@ describe("UpdateUserAttributes target", () => { client: "metadata", }, UserAttributes: [{ Name: "custom:example", Value: "1" }], - }) + }), ).rejects.toEqual(new NotAuthorizedError()); }); @@ -106,7 +106,7 @@ describe("UpdateUserAttributes target", () => { ...user, Attributes: attributesAppend( user.Attributes, - attribute("custom:example", "1") + attribute("custom:example", "1"), ), UserLastModifiedDate: clock.get(), }); @@ -118,38 +118,47 @@ describe("UpdateUserAttributes target", () => { ${"an attribute which isn't mutable in the schema"} | ${"custom:immutable"} | ${"user.custom:immutable: Attribute cannot be updated. (changing an immutable attribute)"} ${"email_verified without an email attribute"} | ${"email_verified"} | ${"Email is required to verify/un-verify an email"} ${"phone_number_verified without an phone_number attribute"} | ${"phone_number_verified"} | ${"Phone Number is required to verify/un-verify a phone number"} - `("req.UserAttributes contains $desc", ({ attribute, expectedError }: { attribute: string, expectedError: string }) => { - beforeEach(() => { - mockUserPoolService.options.SchemaAttributes = [ - { - Name: "email_verified", - Mutable: true, - }, - { - Name: "phone_number_verified", - Mutable: true, - }, - { - Name: "custom:immutable", - Mutable: false, - }, - ]; - }); + `( + "req.UserAttributes contains $desc", + ({ + attribute, + expectedError, + }: { + attribute: string; + expectedError: string; + }) => { + beforeEach(() => { + mockUserPoolService.options.SchemaAttributes = [ + { + Name: "email_verified", + Mutable: true, + }, + { + Name: "phone_number_verified", + Mutable: true, + }, + { + Name: "custom:immutable", + Mutable: false, + }, + ]; + }); - it("throws an invalid parameter error", async () => { - mockUserPoolService.getUserByUsername.mockResolvedValue(TDB.user()); + it("throws an invalid parameter error", async () => { + mockUserPoolService.getUserByUsername.mockResolvedValue(TDB.user()); - await expect( - updateUserAttributes(TestContext, { - AccessToken: validToken, - ClientMetadata: { - client: "metadata", - }, - UserAttributes: [{ Name: attribute, Value: "1" }], - }) - ).rejects.toEqual(new InvalidParameterError(expectedError)); - }); - }); + await expect( + updateUserAttributes(TestContext, { + AccessToken: validToken, + ClientMetadata: { + client: "metadata", + }, + UserAttributes: [{ Name: attribute, Value: "1" }], + }), + ).rejects.toEqual(new InvalidParameterError(expectedError)); + }); + }, + ); describe.each(["email", "phone_number"])( "%s is in req.UserAttributes without the relevant verified attribute", @@ -172,12 +181,12 @@ describe("UpdateUserAttributes target", () => { Attributes: attributesAppend( user.Attributes, attribute(attr, "new value"), - attribute(`${attr}_verified`, "false") + attribute(`${attr}_verified`, "false"), ), UserLastModifiedDate: clock.get(), }); }); - } + }, ); describe("user pool has auto verified attributes enabled", () => { @@ -190,96 +199,99 @@ describe("UpdateUserAttributes target", () => { ${["email"]} ${["phone_number"]} ${["email", "phone_number"]} - `("when $attributes is unverified", ({ attributes }: { attributes: string[] }) => { - describe("the verification status was not affected by the update", () => { - it("does not deliver a OTP code to the user", async () => { - const user = TDB.user({ - Attributes: attributes.map((attr: string) => - attribute(`${attr}_verified`, "false") - ), - }); + `( + "when $attributes is unverified", + ({ attributes }: { attributes: string[] }) => { + describe("the verification status was not affected by the update", () => { + it("does not deliver a OTP code to the user", async () => { + const user = TDB.user({ + Attributes: attributes.map((attr: string) => + attribute(`${attr}_verified`, "false"), + ), + }); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); - mockUserPoolService.options.SchemaAttributes = [ - { Name: "example", Mutable: true }, - ]; + mockUserPoolService.getUserByUsername.mockResolvedValue(user); + mockUserPoolService.options.SchemaAttributes = [ + { Name: "example", Mutable: true }, + ]; - await updateUserAttributes(TestContext, { - AccessToken: validToken, - ClientMetadata: { - client: "metadata", - }, - UserAttributes: [attribute("example", "1")], - }); + await updateUserAttributes(TestContext, { + AccessToken: validToken, + ClientMetadata: { + client: "metadata", + }, + UserAttributes: [attribute("example", "1")], + }); - expect(mockMessages.deliver).not.toHaveBeenCalled(); + expect(mockMessages.deliver).not.toHaveBeenCalled(); + }); }); - }); - describe("the verification status changed because of the update", () => { - it("throws if the user doesn't have a valid way to contact them", async () => { - const user = TDB.user({ - Attributes: [], + describe("the verification status changed because of the update", () => { + it("throws if the user doesn't have a valid way to contact them", async () => { + const user = TDB.user({ + Attributes: [], + }); + + mockUserPoolService.getUserByUsername.mockResolvedValue(user); + + await expect( + updateUserAttributes(TestContext, { + AccessToken: validToken, + ClientMetadata: { + client: "metadata", + }, + UserAttributes: attributes.map((attr: string) => + attribute(attr, "new value"), + ), + }), + ).rejects.toEqual( + new InvalidParameterError( + "User has no attribute matching desired auto verified attributes", + ), + ); }); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); + it("delivers a OTP code to the user", async () => { + const user = TDB.user(); + + mockUserPoolService.getUserByUsername.mockResolvedValue(user); - await expect( - updateUserAttributes(TestContext, { + await updateUserAttributes(TestContext, { AccessToken: validToken, ClientMetadata: { client: "metadata", }, UserAttributes: attributes.map((attr: string) => - attribute(attr, "new value") + attribute(attr, "new value"), ), - }) - ).rejects.toEqual( - new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" - ) - ); - }); - - it("delivers a OTP code to the user", async () => { - const user = TDB.user(); - - mockUserPoolService.getUserByUsername.mockResolvedValue(user); - - await updateUserAttributes(TestContext, { - AccessToken: validToken, - ClientMetadata: { - client: "metadata", - }, - UserAttributes: attributes.map((attr: string) => - attribute(attr, "new value") - ), + }); + + expect(mockMessages.deliver).toHaveBeenCalledWith( + TestContext, + "UpdateUserAttribute", + null, + "test", + user, + "123456", + { client: "metadata" }, + { + AttributeName: "email", + DeliveryMedium: "EMAIL", + Destination: attributeValue("email", user.Attributes), + }, + ); + + expect(mockUserPoolService.saveUser).toHaveBeenCalledWith( + TestContext, + expect.objectContaining({ + AttributeVerificationCode: "123456", + }), + ); }); - - expect(mockMessages.deliver).toHaveBeenCalledWith( - TestContext, - "UpdateUserAttribute", - null, - "test", - user, - "123456", - { client: "metadata" }, - { - AttributeName: "email", - DeliveryMedium: "EMAIL", - Destination: attributeValue("email", user.Attributes), - } - ); - - expect(mockUserPoolService.saveUser).toHaveBeenCalledWith( - TestContext, - expect.objectContaining({ - AttributeVerificationCode: "123456", - }) - ); }); - }); - }); + }, + ); }); describe("user pool does not have auto verified attributes", () => { @@ -292,51 +304,54 @@ describe("UpdateUserAttributes target", () => { ${["email"]} ${["phone_number"]} ${["email", "phone_number"]} - `("when $attributes is unverified", ({ attributes }: { attributes: string[] }) => { - describe("the verification status was not affected by the update", () => { - it("does not deliver a OTP code to the user", async () => { - const user = TDB.user({ - Attributes: attributes.map((attr: string) => - attribute(`${attr}_verified`, "false") - ), - }); + `( + "when $attributes is unverified", + ({ attributes }: { attributes: string[] }) => { + describe("the verification status was not affected by the update", () => { + it("does not deliver a OTP code to the user", async () => { + const user = TDB.user({ + Attributes: attributes.map((attr: string) => + attribute(`${attr}_verified`, "false"), + ), + }); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); - mockUserPoolService.options.SchemaAttributes = [ - { Name: "example", Mutable: true }, - ]; + mockUserPoolService.getUserByUsername.mockResolvedValue(user); + mockUserPoolService.options.SchemaAttributes = [ + { Name: "example", Mutable: true }, + ]; - await updateUserAttributes(TestContext, { - AccessToken: validToken, - ClientMetadata: { - client: "metadata", - }, - UserAttributes: [attribute("example", "1")], - }); + await updateUserAttributes(TestContext, { + AccessToken: validToken, + ClientMetadata: { + client: "metadata", + }, + UserAttributes: [attribute("example", "1")], + }); - expect(mockMessages.deliver).not.toHaveBeenCalled(); + expect(mockMessages.deliver).not.toHaveBeenCalled(); + }); }); - }); - describe("the verification status changed because of the update", () => { - it("does not deliver a OTP code to the user", async () => { - const user = TDB.user(); + describe("the verification status changed because of the update", () => { + it("does not deliver a OTP code to the user", async () => { + const user = TDB.user(); - mockUserPoolService.getUserByUsername.mockResolvedValue(user); + mockUserPoolService.getUserByUsername.mockResolvedValue(user); - await updateUserAttributes(TestContext, { - AccessToken: validToken, - ClientMetadata: { - client: "metadata", - }, - UserAttributes: attributes.map((attr: string) => - attribute(attr, "new value") - ), - }); + await updateUserAttributes(TestContext, { + AccessToken: validToken, + ClientMetadata: { + client: "metadata", + }, + UserAttributes: attributes.map((attr: string) => + attribute(attr, "new value"), + ), + }); - expect(mockMessages.deliver).not.toHaveBeenCalled(); + expect(mockMessages.deliver).not.toHaveBeenCalled(); + }); }); - }); - }); + }, + ); }); }); diff --git a/src/targets/updateUserAttributes.ts b/src/targets/updateUserAttributes.ts index 50ed4067..a4ffd3f8 100644 --- a/src/targets/updateUserAttributes.ts +++ b/src/targets/updateUserAttributes.ts @@ -4,7 +4,11 @@ import { } from "@aws-sdk/client-cognito-identity-provider"; import jwt from "jsonwebtoken"; import { Messages, Services, UserPoolService } from "../services"; -import { InvalidParameterError, MissingParameterError, NotAuthorizedError } from "../errors"; +import { + InvalidParameterError, + MissingParameterError, + NotAuthorizedError, +} from "../errors"; import { USER_POOL_AWS_DEFAULTS } from "../services/cognitoService"; import { selectAppropriateDeliveryMethod } from "../services/messageDelivery/deliveryMethod"; import { Token } from "../services/tokenGenerator"; @@ -24,16 +28,16 @@ const sendAttributeVerificationCode = async ( user: User, messages: Messages, req: UpdateUserAttributesRequest, - code: string + code: string, ) => { const deliveryDetails = selectAppropriateDeliveryMethod( userPool.options.AutoVerifiedAttributes ?? [], - user + user, ); if (!deliveryDetails) { // TODO: I don't know what the real error message should be for this throw new InvalidParameterError( - "User has no attribute matching desired auto verified attributes" + "User has no attribute matching desired auto verified attributes", ); } @@ -45,7 +49,7 @@ const sendAttributeVerificationCode = async ( user, code, req.ClientMetadata, - deliveryDetails + deliveryDetails, ); return deliveryDetails; @@ -80,7 +84,7 @@ export const UpdateUserAttributes = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.sub); if (!user) { @@ -96,8 +100,8 @@ export const UpdateUserAttributes = // fail. userPool.options.SchemaAttributes ?? USER_POOL_AWS_DEFAULTS.SchemaAttributes ?? - [] - ) + [], + ), ); const updatedUser = { @@ -127,7 +131,7 @@ export const UpdateUserAttributes = user, messages, req, - code + code, ); return { diff --git a/src/targets/updateUserPool.ts b/src/targets/updateUserPool.ts index 1022b0ab..0d2cb5af 100644 --- a/src/targets/updateUserPool.ts +++ b/src/targets/updateUserPool.ts @@ -18,7 +18,7 @@ export const UpdateUserPool = ({ cognito }: UpdateUserPoolServices): UpdateUserPoolTarget => async (ctx, req) => { if (!req.UserPoolId) throw new MissingParameterError("UserPoolId"); - + const userPool = await cognito.getUserPool(ctx, req.UserPoolId); const updatedUserPool: UserPool = { diff --git a/src/targets/updateUserPoolClient.test.ts b/src/targets/updateUserPoolClient.test.ts index dbe82fe2..fbed5389 100644 --- a/src/targets/updateUserPoolClient.test.ts +++ b/src/targets/updateUserPoolClient.test.ts @@ -48,7 +48,7 @@ describe("UpdateUserPoolClient target", () => { expect(mockCognitoService.getAppClient).toHaveBeenCalledWith( TestContext, - existingAppClient.ClientId + existingAppClient.ClientId, ); expect(mockUserPoolService.saveAppClient).toHaveBeenCalledWith( @@ -63,7 +63,7 @@ describe("UpdateUserPoolClient target", () => { IdToken: "minutes", RefreshToken: "days", }, - } + }, ); expect(result.UserPoolClient).toEqual({ @@ -86,7 +86,7 @@ describe("UpdateUserPoolClient target", () => { updateUserPoolClient(TestContext, { ClientId: "clientId", UserPoolId: "test", - }) + }), ).rejects.toEqual(new ResourceNotFoundError()); }); }); diff --git a/src/targets/verifyUserAttribute.test.ts b/src/targets/verifyUserAttribute.test.ts index 3c21ed1e..c2eee006 100644 --- a/src/targets/verifyUserAttribute.test.ts +++ b/src/targets/verifyUserAttribute.test.ts @@ -37,7 +37,7 @@ const validToken = jwt.sign( issuer: `http://localhost:9229/test`, expiresIn: "24h", keyid: "CognitoLocal", - } + }, ); describe("VerifyUserAttribute target", () => { @@ -69,7 +69,7 @@ describe("VerifyUserAttribute target", () => { ...user, Attributes: attributesAppend( user.Attributes, - attribute("email_verified", "true") + attribute("email_verified", "true"), ), UserLastModifiedDate: clock.get(), }); @@ -92,7 +92,7 @@ describe("VerifyUserAttribute target", () => { ...user, Attributes: attributesAppend( user.Attributes, - attribute("phone_number_verified", "true") + attribute("phone_number_verified", "true"), ), UserLastModifiedDate: clock.get(), }); @@ -120,7 +120,7 @@ describe("VerifyUserAttribute target", () => { AccessToken: "blah", AttributeName: "email", Code: "123456", - }) + }), ).rejects.toBeInstanceOf(InvalidParameterError); }); @@ -132,7 +132,7 @@ describe("VerifyUserAttribute target", () => { AccessToken: validToken, AttributeName: "email", Code: "123456", - }) + }), ).rejects.toEqual(new NotAuthorizedError()); }); @@ -147,7 +147,7 @@ describe("VerifyUserAttribute target", () => { AccessToken: validToken, AttributeName: "email", Code: "123456", - }) + }), ).rejects.toEqual(new CodeMismatchError()); }); }); diff --git a/src/targets/verifyUserAttribute.ts b/src/targets/verifyUserAttribute.ts index dd1e1bd9..988c2e0f 100644 --- a/src/targets/verifyUserAttribute.ts +++ b/src/targets/verifyUserAttribute.ts @@ -37,7 +37,7 @@ export const VerifyUserAttribute = const userPool = await cognito.getUserPoolForClientId( ctx, - decodedToken.client_id + decodedToken.client_id, ); const user = await userPool.getUserByUsername(ctx, decodedToken.sub); if (!user) { @@ -53,7 +53,7 @@ export const VerifyUserAttribute = ...user, Attributes: attributesAppend( user.Attributes, - attribute("email_verified", "true") + attribute("email_verified", "true"), ), UserLastModifiedDate: clock.get(), }); @@ -62,7 +62,7 @@ export const VerifyUserAttribute = ...user, Attributes: attributesAppend( user.Attributes, - attribute("phone_number_verified", "true") + attribute("phone_number_verified", "true"), ), UserLastModifiedDate: clock.get(), });