Skip to content

Commit 24ea303

Browse files
committed
Adds vk_id
1 parent 26988f0 commit 24ea303

File tree

13 files changed

+82
-57
lines changed

13 files changed

+82
-57
lines changed

backend/src/auth/auth.controller.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
ValidationPipe,
66
UnprocessableEntityException,
77
} from "@nestjs/common";
8-
import { AuthModel, UserModel, AuthVK, IGrant } from "./../models";
8+
import { AuthModel, UserModel, AuthVK, IGrant, UserDTO } from "./../models";
99
import { AuthService } from "./auth.service";
1010
import { UserService } from "./../user";
1111

@@ -17,7 +17,7 @@ export class AuthController {
1717
) {}
1818

1919
@Post("/login/vk")
20-
async vk(@Body(new ValidationPipe()) auth: AuthVK): Promise<any> {
20+
async vk(@Body(new ValidationPipe()) auth: AuthVK): Promise<UserDTO> {
2121
let authData;
2222

2323
try {
@@ -26,14 +26,14 @@ export class AuthController {
2626
throw new UnprocessableEntityException("Wrong VK code");
2727
}
2828

29-
if (!authData.data.hasOwnProperty("email")) {
30-
throw new UnprocessableEntityException("Email should be provided");
31-
}
29+
const hasEmail = authData.data.hasOwnProperty("email");
3230

33-
const emailUser = await this.userService.findByEmail(authData.data.email);
31+
const _user = hasEmail
32+
? await this.userService.findByEmail(authData.data.email)
33+
: await this.userService.findByVkId(authData.data.user_id);
3434

35-
if (emailUser) {
36-
return this.authService.authenticate(emailUser, true);
35+
if (_user) {
36+
return this.authService.authenticate(_user, true);
3737
}
3838

3939
try {
@@ -45,6 +45,7 @@ export class AuthController {
4545
const profile = data.response[0];
4646

4747
let user: UserModel = {
48+
vk_id: authData.data.user_id,
4849
email: authData.data.email,
4950
password: null,
5051
name: `${profile.first_name} ${profile.last_name}`,
@@ -61,18 +62,18 @@ export class AuthController {
6162
}
6263

6364
@Post("/login")
64-
async login(@Body(new ValidationPipe()) auth: AuthModel): Promise<string> {
65+
async login(@Body(new ValidationPipe()) auth: AuthModel): Promise<UserDTO> {
6566
return this.authService.authenticate(auth);
6667
}
6768

6869
@Post("/register")
6970
async register(
7071
@Body(new ValidationPipe()) userModel: UserModel
71-
): Promise<string> {
72+
): Promise<UserDTO> {
7273
const emailExists = await this.userService.findByEmail(userModel.email);
7374

7475
if (emailExists) {
75-
throw new UnprocessableEntityException();
76+
throw new UnprocessableEntityException("Email already exists!");
7677
}
7778

7879
await this.userService.create(userModel);

backend/src/auth/auth.service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { JwtService } from "@nestjs/jwt";
44
import { UserService } from "./../user";
55
import { UserEntity } from "../entities";
66
import { JwtPayloadInterface } from "./interfaces";
7-
import { AuthModel } from "../models";
7+
import { AuthModel, UserDTO } from "../models";
88

99
@Injectable()
1010
export class AuthService {
@@ -21,7 +21,7 @@ export class AuthService {
2121
async authenticate(
2222
auth: AuthModel,
2323
skipPasswordCheck: boolean = false
24-
): Promise<any> {
24+
): Promise<UserDTO> {
2525
const user = await this.userService.findByEmailWithPassword(auth.email);
2626

2727
if (!user) {
@@ -39,6 +39,7 @@ export class AuthService {
3939

4040
return {
4141
id: user.id,
42+
vk_id: user.vk_id,
4243
email: user.email,
4344
grant: user.grant,
4445
name: user.name,

backend/src/entities/user.entity.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { Entity, Column } from "typeorm";
33

44
@Entity()
55
export class UserEntity extends BaseEntity {
6+
@Column({
7+
nullable: true,
8+
})
9+
vk_id: number;
10+
611
@Column()
712
name: string;
813

backend/src/models/user.model.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export enum IGrant {
66
}
77

88
export class UserModel {
9+
vk_id?: number;
10+
911
@IsEmail()
1012
email: string;
1113

@@ -20,3 +22,13 @@ export class UserModel {
2022

2123
avatar_url?: string;
2224
}
25+
26+
export class UserDTO {
27+
id: number;
28+
vk_id: number;
29+
email: string;
30+
name: string;
31+
grant: IGrant;
32+
avatar_url: string;
33+
token: string;
34+
}

backend/src/user/user.service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ export class UserService {
4747
});
4848
}
4949

50+
async findByVkId(vk_id: number): Promise<User | null> {
51+
return await this.userRepository.findOne({
52+
where: {
53+
vk_id,
54+
},
55+
});
56+
}
57+
5058
async findById(id: number): Promise<UserEntity | null> {
5159
return await this.userRepository.findOneOrFail(id);
5260
}

frontend/src/App/index.tsx

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
import React from "react";
2-
import { observer } from "mobx-react";
32
import { BrowserRouter, Switch, Route } from "react-router-dom";
43

54
import NotFound from "pages/404";
65
import SignInPage from "pages/SignInPage";
76
import UserPage from "pages/UserPage";
87
import HomePage from "pages/HomePage";
98

10-
import { RequestState } from "types/RequestState";
11-
12-
import { useStores } from "stores/useStores";
13-
149
interface IProps {}
1510

16-
const App: React.FC<IProps> = observer(() => {
17-
const { user, state, getProfile } = useStores()["UserStore"];
18-
19-
React.useEffect(() => {
20-
const token = sessionStorage.getItem("token");
21-
22-
if (!user && state !== RequestState.LOADING && token) {
23-
getProfile().catch(console.log);
24-
}
25-
}, [user, state, getProfile]);
26-
27-
// if (state === RequestState.LOADING) return <p>Loading..</p>;
28-
11+
const App: React.FC<IProps> = () => {
2912
return (
3013
<BrowserRouter>
3114
<Switch>
@@ -37,6 +20,6 @@ const App: React.FC<IProps> = observer(() => {
3720
</Switch>
3821
</BrowserRouter>
3922
);
40-
});
23+
};
4124

4225
export default App;
Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
11
import React from "react";
2+
import { observer } from "mobx-react";
3+
import { Link, useHistory } from "react-router-dom";
24

3-
import styles from "./LayoutDefault.module.scss";
4-
import { Link } from "react-router-dom";
5-
import { IUser } from "stores/UserStore";
65
import { useStores } from "stores/useStores";
6+
import { RequestState } from "types/RequestState";
7+
8+
import styles from "./LayoutDefault.module.scss";
9+
10+
const PRIVATE_ROUTES = ["/user"];
11+
12+
const LayoutDefault: React.FC = observer((props) => {
13+
const { user, state, getProfile, logout } = useStores()["UserStore"];
14+
let history = useHistory();
15+
16+
React.useEffect(() => {
17+
const token = sessionStorage.getItem("token");
18+
19+
if (PRIVATE_ROUTES.includes(history.location.pathname) && !token)
20+
return history.push("/signin");
721

8-
const LayoutDefault: React.FC = (props) => {
9-
const user: IUser = useStores()["UserStore"].user;
22+
if (!user && state !== RequestState.LOADING && token) {
23+
getProfile().catch(() => {
24+
history.push("/signin");
25+
logout();
26+
});
27+
}
28+
}, [user, state, getProfile, logout, history]);
1029

1130
return (
1231
<div className={styles["layout-default"]}>
@@ -15,12 +34,12 @@ const LayoutDefault: React.FC = (props) => {
1534
{user ? (
1635
<Link to="/user">Мой профиль</Link>
1736
) : (
18-
<Link to="/user">Войти</Link>
37+
<Link to="/signin">Войти</Link>
1938
)}
2039
</div>
2140
<div className={styles["layout-default__content"]}>{props.children}</div>
2241
</div>
2342
);
24-
};
43+
});
2544

2645
export default LayoutDefault;

frontend/src/components/LayoutUser/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const LayoutUser: React.FC<IProps> = (props) => {
1010
return (
1111
<LayoutDefault>
1212
<div className={styles["layout-user"]}>
13-
{/* <h1 className={styles["layout-user__header"]}>Профиль</h1> */}
1413
<div className={styles["layout-user__main"]}>
1514
<div className={styles["layout-user__content"]}>{props.children}</div>
1615
</div>

frontend/src/components/VKButton/VKButton.module.scss

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
.vk-button__input {
2-
width: 150px;
32
display: flex;
4-
background-color: #4680c2;
3+
54
align-items: center;
6-
color: white;
5+
color: #4680c2;
76
border: none;
87
border-radius: 10px;
98
font-weight: bold;
109
padding-right: 20px;
1110
cursor: pointer;
11+
12+
&:hover {
13+
opacity: 0.8;
14+
}
1215
}
1316

1417
.vk-button {

frontend/src/components/VKButton/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const VKButton: React.FC<IProps> = (props) => {
4949
alt="vk logo"
5050
className={styles["vk-button__input-icon"]}
5151
/>
52-
Вконтакте
52+
Войти через Вконтакте
5353
</button>
5454
{isError && <p style={{ color: "red" }}>Ошибка входа через ВК</p>}
5555
</div>

0 commit comments

Comments
 (0)