new login

This commit is contained in:
wil committed 2024-04-11 14:08:34 -04:00
1 parent 925e488a56
commit cb8e93ec3c
12 files changed
+183 -160

No files matched your search

@@ -1,128 +0,0 @@
import {
createContext,
useCallback,
useEffect,
useState,
ReactNode,
Dispatch,
SetStateAction
} from "react";
import {
SessionResponse,
AuthState,
STORAGE_KEYS
} from "./types";
import { CreateSession, DestroySession, GetSession } from "./utilities";
export const AuthenticationContext = createContext<{
authState: AuthState,
setAuthState?: Dispatch<SetStateAction<AuthState>>,
loginAndGetUserInfo?: (
usernameOrEmail: string,
password:string,
failureCallback?:()=>void
)=>void;
logout?: ()=>void;
}>({
authState:{}
});
export const AuthenticationProvider = ({children}:{children:ReactNode})=>{
// console.log('auth provider rerender');
// const [, setAuthCookie, removeAuthCookie] = useCookies([STORAGE_KEYS.USER_INFO]);
const [authState, setAuthState] = useState<AuthState>({});
const loginAndGetUserInfo = useCallback((
usernameOrEmail: string,
password:string,
failureCallback?:()=>void
)=>{
CreateSession({usernameOrEmail, password})
.then((respond)=>{
GetSession().then((
res: SessionResponse
)=>{
if(res.success && res.user && setAuthState){
setAuthState({
isLoggedIn: true,
sessionData: JSON.stringify(res.user),
userInfo: res.user
});
}else{
if(failureCallback) failureCallback();
}
});
});
},[]);
const setLogoutState = useCallback(()=>{
setAuthState({
isLoggedIn: false,
sessionData: null,
userInfo: undefined
});
},[]);
const logout = useCallback(()=>{
DestroySession().then((res)=>{
if (res) setLogoutState();
});
},[]);
//Set Session upon Auth State Changes
useEffect(()=>{
//On First Load
if(authState.isLoggedIn === undefined){
//Persist Login if Session Data exist
const sessionData = localStorage.getItem(STORAGE_KEYS.USER_INFO);
// console.log(`Session Data: ${sessionData?.substring(0, 30)}${sessionData ? '...':''}`);
if (sessionData !== null){
// console.log('Getting session to persist login');
GetSession().then((
res: SessionResponse
)=>{
// console.log('Session Returned');
// console.log(res);
if(res.success && res.user){
// console.log('Setting Auth State');
setAuthState({
isLoggedIn: true,
sessionData: JSON.stringify(res.user),
userInfo: res.user
});
}else{
// console.log('Session expired, setting State');
setLogoutState();
}
});
}else{
setLogoutState();
}
}
// Propagate session data to localstorage
if(authState.sessionData !== null && authState.sessionData !== undefined){
localStorage.setItem(STORAGE_KEYS.USER_INFO, authState.sessionData);
// setAuthCookie(STORAGE_KEYS.USER_INFO, authState.userInfo);
}
// Propagate Logout
else if (authState.sessionData === null){
localStorage.removeItem(STORAGE_KEYS.USER_INFO);
// removeAuthCookie(STORAGE_KEYS.USER_INFO);
}
},[authState]);
return(
<AuthenticationContext.Provider value={{
authState,
setAuthState,
loginAndGetUserInfo,
logout,
}}>
{children}
</AuthenticationContext.Provider>
)
}
@@ -0,0 +1,18 @@
import { createContext, Dispatch, SetStateAction } from "react";
import { AuthState, AUTH_STATUS } from "./types";
export const AuthenticationContext = createContext<{
authState: AuthState,
setAuthState?: Dispatch<SetStateAction<AuthState>>,
login?: (
usernameOrEmail: string,
password:string,
failureCallback?:()=>void
)=>void;
logout?: ()=>void;
}>({
authState:{
authStatus: AUTH_STATUS.INIT
}
});
@@ -0,0 +1,123 @@
import { useCallback, useEffect, useState, ReactNode} from "react";
import { SessionResponse, AuthState, STORAGE_KEYS, AUTH_STATUS, UserInfo} from "./types";
import { CreateSession, DestroySession, GetSession } from "./utilities";
import { AuthenticationContext } from "./AuthenticationContext";
export const AuthenticationProvider = ({children}:{children:ReactNode})=>{
console.log('auth provider rerender');
const [authState, setAuthState] = useState<AuthState>({
authStatus: AUTH_STATUS.INIT
});
const startLoggingState = useCallback(()=>{
setAuthState({
authStatus: AUTH_STATUS.LOGGING,
sessionToken: undefined,
userInfo: undefined
});
}, []);
const updateLoggingState = useCallback((sessionToken: string)=>{
setAuthState({
authStatus: AUTH_STATUS.LOGGING,
sessionToken: sessionToken,
userInfo: undefined
});
}, []);
const setLoginState = useCallback((userInfo: UserInfo)=>{
setAuthState((curr)=>({
...curr,
authStatus: AUTH_STATUS.LOGGED_IN,
userInfo: userInfo,
}));
}, [])
const setLogoutState = useCallback(()=>{
setAuthState({
authStatus: AUTH_STATUS.LOGGED_OUT,
sessionToken: undefined,
userInfo: undefined
});
},[]);
const login = useCallback((
usernameOrEmail: string,
password:string,
failureCallback?:()=>void
)=>{
console.log('CreateSession');
startLoggingState();
CreateSession({usernameOrEmail, password})
.then((loginResponse)=>{
updateLoggingState(loginResponse.signed_session);
GetSession().then((
sessionResponse: SessionResponse
)=>{
if(sessionResponse.success && sessionResponse.user && sessionResponse.user !== null){
setLoginState(sessionResponse.user);
}else{
if(failureCallback) failureCallback();
setLogoutState();
}
});
});
},[]);
const logout = useCallback(()=>{
DestroySession().then((res)=>{
if (res) setLogoutState();
});
},[]);
//Set Session upon Auth State Changes
useEffect(()=>{
//On First Load
if(authState.authStatus === AUTH_STATUS.INIT){
//Persist Login if Session Data exist
const sessionData = localStorage.getItem(STORAGE_KEYS.SESSION_TOKEN);
console.log(`Session Data: ${sessionData?.substring(0, 30)}${sessionData ? '...':''}`);
if (sessionData !== null){
console.log('Getting session to persist login');
updateLoggingState(sessionData);
GetSession().then((
sessionResponse: SessionResponse
)=>{
console.log('Session Returned');
console.log(sessionResponse);
if(sessionResponse.success && sessionResponse.user && sessionResponse.user !== null){
console.log('Setting Auth State');
setLoginState(sessionResponse.user)
}else{
console.log('Session expired, setting State');
setLogoutState();
}
});
}else{
setLogoutState();
}
}
// Propagate session data to localstorage
if(authState.sessionToken !== null && authState.sessionToken !== undefined){
localStorage.setItem(STORAGE_KEYS.SESSION_TOKEN, authState.sessionToken);
}
// Propagate Logout
else if (authState.sessionToken === null){
localStorage.removeItem(STORAGE_KEYS.SESSION_TOKEN);
}
},[authState]);
return(
<AuthenticationContext.Provider value={{
authState,
setAuthState,
login,
logout,
}}>
{children}
</AuthenticationContext.Provider>
)
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { AuthenticationContext, AuthenticationProvider } from "./Authentication";
import { AuthenticationContext, } from "./AuthenticationContext";
import { AuthenticationProvider } from "./AuthenticationProvider";
import { UserInfo, AUTH_STATUS } from "./types";
+5 -3
View File
@@ -1,15 +1,17 @@
export enum STORAGE_KEYS{
USER_INFO = "user_info",
SESSION_TOKEN = "session_token",
}
export enum AUTH_STATUS {
INIT = "INIT",
LOGGED_IN = "logged_in",
LOGGING = "logging",
LOGGED_OUT = "logged_out",
}
export type AuthState = {
isLoggedIn?: boolean;
sessionData?: string | null;
authStatus: AUTH_STATUS;
sessionToken?: string | null;
userInfo?: UserInfo;
}
export interface UserInfo {
+3 -3
View File
@@ -21,7 +21,7 @@ export const CreateSession = async ({
"Accept": "application/json",
"Content-Type": "application/json",
},
credentials: 'include',
// credentials: 'include',
body: JSON.stringify(request)
})
.then(res => res.json())
@@ -39,7 +39,7 @@ export const GetSession = async () => {
headers: {
'Accept': 'application/json',
},
credentials: 'include',
// credentials: 'include',
})
.then(res => res.json())
.then(res => {
@@ -59,7 +59,7 @@ export async function DestroySession() : Promise<boolean> {
headers: {
'Accept': 'application/json',
},
credentials: 'include',
// credentials: 'include',
})
.then(res => res.json())
.then(res => {
@@ -59,7 +59,7 @@ export async function GetInferenceJobStatus(jobToken:string) : Promise<GetJobSta
headers: {
'Accept': 'application/json',
},
credentials: 'include',
// credentials: 'include',
})
.then(res => res.json())
.then(res => {
+2 -3
View File
@@ -1,10 +1,9 @@
import { useContext, } from "react";
import { useSignals } from "@preact/signals-react/runtime";
import { AuthenticationContext } from "~/contexts/Authentication";
import { AUTH_STATUS, AuthenticationContext } from "~/contexts/Authentication";
import { Button, ButtonLink } from "~/components";
import { DialogueInference } from "../DialogueInference";
import { inferenceJobs } from "~/pages/PageEnigma/store/inferenceJobs";
export const AuthButtons = ()=>{
useSignals();
@@ -13,7 +12,7 @@ export const AuthButtons = ()=>{
const handleLogout = ()=>{
if(logout)logout();
}
if ( authState && authState.isLoggedIn ) {
if ( authState && authState.authStatus === AUTH_STATUS.LOGGED_IN ) {
return(
<>
<DialogueInference />
+18 -10
View File
@@ -1,25 +1,33 @@
import { useContext, useEffect, ComponentType } from "react";
import { useNavigate, useLocation } from "@remix-run/react";
import { AuthenticationContext } from "~/contexts/Authentication";
import { AUTH_STATUS, AuthenticationContext } from "~/contexts/Authentication";
import { LoadingDots } from "~/components";
export const withProtectionRoute = <P extends {}>(Component: ComponentType<P>) => (rest:P) => {
const { authState } = useContext(AuthenticationContext);
if (authState.isLoggedIn === undefined ) {
return <>waiting</>;
}
if (authState.isLoggedIn === false) {
if (authState.authStatus === AUTH_STATUS.LOGGED_OUT) {
return <RedirectToLogin />
}
return (
<Component {...rest}/>
);
else if (authState.authStatus === AUTH_STATUS.LOGGED_IN ) {
return (<Component {...rest}/>);
}else {
return(
<div className="fixed w-full h-full flex flex-col justify-center items-center">
<LoadingDots type="bricks" message="Checking for Authentication..."/>
</div>
);
}
}
const RedirectToLogin = ()=>{
const navigate = useNavigate();
const {pathname} = useLocation();
useEffect(()=>{
navigate(`/login?redirect=${pathname}`);
setTimeout(()=>navigate(`/login?redirect=${pathname}`), 2000);
},[]);
return <>redirecting</>
return (
<div className="fixed w-full h-full flex flex-col justify-center items-center">
<LoadingDots type="bricks" message="Failed, redirecting..."/>
</div>
);
}
@@ -40,7 +40,7 @@ export const ListAudioByUser = async(username:string) => {
headers: {
"Accept": "application/json",
},
credentials: 'include'
// credentials: 'include'
})
.then(res => res.json())
.then(res => {
+5 -5
View File
@@ -238,7 +238,7 @@ export class APIManager {
const response = await fetch(url, {
method: "POST",
credentials: "include",
// credentials: "include",
headers: {
Accept: "application/json",
},
@@ -291,7 +291,7 @@ export class APIManager {
const response = await fetch(url, {
method: "POST",
credentials: "include",
// credentials: "include",
headers: {
Accept: "application/json",
},
@@ -325,7 +325,7 @@ export class APIManager {
const response = await fetch(url, {
method: "POST",
credentials: "include",
// credentials: "include",
headers: {
Accept: "application/json",
},
@@ -362,7 +362,7 @@ export class APIManager {
const response = await fetch(url, {
method: "POST",
credentials: "include",
// credentials: "include",
headers: {
Accept: "application/json",
},
@@ -421,7 +421,7 @@ export class APIManager {
const response = await fetch(`${this.baseUrl}/v1/video/enqueue_vst`, {
method: "POST",
credentials: "include",
// credentials: "include",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
+5 -5
View File
@@ -1,7 +1,7 @@
import { useContext, useEffect, useState, useRef } from "react";
import { useNavigate, useSearchParams } from "@remix-run/react";
import { faKey, faUser } from "@fortawesome/pro-solid-svg-icons";
import { AuthenticationContext } from "~/contexts/Authentication";
import { AUTH_STATUS, AuthenticationContext } from "~/contexts/Authentication";
import { Button,H1,Input,Link,P } from '~/components';
import { LoadingDots } from "~/components";
@@ -12,7 +12,7 @@ export default function LoginScreen() {
const [showLoader, setShowLoader] = useState<string|undefined>(undefined);
const formRef = useRef<HTMLFormElement | null>(null);
const {authState, loginAndGetUserInfo} = useContext(AuthenticationContext);
const {authState, login} = useContext(AuthenticationContext);
const handleOnSumbit = (ev: React.FormEvent<HTMLFormElement>)=>{
ev.preventDefault();
@@ -20,9 +20,9 @@ export default function LoginScreen() {
const form = new FormData(formRef.current);
const usernameOrEmail = form.get("usernameOrEmail")?.toString();
const password = form.get("password")?.toString();
if( usernameOrEmail && password && loginAndGetUserInfo){
if( usernameOrEmail && password && login){
setShowLoader("Authenticating");
loginAndGetUserInfo(
login(
usernameOrEmail,
password,
()=>{
@@ -34,7 +34,7 @@ export default function LoginScreen() {
useEffect(()=>{
const redirectPath = searchParams.get('redirect');
if(authState && authState.isLoggedIn)
if(authState && authState.authStatus === AUTH_STATUS.LOGGED_IN)
navigate(redirectPath ? redirectPath:'/');
},[authState]);