Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/next' into task/OV-3-add-sign-up…
Browse files Browse the repository at this point in the history
…-flow
  • Loading branch information
JPjok3r committed Aug 24, 2024
2 parents 3a962ad + e05cf25 commit 0584350
Show file tree
Hide file tree
Showing 78 changed files with 1,522 additions and 131 deletions.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Task
description: Abstract task description
title: 'TASK:'
projects: 'BinaryStudioAcademy/30'
body:
- type: textarea
id: what-feature
attributes:
label: What task?
placeholder: Add descriptions
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Add screenshots
placeholder: Add screenshots, mockups, etc.
2 changes: 2 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"scripts": {
"lint:type": "npx tsc --noEmit",
"lint:js": "npx eslint \"src/**/*.ts\"",
"lint:js:fix": "npx eslint --fix \"src/**/*.ts\"",
"lint": "npm run lint:type && npm run lint:js",
"lint:fix": "npm run lint:type && npm run lint:js:fix",
"start:dev": "nodemon --exec tsx src/index.ts",
"migrate:dev": "node --loader ts-paths-esm-loader ../node_modules/knex/bin/cli.js migrate:latest",
"migrate:dev:make": "node --loader ts-paths-esm-loader ../node_modules/knex/bin/cli.js migrate:make -x ts",
Expand Down
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 @@ -67,6 +134,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
7 changes: 7 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
"scripts": {
"lint:css": "npx stylelint \"src/**/*.scss\" --aei",
"lint:js": "npx eslint \"src/**/*.{ts,tsx}\"",
"lint:js:fix": "npx eslint --fix \"src/**/*.{ts,tsx}\"",
"lint:type": "npx tsc --noEmit",
"lint": "npm run lint:type && npm run lint:js",
"lint:fix": "npm run lint:type && npm run lint:js:fix",
"start:dev": "vite",
"build": "tsc -p tsconfig.build.json && vite build",
"preview": "vite preview"
Expand All @@ -27,16 +29,21 @@
"vite": "5.4.0"
},
"dependencies": {
"@chakra-ui/icons": "2.1.1",
"@chakra-ui/react": "2.8.2",
"@emotion/react": "11.13.0",
"@emotion/styled": "11.13.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@fortawesome/react-fontawesome": "0.2.2",
"@reduxjs/toolkit": "2.2.7",
"@remotion/player": "4.0.201",
"formik": "2.4.6",
"framer-motion": "11.3.24",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-redux": "9.1.2",
"react-router-dom": "6.26.0",
"remotion": "4.0.201",
"shared": "*",
"zod-formik-adapter": "1.3.0"
}
Expand Down
56 changes: 2 additions & 54 deletions frontend/src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,9 @@
import reactLogo from '~/assets/img/react.svg';
import { Link, RouterOutlet } from '~/bundles/common/components/components.js';
import { AppRoute } from '~/bundles/common/enums/enums.js';
import {
useAppDispatch,
useAppSelector,
useEffect,
useLocation,
} from '~/bundles/common/hooks/hooks.js';
import { actions as userActions } from '~/bundles/users/store/users.js';
import { RouterOutlet } from '~/bundles/common/components/components.js';

const App: React.FC = () => {
const { pathname } = useLocation();
const dispatch = useAppDispatch();
const { users, dataStatus } = useAppSelector(({ users }) => ({
users: users.users,
dataStatus: users.dataStatus,
}));

const isRoot = pathname === AppRoute.ROOT;

useEffect(() => {
if (isRoot) {
void dispatch(userActions.loadAll());
}
}, [isRoot, dispatch]);

return (
<>
<img src={reactLogo} width="30" alt="logo" />

<ul>
<li>
<Link to={AppRoute.ROOT}>Root</Link>
</li>
<li>
<Link to={AppRoute.SIGN_IN}>Sign in</Link>
</li>
<li>
<Link to={AppRoute.SIGN_UP}>Sign up</Link>
</li>
</ul>
<p>Current path: {pathname}</p>

<div>
<RouterOutlet />
</div>
{isRoot && (
<>
<h2>Users:</h2>
<h3>Status: {dataStatus}</h3>
<ul>
{users.map((it) => (
<li key={it.id}>{it.email}</li>
))}
</ul>
</>
)}
<RouterOutlet />
</>
);
};
Expand Down
18 changes: 18 additions & 0 deletions frontend/src/bundles/auth/auth-api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ApiPath, ContentType } from '~/bundles/common/enums/enums.js';
import {
type UserSignInRequestDto,
type UserSignInResponseDto,
type UserSignUpRequestDto,
type UserSignUpResponseDto,
} from '~/bundles/users/users.js';
Expand All @@ -20,6 +22,22 @@ class AuthApi extends BaseHttpApi {
super({ path: ApiPath.AUTH, baseUrl, http, storage });
}

public async signIn(
payload: UserSignInRequestDto,
): Promise<UserSignInResponseDto> {
const response = await this.load(
this.getFullEndpoint(AuthApiPath.SIGN_IN, {}),
{
method: 'POST',
contentType: ContentType.JSON,
payload: JSON.stringify(payload),
hasAuth: false,
},
);

return await response.json<UserSignInResponseDto>();
}

public async signUp(
payload: UserSignUpRequestDto,
): Promise<UserSignUpResponseDto> {
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/bundles/auth/components/common/components.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { FormError } from './form-error/form-error.js';
export { FormHeader } from './form-header/form-header.js';
export { PasswordInput } from './password-input/password-input.js';
Loading

0 comments on commit 0584350

Please sign in to comment.