Skip to content

Commit

Permalink
Adds vk_id
Browse files Browse the repository at this point in the history
  • Loading branch information
ndrwbv committed Aug 3, 2020
1 parent 26988f0 commit 24ea303
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 57 deletions.
23 changes: 12 additions & 11 deletions backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ValidationPipe,
UnprocessableEntityException,
} from "@nestjs/common";
import { AuthModel, UserModel, AuthVK, IGrant } from "./../models";
import { AuthModel, UserModel, AuthVK, IGrant, UserDTO } from "./../models";
import { AuthService } from "./auth.service";
import { UserService } from "./../user";

Expand All @@ -17,7 +17,7 @@ export class AuthController {
) {}

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

try {
Expand All @@ -26,14 +26,14 @@ export class AuthController {
throw new UnprocessableEntityException("Wrong VK code");
}

if (!authData.data.hasOwnProperty("email")) {
throw new UnprocessableEntityException("Email should be provided");
}
const hasEmail = authData.data.hasOwnProperty("email");

const emailUser = await this.userService.findByEmail(authData.data.email);
const _user = hasEmail
? await this.userService.findByEmail(authData.data.email)
: await this.userService.findByVkId(authData.data.user_id);

if (emailUser) {
return this.authService.authenticate(emailUser, true);
if (_user) {
return this.authService.authenticate(_user, true);
}

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

let user: UserModel = {
vk_id: authData.data.user_id,
email: authData.data.email,
password: null,
name: `${profile.first_name} ${profile.last_name}`,
Expand All @@ -61,18 +62,18 @@ export class AuthController {
}

@Post("/login")
async login(@Body(new ValidationPipe()) auth: AuthModel): Promise<string> {
async login(@Body(new ValidationPipe()) auth: AuthModel): Promise<UserDTO> {
return this.authService.authenticate(auth);
}

@Post("/register")
async register(
@Body(new ValidationPipe()) userModel: UserModel
): Promise<string> {
): Promise<UserDTO> {
const emailExists = await this.userService.findByEmail(userModel.email);

if (emailExists) {
throw new UnprocessableEntityException();
throw new UnprocessableEntityException("Email already exists!");
}

await this.userService.create(userModel);
Expand Down
5 changes: 3 additions & 2 deletions backend/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { JwtService } from "@nestjs/jwt";
import { UserService } from "./../user";
import { UserEntity } from "../entities";
import { JwtPayloadInterface } from "./interfaces";
import { AuthModel } from "../models";
import { AuthModel, UserDTO } from "../models";

@Injectable()
export class AuthService {
Expand All @@ -21,7 +21,7 @@ export class AuthService {
async authenticate(
auth: AuthModel,
skipPasswordCheck: boolean = false
): Promise<any> {
): Promise<UserDTO> {
const user = await this.userService.findByEmailWithPassword(auth.email);

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

return {
id: user.id,
vk_id: user.vk_id,
email: user.email,
grant: user.grant,
name: user.name,
Expand Down
5 changes: 5 additions & 0 deletions backend/src/entities/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { Entity, Column } from "typeorm";

@Entity()
export class UserEntity extends BaseEntity {
@Column({
nullable: true,
})
vk_id: number;

@Column()
name: string;

Expand Down
12 changes: 12 additions & 0 deletions backend/src/models/user.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export enum IGrant {
}

export class UserModel {
vk_id?: number;

@IsEmail()
email: string;

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

avatar_url?: string;
}

export class UserDTO {
id: number;
vk_id: number;
email: string;
name: string;
grant: IGrant;
avatar_url: string;
token: string;
}
8 changes: 8 additions & 0 deletions backend/src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ export class UserService {
});
}

async findByVkId(vk_id: number): Promise<User | null> {
return await this.userRepository.findOne({
where: {
vk_id,
},
});
}

async findById(id: number): Promise<UserEntity | null> {
return await this.userRepository.findOneOrFail(id);
}
Expand Down
21 changes: 2 additions & 19 deletions frontend/src/App/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,14 @@
import React from "react";
import { observer } from "mobx-react";
import { BrowserRouter, Switch, Route } from "react-router-dom";

import NotFound from "pages/404";
import SignInPage from "pages/SignInPage";
import UserPage from "pages/UserPage";
import HomePage from "pages/HomePage";

import { RequestState } from "types/RequestState";

import { useStores } from "stores/useStores";

interface IProps {}

const App: React.FC<IProps> = observer(() => {
const { user, state, getProfile } = useStores()["UserStore"];

React.useEffect(() => {
const token = sessionStorage.getItem("token");

if (!user && state !== RequestState.LOADING && token) {
getProfile().catch(console.log);
}
}, [user, state, getProfile]);

// if (state === RequestState.LOADING) return <p>Loading..</p>;

const App: React.FC<IProps> = () => {
return (
<BrowserRouter>
<Switch>
Expand All @@ -37,6 +20,6 @@ const App: React.FC<IProps> = observer(() => {
</Switch>
</BrowserRouter>
);
});
};

export default App;
33 changes: 26 additions & 7 deletions frontend/src/components/LayoutDefault/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import React from "react";
import { observer } from "mobx-react";
import { Link, useHistory } from "react-router-dom";

import styles from "./LayoutDefault.module.scss";
import { Link } from "react-router-dom";
import { IUser } from "stores/UserStore";
import { useStores } from "stores/useStores";
import { RequestState } from "types/RequestState";

import styles from "./LayoutDefault.module.scss";

const PRIVATE_ROUTES = ["/user"];

const LayoutDefault: React.FC = observer((props) => {
const { user, state, getProfile, logout } = useStores()["UserStore"];
let history = useHistory();

React.useEffect(() => {
const token = sessionStorage.getItem("token");

if (PRIVATE_ROUTES.includes(history.location.pathname) && !token)
return history.push("/signin");

const LayoutDefault: React.FC = (props) => {
const user: IUser = useStores()["UserStore"].user;
if (!user && state !== RequestState.LOADING && token) {
getProfile().catch(() => {
history.push("/signin");
logout();
});
}
}, [user, state, getProfile, logout, history]);

return (
<div className={styles["layout-default"]}>
Expand All @@ -15,12 +34,12 @@ const LayoutDefault: React.FC = (props) => {
{user ? (
<Link to="/user">Мой профиль</Link>
) : (
<Link to="/user">Войти</Link>
<Link to="/signin">Войти</Link>
)}
</div>
<div className={styles["layout-default__content"]}>{props.children}</div>
</div>
);
};
});

export default LayoutDefault;
1 change: 0 additions & 1 deletion frontend/src/components/LayoutUser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const LayoutUser: React.FC<IProps> = (props) => {
return (
<LayoutDefault>
<div className={styles["layout-user"]}>
{/* <h1 className={styles["layout-user__header"]}>Профиль</h1> */}
<div className={styles["layout-user__main"]}>
<div className={styles["layout-user__content"]}>{props.children}</div>
</div>
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/components/VKButton/VKButton.module.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
.vk-button__input {
width: 150px;
display: flex;
background-color: #4680c2;

align-items: center;
color: white;
color: #4680c2;
border: none;
border-radius: 10px;
font-weight: bold;
padding-right: 20px;
cursor: pointer;

&:hover {
opacity: 0.8;
}
}

.vk-button {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VKButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const VKButton: React.FC<IProps> = (props) => {
alt="vk logo"
className={styles["vk-button__input-icon"]}
/>
Вконтакте
Войти через Вконтакте
</button>
{isError && <p style={{ color: "red" }}>Ошибка входа через ВК</p>}
</div>
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from "react";
import LayoutDefault from "components/LayoutDefault";
import { observer } from "mobx-react";

import { useStores } from "stores/useStores";
import { IUser } from "stores/UserStore";

const HomePage = () => {
import LayoutDefault from "components/LayoutDefault";

const HomePage = observer(() => {
const user: IUser = useStores()["UserStore"].user;

return (
Expand All @@ -13,6 +15,6 @@ const HomePage = () => {
{user && <p>О привет, {user.name}</p>}
</LayoutDefault>
);
};
});

export default HomePage;
7 changes: 2 additions & 5 deletions frontend/src/pages/SignInPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import React from "react";
import { RouteComponentProps } from "react-router-dom";

import VKButton from "components/VKButton";

import styles from "./SignInPage.module.scss";
import LayoutDefault from "components/LayoutDefault";

interface IProps extends RouteComponentProps {}
import styles from "./SignInPage.module.scss";

const SignInPage: React.FC<IProps> = (props) => {
const SignInPage: React.FC = () => {
return (
<LayoutDefault>
<div className={styles["signin-page"]}>
Expand Down
5 changes: 0 additions & 5 deletions frontend/src/pages/UserPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ interface IProps extends RouteComponentProps {

class UserPage extends React.Component<IProps> {
componentDidMount() {
const { getProfile, user } = this.props.UserStore;
const token = sessionStorage.getItem("token");

if (!token) return this.props.history.push("/signin");

if (!user)
return getProfile().catch(() => this.props.history.push("/signin"));
}

handleLogout = () => {
Expand Down

0 comments on commit 24ea303

Please sign in to comment.