From c769f40a15db3f689709c34a1bd1e0fd3307e1e8 Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 1 Apr 2022 13:32:51 -0400 Subject: [PATCH] fixing auth check and content type error --- packages/api/middleware/auth.ts | 2 +- packages/api/routes/user.ts | 38 +++- packages/api/services/user.service.ts | 17 +- .../core/responses/userDetails.response.ts | 5 + packages/desktop/src/controller/index.tsx | 32 ++-- packages/desktop/src/controller/nirvanaApi.ts | 26 ++- .../desktop/src/pages/Home/header/index.tsx | 174 +++++++++--------- packages/desktop/src/pages/Home/index.tsx | 1 + packages/desktop/src/pages/Login/index.tsx | 4 +- 9 files changed, 174 insertions(+), 125 deletions(-) create mode 100644 packages/core/responses/userDetails.response.ts diff --git a/packages/api/middleware/auth.ts b/packages/api/middleware/auth.ts index 90493ec..ef83a94 100644 --- a/packages/api/middleware/auth.ts +++ b/packages/api/middleware/auth.ts @@ -22,7 +22,7 @@ export const authCheck = async ( // verify jwt token with our api secret var decoded: JwtClaims = jwt.verify(authorization, config.JWT_TOKEN_SECRET); - res.locals.jwtClaims = decoded; + res.locals.userInfo = decoded; next(); } catch (error) { diff --git a/packages/api/routes/user.ts b/packages/api/routes/user.ts index fe79654..b766dfd 100644 --- a/packages/api/routes/user.ts +++ b/packages/api/routes/user.ts @@ -1,13 +1,14 @@ import { GoogleUserInfo, User } from "@nirvana/core/models"; +import { JwtClaims, authCheck } from "../middleware/auth"; import express, { Application, Request, Response } from "express"; import LoginResponse from "../../core/responses/login.response"; import { OAuth2Client } from "google-auth-library"; import { ObjectID } from "bson"; import { ObjectId } from "mongodb"; +import UserDetailsResponse from "../../core/responses/userDetails.response"; import { UserService } from "../services/user.service"; import { UserStatus } from "../../core/models/user.model"; -import { authCheck } from "../middleware/auth"; import { collections } from "../services/database.service"; import { loadConfig } from "../config"; @@ -23,7 +24,7 @@ export default function getUserRoutes() { router.use(express.json()); // get user details based on id token - // router.get("/", authCheck, getUserDetails); + router.get("/", authCheck, getUserDetails); router.get("/login", login); @@ -34,9 +35,26 @@ export default function getUserRoutes() { async function handleAuthCheck(req: Request, res: Response) { try { - res.status(200).send(); + res.status(200).json("You are good to go!"); } catch (error) { - res.status(401).send(); + res.status(401).json("Unauthorized"); + } +} + +async function getUserDetails(req: Request, res: Response) { + try { + console.log(res.locals.userInfo as JwtClaims); + + const userInfo = res.locals.userInfo as JwtClaims; + + const user = await UserService.getUserById(userInfo.userId); + + user + ? res.status(200).json(new UserDetailsResponse(user)) + : res.status(404).json("No such user"); + } catch (error) { + console.log(error); + res.status(500).json(`Problem with signing user up or logging in`); } } @@ -56,7 +74,7 @@ async function login(req: Request, res: Response) { const email = ticket.getPayload()?.email as string; if (!googleUserId || !email) { - res.status(401).send("no google account found"); + res.status(401).json("no google account found"); return; } @@ -66,7 +84,7 @@ async function login(req: Request, res: Response) { // if no user found, then go ahead and create user if (!user) { if (!access_token) { - res.status(400).send("No access token provided"); + res.status(400).json("No access token provided"); return; } @@ -109,8 +127,8 @@ async function login(req: Request, res: Response) { ); insertResult - ? res.status(200).send(new LoginResponse(jwtToken, newUser)) - : res.status(500).send("Failed to create account, already exists"); + ? res.status(200).json(new LoginResponse(jwtToken, newUser)) + : res.status(500).json("Failed to create account, already exists"); return; } @@ -127,9 +145,9 @@ async function login(req: Request, res: Response) { config.JWT_TOKEN_SECRET ); - res.status(200).send(new LoginResponse(jwtToken, user)); + res.status(200).json(new LoginResponse(jwtToken, user)); } catch (error) { console.log(error); - res.status(500).send(`Problem with signing user up or logging in`); + res.status(500).json(`Problem with signing user up or logging in`); } } diff --git a/packages/api/services/user.service.ts b/packages/api/services/user.service.ts index 957d73c..7ae564f 100644 --- a/packages/api/services/user.service.ts +++ b/packages/api/services/user.service.ts @@ -6,8 +6,21 @@ import axios from "axios"; import { collections } from "./database.service"; export class UserService { - static async getUserByGoogleId(userId: string) { - const query = { googleId: userId }; + static async getUserById(userId: string) { + const query = { _id: userId }; + + const res = await collections.users?.findOne(query); + + // exists + if (res?._id) { + return res as User; + } + + return null; + } + + static async getUserByGoogleId(googleUserId: string) { + const query = { googleId: googleUserId }; const res = await collections.users?.findOne(query); diff --git a/packages/core/responses/userDetails.response.ts b/packages/core/responses/userDetails.response.ts new file mode 100644 index 0000000..92cb73f --- /dev/null +++ b/packages/core/responses/userDetails.response.ts @@ -0,0 +1,5 @@ +import { User } from "@nirvana/core/models"; + +export default class UserDetailsResponse { + constructor(public user: User) {} +} diff --git a/packages/desktop/src/controller/index.tsx b/packages/desktop/src/controller/index.tsx index a64535a..6bdabb3 100644 --- a/packages/desktop/src/controller/index.tsx +++ b/packages/desktop/src/controller/index.tsx @@ -1,32 +1,28 @@ -import NirvanaApi, { authCheck, login } from "./nirvanaApi"; +import NirvanaApi, { ApiCalls } from "./nirvanaApi"; import { useMutation, useQuery } from "react-query"; // ====== QUERIES export function useAuthCheck() { - return useQuery("AUTH_CHECK", authCheck, { + return useQuery("AUTH_CHECK", ApiCalls.authCheck, { retry: false, + refetchOnWindowFocus: false, + enabled: NirvanaApi._jwtToken ? true : false, }); } export function useLogin() { - return useMutation("LOGIN", login, {}); + return useMutation("LOGIN", ApiCalls.login, {}); } -// export function useGetUserDetails() { -// const authTokens = useRecoilValue($authTokens); - -// return useQuery( -// Querytypes.GET_USER_DETAILS, -// () => getUserDetails(authTokens?.accessToken, authTokens?.idToken), -// { -// retry: false, -// refetchOnWindowFocus: false, -// onError: (err) => { -// console.log(err); -// }, -// } -// ); -// } +export function useGetUserDetails() { + return useQuery("USER_DETAILS", ApiCalls.getUserDetails, { + retry: false, + refetchOnWindowFocus: false, + onError: (err) => { + console.log(err); + }, + }); +} // export function useSearch() { // const authTokens = useRecoilValue($authTokens); diff --git a/packages/desktop/src/controller/nirvanaApi.ts b/packages/desktop/src/controller/nirvanaApi.ts index 62a8d22..012c488 100644 --- a/packages/desktop/src/controller/nirvanaApi.ts +++ b/packages/desktop/src/controller/nirvanaApi.ts @@ -2,6 +2,7 @@ import axios, { AxiosRequestConfig, AxiosResponse, Method } from "axios"; import LoginResponse from "../../../core/responses/login.response"; import { User } from "@nirvana/core/models"; +import UserDetailsResponse from "../../../core/responses/userDetails.response"; // export const localHost = process.env.REACT_APP_API_DOMAIN; @@ -16,9 +17,9 @@ export default class NirvanaApi { // error if no auth token and it's a private route // throw error and show message on anything that is an error from the backend - try { - const fullUrl = localHost + url; + const fullUrl = localHost + url; + try { let res; if (privateRoute && !this._jwtToken) throw Error("No jwt token available!"); @@ -33,19 +34,20 @@ export default class NirvanaApi { } if (!res.ok) { - if (res.status === 401) throw Error("You are not authorized here"); + if (res.status === 401) throw new Error("You are not authorized here"); - throw Error("Something went wrong"); + throw new Error("Something went wrong"); } return await res.json(); - } catch (error: any) { + } catch (error) { console.log(error); + throw error; } } } -export async function login(reqLoginTokens: { +async function login(reqLoginTokens: { accessToken: string; idToken: string; }): Promise { @@ -56,6 +58,16 @@ export async function login(reqLoginTokens: { ); } -export async function authCheck(): Promise { +async function authCheck(): Promise { return await NirvanaApi.fetch(`/user/authcheck`, "GET", true); } + +async function getUserDetails(): Promise { + return await NirvanaApi.fetch(`/user`, "GET", true); +} + +export const ApiCalls = { + login, + authCheck, + getUserDetails, +}; diff --git a/packages/desktop/src/pages/Home/header/index.tsx b/packages/desktop/src/pages/Home/header/index.tsx index 7b67644..1b17775 100644 --- a/packages/desktop/src/pages/Home/header/index.tsx +++ b/packages/desktop/src/pages/Home/header/index.tsx @@ -1,100 +1,102 @@ -// import { $authTokens, $searchQuery } from "../../../controller/recoil"; -// import { Dropdown, Menu } from "antd"; -// import Logo, { LogoType } from "../../../components/Logo"; -// import { useRecoilState, useSetRecoilState } from "recoil"; +import { $authTokens, $searchQuery } from "../../../controller/recoil"; +import { Dropdown, Menu } from "antd"; +import Logo, { LogoType } from "../../../components/Logo"; +import { useRecoilState, useSetRecoilState } from "recoil"; -// import { GlobalHotKeys } from "react-hotkeys"; -// import { STORE_ITEMS } from "../../../electron/constants"; -// import SocketChannels from "@nirvana/core/sockets/channels"; -// import UserAvatarWithStatus from "../../../components/User/userAvatarWithStatus"; -// import { UserStatus } from "@nirvana/core/models"; -// import { socket } from "../../../nirvanaApp"; -// // import { useGetUserDetails } from "../../../controller/index"; -// import { useRef } from "react"; +import { GlobalHotKeys } from "react-hotkeys"; +import { STORE_ITEMS } from "../../../electron/constants"; +import SocketChannels from "@nirvana/core/sockets/channels"; +import UserAvatarWithStatus from "../../../components/User/userAvatarWithStatus"; +import { UserStatus } from "@nirvana/core/models"; +import { socket } from "../../../nirvanaApp"; +import { useGetUserDetails } from "../../../controller/index"; +import { useRef } from "react"; -// export default function Header() { -// // const { data: user, isLoading } = useGetUserDetails(); -// const [searchQuery, setSearchQuery] = useRecoilState($searchQuery); +export default function Header() { + const { data: userDetailsResponse, isLoading } = useGetUserDetails(); + const [searchQuery, setSearchQuery] = useRecoilState($searchQuery); -// const inputRef = useRef(null); + const inputRef = useRef(null); -// const setAuthTokens = useSetRecoilState($authTokens); + const setAuthTokens = useSetRecoilState($authTokens); -// if (isLoading) { -// return getting data; -// } + if (isLoading) { + return getting data; + } -// const logOut = () => { -// window.electronAPI.store.set(STORE_ITEMS.GOOGLE_AUTH_TOKENS, null); -// setAuthTokens(null); -// }; + const logOut = () => { + window.electronAPI.store.set(STORE_ITEMS.GOOGLE_AUTH_TOKENS, null); + setAuthTokens(null); + }; -// const updateStatus = (newStatus: UserStatus) => { -// // send update in socket -// socket.emit( -// SocketChannels.SEND_USER_STATUS_UPDATE, -// user.googleId, -// newStatus -// ); -// }; + const updateStatus = (newStatus: UserStatus) => { + // send update in socket + socket.emit( + SocketChannels.SEND_USER_STATUS_UPDATE, + userDetailsResponse.user.status, + newStatus + ); + }; -// const ProfileMenu = ( -// -// -// -// -// -// {user.status === UserStatus.ONLINE ? ( -// -// ) : ( -// -// )} -// -// -// ); + const ProfileMenu = ( + + + + + + {userDetailsResponse.user.status === UserStatus.ONLINE ? ( + + ) : ( + + )} + + + ); -// // hot keys for selecting search -// const handleSearch = () => { -// if (inputRef?.current) { -// inputRef?.current?.focus(); -// setSearchQuery(""); -// } -// }; + // hot keys for selecting search + const handleSearch = () => { + if (inputRef?.current) { + inputRef?.current?.focus(); + setSearchQuery(""); + } + }; -// const keyMap = { START_SEARCH: "/" }; -// const handlers = { START_SEARCH: handleSearch }; + const keyMap = { START_SEARCH: "/" }; + const handlers = { START_SEARCH: handleSearch }; -// return ( -// <> -// + return ( + <> + -//
-// -// setSearchQuery(e.target.value)} -// /> +
+ + setSearchQuery(e.target.value)} + /> -// + -// -// -// -// -// -//
-// -// ); -// } + + + {userDetailsResponse?.user && ( + + )} + + +
+ + ); +} diff --git a/packages/desktop/src/pages/Home/index.tsx b/packages/desktop/src/pages/Home/index.tsx index c83b8cc..5bb5aae 100644 --- a/packages/desktop/src/pages/Home/index.tsx +++ b/packages/desktop/src/pages/Home/index.tsx @@ -2,6 +2,7 @@ import Logo, { LogoType } from "../../components/Logo"; import { $searchQuery } from "../../controller/recoil"; import Conversations from "./conversations"; +import Header from "./header"; // import Header from "./header"; import Search from "./search"; // import SelectedConversation from "./selectedConversation"; diff --git a/packages/desktop/src/pages/Login/index.tsx b/packages/desktop/src/pages/Login/index.tsx index 05a6da9..fedfa69 100644 --- a/packages/desktop/src/pages/Login/index.tsx +++ b/packages/desktop/src/pages/Login/index.tsx @@ -42,7 +42,9 @@ export default function Login() { window.electronAPI.store.set(STORE_ITEMS.AUTH_SESSION_JWT, jwtToken); - window.location.reload(); + console.log(loginResponse); + + // window.location.reload(); } );