codeautopilot / docs

Public docs for autopilot
1 stars 1 forks source link

Task Tile #8

Open nagysobhy opened 1 week ago

nagysobhy commented 1 week ago

What - description of what you me to do Example: Hey @autopilot implement a Google sign-in on my website. Make changes to the front end and the back end of the application

Why - explain why this is important Example: I want to allow users to signup and login using their Google account

codeautopilot[bot] commented 1 week ago

Potential solution

To implement Google sign-in functionality on your website, we need to make changes to both the front end and the back end of the application. This involves adding a Google sign-in button on the front end, handling the sign-in process, and managing user sessions on the back end.

How to implement

Front End Changes

1. Add CSS Styles for Google Sign-In Button

File: src/css/custom.css

.google-signin-button {
  background-color: #4285F4;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  font-size: 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  transition: background-color 0.3s ease;
}

.google-signin-button:hover {
  background-color: #357ae8;
}

.google-signin-button:active {
  background-color: #2a65c7;
}

.google-signin-button img {
  margin-right: 8px;
}

2. Add Google Sign-In Button Component

File: src/components/HomepageFeatures/index.js

import React from 'react';
import clsx from 'clsx';
import { GoogleLogin } from 'react-google-login';
import styles from './styles.module.css';

const FeatureList = [
  {
    title: 'Easy to Use',
    Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
    description: (
      <>
        Docusaurus was designed from the ground up to be easily installed and
        used to get your website up and running quickly.
      </>
    ),
  },
  {
    title: 'Focus on What Matters',
    Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
    description: (
      <>
        Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
        ahead and move your docs into the <code>docs</code> directory.
      </>
    ),
  },
  {
    title: 'Powered by React',
    Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
    description: (
      <>
        Extend or customize your website layout by reusing React. Docusaurus can
        be extended while reusing the same header and footer.
      </>
    ),
  },
];

function Feature({Svg, title, description}) {
  return (
    <div className={clsx('col col--4')}>
      <div className="text--center">
        <Svg className={styles.featureSvg} role="img" />
      </div>
      <div className="text--center padding-horiz--md">
        <h3>{title}</h3>
        <p>{description}</p>
      </div>
    </div>
  );
}

export default function HomepageFeatures() {
  const handleLoginSuccess = (response) => {
    console.log('Login Success:', response);
    // Handle login success (e.g., send token to the server)
  };

  const handleLoginFailure = (response) => {
    console.log('Login Failed:', response);
    // Handle login failure
  };

  return (
    <section className={styles.features}>
      <div className="container">
        <div className="row">
          {FeatureList.map((props, idx) => (
            <Feature key={idx} {...props} />
          ))}
        </div>
        <div className="text--center">
          <GoogleLogin
            clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}
            buttonText="Sign in with Google"
            onSuccess={handleLoginSuccess}
            onFailure={handleLoginFailure}
            cookiePolicy={'single_host_origin'}
          />
        </div>
      </div>
    </section>
  );
}

3. Add react-google-login Dependency

File: package.json

{
  "dependencies": {
    "react-google-login": "^5.2.2"
  }
}

Run the following command to install the new dependency:

npm install

Back End Changes

1. Add Routes for Google Sign-In

File: src/server/routes.js

const express = require('express');
const { verifyGoogleToken, createSession, destroySession } = require('./auth');

const router = express.Router();

router.get('/auth/google/callback', async (req, res) => {
  try {
    const token = req.query.token;
    const user = await verifyGoogleToken(token);
    if (user) {
      await createSession(req, user);
      res.redirect('/dashboard');
    } else {
      res.status(401).send('Unauthorized');
    }
  } catch (error) {
    res.status(500).send('Internal Server Error');
  }
});

router.post('/auth/logout', (req, res) => {
  destroySession(req);
  res.redirect('/');
});

module.exports = router;

2. Implement Authentication Logic

File: src/server/auth.js

const { OAuth2Client } = require('google-auth-library');
const client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID);

async function verifyGoogleToken(idToken) {
    try {
        const ticket = await client.verifyIdToken({
            idToken,
            audience: process.env.GOOGLE_CLIENT_ID,
        });
        const payload = ticket.getPayload();
        return payload;
    } catch (error) {
        console.error('Error verifying Google ID token:', error);
        throw new Error('Invalid Google ID token');
    }
}

function createSession(user) {
    // Implement session creation logic here
    return {
        sessionId: 'some-session-id',
        user,
    };
}

module.exports = {
    verifyGoogleToken,
    createSession,
};

3. Add Environment Variables

File: docusaurus.config.js

require('dotenv').config();

const config = {
  customFields: {
    googleClientId: process.env.GOOGLE_CLIENT_ID,
    googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
  },
};

module.exports = config;

Create a .env file in the root directory:

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

4. Install google-auth-library

Run the following command to install the necessary dependency:

npm install google-auth-library

This setup ensures that your application can handle Google sign-in on both the front end and the back end, providing a seamless user experience.

Click here to create a Pull Request with the proposed solution

Files used for this task:

Changes on src/css/custom.css To add CSS styles for the Google sign-in button and ensure it matches the website's design, you can follow these steps: 1. **Define the Button Styles**: Add CSS rules to style the Google sign-in button. This includes setting the background color, text color, padding, border, and any other styles that match your website's design. 2. **Add Hover and Active States**: Ensure the button has appropriate styles for hover and active states to enhance user experience. Here's a concrete proposal for the changes to be made in `src/css/custom.css`: ```css /* Google Sign-In Button Styles */ .google-signin-button { background-color: #4285F4; /* Google Blue */ color: white; padding: 10px 20px; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; transition: background-color 0.3s ease; } .google-signin-button:hover { background-color: #357ae8; /* Darker Google Blue */ } .google-signin-button:active { background-color: #2a65c7; /* Even Darker Google Blue */ } .google-signin-button img { margin-right: 8px; } ``` ### Explanation: - **`.google-signin-button`**: This class styles the Google sign-in button with a background color matching Google's blue, white text, padding for spacing, no border, rounded corners, and a pointer cursor. - **Hover and Active States**: These states change the background color to a darker shade of blue when the button is hovered over or clicked. - **Image Margin**: If you include a Google logo image inside the button, this rule ensures there's space between the image and the text. ### Usage: Ensure that the button in your HTML or JSX has the class `google-signin-button` applied to it. For example: ```jsx ``` This will apply the styles defined in `custom.css` to your Google sign-in button, ensuring it matches the design of your website.
Changes on src/server/routes.js To implement the Google sign-in functionality, you need to define routes in `src/server/routes.js` for handling Google sign-in callbacks and managing user sessions. Here is a step-by-step plan for this file: 1. **Import Necessary Modules**: Import the required modules such as `express` and the authentication logic from `auth.js`. 2. **Initialize Router**: Create an instance of the Express router. 3. **Define Routes**: - **Google Sign-In Callback Route**: Define a route to handle the callback from Google after a user signs in. - **User Session Management Route**: Define a route to manage user sessions, such as logging out. Here is a concrete implementation for `src/server/routes.js`: ```javascript const express = require('express'); const { verifyGoogleToken, createSession, destroySession } = require('./auth'); const router = express.Router(); // Route to handle Google sign-in callback router.get('/auth/google/callback', async (req, res) => { try { const token = req.query.token; const user = await verifyGoogleToken(token); if (user) { await createSession(req, user); res.redirect('/dashboard'); // Redirect to a protected route after successful sign-in } else { res.status(401).send('Unauthorized'); } } catch (error) { res.status(500).send('Internal Server Error'); } }); // Route to handle user logout router.post('/auth/logout', (req, res) => { destroySession(req); res.redirect('/'); // Redirect to homepage after logout }); module.exports = router; ``` ### Explanation: 1. **Import Modules**: The `express` module is imported to create the router, and functions from `auth.js` are imported to handle token verification and session management. 2. **Initialize Router**: `express.Router()` is used to create a new router instance. 3. **Google Sign-In Callback Route**: - The route `/auth/google/callback` handles the callback from Google. - It extracts the token from the query parameters and verifies it using `verifyGoogleToken`. - If the token is valid, it creates a session and redirects the user to the dashboard. - If the token is invalid, it sends a 401 Unauthorized response. 4. **User Logout Route**: - The route `/auth/logout` handles user logout. - It destroys the session and redirects the user to the homepage. This implementation ensures that the server can handle Google sign-in callbacks and manage user sessions effectively.
Changes on package.json To implement Google sign-in functionality, you need to add the `react-google-login` package to your project. This package will help you handle the Google sign-in process on the front end. Here’s how you can update your `package.json` file to include this dependency: 1. **Add the `react-google-login` dependency:** Open your `package.json` file and add `react-google-login` to the dependencies section. Here is the updated `package.json` file: ```json { "name": "documentation", "version": "0.0.0", "private": true, "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { "@docusaurus/core": "2.4.3", "@docusaurus/preset-classic": "2.4.3", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", "react-dom": "^17.0.2", "react-google-login": "^5.2.2" // Added dependency }, "devDependencies": { "@docusaurus/module-type-aliases": "2.4.3" }, "browserslist": { "production": [ ">0.5%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "engines": { "node": ">=16.14" } } ``` 2. **Install the new dependency:** After updating the `package.json` file, run the following command to install the new dependency: ```sh npm install ``` This will add the `react-google-login` package to your project, allowing you to use it in your front-end components to handle Google sign-in. If there are no other changes needed in this file, you can proceed to update the other files as per the plan.
Changes on src/server/auth.js To implement the back-end logic for verifying Google sign-in tokens and managing user sessions in the `src/server/auth.js` file, follow these steps: 1. **Install Necessary Dependencies**: Ensure you have the `google-auth-library` package installed. You can add it to your `package.json` and install it using npm or yarn. ```bash npm install google-auth-library ``` 2. **Set Up Google OAuth Client**: Use the Google OAuth client to verify the ID tokens received from the front end. 3. **Create Functions for Token Verification and Session Management**: Implement functions to verify the Google ID token and manage user sessions. Here's a concrete implementation for `src/server/auth.js`: ```javascript const { OAuth2Client } = require('google-auth-library'); const client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID); async function verifyGoogleToken(idToken) { try { const ticket = await client.verifyIdToken({ idToken, audience: process.env.GOOGLE_CLIENT_ID, }); const payload = ticket.getPayload(); return payload; // This contains user information like email, name, etc. } catch (error) { console.error('Error verifying Google ID token:', error); throw new Error('Invalid Google ID token'); } } function createSession(user) { // Implement session creation logic here // For example, using express-session or JWT // This is a placeholder function return { sessionId: 'some-session-id', user, }; } module.exports = { verifyGoogleToken, createSession, }; ``` ### Explanation: 1. **OAuth2Client Initialization**: - The `OAuth2Client` is initialized with the Google Client ID from environment variables. 2. **verifyGoogleToken Function**: - This function takes an ID token as input and verifies it using the `verifyIdToken` method of the `OAuth2Client`. - If the token is valid, it returns the payload containing user information. - If the token is invalid, it throws an error. 3. **createSession Function**: - This is a placeholder function where you can implement your session management logic. - You can use libraries like `express-session` for session management or `jsonwebtoken` for JWT-based sessions. ### Next Steps: - **Integrate with Routes**: Ensure that the routes in `src/server/routes.js` call these functions appropriately. - **Environment Variables**: Make sure to add `GOOGLE_CLIENT_ID` to your environment variables in `docusaurus.config.js`. This implementation provides a solid foundation for handling Google sign-in on the back end.
Changes on docusaurus.config.js To add environment variables for the Google OAuth client ID and secret in the `docusaurus.config.js` file, you can follow these steps: 1. **Install dotenv package**: This package helps in loading environment variables from a `.env` file into `process.env`. ```bash npm install dotenv ``` 2. **Create a `.env` file**: In the root directory of your project, create a `.env` file and add your Google OAuth client ID and secret. ```env GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret ``` 3. **Modify `docusaurus.config.js` to load environment variables**: Update the `docusaurus.config.js` file to load the environment variables using the `dotenv` package. Here's how you can modify the `docusaurus.config.js` file: ```javascript // @ts-check // Note: type annotations allow type checking and IDEs autocompletion const lightCodeTheme = require('prism-react-renderer/themes/github'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); require('dotenv').config(); // Add this line to load environment variables /** @type {import('@docusaurus/types').Config} */ const config = { title: 'Code Autopilot', tagline: 'Documentation for ', favicon: 'img/favicon.ico', // Set the production url of your site here url: 'https://docs.codeautopilot.com', // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' baseUrl: '/', // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. organizationName: 'codeautopilot', // Usually your GitHub org/user name. projectName: 'codeautopilot', // Usually your repo name. onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', // Even if you don't use internalization, you can use this field to set useful // metadata like html lang. For example, if your site is Chinese, you may want // to replace "en" with "zh-Hans". i18n: { defaultLocale: 'en', locales: ['en'], }, presets: [ [ 'classic', /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { routeBasePath: '/', // Serve the docs at the site's root editUrl: 'https://github.com/codeautopilot/docs/tree/main/', }, blog: false, theme: { customCss: require.resolve('./src/css/custom.css'), }, }), ], ], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ // Replace with your project's social card image: 'img/autopilot.png', navbar: { title: '', // logo: { // alt: 'My Site Logo', // src: 'img/logo.svg', // }, items: [ ], }, footer: { style: 'dark', links: [ { title: 'Community', items: [ { label: 'Discord', href: 'https://discord.gg/r72ykfvyx7', }, ], }, ], copyright: `Copyright © ${new Date().getFullYear()} Code Autopilot`, }, prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, }, }), customFields: { googleClientId: process.env.GOOGLE_CLIENT_ID, googleClientSecret: process.env.GOOGLE_CLIENT_SECRET, }, }; module.exports = config; ``` ### Explanation: 1. **Loading Environment Variables**: The `require('dotenv').config();` line loads the environment variables from the `.env` file into `process.env`. 2. **Adding Custom Fields**: The `customFields` section in the `config` object is used to store the Google OAuth client ID and secret. These can be accessed throughout your Docusaurus site using `siteConfig.customFields`. This setup ensures that your Google OAuth credentials are securely managed and can be easily accessed wherever needed in your application.
Changes on src/components/HomepageFeatures/index.js To add a Google sign-in button and handle the click event to initiate the Google sign-in process in the `src/components/HomepageFeatures/index.js` file, follow these steps: 1. **Install the `react-google-login` package**: Ensure that the `react-google-login` package is added to your project. This will be handled in the `package.json` file, but you can install it using npm or yarn: ```sh npm install react-google-login ``` or ```sh yarn add react-google-login ``` 2. **Import the necessary components**: Import the `GoogleLogin` component from the `react-google-login` package at the top of the file. 3. **Add the Google sign-in button**: Add the `GoogleLogin` component to the `HomepageFeatures` function and handle the click event to initiate the Google sign-in process. Here is the updated code for `src/components/HomepageFeatures/index.js`: ```javascript import React from 'react'; import clsx from 'clsx'; import { GoogleLogin } from 'react-google-login'; import styles from './styles.module.css'; const FeatureList = [ { title: 'Easy to Use', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> Docusaurus was designed from the ground up to be easily installed and used to get your website up and running quickly. ), }, { title: 'Focus on What Matters', Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, description: ( <> Docusaurus lets you focus on your docs, and we'll do the chores. Go ahead and move your docs into the docs directory. ), }, { title: 'Powered by React', Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, description: ( <> Extend or customize your website layout by reusing React. Docusaurus can be extended while reusing the same header and footer. ), }, ]; function Feature({Svg, title, description}) { return (

{title}

{description}

); } export default function HomepageFeatures() { const handleLoginSuccess = (response) => { console.log('Login Success:', response); // Handle login success (e.g., send token to the server) }; const handleLoginFailure = (response) => { console.log('Login Failed:', response); // Handle login failure }; return (
{FeatureList.map((props, idx) => ( ))}
); } ``` ### Explanation: 1. **Import `GoogleLogin`**: The `GoogleLogin` component is imported from the `react-google-login` package. 2. **Handle Login Success and Failure**: Two functions, `handleLoginSuccess` and `handleLoginFailure`, are defined to handle the respective outcomes of the Google sign-in process. 3. **Add `GoogleLogin` Component**: The `GoogleLogin` component is added within the `HomepageFeatures` function, with the necessary props such as `clientId`, `buttonText`, `onSuccess`, `onFailure`, and `cookiePolicy`. Make sure to replace `process.env.REACT_APP_GOOGLE_CLIENT_ID` with your actual Google OAuth client ID. This value should be securely stored in your environment variables. This change will add a Google sign-in button to the homepage features section and handle the sign-in process accordingly.