2019-08-09 10:26:22 +00:00
|
|
|
import React from "react";
|
2019-06-19 14:40:52 +00:00
|
|
|
|
|
|
|
import { getMutationProviderData } from "../misc";
|
|
|
|
import { PartialMutationProviderOutput } from "../types";
|
|
|
|
import { getAuthToken, removeAuthToken, setAuthToken, UserContext } from "./";
|
|
|
|
import { TypedTokenAuthMutation, TypedVerifyTokenMutation } from "./mutations";
|
|
|
|
import { TokenAuth, TokenAuthVariables } from "./types/TokenAuth";
|
|
|
|
import { User } from "./types/User";
|
|
|
|
import { VerifyToken, VerifyTokenVariables } from "./types/VerifyToken";
|
|
|
|
|
|
|
|
interface AuthProviderOperationsProps {
|
2019-09-02 19:23:37 +00:00
|
|
|
children: (props: {
|
|
|
|
hasToken: boolean;
|
|
|
|
isAuthenticated: boolean;
|
|
|
|
tokenAuthLoading: boolean;
|
|
|
|
tokenVerifyLoading: boolean;
|
|
|
|
user: User;
|
|
|
|
}) => React.ReactNode;
|
2019-06-19 14:40:52 +00:00
|
|
|
}
|
|
|
|
const AuthProviderOperations: React.StatelessComponent<
|
|
|
|
AuthProviderOperationsProps
|
|
|
|
> = ({ children }) => {
|
|
|
|
return (
|
|
|
|
<TypedTokenAuthMutation>
|
|
|
|
{(...tokenAuth) => (
|
|
|
|
<TypedVerifyTokenMutation>
|
|
|
|
{(...tokenVerify) => (
|
|
|
|
<AuthProvider
|
|
|
|
tokenAuth={getMutationProviderData(...tokenAuth)}
|
|
|
|
tokenVerify={getMutationProviderData(...tokenVerify)}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</AuthProvider>
|
|
|
|
)}
|
|
|
|
</TypedVerifyTokenMutation>
|
|
|
|
)}
|
|
|
|
</TypedTokenAuthMutation>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
interface AuthProviderProps {
|
2019-09-02 19:23:37 +00:00
|
|
|
children: (props: {
|
|
|
|
hasToken: boolean;
|
|
|
|
isAuthenticated: boolean;
|
|
|
|
tokenAuthLoading: boolean;
|
|
|
|
tokenVerifyLoading: boolean;
|
|
|
|
user: User;
|
|
|
|
}) => React.ReactNode;
|
2019-06-19 14:40:52 +00:00
|
|
|
tokenAuth: PartialMutationProviderOutput<TokenAuth, TokenAuthVariables>;
|
|
|
|
tokenVerify: PartialMutationProviderOutput<VerifyToken, VerifyTokenVariables>;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface AuthProviderState {
|
|
|
|
user: User;
|
|
|
|
persistToken: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
class AuthProvider extends React.Component<
|
|
|
|
AuthProviderProps,
|
|
|
|
AuthProviderState
|
|
|
|
> {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = { user: undefined, persistToken: false };
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(props: AuthProviderProps) {
|
|
|
|
const { tokenAuth, tokenVerify } = props;
|
|
|
|
if (tokenAuth.opts.error || tokenVerify.opts.error) {
|
|
|
|
this.logout();
|
|
|
|
}
|
|
|
|
if (tokenAuth.opts.data) {
|
|
|
|
const user = tokenAuth.opts.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.
|
|
|
|
this.setState({ user });
|
|
|
|
if (user) {
|
|
|
|
setAuthToken(
|
|
|
|
tokenAuth.opts.data.tokenCreate.token,
|
|
|
|
this.state.persistToken
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (tokenVerify.opts.data && tokenVerify.opts.data.tokenVerify.user) {
|
|
|
|
const user = tokenVerify.opts.data.tokenVerify.user;
|
|
|
|
this.setState({ user });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
const { user } = this.state;
|
|
|
|
const { tokenVerify } = this.props;
|
|
|
|
const token = getAuthToken();
|
|
|
|
if (!!token && !user) {
|
|
|
|
tokenVerify.mutate({ token });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
login = (email: string, password: string, persistToken: boolean) => {
|
|
|
|
const { tokenAuth } = this.props;
|
|
|
|
this.setState({ persistToken });
|
|
|
|
tokenAuth.mutate({ email, password });
|
|
|
|
};
|
|
|
|
|
|
|
|
logout = () => {
|
|
|
|
this.setState({ user: undefined });
|
|
|
|
removeAuthToken();
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { children, tokenAuth, tokenVerify } = this.props;
|
|
|
|
const { user } = this.state;
|
|
|
|
const isAuthenticated = !!user;
|
2019-09-02 19:23:37 +00:00
|
|
|
|
2019-06-19 14:40:52 +00:00
|
|
|
return (
|
|
|
|
<UserContext.Provider
|
2019-09-02 19:23:37 +00:00
|
|
|
value={{
|
|
|
|
login: this.login,
|
|
|
|
logout: this.logout,
|
|
|
|
tokenAuthLoading: tokenAuth.opts.loading,
|
|
|
|
tokenVerifyLoading: tokenVerify.opts.loading,
|
|
|
|
user
|
|
|
|
}}
|
2019-06-19 14:40:52 +00:00
|
|
|
>
|
|
|
|
{children({
|
|
|
|
hasToken: !!getAuthToken(),
|
|
|
|
isAuthenticated,
|
|
|
|
tokenAuthLoading: tokenAuth.opts.loading,
|
|
|
|
tokenVerifyLoading: tokenVerify.opts.loading,
|
|
|
|
user
|
|
|
|
})}
|
|
|
|
</UserContext.Provider>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default AuthProviderOperations;
|