2020-09-05 23:35:53 +02:00
|
|
|
import React, {
|
|
|
|
|
createContext,
|
|
|
|
|
useCallback,
|
|
|
|
|
useContext,
|
|
|
|
|
useEffect,
|
|
|
|
|
useState,
|
|
|
|
|
} from "react";
|
|
|
|
|
import { getUsersMe, postAuthTokenRefresh } from "../api/auth-api";
|
2020-05-02 21:46:41 +02:00
|
|
|
import { User } from "../api/entities/user";
|
2020-05-02 03:03:19 +02:00
|
|
|
|
|
|
|
|
interface AuthContext {
|
|
|
|
|
isLoaded: boolean;
|
2020-09-05 23:35:53 +02:00
|
|
|
user: User | null;
|
|
|
|
|
accessToken: string;
|
|
|
|
|
error: Error | null;
|
|
|
|
|
refreshAccessToken: () => Promise<string>;
|
2020-05-02 03:03:19 +02:00
|
|
|
loginWithSpotifyProps: () => { href: string };
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-25 16:01:55 +02:00
|
|
|
const authContext = createContext<AuthContext>(undefined as any as AuthContext);
|
2020-09-05 23:35:53 +02:00
|
|
|
|
2020-05-02 03:03:19 +02:00
|
|
|
export const ProvideAuth: React.FC = ({ children }) => {
|
|
|
|
|
const auth = useProvideAuth();
|
|
|
|
|
|
|
|
|
|
return <authContext.Provider value={auth}>{children}</authContext.Provider>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function useAuth() {
|
|
|
|
|
return useContext(authContext);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function useProvideAuth(): AuthContext {
|
|
|
|
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
|
|
|
const [user, setUser] = useState<User | null>(null);
|
2020-09-05 23:35:53 +02:00
|
|
|
const [accessToken, setAccessToken] = useState<string>("");
|
|
|
|
|
const [error, setError] = useState<Error | null>(null);
|
2020-05-02 03:03:19 +02:00
|
|
|
|
|
|
|
|
const loginWithSpotifyProps = () => ({ href: "/api/v1/auth/spotify" });
|
|
|
|
|
|
2020-09-05 23:35:53 +02:00
|
|
|
const refreshAccessToken = useCallback(async () => {
|
|
|
|
|
try {
|
|
|
|
|
const { accessToken: newAccessToken } = await postAuthTokenRefresh();
|
|
|
|
|
setAccessToken(newAccessToken);
|
|
|
|
|
return newAccessToken;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setAccessToken("");
|
|
|
|
|
setUser(null);
|
|
|
|
|
setIsLoaded(true);
|
|
|
|
|
setError(err);
|
|
|
|
|
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
2020-05-02 03:03:19 +02:00
|
|
|
}, []);
|
|
|
|
|
|
2020-09-05 23:35:53 +02:00
|
|
|
useEffect(() => {
|
|
|
|
|
refreshAccessToken().catch(() => {
|
|
|
|
|
console.log("Unable to refresh access token");
|
|
|
|
|
});
|
|
|
|
|
}, [refreshAccessToken]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!accessToken) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
async function getUser(token: string) {
|
|
|
|
|
const newUser = await getUsersMe(token);
|
|
|
|
|
setUser(newUser);
|
|
|
|
|
setIsLoaded(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getUser(accessToken);
|
|
|
|
|
}, [accessToken]);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
isLoaded,
|
|
|
|
|
user,
|
|
|
|
|
accessToken,
|
|
|
|
|
error,
|
|
|
|
|
refreshAccessToken,
|
|
|
|
|
loginWithSpotifyProps,
|
|
|
|
|
};
|
2020-05-02 03:03:19 +02:00
|
|
|
}
|