Updated fetch cookie

This commit is contained in:
Benjamin Sherriff
2023-10-19 19:48:24 -04:00
parent 72c7f2427c
commit 00a6629e60
5 changed files with 101 additions and 89 deletions

View File

@@ -1,17 +1,18 @@
import { getRequest, postRequest } from '.'; import Cookies from 'js-cookie';
import { get, post } from '.';
import { RegisterUser, ResponseAuth } from './auth.types'; import { RegisterUser, ResponseAuth } from './auth.types';
export async function login(email: string, password: string): Promise<ResponseAuth | undefined> { export async function login(email: string, password: string): Promise<ResponseAuth | undefined> {
const response = await postRequest('auth/login', { email, password }); const response = await post('auth/login', { email, password });
if (response?.status === 200) { if (response?.status === 200) {
return response.data as ResponseAuth; return response.json();
} else { } else {
return undefined; return undefined;
} }
} }
export async function register(user: RegisterUser): Promise<boolean> { export async function register(user: RegisterUser): Promise<boolean> {
const response = await postRequest('auth/register', user); const response = await post('auth/register', user);
if (response?.status === 201) { if (response?.status === 201) {
return true; return true;
} else { } else {
@@ -20,23 +21,45 @@ export async function register(user: RegisterUser): Promise<boolean> {
} }
export async function logout() { export async function logout() {
return await postRequest('auth/logout', {}); return await post('auth/logout', {});
} }
export async function refresh(refresh_token_rotation?: boolean): Promise<ResponseAuth | undefined> { export async function refresh(refresh_token_rotation?: boolean): Promise<ResponseAuth | undefined> {
const response = await getRequest('auth/refresh', { params: { refresh_token_rotation } }); const response = await get('auth/refresh', { params: { refresh_token_rotation } });
if (response?.status === 200) { if (response?.status === 200) {
return response.data as ResponseAuth; return response.json();
} else { } else {
return undefined; return undefined;
} }
} }
export async function me(): Promise<ResponseAuth | undefined> { export async function me(): Promise<ResponseAuth | undefined> {
const response = await getRequest('auth/me'); const response = await get('auth/me');
if (response?.status === 200) { if (response?.status === 200) {
return response.data; return response.json();
} else { } else {
return undefined; 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;
}

View File

@@ -1,50 +1,51 @@
import { getRequest, postRequest } from '.'; import { get, post } from '.';
import { GuildChannel, GuildInfo } from './guilds.types'; import { GuildChannel, GuildInfo } from './guilds.types';
export async function getGuilds(): Promise<GuildInfo[]> { export async function getGuilds(): Promise<GuildInfo[]> {
const response = await getRequest('guilds'); const response = await get('guilds');
return response?.data || { data: [] }; return response?.json() || { data: [] };
} }
export async function getTextChannels(guildId: number): Promise<GuildChannel[]> { export async function getTextChannels(guildId: number): Promise<GuildChannel[]> {
const response = await getRequest(`guilds/${guildId}/text`); const response = await get(`guilds/${guildId}/text`);
return response?.data || { data: [] }; return response?.json() || { data: [] };
} }
export async function sendMessage(guildId: number, channelId: number, message: string): Promise<void> { export async function sendMessage(guildId: number, channelId: number, message: string): Promise<void> {
await postRequest(`guilds/${guildId}/text/${channelId}/message`, { message }); await post(`guilds/${guildId}/text/${channelId}/message`, { message });
} }
export async function getVoiceChannels(guildId: number): Promise<GuildChannel[]> { export async function getVoiceChannels(guildId: number): Promise<GuildChannel[]> {
const response = await getRequest(`guilds/${guildId}/voice`); const response = await get(`guilds/${guildId}/voice`);
return response?.data || { data: [] }; return response?.json() || { data: [] };
} }
export async function playTrack(guildId: number, channelId: number, track: string): Promise<void> { export async function playTrack(guildId: number, channelId: number, track: string): Promise<void> {
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<void> { export async function stopTrack(guildId: number): Promise<void> {
await postRequest(`guilds/${guildId}/voice/stop`, {}); await post(`guilds/${guildId}/voice/stop`, {});
} }
export async function pauseTrack(guildId: number): Promise<void> { export async function pauseTrack(guildId: number): Promise<void> {
await postRequest(`guilds/${guildId}/voice/pause`, {}); await post(`guilds/${guildId}/voice/pause`, {});
} }
export async function resumeTrack(guildId: number): Promise<void> { export async function resumeTrack(guildId: number): Promise<void> {
await postRequest(`guilds/${guildId}/voice/resume`, {}); await post(`guilds/${guildId}/voice/resume`, {});
} }
export async function setVolume(guildId: number, volume: number): Promise<void> { export async function setVolume(guildId: number, volume: number): Promise<void> {
await postRequest(`guilds/${guildId}/voice/volume`, { volume: `${volume}` }); await post(`guilds/${guildId}/voice/volume`, { volume: `${volume}` });
} }
export async function skipTrack(guildId: number): Promise<void> { export async function skipTrack(guildId: number): Promise<void> {
await postRequest(`guilds/${guildId}/voice/skip`, {}); await post(`guilds/${guildId}/voice/skip`, {});
} }
export async function getVolume(guildId: number): Promise<number> { export async function getVolume(guildId: number): Promise<number> {
const response = await getRequest(`guilds/${guildId}/voice/volume`); const response = await get(`guilds/${guildId}/voice/volume`);
return response?.data?.volume || 0; const volume: number = await response?.json();
return volume || 0;
} }

View File

@@ -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 serviceHost = process.env.SERVICE_HOST || 'http://localhost';
const servicePort = process.env.SERVICE_PORT || 5000; const servicePort = process.env.SERVICE_PORT || 5000;
const baseURL = `${serviceHost}:${servicePort}`;
function createAxiosClient(): AxiosInstance { export async function get(endpoint: string, params: Record<string, any> = {}): Promise<Response> {
const axiosClient = axios.create({ // Remove undefined params
baseURL: `${serviceHost}:${servicePort}` 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( export async function post(endpoint: string, body = {}): Promise<Response> {
(request) => { const url = `${baseURL}/${endpoint}`;
request.withCredentials = true; const response = await fetch(url, {
return request; method: 'POST',
headers: {
'Content-Type': 'application/json'
}, },
(error) => { credentials: 'include',
console.error(error); body: JSON.stringify(body)
return Promise.reject(error); });
} return response;
);
return axiosClient;
}
const axiosClient = createAxiosClient();
export async function getRequest(
url: string,
config?: AxiosRequestConfig<any>
): Promise<AxiosResponse<any, any> | undefined> {
const response = await axiosClient.get(`/${url}`, config);
return response || undefined;
}
export async function postRequest(
url: string,
data?: any,
config?: AxiosRequestConfig<any>
): Promise<AxiosResponse<any, any> | undefined> {
const response = await axiosClient.post(`/${url}`, data, config);
return response || undefined;
} }
export interface Metadata { export interface Metadata {

View File

@@ -1,4 +1,4 @@
import { getRequest } from '.'; import { get } from '.';
import { GetSpellsResponse } from './spells.types'; import { GetSpellsResponse } from './spells.types';
interface GetSpellsParams { interface GetSpellsParams {
@@ -19,8 +19,7 @@ interface GetSpellsParams {
} }
export async function getSpells(params?: GetSpellsParams): Promise<GetSpellsResponse> { export async function getSpells(params?: GetSpellsParams): Promise<GetSpellsResponse> {
const response = await getRequest('dnd/spells', { const response = await get('dnd/spells', {
params: {
name: params?.name, name: params?.name,
like_name: params?.like_name, like_name: params?.like_name,
schools: params?.schools?.join(','), schools: params?.schools?.join(','),
@@ -35,7 +34,6 @@ export async function getSpells(params?: GetSpellsParams): Promise<GetSpellsResp
attack_type: params?.attack_type?.join(','), attack_type: params?.attack_type?.join(','),
limit: params?.limit, limit: params?.limit,
page: params?.page page: params?.page
}
}); });
return response?.data || { data: [] }; return response?.json() || { data: [] };
} }

View File

@@ -24,7 +24,7 @@ import {
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useForm } from '@mantine/form'; 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 { User } from '@/api/auth.types';
import { useToggle } from '@mantine/hooks'; import { useToggle } from '@mantine/hooks';
import { notifications } from '@mantine/notifications'; import { notifications } from '@mantine/notifications';
@@ -76,23 +76,18 @@ export default function Topbar() {
const [modalType, toggle] = useToggle([undefined, 'login', 'register', 'reset']); const [modalType, toggle] = useToggle([undefined, 'login', 'register', 'reset']);
const [headers, setHeaders] = useState<HeaderItem[]>([]); const [headers, setHeaders] = useState<HeaderItem[]>([]);
const [user, setUser] = useState<User | undefined>(undefined); const [user, setUser] = useState<User | undefined>(undefined);
const [refreshId, setRefreshId] = useState<NodeJS.Timeout | undefined>(undefined);
useEffect(() => { useEffect(() => {
if (Cookies.get('logged_in')) { if (Cookies.get('logged_in')) {
me().then((response) => { me().then((response) => {
if (response) { if (response) {
setRefreshId(refreshLoggedIn());
setUser(response.user); setUser(response.user);
} }
}); });
} else {
refresh(true).then((response) => {
if (response) {
setUser(response.user);
} else {
setUser(undefined);
} }
}); }, []);
}
}, [pathName]);
useEffect(() => { useEffect(() => {
const h: HeaderItem[] = []; const h: HeaderItem[] = [];
@@ -172,6 +167,9 @@ export default function Topbar() {
const response = await logout(); const response = await logout();
if (response?.status == 200) { if (response?.status == 200) {
Cookies.remove('logged_in'); Cookies.remove('logged_in');
if (refreshId) {
clearInterval(refreshId);
}
setUser(undefined); setUser(undefined);
} }
}} }}
@@ -193,7 +191,7 @@ export default function Topbar() {
)} )}
</div> </div>
</nav> </nav>
<LoginModal type={modalType} toggle={toggle} setUser={setUser} /> <LoginModal type={modalType} toggle={toggle} setUser={setUser} setRefreshId={setRefreshId} />
</> </>
); );
} }
@@ -202,9 +200,10 @@ interface LoginModalProps {
type?: string; type?: string;
toggle: any; toggle: any;
setUser: (user: User) => void; 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) { function passwordValidator(value: string) {
if (value.trim().length < 10) { if (value.trim().length < 10) {
return 'Password must be at least 10 characters'; 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); const loginResponse = await login(values.email, values.password);
if (loginResponse) { if (loginResponse) {
setUser(loginResponse.user); setUser(loginResponse.user);
setRefreshId(refreshLoggedIn());
onClose(); onClose();
notifications.update({ notifications.update({
id, id,
@@ -400,6 +400,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
const response = await login(values.email, values.password); const response = await login(values.email, values.password);
if (response) { if (response) {
setUser(response.user); setUser(response.user);
setRefreshId(refreshLoggedIn());
onClose(); onClose();
} else { } else {
notifications.show({ notifications.show({