Skip to content

Commit c27a3aa

Browse files
committed
refactor: add axios wrapper for authenticated requests
1 parent 876c9c8 commit c27a3aa

File tree

10 files changed

+82
-98
lines changed

10 files changed

+82
-98
lines changed

src/components/Benchmarks/CreateBenchmark.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ const CreateBenchmark: React.FC = () => {
127127
</div>
128128
</Page>
129129
);
130-
// }
131130
};
132131

133132
export default CreateBenchmark;

src/components/Login.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { LockClosedIcon } from '@heroicons/react/solid';
22
import React from 'react';
33
import { useHistory } from 'react-router-dom';
44
import { login } from '../api/auth';
5-
import useToken from '../hooks/token';
5+
import { useToken } from '../hooks/token';
66

77
const Login: React.FC = () => {
88
const history = useHistory();

src/components/Page/Navbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { BellIcon, MenuIcon, XIcon } from '@heroicons/react/outline';
33
import React, { Fragment } from 'react';
44
import Gravatar from 'react-gravatar';
55
import { Link, useHistory } from 'react-router-dom';
6-
import useToken from '../../hooks/token';
6+
import { useToken } from '../../hooks/token';
77
import useProfile from '../../hooks/users';
88

99
const navigation = [

src/components/Register.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState } from 'react';
22
import { Link, useHistory } from 'react-router-dom';
33
import { login, register } from '../api/auth';
4-
import useToken from '../hooks/token';
4+
import { useToken } from '../hooks/token';
55
import Label from './utils/Label';
66

77
const Register: React.FC = () => {

src/components/Routing/PrivateRoute.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
RouteComponentProps,
66
RouteProps,
77
} from 'react-router-dom';
8-
import useToken from '../../hooks/token';
8+
import { useToken } from '../../hooks/token';
99

1010
interface PrivateRouteProps extends RouteProps {
1111
component:

src/components/utils/request.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import axios, { AxiosRequestConfig } from 'axios';
2+
import { getToken } from '../../hooks/token';
3+
4+
const client = axios.create({
5+
baseURL: process.env.REACT_APP_API_ENDPOINT,
6+
});
7+
8+
// Wrapper around axios that adds the JWT token in req header
9+
const authenticatedRequest = (options: AxiosRequestConfig) => {
10+
client.defaults.headers.common.Authorization = `Bearer ${getToken()}`;
11+
12+
const onSuccess = (response: any) => response;
13+
const onError = (error: any) => {
14+
// optionaly catch errors and add some additional logging here
15+
return error;
16+
};
17+
18+
return client({ timeout: 5000, ...options })
19+
.then(onSuccess)
20+
.catch(onError);
21+
};
22+
23+
export default authenticatedRequest;

src/hooks/benchmark.ts

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,23 @@
1-
import axios, { AxiosResponse } from 'axios';
21
import { useQuery } from 'react-query';
32
import benchmarkModel from '../components/Benchmarks/BenchmarkModel';
4-
import useToken from './token';
3+
import authenticatedRequest from '../components/utils/request';
54

65
export default function useBenchmarkDetail(id: string) {
7-
const { token } = useToken();
8-
96
return useQuery<benchmarkModel, Error>(`benchmark-${id}`, async () => {
107
if (id) {
11-
const { data } = await axios.get(
12-
`${process.env.REACT_APP_API_ENDPOINT}/benchmarks/${id}`,
13-
{
14-
headers: {
15-
Authorization: `Bearer ${token}`,
16-
},
17-
},
18-
);
8+
const { data } = await authenticatedRequest({
9+
url: `benchmarks/${id}`,
10+
});
1911
return data;
2012
}
2113
});
2214
}
2315

2416
export function useBenchmarkSList() {
25-
const { token } = useToken();
26-
2717
return useQuery<benchmarkModel[], Error>(`benchmark`, async () => {
28-
const { data } = await axios.get(
29-
`${process.env.REACT_APP_API_ENDPOINT}/benchmarks`,
30-
{
31-
headers: {
32-
Authorization: `Bearer ${token}`,
33-
},
34-
},
35-
);
18+
const { data } = await authenticatedRequest({
19+
url: `benchmarks`,
20+
});
3621
return data;
3722
});
3823
}
@@ -42,15 +27,10 @@ export async function createBenchmark(bench: {
4227
subject: string;
4328
difficulty: string;
4429
}): Promise<benchmarkModel> {
45-
const res: AxiosResponse<benchmarkModel> = await axios.post(
46-
`${process.env.REACT_APP_API_ENDPOINT}/benchmarks`,
47-
bench,
48-
{
49-
timeout: 5000,
50-
headers: {
51-
Authorization: 'Bearer ' + localStorage.getItem('access_token'), // FIX ME
52-
},
53-
},
54-
);
55-
return res.data;
30+
const { data } = await authenticatedRequest({
31+
url: `/benchmarks`,
32+
method: 'POST',
33+
data: bench,
34+
});
35+
return data;
5636
}

src/hooks/submissions.ts

Lines changed: 28 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import axios, { AxiosResponse } from 'axios';
21
import { useState } from 'react';
32
import { useMutation, useQuery } from 'react-query';
4-
import useToken from './token';
3+
import authenticatedRequest from '../components/utils/request';
4+
import { useToken } from './token';
55

66
function useProcessInterval({
77
onSuccess,
@@ -22,35 +22,27 @@ function useProcessInterval({
2222
code: string;
2323
benchmarkId: string;
2424
}) {
25-
const response = await fetch(
26-
`${process.env.REACT_APP_API_ENDPOINT}/submissions`,
27-
{
28-
method: 'POST',
29-
headers: {
30-
'Content-Type': 'application/json',
31-
Authorization: `Bearer ${token}`,
32-
},
33-
body: JSON.stringify({
34-
language: 'cpython3',
35-
code: code,
36-
benchmarkId: benchmarkId,
37-
}),
25+
const { data } = await authenticatedRequest({
26+
url: `/submissions`,
27+
method: 'POST',
28+
data: {
29+
language: 'cpython3',
30+
code: code,
31+
benchmarkId: benchmarkId,
3832
},
39-
);
40-
return await response.json();
33+
});
34+
return data;
4135
}
4236

4337
const { mutate } = useMutation(createJob, {
4438
onMutate: () => {
4539
setIsPollingEnabled(true);
4640
},
4741
onError: (error) => {
48-
console.error(error);
4942
setIsPollingEnabled(false);
5043
onError();
5144
},
5245
onSuccess: (data) => {
53-
console.log(data);
5446
setProcessId(data.id);
5547
},
5648
});
@@ -59,19 +51,18 @@ function useProcessInterval({
5951
const { isLoading, data } = useQuery(
6052
['processProgress', token, processId],
6153
async () => {
62-
const res: AxiosResponse<{
63-
status: string;
64-
stdout: string;
65-
stderr: string;
66-
}> = await axios.get(
67-
`${process.env.REACT_APP_API_ENDPOINT}/submissions/${processId}`,
68-
{
69-
headers: {
70-
Authorization: `Bearer ${token}`,
71-
},
72-
},
73-
);
74-
return res.data;
54+
const {
55+
data,
56+
}: {
57+
data: {
58+
status: string;
59+
stdout: string;
60+
stderr: string;
61+
};
62+
} = await authenticatedRequest({
63+
url: `submissions/${processId}`,
64+
});
65+
return data;
7566
},
7667
{
7768
onSuccess: (data) => {
@@ -101,23 +92,16 @@ export function useLastSubmissionForUser(
10192
benchmarkId: string,
10293
language: string,
10394
) {
104-
const { token } = useToken();
105-
10695
return useQuery<{ code: string }, Error>(
10796
`last-submission-${benchmarkId}-${language}`,
10897
async () => {
10998
if (benchmarkId && language) {
110-
const { data } = await axios.get(
111-
`${process.env.REACT_APP_API_ENDPOINT}/benchmarks/${benchmarkId}/submissions/last`,
112-
{
113-
headers: {
114-
Authorization: `Bearer ${token}`,
115-
},
116-
params: {
117-
language,
118-
},
99+
const { data } = await authenticatedRequest({
100+
url: `benchmarks/${benchmarkId}/submissions/last`,
101+
params: {
102+
language,
119103
},
120-
);
104+
});
121105
return data;
122106
}
123107
},

src/hooks/token.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { useState } from 'react';
22

3-
export default function useToken() {
4-
function getToken(): any {
5-
const tokenString = localStorage.getItem('access_token');
6-
if (tokenString) {
7-
return tokenString;
8-
}
3+
function getToken(): string {
4+
const tokenString = localStorage.getItem('access_token');
5+
if (tokenString) {
6+
return tokenString;
97
}
8+
return ''; // FIX ME
9+
}
1010

11+
function useToken() {
1112
function setToken(userToken: string) {
1213
localStorage.setItem('access_token', userToken);
1314
}
@@ -18,3 +19,5 @@ export default function useToken() {
1819
token,
1920
};
2021
}
22+
23+
export { getToken, useToken };

src/hooks/users.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import axios from 'axios';
21
import { useQuery } from 'react-query';
3-
import useToken from './token';
2+
import authenticatedRequest from '../components/utils/request';
3+
import { useToken } from './token';
44

55
function useProfile() {
66
const { token } = useToken();
@@ -18,14 +18,9 @@ function useProfile() {
1818
return useQuery<{ email: string }, Error>('profile', async () => {
1919
if (token) {
2020
const username = parseJwt(token).username;
21-
const { data } = await axios.get(
22-
`${process.env.REACT_APP_API_ENDPOINT}/users/${username}`,
23-
{
24-
headers: {
25-
Authorization: `Bearer ${token}`,
26-
},
27-
},
28-
);
21+
const { data } = await authenticatedRequest({
22+
url: `users/${username}`,
23+
});
2924
return data;
3025
}
3126
});

0 commit comments

Comments
 (0)