..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 | // apolloClient.ts
import {
ApolloClient,
InMemoryCache,
createHttpLink,
ApolloProvider,
makeVar,
} from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { onError } from '@apollo/client/link/error';
import axios from 'axios';
import { buildAuthUrl, fetchUserData, UserData } from '../index';
import { ReactNode, useEffect } from 'react';
// Reactive variables for user authentication state
const isLoggedInVar = makeVar<boolean>(false);
const userDataVar = makeVar<UserData | null>(null);
const httpLink = createHttpLink({
uri: 'https://graphql.anilist.co', // Update to your GraphQL server URL
});
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('accessToken');
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
};
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, locations, path }) =>
console.error(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
}
if (networkError) console.error(`[Network error]: ${networkError}`);
});
const client = new ApolloClient({
link: errorLink.concat(authLink.concat(httpLink)),
cache: new InMemoryCache(),
});
// Functions for handling authentication
function login() {
axios
.get('/get-csrf-token')
.then((response) => {
const csrfToken = response.data.csrfToken;
const authUrl = buildAuthUrl(csrfToken);
window.location.href = authUrl;
})
.catch((error) => {
console.error('Error fetching CSRF token or building auth URL:', error);
});
}
function logout() {
localStorage.removeItem('accessToken');
isLoggedInVar(false);
userDataVar(null);
window.location.href = '/profile'; // Adjust as necessary
window.dispatchEvent(new CustomEvent('authUpdate'));
}
function handleAuthUpdate() {
const token = localStorage.getItem('accessToken');
if (token) {
fetchUserData(token)
.then((data) => {
userDataVar(data);
isLoggedInVar(true);
})
.catch((err) => {
console.error('Failed to fetch user data:', err);
logout(); // Ensures clean state on failure
});
} else {
isLoggedInVar(false);
userDataVar(null);
}
}
export const ApolloClientProvider = ({ children }: { children: ReactNode }) => {
useEffect(() => {
window.addEventListener('authUpdate', handleAuthUpdate);
handleAuthUpdate();
return () => {
window.removeEventListener('authUpdate', handleAuthUpdate);
};
}, []);
return <ApolloProvider client={client}>{children}</ApolloProvider>;
};
export {
client as defaultApolloClient,
login,
logout,
isLoggedInVar,
userDataVar,
};
|
|