Skip to content

Commit

Permalink
Fix signup page crash
Browse files Browse the repository at this point in the history
  • Loading branch information
DukeManh committed Jan 28, 2022
1 parent 64ff08d commit 430e3e7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 49 deletions.
2 changes: 2 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ tasks:
eval $(gp env -e API_URL=$(gp url 3000))
eval $(gp env -e WEB_URL=$(gp url 8000))
eval $(gp env -e API_HOST=$(gp url 8443))
eval $(gp env -e SSO_LOGIN_URL=$(gp url 8081))
eval $(gp env -e SERVICES="status image sso search posts feed-discovery users redis elasticsearch login firebase")
sed -r \
-e "s@(.+=)http://localhost:8000(/[^ ]*)*@\1$WEB_URL\2@g" \
-e "s@(.+=)http://localhost:3000(/[^ ]*)*@\1$API_URL\2@g" \
-e "s@(.+=)http://localhost:8081(/[^ ]*)*@\1$SSO_LOGIN_URL\2@g" \
-e "s@(.+=)http://localhost([^:]*)@\1$API_HOST\2@g" \
-e "s@development\.yml@gitpod\.yml@" \
config/env.development > .env
Expand Down
101 changes: 54 additions & 47 deletions src/web/src/components/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createContext, ReactNode, useState, useEffect } from 'react';
import { createContext, ReactNode, useState, useEffect, useCallback } from 'react';
import { useLocalStorage } from 'react-use';
import { useRouter } from 'next/router';
import { nanoid } from 'nanoid';
Expand Down Expand Up @@ -65,31 +65,67 @@ const AuthProvider = ({ children }: Props) => {
console.error('Error parsing token for user', err);
cleanup();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token]);

const login = (returnTo?: string) => {
// Create and store some random state that we'll send along with this login request
const loginState = nanoid();
setAuthState(loginState);

// Set our return URL
const url = new URL(returnTo || '', webUrl);
window.location.href = `${loginUrl}?redirect_uri=${url.href}&state=${loginState}`;
};
}, [removeAuthState, removeToken, token]);

const login = useCallback(
(returnTo?: string) => {
// Create and store some random state that we'll send along with this login request
const loginState = nanoid();
setAuthState(loginState);

// Set our return URL
const url = new URL(returnTo || '', webUrl);
window.location.href = `${loginUrl}?redirect_uri=${url.href}&state=${loginState}`;
},
[setAuthState]
);

const logout = () => {
const logout = useCallback(() => {
// Clear our existing token and state
removeToken();
removeAuthState();

// Redirect to logout
window.location.href = `${logoutUrl}?redirect_uri=${webUrl}`;
};
}, [removeAuthState, removeToken]);

const register = useCallback(
(receivedToken: string) => {
setToken(receivedToken);
},
[setToken]
);

const register = (receivedToken: string) => {
setToken(receivedToken);
};
useEffect(() => {
// Browser-side rendering
try {
// Try to extract access_token and state query params from the URL, which may not be there
const params = new URL(asPath, document.location.href).searchParams;
const accessToken = params.get('access_token');
const state = params.get('state');

if (!token && accessToken) {
// Remove the ?access_token=...&state=... from URL
router.replace(pathname, undefined, { shallow: true });

// Make sure we initiated the login flow. When we start the login
// we store some random state in localStorage. When we get redirected
// back with an access token, we should also get our original random state.
// If we do, all is well. If not, don't use this token, since it wasn't
// us who initiated the login.
if (authState !== state) {
throw new Error(`login state '${state}' doesn't match expected state '${authState}'`);
}

// Store this token in localStorage and clear login state
setToken(accessToken);
removeAuthState();
}
} catch (err) {
// TODO: should we do more in the error case? If so, what?
console.error('Error parsing access_token from URL', err);
}
}, [asPath, authState, pathname, removeAuthState, router, setToken, token]);

// Server-side rendering.
if (typeof window === 'undefined') {
Expand All @@ -100,35 +136,6 @@ const AuthProvider = ({ children }: Props) => {
);
}

// Browser-side rendering
try {
// Try to extract access_token and state query params from the URL, which may not be there
const params = new URL(asPath, document.location.href).searchParams;
const accessToken = params.get('access_token');
const state = params.get('state');

if (!token && accessToken) {
// Remove the ?access_token=...&state=... from URL
router.replace(pathname, undefined, { shallow: true });

// Make sure we initiated the login flow. When we start the login
// we store some random state in localStorage. When we get redirected
// back with an access token, we should also get our original random state.
// If we do, all is well. If not, don't use this token, since it wasn't
// us who initiated the login.
if (authState !== state) {
throw new Error(`login state '${state}' doesn't match expected state '${authState}'`);
}

// Store this token in localStorage and clear login state
setToken(accessToken);
removeAuthState();
}
} catch (err) {
// TODO: should we do more in the error case? If so, what?
console.error('Error parsing access_token from URL', err);
}

return (
<AuthContext.Provider value={{ login, logout, register, user, token }}>
{children}
Expand Down
4 changes: 2 additions & 2 deletions src/web/src/pages/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@ const SignUpPage = () => {

useEffect(() => {
if (user) {
setActiveStep(SIGN_UP_STEPS.BASIC_INFO);
setLoggedIn(true);
handleNext();
}
}, [handleNext, user]);
}, [user]);

const handleSubmit = async (values: SignUpForm, actions: FormikHelpers<SignUpForm>) => {
if (activeStep < 4) {
Expand Down

0 comments on commit 430e3e7

Please sign in to comment.