Fix logout

This commit is contained in:
dominik-zeglen 2020-07-20 11:46:59 +02:00
parent d203a26bde
commit 4de1a6682c

View file

@ -1,7 +1,7 @@
import { DEMO_MODE } from "@saleor/config"; import { DEMO_MODE } from "@saleor/config";
import { User } from "@saleor/fragments/types/User"; import { User } from "@saleor/fragments/types/User";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationStatus, maybe } from "@saleor/misc"; import { getMutationStatus } from "@saleor/misc";
import { import {
isSupported as isCredentialsManagementAPISupported, isSupported as isCredentialsManagementAPISupported,
login as loginWithCredentialsManagementAPI, login as loginWithCredentialsManagementAPI,
@ -27,6 +27,8 @@ import {
setAuthToken setAuthToken
} from "./utils"; } from "./utils";
const persistToken = false;
interface AuthProviderProps { interface AuthProviderProps {
children: React.ReactNode; children: React.ReactNode;
} }
@ -35,17 +37,55 @@ const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
const intl = useIntl(); const intl = useIntl();
const notify = useNotifier(); const notify = useNotifier();
const [userContext, setUserContext] = useState<undefined | User>(undefined);
const logout = () => {
setUserContext(undefined);
if (isCredentialsManagementAPISupported) {
navigator.credentials.preventSilentAccess();
}
removeAuthToken();
};
const [tokenAuth, tokenAuthResult] = useMutation< const [tokenAuth, tokenAuthResult] = useMutation<
TokenAuth, TokenAuth,
TokenAuthVariables TokenAuthVariables
>(tokenAuthMutation); >(tokenAuthMutation, {
onCompleted: result => {
const user = result.tokenCreate.user;
// FIXME: Now we set state also when auth fails and returned user is
// `null`, because the LoginView uses this `null` to display error.
setUserContext(user);
if (user) {
setAuthToken(result.tokenCreate.token, persistToken);
}
},
onError: logout
});
const [tokenRefresh] = useMutation<RefreshToken, RefreshTokenVariables>( const [tokenRefresh] = useMutation<RefreshToken, RefreshTokenVariables>(
tokenRefreshMutation tokenRefreshMutation,
{
onError: logout
}
); );
const [tokenVerify, tokenVerifyResult] = useMutation< const [tokenVerify, tokenVerifyResult] = useMutation<
VerifyToken, VerifyToken,
VerifyTokenVariables VerifyTokenVariables
>(tokenVerifyMutation); >(tokenVerifyMutation, {
onCompleted: result => {
if (result.tokenVerify === null) {
logout();
} else {
const user = result.tokenVerify?.user;
if (!!user) {
setUserContext(user);
}
}
},
onError: logout
});
const tokenAuthOpts = { const tokenAuthOpts = {
...tokenAuthResult, ...tokenAuthResult,
@ -56,39 +96,12 @@ const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
status: getMutationStatus(tokenVerifyResult) status: getMutationStatus(tokenVerifyResult)
}; };
const [userContext, setUserContext] = useState<undefined | User>(undefined);
const [persistToken] = useState<boolean>(false);
const onLogin = () => { const onLogin = () => {
if (DEMO_MODE) { if (DEMO_MODE) {
displayDemoMessage(intl, notify); displayDemoMessage(intl, notify);
} }
}; };
useEffect(() => {
if (tokenAuthOpts.error || tokenVerifyOpts.error) {
logout();
}
if (tokenAuthOpts.data) {
const user = tokenAuthOpts.data.tokenCreate.user;
// FIXME: Now we set state also when auth fails and returned user is
// `null`, because the LoginView uses this `null` to display error.
setUserContext(user);
if (user) {
setAuthToken(tokenAuthOpts.data.tokenCreate.token, persistToken);
}
} else {
if (maybe(() => tokenVerifyOpts.data.tokenVerify === null)) {
logout();
} else {
const user = maybe(() => tokenVerifyOpts.data.tokenVerify.user);
if (!!user) {
setUserContext(user);
}
}
}
}, [tokenAuthOpts, tokenVerifyOpts]);
useEffect(() => { useEffect(() => {
const token = getAuthToken(); const token = getAuthToken();
if (!!token && !userContext) { if (!!token && !userContext) {
@ -114,14 +127,6 @@ const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
setAuthToken(token, persistToken); setAuthToken(token, persistToken);
}; };
const logout = () => {
setUserContext(undefined);
if (isCredentialsManagementAPISupported) {
navigator.credentials.preventSilentAccess();
}
removeAuthToken();
};
const verifyToken = (token: string) => tokenVerify({ variables: { token } }); const verifyToken = (token: string) => tokenVerify({ variables: { token } });
const refreshToken = async () => { const refreshToken = async () => {