import { useState } from 'react' import { API_URL } from '../../config' import { isConst, isObject } from '../../utils/types' import { handleHTTPErrors } from '../../utils' interface AuthData { email: string, password: string, } // interface LoginData extends AuthData { } // interface SignUpData extends AuthData { // name: string, // surname: string // } type SignUpResponse = { Success: true } | { Success: false, Message: string } const isSignUpResponse = (obj: unknown): obj is SignUpResponse => ( isObject(obj, { 'Success': isConst(true) }) || isObject(obj, { 'Success': isConst(false), 'Message': 'string' }) ) interface LogInResponse { access_token: string, token_type: 'bearer' } const isLogInResponse = (obj: unknown): obj is LogInResponse => ( isObject(obj, { 'access_token': 'string', 'token_type': isConst('bearer') }) ) function useAuth() { const [loading, setLoading] = useState(false) const [error, setError] = useState('') async function doAuth(data: AuthData, newAccount: boolean) { setLoading(true) if (newAccount) { try { const res = await fetch(API_URL + '/signup', { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } }) handleHTTPErrors(res) const signupData: unknown = await res.json() if (!isSignUpResponse(signupData)) { throw new Error('Malformed server response') } if (signupData.Success === false) { throw new Error(signupData.Message) } } catch (err) { setError(err instanceof Error ? err.message : err as string) setLoading(false) return null } } try { const res = await fetch(API_URL + '/auth/token' + new URLSearchParams({ username: data.email, password: data.password }).toString(), { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) const logInData: unknown = await res.json() if (!isLogInResponse(logInData)) { throw new Error('Malformed server response') } const token = logInData.access_token setError('') setLoading(false) return token } catch (err) { setError(err instanceof Error ? err.message : err as string) setLoading(false) return null } } return { doAuth, loading, error } } export default useAuth