handling all of the stuff with header logout and handling better jwttoken

This commit is contained in:
talksik
2022-04-01 13:48:30 -04:00
parent c769f40a15
commit 7d8d05ad39
13 changed files with 58 additions and 65 deletions
-1
View File
@@ -26,7 +26,6 @@ export const authCheck = async (
next(); next();
} catch (error) { } catch (error) {
console.log(error);
res.status(401).send("unauthorized"); res.status(401).send("unauthorized");
} }
}; };
-2
View File
@@ -43,8 +43,6 @@ async function handleAuthCheck(req: Request, res: Response) {
async function getUserDetails(req: Request, res: Response) { async function getUserDetails(req: Request, res: Response) {
try { try {
console.log(res.locals.userInfo as JwtClaims);
const userInfo = res.locals.userInfo as JwtClaims; const userInfo = res.locals.userInfo as JwtClaims;
const user = await UserService.getUserById(userInfo.userId); const user = await UserService.getUserById(userInfo.userId);
+1 -1
View File
@@ -7,7 +7,7 @@ import { collections } from "./database.service";
export class UserService { export class UserService {
static async getUserById(userId: string) { static async getUserById(userId: string) {
const query = { _id: userId }; const query = { _id: new ObjectId(userId) };
const res = await collections.users?.findOne(query); const res = await collections.users?.findOne(query);
@@ -1,11 +1,12 @@
import { useAuthCheck, useLogin } from "../../controller/index"; import { useAuthCheck, useLogin } from "../../controller/index";
import { $authTokens } from "../../controller/recoil"; import { $jwtToken } from "../../controller/recoil";
import Login from "../../pages/Login"; import Login from "../../pages/Login";
import NirvanaApi from "../../controller/nirvanaApi"; import NirvanaApi from "../../controller/nirvanaApi";
import { STORE_ITEMS } from "../../electron/constants"; import { STORE_ITEMS } from "../../electron/constants";
import SkeletonLoader from "../loading/skeleton"; import SkeletonLoader from "../loading/skeleton";
import { useEffect } from "react"; import { useEffect } from "react";
import { useRecoilState } from "recoil";
export default function ProtectedRoute({ export default function ProtectedRoute({
children, children,
@@ -14,6 +15,8 @@ export default function ProtectedRoute({
}) { }) {
const { isLoading, isError, isSuccess, refetch } = useAuthCheck(); const { isLoading, isError, isSuccess, refetch } = useAuthCheck();
const [jwtToken, setJwtToken] = useRecoilState($jwtToken);
useEffect(() => { useEffect(() => {
// on load of this, if we already have jwt tokens in store, // on load of this, if we already have jwt tokens in store,
// then try using them with auth check // then try using them with auth check
@@ -27,6 +30,17 @@ export default function ProtectedRoute({
}); });
}, []); }, []);
useEffect(() => {
if (jwtToken) {
window.electronAPI.store.set(STORE_ITEMS.AUTH_SESSION_JWT, jwtToken);
} else {
window.electronAPI.store.set(STORE_ITEMS.AUTH_SESSION_JWT, null);
}
NirvanaApi._jwtToken = jwtToken;
refetch();
}, [jwtToken]);
if (isLoading) { if (isLoading) {
return ( return (
<div className="container h-screen w-screen flex flex-col justify-center mx-10"> <div className="container h-screen w-screen flex flex-col justify-center mx-10">
@@ -18,19 +18,19 @@ export function UserStatusBubble(props: { status: UserStatus }) {
switch (props.status) { switch (props.status) {
case UserStatus.ONLINE: case UserStatus.ONLINE:
return ( return (
<span className="absolute -bottom-1 -right-1 rounded-full bg-emerald-600 h-3 w-3 border border-zinc-300"></span> <span className="absolute -bottom-1 -right-1 rounded-full bg-emerald-600 h-3 w-3 border"></span>
); );
case UserStatus.OFFLINE: case UserStatus.OFFLINE:
return ( return (
<span className="absolute -bottom-1 -right-1 rounded-full bg-zinc-400 h-3 w-3 border border-zinc-300"></span> <span className="absolute -bottom-1 -right-1 rounded-full bg-zinc-400 h-3 w-3 border"></span>
); );
case UserStatus.FLOW_STATE: case UserStatus.FLOW_STATE:
return ( return (
<span className="absolute -bottom-1 -right-1 rounded-full bg-pink-400 h-3 w-3 border border-zinc-300"></span> <span className="absolute -bottom-1 -right-1 rounded-full bg-pink-400 h-3 w-3 border"></span>
); );
default: default:
return ( return (
<span className="absolute -bottom-1 -right-1 rounded-full bg-pink-400 h-3 w-3 border border-zinc-300"></span> <span className="absolute -bottom-1 -right-1 rounded-full bg-pink-400 h-3 w-3 border"></span>
); );
} }
} }
@@ -6,7 +6,6 @@ export function useAuthCheck() {
return useQuery("AUTH_CHECK", ApiCalls.authCheck, { return useQuery("AUTH_CHECK", ApiCalls.authCheck, {
retry: false, retry: false,
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
enabled: NirvanaApi._jwtToken ? true : false,
}); });
} }
+17 -23
View File
@@ -19,31 +19,25 @@ export default class NirvanaApi {
const fullUrl = localHost + url; const fullUrl = localHost + url;
try { let res;
let res; if (privateRoute && !this._jwtToken) throw Error("No jwt token available!");
if (privateRoute && !this._jwtToken)
throw Error("No jwt token available!");
if (privateRoute && this._jwtToken) { if (privateRoute && this._jwtToken) {
res = await fetch(fullUrl, { res = await fetch(fullUrl, {
method: method, method: method,
headers: { Authorization: this._jwtToken }, headers: { Authorization: this._jwtToken },
}); });
} else { } else {
res = await fetch(fullUrl); res = await fetch(fullUrl);
}
if (!res.ok) {
if (res.status === 401) throw new Error("You are not authorized here");
throw new Error("Something went wrong");
}
return await res.json();
} catch (error) {
console.log(error);
throw error;
} }
if (!res.ok) {
if (res.status === 401) throw new Error("You are not authorized here");
throw new Error("Something went wrong");
}
return await res.json();
} }
} }
+5 -9
View File
@@ -1,19 +1,15 @@
import { atom } from "recoil"; import { atom } from "recoil";
export const $authTokens = atom<{
accessToken: string;
refreshToken: string;
idToken: string;
} | null>({
key: "AUTH_TOKENS", // unique ID (with respect to other atoms/selectors)
default: null, // default value (aka initial value)
});
export const $searchQuery = atom<string>({ export const $searchQuery = atom<string>({
key: "SEARCH_QUERY", key: "SEARCH_QUERY",
default: "", default: "",
}); });
export const $jwtToken = atom<string>({
key: "JWT_TOKEN",
default: null,
});
// conversation id // conversation id
export const $selectedConversation = atom<string>({ export const $selectedConversation = atom<string>({
key: "SELECTED_CONVERSATION", key: "SELECTED_CONVERSATION",
@@ -8,7 +8,6 @@ enum Channels {
} }
export enum STORE_ITEMS { export enum STORE_ITEMS {
GOOGLE_AUTH_TOKENS = "GOOGLE_AUTH_TOKENS",
AUTH_SESSION_JWT = "AUTH_SESSION_JWT", AUTH_SESSION_JWT = "AUTH_SESSION_JWT",
} }
@@ -16,7 +16,5 @@ const myApiOauth = new ElectronGoogleOAuth2(
export async function handleGoogleLogin() { export async function handleGoogleLogin() {
const tokens = await myApiOauth.openAuthWindowAndGetTokens(); const tokens = await myApiOauth.openAuthWindowAndGetTokens();
store.set(STORE_ITEMS.GOOGLE_AUTH_TOKENS, tokens);
browserWindow.webContents.send(Channels.GOOGLE_AUTH_TOKENS, tokens); browserWindow.webContents.send(Channels.GOOGLE_AUTH_TOKENS, tokens);
} }
@@ -1,9 +1,10 @@
import { $authTokens, $searchQuery } from "../../../controller/recoil"; import { $jwtToken, $searchQuery } from "../../../controller/recoil";
import { Dropdown, Menu } from "antd"; import { Dropdown, Menu } from "antd";
import Logo, { LogoType } from "../../../components/Logo"; import Logo, { LogoType } from "../../../components/Logo";
import { useRecoilState, useSetRecoilState } from "recoil"; import { useRecoilState, useSetRecoilState } from "recoil";
import { GlobalHotKeys } from "react-hotkeys"; import { GlobalHotKeys } from "react-hotkeys";
import NirvanaApi from "../../../controller/nirvanaApi";
import { STORE_ITEMS } from "../../../electron/constants"; import { STORE_ITEMS } from "../../../electron/constants";
import SocketChannels from "@nirvana/core/sockets/channels"; import SocketChannels from "@nirvana/core/sockets/channels";
import UserAvatarWithStatus from "../../../components/User/userAvatarWithStatus"; import UserAvatarWithStatus from "../../../components/User/userAvatarWithStatus";
@@ -16,17 +17,16 @@ export default function Header() {
const { data: userDetailsResponse, isLoading } = useGetUserDetails(); const { data: userDetailsResponse, isLoading } = useGetUserDetails();
const [searchQuery, setSearchQuery] = useRecoilState($searchQuery); const [searchQuery, setSearchQuery] = useRecoilState($searchQuery);
const inputRef = useRef(null); const setJwtToken = useSetRecoilState($jwtToken);
const setAuthTokens = useSetRecoilState($authTokens); const inputRef = useRef(null);
if (isLoading) { if (isLoading) {
return <span>getting data</span>; return <span>getting data</span>;
} }
const logOut = () => { const logOut = () => {
window.electronAPI.store.set(STORE_ITEMS.GOOGLE_AUTH_TOKENS, null); setJwtToken(undefined);
setAuthTokens(null);
}; };
const updateStatus = (newStatus: UserStatus) => { const updateStatus = (newStatus: UserStatus) => {
+1 -1
View File
@@ -17,7 +17,7 @@ export default function Home() {
<div className="h-screen bg-zinc-700 flex flex-row"> <div className="h-screen bg-zinc-700 flex flex-row">
<div className="flex-1"> <div className="flex-1">
{/* header */} {/* header */}
{/* <Header /> */} <Header />
{/* main content */} {/* main content */}
+10 -14
View File
@@ -2,23 +2,17 @@ import Channels, { STORE_ITEMS } from "../../electron/constants";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useRecoilState, useSetRecoilState } from "recoil"; import { useRecoilState, useSetRecoilState } from "recoil";
import { $authTokens } from "../../controller/recoil"; import { $jwtToken } from "../../controller/recoil";
import { CircularProgress } from "@mui/material"; import { CircularProgress } from "@mui/material";
import { FcGoogle } from "react-icons/fc"; import { FcGoogle } from "react-icons/fc";
import Logo from "../../components/Logo"; import Logo from "../../components/Logo";
import NirvanaApi from "../../controller/nirvanaApi";
import { useLogin } from "../../controller/index"; import { useLogin } from "../../controller/index";
export default function Login() { export default function Login() {
const { mutateAsync } = useLogin(); const { mutateAsync } = useLogin();
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const continueAuth = () => { const setJwtToken = useSetRecoilState($jwtToken);
setIsLoading(true);
// send to main process
window.electronAPI.auth.initiateLogin();
};
useEffect(() => { useEffect(() => {
window.electronAPI.once( window.electronAPI.once(
@@ -39,12 +33,7 @@ export default function Login() {
}); });
const { jwtToken, userDetails } = loginResponse; const { jwtToken, userDetails } = loginResponse;
setJwtToken(jwtToken);
window.electronAPI.store.set(STORE_ITEMS.AUTH_SESSION_JWT, jwtToken);
console.log(loginResponse);
// window.location.reload();
} }
); );
@@ -54,6 +43,13 @@ export default function Login() {
// }; // };
}, []); }, []);
const continueAuth = () => {
setIsLoading(true);
// send to main process
window.electronAPI.auth.initiateLogin();
};
return ( return (
<div className="container flex flex-col space-y-5 justify-center items-center h-screen bg-zinc-700"> <div className="container flex flex-col space-y-5 justify-center items-center h-screen bg-zinc-700">
<Logo className="scale-50" /> <Logo className="scale-50" />