From 5eb57726abab866ca05682c04910f199b80273a5 Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 13 May 2022 05:40:07 -0500 Subject: [PATCH] progress in auth and other contexts --- packages/desktop/.eslintrc.json | 2 +- packages/desktop/src/app.tsx | 3 +- .../desktop/src/providers/AuthProvider.tsx | 20 ++++ .../src/providers/ElectronProvider.tsx | 8 +- .../desktop/src/providers/SocketProvider.tsx | 35 +++++- packages/desktop/src/tree/electronApp.tsx | 14 +++ .../src/tree/protected/ProtectedRoute.tsx | 9 ++ .../src/tree/protected/login/Login.tsx | 103 ++++++++++++++++++ 8 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 packages/desktop/src/providers/AuthProvider.tsx create mode 100644 packages/desktop/src/tree/electronApp.tsx create mode 100644 packages/desktop/src/tree/protected/ProtectedRoute.tsx create mode 100644 packages/desktop/src/tree/protected/login/Login.tsx diff --git a/packages/desktop/.eslintrc.json b/packages/desktop/.eslintrc.json index 5d6893b..a115205 100644 --- a/packages/desktop/.eslintrc.json +++ b/packages/desktop/.eslintrc.json @@ -13,7 +13,7 @@ "plugin:import/typescript", "plugin:react/recommended", "plugin:react-hooks/recommended", - "plugin:jsx-a11y" + "plugin:jsx-a11y/recommended" ], "parser": "@typescript-eslint/parser", "rules": { diff --git a/packages/desktop/src/app.tsx b/packages/desktop/src/app.tsx index ab1f10a..4a1e562 100644 --- a/packages/desktop/src/app.tsx +++ b/packages/desktop/src/app.tsx @@ -2,9 +2,10 @@ import './styles/index.css'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; +import ElectronApp from './tree/electronApp'; function render() { - ReactDOM.render(
test
, document.getElementById('root')); + ReactDOM.render(, document.getElementById('root')); } render(); diff --git a/packages/desktop/src/providers/AuthProvider.tsx b/packages/desktop/src/providers/AuthProvider.tsx new file mode 100644 index 0000000..01293e7 --- /dev/null +++ b/packages/desktop/src/providers/AuthProvider.tsx @@ -0,0 +1,20 @@ +import React, { useContext, useState, useEffect } from 'react'; +import { User } from '@nirvana/core/models/user.model'; + +interface IAuthProvider { + user: User; +} + +const AuthContext = React.createContext({ + user: null, +}); + +export function AuthProvider({ children }: { children: React.ReactNode }) { + if (true) return <>; + + return {children}; +} + +export default function useAuth() { + return useContext(AuthContext); +} diff --git a/packages/desktop/src/providers/ElectronProvider.tsx b/packages/desktop/src/providers/ElectronProvider.tsx index bef3f0d..a63044c 100644 --- a/packages/desktop/src/providers/ElectronProvider.tsx +++ b/packages/desktop/src/providers/ElectronProvider.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import Channels, { DEFAULT_APP_PRESET, Dimensions } from '../electron/constants'; interface IElectronProvider { @@ -12,7 +12,7 @@ const ElectronContext = React.createContext({ desktopMode: 'mainApp', }); -export default function ElectronProvider({ children }: { children: React.ReactNode }) { +export function ElectronProvider({ children }: { children: React.ReactNode }) { const [desktopMode, setDesktopMode] = useState('mainApp'); // handle all window resizing logic @@ -62,3 +62,7 @@ export default function ElectronProvider({ children }: { children: React.ReactNo return {children}; } + +export default function useElectron() { + return useContext(ElectronContext); +} diff --git a/packages/desktop/src/providers/SocketProvider.tsx b/packages/desktop/src/providers/SocketProvider.tsx index 30f43b1..dd4dd10 100644 --- a/packages/desktop/src/providers/SocketProvider.tsx +++ b/packages/desktop/src/providers/SocketProvider.tsx @@ -1,5 +1,34 @@ -import React from 'react'; +import React, { useState, useEffect, useContext } from 'react'; +import { Socket } from 'socket.io-client'; -export default function SocketProvider() { - return
; +interface ISocketProvider { + $ws: Socket; +} + +const SocketContext = React.createContext({ + $ws: null, +}); + +export function SocketProvider({ children }: { children: React.ReactNode }) { + const [$ws, set$ws] = useState(null); + + useEffect(() => { + const socketConnection = io('http://localhost:5000', { + query: { token: jwtToken }, + transports: ['websocket'], + upgrade: false, + forceNew: true, + reconnection: false, // ! TESTING THE PROBLEM WITH RECONNECTION CLIENT LISTENERS NOT ACTIVATING + }); + + set$ws(socketConnection); + }, [set$ws]); + + if (!$ws) return please wait for a solid connection; + + return {children}; +} + +export default function useSockets() { + return useContext(SocketContext); } diff --git a/packages/desktop/src/tree/electronApp.tsx b/packages/desktop/src/tree/electronApp.tsx new file mode 100644 index 0000000..3470b70 --- /dev/null +++ b/packages/desktop/src/tree/electronApp.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { ElectronProvider } from '../providers/ElectronProvider'; +import SocketProvider from '../providers/SocketProvider'; + +export default function ElectronApp() { + return ( + + +
this is the bottom of the tree
+
+
+ ); +} diff --git a/packages/desktop/src/tree/protected/ProtectedRoute.tsx b/packages/desktop/src/tree/protected/ProtectedRoute.tsx new file mode 100644 index 0000000..0661c2c --- /dev/null +++ b/packages/desktop/src/tree/protected/ProtectedRoute.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import useAuth from '../../providers/AuthProvider'; + +export default function ProtectedRoute({ children }: { children: React.ReactNode }) { + const { user } = useAuth(); + + if (user) return; + return <>hey; +} diff --git a/packages/desktop/src/tree/protected/login/Login.tsx b/packages/desktop/src/tree/protected/login/Login.tsx new file mode 100644 index 0000000..251666e --- /dev/null +++ b/packages/desktop/src/tree/protected/login/Login.tsx @@ -0,0 +1,103 @@ +import Channels, { STORE_ITEMS } from '../../electron/constants'; +import { useEffect, useState } from 'react'; +import { useRecoilState, useSetRecoilState } from 'recoil'; + +import { $jwtToken } from '../../controller/recoil'; +import { FcGoogle } from 'react-icons/fc'; +import Logo from '../../components/Logo'; +import { useLogin } from '../../controller/index'; + +export default function Login() { + const [isLoading, setIsLoading] = useState(false); + + const setJwtToken = useSetRecoilState($jwtToken); + + useEffect(() => { + window.electronAPI.once( + Channels.GOOGLE_AUTH_TOKENS, + async (tokens: { access_token: string; id_token: string; refresh_token: string }) => { + console.log('got tokens', tokens); + + setIsLoading(true); + // todo: implement refresh token procedure in api layer by sending refresh_token and such + + const loginResponse = await mutateAsync({ + accessToken: tokens.access_token, + idToken: tokens.id_token, + }); + + const { jwtToken, userDetails } = loginResponse; + setJwtToken(jwtToken); + }, + ); + + // todo: figure out how to clean up with the preload api + // return () => { + // window.electronAPI.removeAllListeners(Channels.GOOGLE_AUTH_TOKENS); + // }; + }, []); + + const continueAuth = () => { + setIsLoading(true); + + // send to main process + window.electronAPI.auth.initiateLogin(); + }; + + return ( +
+ + + {/* ! TESTING PURPOSES */} +
+ + + + + +
+ + {isLoading ? ( + <> + Attempting to log you in + + ) : ( + + )} +
+ ); +}