Use http wrapper instead of fetch

pull/3813/head
Kamran Ahmed 2 years ago
parent 0da417735e
commit a544cfea8d
  1. 58
      src/components/AuthenticationFlow/EmailLoginForm.tsx
  2. 106
      src/components/AuthenticationFlow/GitHubButton.tsx
  3. 93
      src/components/AuthenticationFlow/GoogleButton.tsx
  4. 28
      src/components/AuthenticationFlow/TriggerVerifyAccount.tsx
  5. 31
      src/components/AuthenticationFlow/VerificationEmailMessage.tsx
  6. 18
      src/hooks/use-auth.ts

@ -2,7 +2,7 @@ import Cookies from 'js-cookie';
import type { FunctionComponent } from 'preact';
import { useState } from 'preact/hooks';
import { httpPost } from '../../lib/http';
import {TOKEN_COOKIE_NAME} from "../../lib/jwt";
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
const EmailLoginForm: FunctionComponent<{}> = () => {
const [email, setEmail] = useState<string>('');
@ -16,44 +16,32 @@ const EmailLoginForm: FunctionComponent<{}> = () => {
setIsLoading(true);
setError('');
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
const { response, error } = await httpPost<{ token: string }>(
`${import.meta.env.PUBLIC_API_URL}/v1-login`,
{
email,
password,
}),
})
.then((res) => res.json())
.then((data) => {
if (data.type === 'user_not_verified') {
window.location.href = `/verification-pending?email=${encodeURIComponent(
email
)}`;
return;
}
}
);
if (!data.token) {
setIsLoading(false);
setError(
data.message || 'Something went wrong. Please try again later.'
);
return;
}
// Log the user in and reload the page
if (response?.token) {
Cookies.set(TOKEN_COOKIE_NAME, response.token);
window.location.reload();
// If the response is ok, we'll set the token in a cookie
Cookies.set(TOKEN_COOKIE_NAME, data.token);
// Refreshing will automatically redirect to the relevant page
// Doing this to avoid redirecting to home page from any pages
// such as roadmap, best-practice etc
window.location.reload();
})
.catch((err) => {
setIsLoading(false);
setError('Something went wrong. Please try again later.');
});
return;
}
// @todo use proper types
if ((error as any).type === 'user_not_verified') {
window.location.href = `/verification-pending?email=${encodeURIComponent(
email
)}`;
return;
}
setIsLoading(false);
setError(error?.message || 'Something went wrong. Please try again later.');
};
return (

@ -4,6 +4,7 @@ import GitHubIcon from '../../icons/github.svg';
import SpinnerIcon from '../../icons/spinner.svg';
import Cookies from 'js-cookie';
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
import { httpGet } from '../../lib/http';
type GitHubButtonProps = {};
@ -26,42 +27,40 @@ export function GitHubButton(props: GitHubButtonProps) {
}
setIsLoading(true);
fetch(
httpGet<{ token: string }>(
`${import.meta.env.PUBLIC_API_URL}/v1-github-callback${
window.location.search
}`,
{
method: 'GET',
credentials: 'include',
}
}`
)
.then((res) => res.json())
.then((data: any) => {
if (!data.token) {
setError('Something went wrong. Please try again later.');
.then(({ response, error }) => {
if (!response?.token) {
const errMessage = error?.message || 'Something went wrong.';
setError(errMessage);
setIsLoading(false);
} else {
let redirectUrl = '/';
const gitHubRedirectAt = localStorage.getItem(GITHUB_REDIRECT_AT);
const lastPageBeforeGithub = localStorage.getItem(GITHUB_LAST_PAGE);
// If the social redirect is there and less than 30 seconds old
// redirect to the page that user was on before they clicked the github login button
if (gitHubRedirectAt && lastPageBeforeGithub) {
const socialRedirectAtTime = parseInt(gitHubRedirectAt, 10);
const now = Date.now();
const timeSinceRedirect = now - socialRedirectAtTime;
if (timeSinceRedirect < 30 * 1000) {
redirectUrl = lastPageBeforeGithub;
}
}
localStorage.removeItem(GITHUB_REDIRECT_AT);
localStorage.removeItem(GITHUB_LAST_PAGE);
Cookies.set(TOKEN_COOKIE_NAME, data.token);
window.location.href = redirectUrl;
return;
}
let redirectUrl = '/';
const gitHubRedirectAt = localStorage.getItem(GITHUB_REDIRECT_AT);
const lastPageBeforeGithub = localStorage.getItem(GITHUB_LAST_PAGE);
// If the social redirect is there and less than 30 seconds old
// redirect to the page that user was on before they clicked the github login button
if (gitHubRedirectAt && lastPageBeforeGithub) {
const socialRedirectAtTime = parseInt(gitHubRedirectAt, 10);
const now = Date.now();
const timeSinceRedirect = now - socialRedirectAtTime;
if (timeSinceRedirect < 30 * 1000) {
redirectUrl = lastPageBeforeGithub;
}
}
localStorage.removeItem(GITHUB_REDIRECT_AT);
localStorage.removeItem(GITHUB_LAST_PAGE);
Cookies.set(TOKEN_COOKIE_NAME, response.token);
window.location.href = redirectUrl;
})
.catch((err) => {
setError('Something went wrong. Please try again later.');
@ -69,33 +68,30 @@ export function GitHubButton(props: GitHubButtonProps) {
});
}, []);
const handleClick = () => {
const handleClick = async () => {
setIsLoading(true);
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-github-login`, {
credentials: 'include',
redirect: 'follow',
})
.then((res) => res.json())
.then((data: any) => {
// @todo proper typing for API response
if (data.loginUrl) {
// For non authentication pages, we want to redirect back to the page
// the user was on before they clicked the social login button
if (!['/login', '/signup'].includes(window.location.pathname)) {
localStorage.setItem(GITHUB_REDIRECT_AT, Date.now().toString());
localStorage.setItem(GITHUB_LAST_PAGE, window.location.pathname);
}
window.location.href = data.loginUrl;
} else {
setError('Something went wrong. Please try again later.');
setIsLoading(false);
}
})
.catch((err) => {
setError('Something went wrong. Please try again later.');
setIsLoading(false);
});
const { response, error } = await httpGet<{ loginUrl: string }>(
`${import.meta.env.PUBLIC_API_URL}/v1-github-login`
);
if (error || !response?.loginUrl) {
setError(
error?.message || 'Something went wrong. Please try again later.'
);
setIsLoading(false);
return;
}
// For non authentication pages, we want to redirect back to the page
// the user was on before they clicked the social login button
if (!['/login', '/signup'].includes(window.location.pathname)) {
localStorage.setItem(GITHUB_REDIRECT_AT, Date.now().toString());
localStorage.setItem(GITHUB_LAST_PAGE, window.location.pathname);
}
window.location.href = response.loginUrl;
};
return (

@ -3,6 +3,7 @@ import Cookies from 'js-cookie';
import GoogleIcon from '../../icons/google.svg';
import SpinnerIcon from '../../icons/spinner.svg';
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
import { httpGet } from '../../lib/http';
type GoogleButtonProps = {};
@ -25,42 +26,39 @@ export function GoogleButton(props: GoogleButtonProps) {
}
setIsLoading(true);
fetch(
httpGet<{ token: string }>(
`${import.meta.env.PUBLIC_API_URL}/v1-google-callback${
window.location.search
}`,
{
method: 'GET',
credentials: 'include',
}
}`
)
.then((res) => res.json())
.then((data: any) => {
if (!data.token) {
setError('Something went wrong. Please try again later.');
.then(({ response, error }) => {
if (!response?.token) {
setError(error?.message || 'Something went wrong.');
setIsLoading(false);
} else {
let redirectUrl = '/';
const googleRedirectAt = localStorage.getItem(GOOGLE_REDIRECT_AT);
const lastPageBeforeGoogle = localStorage.getItem(GOOGLE_LAST_PAGE);
// If the social redirect is there and less than 30 seconds old
// redirect to the page that user was on before they clicked the github login button
if (googleRedirectAt && lastPageBeforeGoogle) {
const socialRedirectAtTime = parseInt(googleRedirectAt, 10);
const now = Date.now();
const timeSinceRedirect = now - socialRedirectAtTime;
if (timeSinceRedirect < 30 * 1000) {
redirectUrl = lastPageBeforeGoogle;
}
}
localStorage.removeItem(GOOGLE_REDIRECT_AT);
localStorage.removeItem(GOOGLE_LAST_PAGE);
Cookies.set(TOKEN_COOKIE_NAME, data.token);
window.location.href = redirectUrl;
return;
}
let redirectUrl = '/';
const googleRedirectAt = localStorage.getItem(GOOGLE_REDIRECT_AT);
const lastPageBeforeGoogle = localStorage.getItem(GOOGLE_LAST_PAGE);
// If the social redirect is there and less than 30 seconds old
// redirect to the page that user was on before they clicked the github login button
if (googleRedirectAt && lastPageBeforeGoogle) {
const socialRedirectAtTime = parseInt(googleRedirectAt, 10);
const now = Date.now();
const timeSinceRedirect = now - socialRedirectAtTime;
if (timeSinceRedirect < 30 * 1000) {
redirectUrl = lastPageBeforeGoogle;
}
}
localStorage.removeItem(GOOGLE_REDIRECT_AT);
localStorage.removeItem(GOOGLE_LAST_PAGE);
Cookies.set(TOKEN_COOKIE_NAME, response.token);
window.location.href = redirectUrl;
})
.catch((err) => {
setError('Something went wrong. Please try again later.');
@ -70,26 +68,25 @@ export function GoogleButton(props: GoogleButtonProps) {
const handleClick = () => {
setIsLoading(true);
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-google-login`, {
credentials: 'include',
redirect: 'follow',
})
.then((res) => res.json())
.then((data: any) => {
// @todo proper typing for API response
if (data.loginUrl) {
// For non authentication pages, we want to redirect back to the page
// the user was on before they clicked the social login button
if (!['/login', '/signup'].includes(window.location.pathname)) {
localStorage.setItem(GOOGLE_REDIRECT_AT, Date.now().toString());
localStorage.setItem(GOOGLE_LAST_PAGE, window.location.pathname);
}
window.location.href = data.loginUrl;
} else {
setError('Something went wrong. Please try again later.');
httpGet<{ loginUrl: string }>(
`${import.meta.env.PUBLIC_API_URL}/v1-google-login`
)
.then(({ response, error }) => {
if (!response?.loginUrl) {
setError(error?.message || 'Something went wrong.');
setIsLoading(false);
return;
}
// For non authentication pages, we want to redirect back to the page
// the user was on before they clicked the social login button
if (!['/login', '/signup'].includes(window.location.pathname)) {
localStorage.setItem(GOOGLE_REDIRECT_AT, Date.now().toString());
localStorage.setItem(GOOGLE_LAST_PAGE, window.location.pathname);
}
window.location.href = response.loginUrl;
})
.catch((err) => {
setError('Something went wrong. Please try again later.');

@ -3,7 +3,8 @@ import ErrorIcon from '../../icons/error.svg';
import { useEffect, useState } from 'preact/hooks';
import Cookies from 'js-cookie';
import {TOKEN_COOKIE_NAME} from "../../lib/jwt";
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
import { httpPost } from '../../lib/http';
export function TriggerVerifyAccount() {
const [isLoading, setIsLoading] = useState(true);
@ -12,22 +13,21 @@ export function TriggerVerifyAccount() {
const triggerVerify = (code: string) => {
setIsLoading(true);
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-verify-account`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
httpPost<{ token: string }>(
`${import.meta.env.PUBLIC_API_URL}/v1-verify-account`,
{
code,
}),
})
.then((res) => res.json())
.then((data: any) => {
if (!data.token) {
throw new Error('Something went wrong. Please try again..');
}
)
.then(({ response, error }) => {
if (!response?.token) {
setError(error?.message || 'Something went wrong. Please try again.');
setIsLoading(false);
return;
}
Cookies.set(TOKEN_COOKIE_NAME, data.token);
Cookies.set(TOKEN_COOKIE_NAME, response.token);
window.location.href = '/';
})
.catch((err) => {

@ -1,5 +1,6 @@
import VerifyLetterIcon from '../../icons/verify-letter.svg';
import { useEffect, useState } from 'preact/hooks';
import { httpPost } from '../../lib/http';
export function VerificationEmailMessage() {
const [email, setEmail] = useState('..');
@ -14,18 +15,15 @@ export function VerificationEmailMessage() {
}, []);
const resendVerificationEmail = () => {
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-send-verification-email`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
}),
httpPost(`${import.meta.env.PUBLIC_API_URL}/v1-send-verification-email`, {
email,
})
.then((res) => {
if (!res.ok) {
throw new Error('Something went wrong. Please try again later.');
.then(({ response, error }) => {
if (error) {
setIsEmailResent(false);
setError(error?.message || 'Something went wrong.');
setIsLoading(false);
return;
}
setIsEmailResent(true);
@ -49,9 +47,10 @@ export function VerificationEmailMessage() {
</h2>
<div class="text-sm sm:text-base">
<p>
We have sent you an email at <span className="font-bold">{email}</span>.
Please click the link to verify your account. This link will expire
shortly, so please verify soon!
We have sent you an email at{' '}
<span className="font-bold">{email}</span>. Please click the link to
verify your account. This link will expire shortly, so please verify
soon!
</p>
<hr class="my-4" />
@ -77,7 +76,9 @@ export function VerificationEmailMessage() {
</>
)}
{isEmailResent && <p class="text-green-700">Verification email has been sent!</p>}
{isEmailResent && (
<p class="text-green-700">Verification email has been sent!</p>
)}
</div>
</div>
);

@ -1,18 +0,0 @@
import { useEffect, useState } from 'preact/hooks';
import {TokenPayload, decodeToken, TOKEN_COOKIE_NAME} from '../lib/jwt';
import Cookies from 'js-cookie';
export const useAuth = () => {
const [user, setUser] = useState<TokenPayload | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const token = Cookies.get(TOKEN_COOKIE_NAME);
const payload = token ? decodeToken(token) : null;
setUser(payload);
setIsLoading(false);
}, []);
return { user, isLoading };
};
Loading…
Cancel
Save