diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index cb64a23..d947f10 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -9,7 +9,6 @@ export type Client = { export const getClient = (authToken?: string): Client => { if (authToken) { - console.log(authToken) return { axios: axios.create({ headers: { diff --git a/frontend/src/api/endpoints/AccountEndpoint.ts b/frontend/src/api/endpoints/AccountEndpoint.ts new file mode 100644 index 0000000..b2ef4d7 --- /dev/null +++ b/frontend/src/api/endpoints/AccountEndpoint.ts @@ -0,0 +1,18 @@ +import {Client} from "../client"; +import Account from "../entities/Account"; +import Endpoint from "./Endpoint"; + +const API_PREFIX = "/api/account/" + +class AccountEndpoint extends Endpoint { + constructor(client: Client) { + super(client) + this.requireAuthenticated() + } + + public async getAll(): Promise { + return await this.get(API_PREFIX) + } +} + +export default AccountEndpoint \ No newline at end of file diff --git a/frontend/src/api/entities/Account.ts b/frontend/src/api/entities/Account.ts new file mode 100644 index 0000000..3f15090 --- /dev/null +++ b/frontend/src/api/entities/Account.ts @@ -0,0 +1,10 @@ + +type Account = { + id: string + screen_name: string + twitter_handle: string + twitter_id: string + avatar_url: string +} + +export default Account \ No newline at end of file diff --git a/frontend/src/auth/AuthProvider.tsx b/frontend/src/auth/AuthProvider.tsx index f97f09c..f3fbc8f 100644 --- a/frontend/src/auth/AuthProvider.tsx +++ b/frontend/src/auth/AuthProvider.tsx @@ -1,16 +1,19 @@ -import React, {FunctionComponent, useContext, useState} from "react"; +import React, {FunctionComponent, useContext, useEffect, useState} from "react"; import AuthenticationEndpoint from "../api/endpoints/AuthenticationEndpoint"; import {Client, getClient} from "../api/client"; import User from "../api/entities/User"; +import {Backdrop, CircularProgress} from "@material-ui/core"; type AuthState = { loggedIn: boolean + user: User|null login: (username: string, password: string) => Promise } const emptyAuthState = { loggedIn: false, + user: null, login: async () => { throw "not implemented" @@ -26,9 +29,14 @@ export const useAuth = (): AuthState => { type AuthProviderProps = { } +const LOCAL_STORAGE_SESSION_TOKEN_KEY = "session_token" + +const initialSessionToken = localStorage.getItem(LOCAL_STORAGE_SESSION_TOKEN_KEY) const AuthProvider: FunctionComponent = ({children}) => { - const [client, setClient] = useState(getClient()) + const [loading, setLoading] = useState(true) + + const [client, setClient] = useState(getClient(initialSessionToken ? initialSessionToken : undefined)) const authenticationEndpoint = new AuthenticationEndpoint(client) const [authState, setAuthState] = useState({ @@ -41,21 +49,58 @@ const AuthProvider: FunctionComponent = ({children}) => { }) // local new client - console.log(response) const tmpClient = getClient(response.token) setClient(tmpClient) + localStorage.setItem(LOCAL_STORAGE_SESSION_TOKEN_KEY, response.token); + // local new authenticationEndpoint const tmpAuthenticationEndpoint = new AuthenticationEndpoint(tmpClient) - return await tmpAuthenticationEndpoint.getUser() + const user = await tmpAuthenticationEndpoint.getUser() + + setAuthState({ + ...authState, + loggedIn: true, + user: user + }) + + return user } }) - return ( - - {children} - - ) + useEffect(() => { + if (initialSessionToken) { + authenticationEndpoint.getUser() + .then(user => { + setAuthState({ + ...authState, + loggedIn: true, + user: user + }) + setLoading(false) + }) + .catch(_ => { + localStorage.removeItem(LOCAL_STORAGE_SESSION_TOKEN_KEY); + setLoading(false) + }) + } else { + setLoading(false) + } + }, []) + + if (loading) { + return ( + + + + ) + } else { + return ( + + {children} + + ) + } } export default AuthProvider \ No newline at end of file diff --git a/frontend/src/components/Login/index.tsx b/frontend/src/components/Login/index.tsx index b5f2380..9ac0589 100644 --- a/frontend/src/components/Login/index.tsx +++ b/frontend/src/components/Login/index.tsx @@ -5,6 +5,7 @@ import {TextField} from "formik-material-ui"; import {useAuth} from "../../auth/AuthProvider"; import * as yup from "yup" import {useState} from "react"; +import {useHistory} from "react-router-dom"; type LoginFormProps = { username: string @@ -19,13 +20,15 @@ const LoginFormValidationSchema = yup.object({ const Login = () => { const auth = useAuth() + const history = useHistory() + const [error, setError] = useState(null) const onSubmit = async (values: LoginFormProps, helper: FormikHelpers) => { - console.log(values) try { const user = await auth.login(values.username, values.password) console.log(user) + history.push("/"); } catch (e) { helper.setSubmitting(false) setError("Login failed!")