Skip to content

Commit

Permalink
view my own profile
Browse files Browse the repository at this point in the history
  • Loading branch information
codekansas committed Aug 15, 2024
1 parent e31c7ff commit b43d7d4
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 135 deletions.
1 change: 0 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ jobs:
- name: Write .env.production
working-directory: frontend
run: |
echo "VITE_APP_GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env.production
echo "VITE_APP_BACKEND_URL=${{ secrets.BACKEND_URL }}" >> .env.production
- name: Build frontend
Expand Down
21 changes: 4 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,15 @@ export SMTP_SENDER_EMAIL=''
export SMTP_PASSWORD=''
export SMTP_SENDER_NAME=''
export SMTP_USERNAME=''
```

# For Github OAuth
export GITHUB_CLIENT_ID=''
export GITHUB_CLIENT_SECRET=''
### Google OAuth Configuration

# For Google OAuth
export VITE_GOOGLE_CLIENT_ID=''
```
The repository's local configuration comes with Google OAuth credentials for a test application. Alternatively, you can set up your own Google OAuth application to test the application locally, by following the instructions [here](https://blog.logrocket.com/guide-adding-google-login-react-app/).

### Github OAuth Configuration

To run Github OAuth locally, you must follow these steps:
The repository's local configuration comes with Github OAuth credentials for a test application. Alternatively, you can set up your own Github OAuth application to test the application locally:

1. Create an OAuth App on [Github Developer Settings](https://github.com/settings/developers)
2. Set both Homepage URL and Authorization callback URL to `http://127.0.0.1:3000/login` before you `Update application` on Github Oauth App configuration
Expand Down Expand Up @@ -168,16 +165,6 @@ To run code formatting:
npm run format
```

### Google Client ID

You will need to set `VITE_APP_GOOGLE_CLIENT_ID`. To do this, first create a Google client id (see [this LogRocket post](https://blog.logrocket.com/guide-adding-google-login-react-app/)). Then create a `.env.local` file in the `frontend` directory and add the following line:

```
VITE_APP_GOOGLE_CLIENT_ID=your-client-id
```

Additionally, you should set `VITE_APP_BACKEND_URL` to the URL of the FastAPI backend. This should be `http://127.0.0.1:8080` when developing locally.

## Testing

To run the tests, you can use the following commands:
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ start-backend:
start-frontend:
@cd frontend && npm run dev

update-api:
@cd frontend && openapi-typescript http://localhost:8080/openapi.json --output src/gen/api.ts

start-docker-dynamodb:
@docker kill store-db || true
@docker rm store-db || true
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const App = () => {
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/keys" element={<APIKeys />} />
<Route path="/profile/:id" element={<Profile />} />
<Route path="/profile/:id?" element={<Profile />} />
<Route path="/login" element={<Login />} />
<Route path="/logout" element={<Logout />} />
<Route path="/signup/:id" element={<Signup />} />
Expand Down
22 changes: 4 additions & 18 deletions frontend/src/components/auth/AuthBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,21 @@ import { useEffect, useState } from "react";
import { useAlertQueue } from "hooks/useAlertQueue";
import { useAuthentication } from "hooks/useAuth";

import AuthProvider from "components/auth/AuthProvider";
import LoginForm from "components/auth/LoginForm";
import SignupWithEmail from "components/auth/SignupWithEmail";
import BackButton from "components/ui/Button/BackButton";
import { Card, CardContent, CardFooter, CardHeader } from "components/ui/Card";
import Header from "components/ui/Header";
import Spinner from "components/ui/Spinner";

import AuthProvider from "./AuthProvider";
import LoginForm from "./LoginForm";
import SignupWithEmail from "./SignupWithEmail";

export const AuthBlockInner = () => {
const auth = useAuthentication();
const { addErrorAlert } = useAlertQueue();

const [isSignup, setIsSignup] = useState(false);
const [useSpinner, setUseSpinner] = useState(false);

const handleGithubSubmit = async (
event: React.MouseEvent<HTMLButtonElement>,
) => {
event.preventDefault();

const { data, error } = await auth.client.GET("/users/github/login");
if (error) {
addErrorAlert(error);
} else {
window.open(data, "_self");
}
};

useEffect(() => {
(async () => {
// Get the code from the query string to carry out OAuth login.
Expand Down Expand Up @@ -70,7 +56,7 @@ export const AuthBlockInner = () => {
{isSignup ? <SignupWithEmail /> : <LoginForm />}
</CardContent>
<CardFooter>
<AuthProvider handleGithubSubmit={handleGithubSubmit} />
<AuthProvider />
</CardFooter>
<CardFooter>
<BackButton
Expand Down
97 changes: 72 additions & 25 deletions frontend/src/components/auth/AuthProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,13 @@ import { FaGithub } from "react-icons/fa";
import { FcGoogle } from "react-icons/fc";

import { GoogleOAuthProvider, useGoogleLogin } from "@react-oauth/google";
import { GOOGLE_CLIENT_ID } from "constants/env";
import { useAlertQueue } from "hooks/useAlertQueue";
import { useAuthentication } from "hooks/useAuth";

import { Button } from "components/ui/Button/Button";
import Spinner from "components/ui/Spinner";

interface AuthProvider {
handleGoogleSubmit?: (
event: React.MouseEvent<HTMLButtonElement>,
) => Promise<void>;
handleGithubSubmit?: (
event: React.MouseEvent<HTMLButtonElement>,
) => Promise<void>;
}

const GoogleAuthComponentInner = () => {
const GoogleAuthButton = () => {
const [credential, setCredential] = useState<string | null>(null);
const auth = useAuthentication();
const { addErrorAlert } = useAlertQueue();
Expand All @@ -31,6 +22,7 @@ const GoogleAuthComponentInner = () => {
token: credential,
},
});

if (error) {
addErrorAlert(error);
} else {
Expand All @@ -40,7 +32,7 @@ const GoogleAuthComponentInner = () => {
})();
}, [credential]);

const login = useGoogleLogin({
const handleGoogleLogin = useGoogleLogin({
onSuccess: (tokenResponse) => {
const returnedCredential = tokenResponse.access_token;
if (returnedCredential === undefined) {
Expand All @@ -62,14 +54,78 @@ const GoogleAuthComponentInner = () => {
variant={"outline"}
size={"lg"}
className="w-full hover:bg-gray-100 dark:hover:bg-gray-600"
onClick={() => login()}
onClick={() => handleGoogleLogin()}
disabled={credential !== null}
>
<FcGoogle className="w-5 h-5" />
</Button>
);
};

const AuthProvider = ({ handleGithubSubmit }: AuthProvider) => {
const GoogleAuthButtonWrapper = () => {
const [googleClientId, setGoogleClientId] = useState<string | null>(null);
const auth = useAuthentication();
const { addErrorAlert } = useAlertQueue();

useEffect(() => {
(async () => {
if (googleClientId !== null) return;

const { data, error } = await auth.client.GET("/users/google/client-id");
if (error) {
addErrorAlert(error);
} else {
setGoogleClientId(data.client_id);
}
})();
}, [googleClientId]);

return googleClientId === null ? (
<Button
variant={"outline"}
size={"lg"}
className="w-full hover:bg-gray-100 dark:hover:bg-gray-600"
disabled={true}
>
<Spinner />
</Button>
) : (
<GoogleOAuthProvider clientId={googleClientId}>
<GoogleAuthButton />
</GoogleOAuthProvider>
);
};

const GithubAuthButton = () => {
const auth = useAuthentication();
const { addErrorAlert } = useAlertQueue();

const handleGithubSubmit = async (
event: React.MouseEvent<HTMLButtonElement>,
) => {
event.preventDefault();

const { data, error } = await auth.client.GET("/users/github/login");
if (error) {
addErrorAlert(error);
} else {
window.open(data, "_self");
}
};

return (
<Button
variant="outline"
size="lg"
className="w-full hover:bg-gray-100 dark:hover:bg-gray-600"
onClick={handleGithubSubmit}
>
<FaGithub className="w-5 h-5" />
</Button>
);
};

const AuthProvider = () => {
return (
<div className="flex flex-col w-full">
<div className="flex justify-center items-center mb-4">
Expand All @@ -79,19 +135,10 @@ const AuthProvider = ({ handleGithubSubmit }: AuthProvider) => {
</div>
<div className="flex items-center w-full gap-x-2">
{/* Google */}
<GoogleOAuthProvider clientId={GOOGLE_CLIENT_ID}>
<GoogleAuthComponentInner />
</GoogleOAuthProvider>
<GoogleAuthButtonWrapper />

{/* Github */}
<Button
variant="outline"
size="lg"
className="w-full hover:bg-gray-100 dark:hover:bg-gray-600"
onClick={handleGithubSubmit}
>
<FaGithub className="w-5 h-5" />
</Button>
<GithubAuthButton />
</div>
</div>
);
Expand Down
1 change: 0 additions & 1 deletion frontend/src/constants/env.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export const BACKEND_URL =
import.meta.env.VITE_APP_BACKEND_URL || "http://127.0.0.1:8080";
export const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID || "";
Loading

0 comments on commit b43d7d4

Please sign in to comment.