Skip to content

Commit

Permalink
Merge branch 'next' into task/OV-1-add-sign-in-flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksandra Nedashkivska committed Aug 21, 2024
2 parents f554d56 + a9f040c commit fc3f5f3
Show file tree
Hide file tree
Showing 15 changed files with 231 additions and 9 deletions.
70 changes: 69 additions & 1 deletion backend/src/bundles/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { type UserSignUpRequestDto } from '~/bundles/users/users.js';
import {
type UserSignInRequestDto,
type UserSignUpRequestDto,
userSignInValidationSchema,
} from '~/bundles/users/users.js';
import { userSignUpValidationSchema } from '~/bundles/users/users.js';
import {
type ApiHandlerOptions,
Expand All @@ -20,6 +24,20 @@ class AuthController extends BaseController {

this.authService = authService;

this.addRoute({
path: AuthApiPath.SIGN_IN,
method: 'POST',
validation: {
body: userSignInValidationSchema,
},
handler: (options) =>
this.signIn(
options as ApiHandlerOptions<{
body: UserSignInRequestDto;
}>,
),
});

this.addRoute({
path: AuthApiPath.SIGN_UP,
method: 'POST',
Expand All @@ -35,6 +53,55 @@ class AuthController extends BaseController {
});
}

/**
* @swagger
* /auth/sign-in:
* post:
* description: Sign in user into the application
* requestBody:
* description: User auth data
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* format: email
* password:
* type: string
* responses:
* 200:
* description: Successful operation
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: object
* $ref: '#/components/schemas/User'
* 400:
* description: Failed operation
* content:
* application/json:
* schema:
* type: object
* $ref: '#/components/schemas/Error'
*/

private async signIn(
options: ApiHandlerOptions<{
body: UserSignInRequestDto;
}>,
): Promise<ApiHandlerResponse> {
return {
payload: await this.authService.signIn(options.body),
status: HttpCode.OK,
};
}

/**
* @swagger
* /auth/sign-up:
Expand Down Expand Up @@ -65,6 +132,7 @@ class AuthController extends BaseController {
* type: object
* $ref: '#/components/schemas/User'
*/

private async signUp(
options: ApiHandlerOptions<{
body: UserSignUpRequestDto;
Expand Down
38 changes: 38 additions & 0 deletions backend/src/bundles/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import {
type UserSignUpResponseDto,
} from '~/bundles/users/types/types.js';
import { type UserService } from '~/bundles/users/user.service.js';
import {
type UserSignInRequestDto,
type UserSignInResponseDto,
} from '~/bundles/users/users.js';
import { HttpCode, HttpError } from '~/common/http/http.js';
import { cryptService } from '~/common/services/services.js';

import { UserValidationMessage } from './enums/enums.js';

class AuthService {
private userService: UserService;
Expand All @@ -11,6 +19,36 @@ class AuthService {
this.userService = userService;
}

public async signIn(
userRequestDto: UserSignInRequestDto,
): Promise<UserSignInResponseDto> {
const { email, password } = userRequestDto;
const user = await this.userService.findByEmail(email);

if (!user) {
throw new HttpError({
message: UserValidationMessage.WRONG_CREDENTIALS,
status: HttpCode.BAD_REQUEST,
});
}

const { passwordHash } = user.toNewObject();

const isPwdCorrect = cryptService.compareSyncPassword(
password,
passwordHash,
);

if (!isPwdCorrect) {
throw new HttpError({
message: UserValidationMessage.WRONG_CREDENTIALS,
status: HttpCode.BAD_REQUEST,
});
}

return user.toObject();
}

public signUp(
userRequestDto: UserSignUpRequestDto,
): Promise<UserSignUpResponseDto> {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/bundles/auth/enums/enums.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { AuthApiPath } from 'shared';
export { AuthApiPath, UserValidationMessage } from 'shared';
2 changes: 2 additions & 0 deletions backend/src/bundles/users/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export {
type UserGetAllResponseDto,
type UserSignInRequestDto,
type UserSignInResponseDto,
type UserSignUpRequestDto,
type UserSignUpResponseDto,
} from 'shared';
6 changes: 6 additions & 0 deletions backend/src/bundles/users/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class UserRepository implements Repository {
return Promise.resolve(null);
}

public async findByEmail(email: string): Promise<UserEntity | null> {
const user = await this.userModel.query().findOne({ email }).execute();

return user ? UserEntity.initialize(user) : null;
}

public async findAll(): Promise<UserEntity[]> {
const users = await this.userModel.query().execute();

Expand Down
4 changes: 4 additions & 0 deletions backend/src/bundles/users/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class UserService implements Service {
return Promise.resolve(null);
}

public async findByEmail(email: string): Promise<UserEntity | null> {
return await this.userRepository.findByEmail(email);
}

public async findAll(): Promise<UserGetAllResponseDto> {
const items = await this.userRepository.findAll();

Expand Down
7 changes: 6 additions & 1 deletion backend/src/bundles/users/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ const userController = new UserController(logger, userService);

export { userController, userService };
export {
type UserSignInRequestDto,
type UserSignInResponseDto,
type UserSignUpRequestDto,
type UserSignUpResponseDto,
} from './types/types.js';
export { UserModel } from './user.model.js';
export { userSignUpValidationSchema } from './validation-schemas/validation-schemas.js';
export {
userSignInValidationSchema,
userSignUpValidationSchema,
} from './validation-schemas/validation-schemas.js';
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { userSignUpValidationSchema } from 'shared';
export { userSignInValidationSchema, userSignUpValidationSchema } from 'shared';
20 changes: 18 additions & 2 deletions backend/src/common/server-application/base-server-app-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,27 @@ class BaseServerAppApi implements ServerAppApi {
definition: {
openapi: '3.0.0',
info: {
title: 'Hello World',
title: 'OutreachVids API documentation',
version: `${this.version}.0.0`,
},
components: {
schemas: {
Error: {
type: 'object',
properties: {
errorType: {
type: 'string',
enum: ['COMMON', 'VALIDATION'],
},
message: {
type: 'string',
},
},
},
},
},
},
apis: [`src/packages/**/*.controller.${controllerExtension}`],
apis: [`src/bundles/**/*.controller.${controllerExtension}`],
});
}
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/bundles/common/components/components.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { Button } from './button/button.js';
export { Header } from './header/header.js';
export { Input } from './input/input.js';
export { Link } from './link/link.js';
export { Loader } from './loader/loader.js';
Expand Down
33 changes: 33 additions & 0 deletions frontend/src/bundles/common/components/header/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Flex, Text } from '@chakra-ui/react';

const Header = (): JSX.Element => {
return (
<Flex
as="header"
height="75px"
position="sticky"
top="0"
left="0"
width="100%"
backgroundColor="background.900"
color="white"
boxShadow="md"
zIndex="1000"
padding="4"
marginBottom="20px"
>
<Flex
width="full"
alignItems="center"
maxWidth="1440px"
justifyContent="space-between"
>
<Text fontSize="xl" fontWeight="lighter">
Logo
</Text>
</Flex>
</Flex>
);
};

export { Header };
3 changes: 1 addition & 2 deletions frontend/src/framework/theme/styles/colors.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ const colors = {
50: '#e2e1ec',
},
brand: {
900: '#1a365d',
200: '#b3e0ff',
secondary: {
50: '#3BAF28',
300: '#ff6e1c',
600: '#eb5500',
900: '#e13b00',
Expand Down
50 changes: 49 additions & 1 deletion frontend/src/framework/theme/styles/components.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,55 @@ import { colors } from './colors.styles.js';
const components = {
Heading: {
baseStyle: {
color: colors.text.accent,
color: colors.white,
fontFamily: 'Poppins, sans-serif',
textAlign: 'left',
},
variants: {
H1: {
fontSize: '54px',
fontWeight: '600',
lineHeight: '64px',
},
H2: {
fontSize: '30px',
fontWeight: '600',
lineHeight: '32px',
},
H3: {
fontSize: '18px',
fontWeight: '700',
lineHeight: '27px',
},
},
},
Text: {
baseStyle: {
color: colors.white,
fontFamily: 'Poppins, sans-serif',
textAlign: 'left',
},
variants: {
body1: {
fontSize: '16px',
fontWeight: '500',
lineHeight: '22px',
},
bodySmall: {
fontSize: '14px',
fontWeight: '400',
lineHeight: '20px',
},
caption: {
fontSize: '12px',
fontWeight: '400',
lineHeight: '16px',
},
button: {
fontSize: '14px',
fontWeight: '600',
lineHeight: '16px',
},
},
},
Button: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const UserValidationMessage = {
EMAIL_INVALID: 'Please enter a valid email',
PASSWORD_LENGTH: 'Password must have from 6 to 12 characters',
INVALID_DATA: 'Incorrect email or password. Please try again.',
WRONG_CREDENTIALS: 'Email or password are incorrect',
} as const;

export { UserValidationMessage };
1 change: 1 addition & 0 deletions shared/src/framework/http/enums/http-code.enum.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const HttpCode = {
OK: 200,
CREATED: 201,
BAD_REQUEST: 400,
UNPROCESSED_ENTITY: 422,
INTERNAL_SERVER_ERROR: 500,
} as const;
Expand Down

0 comments on commit fc3f5f3

Please sign in to comment.