From 00a6629e6057aaac748b99a7aa2c73448c2a07c7 Mon Sep 17 00:00:00 2001 From: Benjamin Sherriff Date: Thu, 19 Oct 2023 19:48:24 -0400 Subject: [PATCH] Updated fetch cookie --- ui/src/api/auth.ts | 41 +++++++++++++++++----- ui/src/api/guilds.ts | 33 +++++++++--------- ui/src/api/index.ts | 55 ++++++++++++------------------ ui/src/api/spells.ts | 36 +++++++++---------- ui/src/components/Topbar/index.tsx | 25 +++++++------- 5 files changed, 101 insertions(+), 89 deletions(-) diff --git a/ui/src/api/auth.ts b/ui/src/api/auth.ts index 9b460b0..f757fd6 100644 --- a/ui/src/api/auth.ts +++ b/ui/src/api/auth.ts @@ -1,17 +1,18 @@ -import { getRequest, postRequest } from '.'; +import Cookies from 'js-cookie'; +import { get, post } from '.'; import { RegisterUser, ResponseAuth } from './auth.types'; export async function login(email: string, password: string): Promise { - const response = await postRequest('auth/login', { email, password }); + const response = await post('auth/login', { email, password }); if (response?.status === 200) { - return response.data as ResponseAuth; + return response.json(); } else { return undefined; } } export async function register(user: RegisterUser): Promise { - const response = await postRequest('auth/register', user); + const response = await post('auth/register', user); if (response?.status === 201) { return true; } else { @@ -20,23 +21,45 @@ export async function register(user: RegisterUser): Promise { } export async function logout() { - return await postRequest('auth/logout', {}); + return await post('auth/logout', {}); } export async function refresh(refresh_token_rotation?: boolean): Promise { - const response = await getRequest('auth/refresh', { params: { refresh_token_rotation } }); + const response = await get('auth/refresh', { params: { refresh_token_rotation } }); if (response?.status === 200) { - return response.data as ResponseAuth; + return response.json(); } else { return undefined; } } export async function me(): Promise { - const response = await getRequest('auth/me'); + const response = await get('auth/me'); if (response?.status === 200) { - return response.data; + return response.json(); } else { return undefined; } } + +/** + * Refreshes the logged_in cookie every interval. By default, the interval is 14 minutes. + * @param interval + * @returns interval id + */ +export function refreshLoggedIn(interval = 840000) { + let loggedIn = Cookies.get('logged_in'); + const id = setInterval(async () => { + const cookie = Cookies.get('logged_in'); + if (cookie != loggedIn) { + loggedIn = cookie; + const response = await refresh(true); + if (response) { + Cookies.set('logged_in', 'true'); + } else { + Cookies.set('test', 'failed'); + } + } + }, interval); + return id; +} diff --git a/ui/src/api/guilds.ts b/ui/src/api/guilds.ts index a3f662e..0a3fd1d 100644 --- a/ui/src/api/guilds.ts +++ b/ui/src/api/guilds.ts @@ -1,50 +1,51 @@ -import { getRequest, postRequest } from '.'; +import { get, post } from '.'; import { GuildChannel, GuildInfo } from './guilds.types'; export async function getGuilds(): Promise { - const response = await getRequest('guilds'); - return response?.data || { data: [] }; + const response = await get('guilds'); + return response?.json() || { data: [] }; } export async function getTextChannels(guildId: number): Promise { - const response = await getRequest(`guilds/${guildId}/text`); - return response?.data || { data: [] }; + const response = await get(`guilds/${guildId}/text`); + return response?.json() || { data: [] }; } export async function sendMessage(guildId: number, channelId: number, message: string): Promise { - await postRequest(`guilds/${guildId}/text/${channelId}/message`, { message }); + await post(`guilds/${guildId}/text/${channelId}/message`, { message }); } export async function getVoiceChannels(guildId: number): Promise { - const response = await getRequest(`guilds/${guildId}/voice`); - return response?.data || { data: [] }; + const response = await get(`guilds/${guildId}/voice`); + return response?.json() || { data: [] }; } export async function playTrack(guildId: number, channelId: number, track: string): Promise { - await postRequest(`guilds/${guildId}/voice/${channelId}/play`, { track_url: track }); + await post(`guilds/${guildId}/voice/${channelId}/play`, { track_url: track }); } export async function stopTrack(guildId: number): Promise { - await postRequest(`guilds/${guildId}/voice/stop`, {}); + await post(`guilds/${guildId}/voice/stop`, {}); } export async function pauseTrack(guildId: number): Promise { - await postRequest(`guilds/${guildId}/voice/pause`, {}); + await post(`guilds/${guildId}/voice/pause`, {}); } export async function resumeTrack(guildId: number): Promise { - await postRequest(`guilds/${guildId}/voice/resume`, {}); + await post(`guilds/${guildId}/voice/resume`, {}); } export async function setVolume(guildId: number, volume: number): Promise { - await postRequest(`guilds/${guildId}/voice/volume`, { volume: `${volume}` }); + await post(`guilds/${guildId}/voice/volume`, { volume: `${volume}` }); } export async function skipTrack(guildId: number): Promise { - await postRequest(`guilds/${guildId}/voice/skip`, {}); + await post(`guilds/${guildId}/voice/skip`, {}); } export async function getVolume(guildId: number): Promise { - const response = await getRequest(`guilds/${guildId}/voice/volume`); - return response?.data?.volume || 0; + const response = await get(`guilds/${guildId}/voice/volume`); + const volume: number = await response?.json(); + return volume || 0; } diff --git a/ui/src/api/index.ts b/ui/src/api/index.ts index 5facad5..d990220 100644 --- a/ui/src/api/index.ts +++ b/ui/src/api/index.ts @@ -1,43 +1,32 @@ -import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; +// import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; const serviceHost = process.env.SERVICE_HOST || 'http://localhost'; const servicePort = process.env.SERVICE_PORT || 5000; +const baseURL = `${serviceHost}:${servicePort}`; -function createAxiosClient(): AxiosInstance { - const axiosClient = axios.create({ - baseURL: `${serviceHost}:${servicePort}` +export async function get(endpoint: string, params: Record = {}): Promise { + // Remove undefined params + Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); + const urlParams = new URLSearchParams(params); + const url = urlParams ? `${baseURL}/${endpoint}?${urlParams}` : `${baseURL}/${endpoint}`; + const response = await fetch(url, { + method: 'GET', + credentials: 'include' }); + return response; +} - axiosClient.interceptors.request.use( - (request) => { - request.withCredentials = true; - return request; +export async function post(endpoint: string, body = {}): Promise { + const url = `${baseURL}/${endpoint}`; + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' }, - (error) => { - console.error(error); - return Promise.reject(error); - } - ); - return axiosClient; -} - -const axiosClient = createAxiosClient(); - -export async function getRequest( - url: string, - config?: AxiosRequestConfig -): Promise | undefined> { - const response = await axiosClient.get(`/${url}`, config); - return response || undefined; -} - -export async function postRequest( - url: string, - data?: any, - config?: AxiosRequestConfig -): Promise | undefined> { - const response = await axiosClient.post(`/${url}`, data, config); - return response || undefined; + credentials: 'include', + body: JSON.stringify(body) + }); + return response; } export interface Metadata { diff --git a/ui/src/api/spells.ts b/ui/src/api/spells.ts index 426c5d3..db838f4 100644 --- a/ui/src/api/spells.ts +++ b/ui/src/api/spells.ts @@ -1,4 +1,4 @@ -import { getRequest } from '.'; +import { get } from '.'; import { GetSpellsResponse } from './spells.types'; interface GetSpellsParams { @@ -19,23 +19,21 @@ interface GetSpellsParams { } export async function getSpells(params?: GetSpellsParams): Promise { - const response = await getRequest('dnd/spells', { - params: { - name: params?.name, - like_name: params?.like_name, - schools: params?.schools?.join(','), - levels: params?.levels?.join(','), - ritual: params?.ritual, - concentration: params?.concentration, - classes: params?.classes?.join(','), - damage_inflict: params?.damage_inflict?.join(','), - damage_resist: params?.damage_resist?.join(','), - conditions: params?.conditions?.join(','), - saving_throw: params?.saving_throw?.join(','), - attack_type: params?.attack_type?.join(','), - limit: params?.limit, - page: params?.page - } + const response = await get('dnd/spells', { + name: params?.name, + like_name: params?.like_name, + schools: params?.schools?.join(','), + levels: params?.levels?.join(','), + ritual: params?.ritual, + concentration: params?.concentration, + classes: params?.classes?.join(','), + damage_inflict: params?.damage_inflict?.join(','), + damage_resist: params?.damage_resist?.join(','), + conditions: params?.conditions?.join(','), + saving_throw: params?.saving_throw?.join(','), + attack_type: params?.attack_type?.join(','), + limit: params?.limit, + page: params?.page }); - return response?.data || { data: [] }; + return response?.json() || { data: [] }; } diff --git a/ui/src/components/Topbar/index.tsx b/ui/src/components/Topbar/index.tsx index b68a663..7efb7bb 100644 --- a/ui/src/components/Topbar/index.tsx +++ b/ui/src/components/Topbar/index.tsx @@ -24,7 +24,7 @@ import { import Cookies from 'js-cookie'; import { useEffect, useState } from 'react'; import { useForm } from '@mantine/form'; -import { login, register, logout, me, refresh } from '@/api/auth'; +import { login, register, logout, me, refreshLoggedIn } from '@/api/auth'; import { User } from '@/api/auth.types'; import { useToggle } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; @@ -76,23 +76,18 @@ export default function Topbar() { const [modalType, toggle] = useToggle([undefined, 'login', 'register', 'reset']); const [headers, setHeaders] = useState([]); const [user, setUser] = useState(undefined); + const [refreshId, setRefreshId] = useState(undefined); + useEffect(() => { if (Cookies.get('logged_in')) { me().then((response) => { if (response) { + setRefreshId(refreshLoggedIn()); setUser(response.user); } }); - } else { - refresh(true).then((response) => { - if (response) { - setUser(response.user); - } else { - setUser(undefined); - } - }); } - }, [pathName]); + }, []); useEffect(() => { const h: HeaderItem[] = []; @@ -172,6 +167,9 @@ export default function Topbar() { const response = await logout(); if (response?.status == 200) { Cookies.remove('logged_in'); + if (refreshId) { + clearInterval(refreshId); + } setUser(undefined); } }} @@ -193,7 +191,7 @@ export default function Topbar() { )} - + ); } @@ -202,9 +200,10 @@ interface LoginModalProps { type?: string; toggle: any; setUser: (user: User) => void; + setRefreshId: (id: NodeJS.Timeout) => void; } -function LoginModal({ type, toggle, setUser }: LoginModalProps) { +function LoginModal({ type, toggle, setUser, setRefreshId }: LoginModalProps) { function passwordValidator(value: string) { if (value.trim().length < 10) { return 'Password must be at least 10 characters'; @@ -325,6 +324,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) { const loginResponse = await login(values.email, values.password); if (loginResponse) { setUser(loginResponse.user); + setRefreshId(refreshLoggedIn()); onClose(); notifications.update({ id, @@ -400,6 +400,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) { const response = await login(values.email, values.password); if (response) { setUser(response.user); + setRefreshId(refreshLoggedIn()); onClose(); } else { notifications.show({