Skip to content

Commit

Permalink
fix: return UserEntity from userQuery.findByName
Browse files Browse the repository at this point in the history
  • Loading branch information
solufa committed Dec 30, 2024
1 parent 64c4139 commit 95e2c81
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 24 deletions.
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@ export default tseslint.config(
files: ['**/*.js'],
rules: { '@typescript-eslint/no-require-imports': ['off'] },
},
{ files: ['server/tests/**/*.ts'], rules: { 'max-lines': 'off' } },
prettierConfig,
);
10 changes: 4 additions & 6 deletions server/domain/user/repository/userQuery.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Prisma } from '@prisma/client';
import { USER_KINDS } from 'common/constants';
import type { MaybeId } from 'common/types/brandedId';
import type { CognitoUserEntity, SocialUserEntity, UserEntity } from 'common/types/user';
import { toCognitoUserEntity, toSocialUserEntity, toUserEntity } from './toUserEntity';
import type { SocialUserEntity, UserEntity } from 'common/types/user';
import { toSocialUserEntity, toUserEntity } from './toUserEntity';

export const userQuery = {
countId: (tx: Prisma.TransactionClient, id: string): Promise<number> =>
Expand Down Expand Up @@ -39,10 +39,8 @@ export const userQuery = {
id: UserEntity['id'] | MaybeId['socialUser'],
): Promise<UserEntity> =>
tx.user.findUniqueOrThrow({ where: { id }, include: { attributes: true } }).then(toUserEntity),
findByName: (tx: Prisma.TransactionClient, name: string): Promise<CognitoUserEntity> =>
tx.user
.findFirstOrThrow({ where: { name }, include: { attributes: true } })
.then(toCognitoUserEntity),
findByName: (tx: Prisma.TransactionClient, name: string): Promise<UserEntity> =>
tx.user.findFirstOrThrow({ where: { name }, include: { attributes: true } }).then(toUserEntity),
findByRefreshToken: (tx: Prisma.TransactionClient, refreshToken: string): Promise<UserEntity> =>
tx.user
.findFirstOrThrow({ where: { refreshToken }, include: { attributes: true } })
Expand Down
21 changes: 11 additions & 10 deletions server/domain/user/useCase/adminUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ import { toAttributeTypes } from '../service/createAttributes';
import { genTokens } from '../service/genTokens';
import { sendTemporaryPassword } from '../service/sendAuthMail';

const findUser = async (
tx: Prisma.TransactionClient,
req: AdminCreateUserTarget['reqBody'],
): Promise<CognitoUserEntity> => {
assert(req.Username);

return await userQuery.findByName(tx, req.Username);
};

const createUser = async (
tx: Prisma.TransactionClient,
req: AdminCreateUserTarget['reqBody'],
Expand All @@ -57,7 +48,13 @@ export const adminUseCase = {
},
createUser: (req: AdminCreateUserTarget['reqBody']): Promise<AdminCreateUserTarget['resBody']> =>
transaction(async (tx) => {
const user = await (req.MessageAction === 'RESEND' ? findUser : createUser)(tx, req);
assert(req.Username);

const user = await (req.MessageAction === 'RESEND'
? userQuery.findByName(tx, req.Username)
: createUser(tx, req));

assert(user.kind === 'cognito');

if (req.MessageAction !== 'SUPPRESS') await sendTemporaryPassword(user);

Expand Down Expand Up @@ -115,6 +112,8 @@ export const adminUseCase = {

const user = await userQuery.findByName(tx, req.Username);

assert(user.kind === 'cognito');

await userCommand.save(tx, adminMethod.setUserPassword(user, req));

return {};
Expand All @@ -127,6 +126,8 @@ export const adminUseCase = {

const user = await userQuery.findByName(tx, req.Username);

assert(user.kind === 'cognito');

await userCommand.save(tx, adminMethod.updateAttributes(user, req.UserAttributes));

return {};
Expand Down
4 changes: 4 additions & 0 deletions server/domain/user/useCase/authUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ export const authUseCase = {
transaction(async (tx) => {
const poolClient = await userPoolQuery.findClientById(tx, req.ClientId);
const user = await userQuery.findByName(tx, req.Username);

assert(poolClient.userPoolId === user.userPoolId);
assert(user.kind === 'cognito');

const forgotUser = cognitoUserMethod.forgotPassword(user);
await userCommand.save(tx, forgotUser);
Expand All @@ -93,6 +95,8 @@ export const authUseCase = {
transaction(async (tx) => {
const user = await userQuery.findByName(tx, req.Username);

assert(user.kind === 'cognito');

await userCommand.save(
tx,
cognitoUserMethod.confirmForgotPassword({
Expand Down
3 changes: 3 additions & 0 deletions server/domain/user/useCase/signInUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export const signInUseCase = {
userSrpAuth: (req: UserSrpAuthTarget['reqBody']): Promise<UserSrpAuthTarget['resBody']> =>
transaction(async (tx) => {
const user = await userQuery.findByName(tx, req.AuthParameters.USERNAME).catch(() => null);

cognitoAssert(user, 'Incorrect username or password.');
assert(user.kind === 'cognito');

const { userWithChallenge, ChallengeParameters } = signInMethod.createChallenge(
user,
Expand Down Expand Up @@ -65,6 +67,7 @@ export const signInUseCase = {
const jwks = await userPoolQuery.findJwks(tx, user.userPoolId);

assert(pool.id === poolClient.userPoolId);
assert(user.kind === 'cognito');

if (req.ChallengeName === 'PASSWORD_VERIFIER') {
assert(user.challenge);
Expand Down
4 changes: 4 additions & 0 deletions server/domain/user/useCase/signUpUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export const signUpUseCase = {
confirmSignUp: (req: ConfirmSignUpTarget['reqBody']): Promise<ConfirmSignUpTarget['resBody']> =>
transaction(async (tx) => {
const user = await userQuery.findByName(tx, req.Username);

assert(user.kind === 'cognito');

const confirmed = cognitoUserMethod.confirm(user, req.ConfirmationCode);

await userCommand.save(tx, confirmed);
Expand All @@ -57,6 +60,7 @@ export const signUpUseCase = {
const user = await userQuery.findByName(tx, req.Username);

assert(poolClient.userPoolId === user.userPoolId);
assert(user.kind === 'cognito');

await sendConfirmationCode(user);

Expand Down
3 changes: 0 additions & 3 deletions server/domain/user/useCase/userUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ export const userUseCase = {

const decoded = jwtDecode<AccessTokenJwt>(req.AccessToken);
const user = await userQuery.findById(tx, decoded.sub);

assert(user.kind === 'cognito');

const deletableId = userMethod.delete(user);

await userCommand.delete(tx, deletableId);
Expand Down
2 changes: 1 addition & 1 deletion server/tests/api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const createSocialUserAndToken = async (): Promise<{ AccessToken: string
const user = await noCookieClient.public.socialUsers.$post({
body: {
provider: 'Google',
name: 'user1',
name: testUserName,
email: `${ulid()}@example.com`,
codeChallenge: createHash('sha256').update(codeVerifier).digest('base64url'),
userPoolClientId: DEFAULT_USER_POOL_CLIENT_ID,
Expand Down
19 changes: 17 additions & 2 deletions server/tests/sdk/admin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import assert from 'assert';
import { cognitoClient } from 'service/cognito';
import { DEFAULT_USER_POOL_CLIENT_ID, DEFAULT_USER_POOL_ID } from 'service/envValues';
import { createUserClient, testPassword, testUserName } from 'tests/api/apiClient';
import { createCognitoUserAndToken, fetchMailBodyAndTrash, inbucketClient } from 'tests/api/utils';
import {
createCognitoUserAndToken,
createSocialUserAndToken,
fetchMailBodyAndTrash,
inbucketClient,
} from 'tests/api/utils';
import { ulid } from 'ulid';
import { expect, test } from 'vitest';

Expand Down Expand Up @@ -107,7 +112,7 @@ test(`${AdminCreateUserCommand.name} - unset TemporaryPassword`, async () => {
expect(res.UserStatus).toBe(UserStatusType.FORCE_CHANGE_PASSWORD);
});

test(AdminDeleteUserCommand.name, async () => {
test(`${AdminDeleteUserCommand.name} - cognito`, async () => {
const userClient = await createCognitoUserAndToken().then(createUserClient);

await cognitoClient.send(
Expand All @@ -117,6 +122,16 @@ test(AdminDeleteUserCommand.name, async () => {
await expect(userClient.private.me.get()).rejects.toThrow();
});

test(`${AdminDeleteUserCommand.name} - social`, async () => {
const userClient = await createSocialUserAndToken().then(createUserClient);

await cognitoClient.send(
new AdminDeleteUserCommand({ UserPoolId: DEFAULT_USER_POOL_ID, Username: testUserName }),
);

await expect(userClient.private.me.get()).rejects.toThrow();
});

test(AdminUpdateUserAttributesCommand.name, async () => {
const newEmail = `${ulid()}@example.com`;
const attrName1 = 'custom:test1';
Expand Down
40 changes: 38 additions & 2 deletions server/tests/sdk/user.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,20 @@ test(VerifyUserAttributeCommand.name, async () => {
expect(emailAttr?.Value).toBe(newEmail);
});

test(DeleteUserCommand.name, async () => {
test(`${DeleteUserCommand.name} - cognito`, async () => {
const token = await createCognitoUserAndToken();
const res1 = await cognitoClient.send(new ListUsersCommand({ UserPoolId: DEFAULT_USER_POOL_ID }));

await cognitoClient.send(new DeleteUserCommand(token));

const res2 = await cognitoClient.send(new ListUsersCommand({ UserPoolId: DEFAULT_USER_POOL_ID }));

expect(res1.Users).toHaveLength(1);
expect(res2.Users).toHaveLength(0);
});

test(`${DeleteUserCommand.name} - social`, async () => {
const token = await createSocialUserAndToken();
const res1 = await cognitoClient.send(new ListUsersCommand({ UserPoolId: DEFAULT_USER_POOL_ID }));

await cognitoClient.send(new DeleteUserCommand(token));
Expand All @@ -122,7 +133,7 @@ test(DeleteUserCommand.name, async () => {
expect(res2.Users).toHaveLength(0);
});

test(DeleteUserAttributesCommand.name, async () => {
test(`${DeleteUserAttributesCommand.name} - cognito`, async () => {
const token = await createCognitoUserAndToken();
const attrName1 = 'custom:test1';
const attrName2 = 'custom:test2';
Expand All @@ -146,3 +157,28 @@ test(DeleteUserAttributesCommand.name, async () => {
expect(user.UserAttributes?.every((attr) => attr.Name !== attrName1)).toBeTruthy();
expect(user.UserAttributes?.some((attr) => attr.Name === attrName2)).toBeTruthy();
});

test(`${DeleteUserAttributesCommand.name} - social`, async () => {
const token = await createSocialUserAndToken();
const attrName1 = 'custom:test1';
const attrName2 = 'custom:test2';

await cognitoClient.send(
new UpdateUserAttributesCommand({
...token,
UserAttributes: [
{ Name: attrName1, Value: 'sample1' },
{ Name: attrName2, Value: 'sample2' },
],
}),
);

await cognitoClient.send(
new DeleteUserAttributesCommand({ ...token, UserAttributeNames: [attrName1] }),
);

const user = await cognitoClient.send(new GetUserCommand(token));

expect(user.UserAttributes?.every((attr) => attr.Name !== attrName1)).toBeTruthy();
expect(user.UserAttributes?.some((attr) => attr.Name === attrName2)).toBeTruthy();
});

0 comments on commit 95e2c81

Please sign in to comment.