Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task Tile #8

Open
nagysobhy opened this issue Jul 4, 2024 · 2 comments
Open

Task Tile #8

nagysobhy opened this issue Jul 4, 2024 · 2 comments

Comments

@nagysobhy
Copy link

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

Copy link

codeautopilot bot commented Jul 4, 2024

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:

/* 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:

<button className="google-signin-button">
  <img src="path/to/google-logo.png" alt="Google logo" />
  Sign in with Google
</button>

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:

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:

{
  "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"
  }
}
  1. Install the new dependency:
    After updating the package.json file, run the following command to install the new dependency:

    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.

    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:

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.

    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.

    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:

// @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 </ autopilot >',
  favicon: 'img/favicon.ico',

  // Set the production url of your site here
  url: 'https://docs.codeautopilot.com',
  // Set the /<baseUrl>/ pathname under which your site is served
  // For GitHub pages deployment, it is often '/<projectName>/'
  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: '</ autopilot >',
        // 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:

    npm install react-google-login

    or

    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:

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>
  );
}

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.

Disclaimer: This comment was entirely generated using AI. Be aware that the information provided may be incorrect.

Current plan usage: 0.98%

Have feedback or need help?
Discord
Documentation
[email protected]

@wheelify1
Copy link

Please insert ALL functions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants