From 15ad1a5deb29cc80da1de7ca8ef9002c3c110afa Mon Sep 17 00:00:00 2001 From: Carlos Lostao Date: Tue, 11 Feb 2025 14:05:38 +0100 Subject: [PATCH] feat: add github sso --- auth/src/services/authManager/index.ts | 4 ++- .../services/authManager/providers/github.ts | 31 +++++++++++++++++++ .../services/authManager/providers/index.ts | 1 + .../src/app/api/auth/[...nextauth]/config.ts | 5 +++ frontend/src/components/common/Disclaimer.tsx | 2 +- frontend/src/components/common/GithubIcon.tsx | 17 ++++++++++ frontend/src/views/Home/SignInButtons.tsx | 15 +++++++++ frontend/src/views/Onboarding/index.tsx | 13 ++++---- 8 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 auth/src/services/authManager/providers/github.ts create mode 100644 frontend/src/components/common/GithubIcon.tsx diff --git a/auth/src/services/authManager/index.ts b/auth/src/services/authManager/index.ts index 4491380f..23d61661 100644 --- a/auth/src/services/authManager/index.ts +++ b/auth/src/services/authManager/index.ts @@ -1,7 +1,7 @@ import { OAuthUser } from "../../models/index"; import { ApiKeyAuth } from "./providers/apikey"; import { CustomJWTAuth } from "./providers/custom"; -import { DiscordAuth, GoogleAuth } from "./providers/index"; +import { DiscordAuth, GitHubAuth, GoogleAuth } from "./providers/index"; const getUserFromAccessToken = async ( provider: string, @@ -16,6 +16,8 @@ const getUserFromAccessToken = async ( return ApiKeyAuth.getUserFromApiKey(accessToken); case "custom-jwt": return CustomJWTAuth.getUserFromAccessToken(accessToken); + case "github": + return GitHubAuth.getUserFromAccessToken(accessToken); default: throw new Error("Invalid provider"); } diff --git a/auth/src/services/authManager/providers/github.ts b/auth/src/services/authManager/providers/github.ts new file mode 100644 index 00000000..6a449346 --- /dev/null +++ b/auth/src/services/authManager/providers/github.ts @@ -0,0 +1,31 @@ +import { OAuthUser } from "../../../models"; + +type GitHubUser = { + id: number; + login: string; +}; + +const getUserFromAccessToken = async ( + accessToken: string +): Promise => { + const githubUser = await fetch("https://api.github.com/user", { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }).then((res) => { + if (res.status >= 400) { + throw new Error("Failed to fetch user info"); + } + return res.json() as Promise; + }); + + return { + provider: "github", + // Convert numeric GitHub ID to string if you want a uniform type + id: githubUser.id.toString(), + }; +}; + +export const GitHubAuth = { + getUserFromAccessToken, +}; diff --git a/auth/src/services/authManager/providers/index.ts b/auth/src/services/authManager/providers/index.ts index 6f972885..95b6bf1b 100644 --- a/auth/src/services/authManager/providers/index.ts +++ b/auth/src/services/authManager/providers/index.ts @@ -1,2 +1,3 @@ export * from "./google"; export * from "./discord"; +export * from "./github"; diff --git a/frontend/src/app/api/auth/[...nextauth]/config.ts b/frontend/src/app/api/auth/[...nextauth]/config.ts index 8cf6ce52..1190c542 100644 --- a/frontend/src/app/api/auth/[...nextauth]/config.ts +++ b/frontend/src/app/api/auth/[...nextauth]/config.ts @@ -1,5 +1,6 @@ import { AuthOptions } from 'next-auth'; import GoogleProvider from 'next-auth/providers/google'; +import GithubProvider from 'next-auth/providers/github'; import DiscordProvider from 'next-auth/providers/discord'; import { generateAccessToken, @@ -19,6 +20,10 @@ export const authOptions: AuthOptions = { clientId: process.env.DISCORD_AUTH_CLIENT_ID as string, clientSecret: process.env.DISCORD_AUTH_CLIENT_SECRET as string, }), + GithubProvider({ + clientId: process.env.GITHUB_AUTH_CLIENT_ID as string, + clientSecret: process.env.GITHUB_AUTH_CLIENT_SECRET as string, + }), ], callbacks: { async jwt({ account, token }) { diff --git a/frontend/src/components/common/Disclaimer.tsx b/frontend/src/components/common/Disclaimer.tsx index 4424c7f6..289cd63e 100644 --- a/frontend/src/components/common/Disclaimer.tsx +++ b/frontend/src/components/common/Disclaimer.tsx @@ -1,6 +1,6 @@ export const Disclaimer = () => { return ( -
+

Please, note:

  • Uploaded content will be visible and searchable by everyone
  • diff --git a/frontend/src/components/common/GithubIcon.tsx b/frontend/src/components/common/GithubIcon.tsx new file mode 100644 index 00000000..53ad8fd0 --- /dev/null +++ b/frontend/src/components/common/GithubIcon.tsx @@ -0,0 +1,17 @@ +export const GithubIcon = ({ fillColor }: { fillColor: string }) => { + return ( + + GitHub + + + ); +}; diff --git a/frontend/src/views/Home/SignInButtons.tsx b/frontend/src/views/Home/SignInButtons.tsx index 1fded58b..d78e8637 100644 --- a/frontend/src/views/Home/SignInButtons.tsx +++ b/frontend/src/views/Home/SignInButtons.tsx @@ -2,6 +2,7 @@ import { signIn } from 'next-auth/react'; import { useCallback, useState } from 'react'; import { DiscordIcon } from '../../components/common/DiscordIcon'; import { GoogleIcon } from '../../components/common/GoogleIcon'; +import { GithubIcon } from '../../components/common/GithubIcon'; import { BuiltInProviderType } from 'next-auth/providers'; import { LoaderCircle } from 'lucide-react'; @@ -17,6 +18,11 @@ export const SigningInButtons = () => { signIn('discord'); }, []); + const handleGithubAuth = useCallback(() => { + setIsClicked('github'); + signIn('github'); + }, []); + return (
    +
    ); }; diff --git a/frontend/src/views/Onboarding/index.tsx b/frontend/src/views/Onboarding/index.tsx index 9ee3e846..2df27718 100644 --- a/frontend/src/views/Onboarding/index.tsx +++ b/frontend/src/views/Onboarding/index.tsx @@ -5,9 +5,8 @@ import { Button, Checkbox } from '@headlessui/react'; import { CheckIcon } from 'lucide-react'; import { AuthService } from '../../services/auth/auth'; import { Disclaimer } from '../../components/common/Disclaimer'; -// import { getDrivePath } from '../UserFiles'; -import Image from 'next/image'; import { ROUTES } from '../../constants/routes'; +import { AutonomysSymbol } from '../../components/common/AutonomysSymbol'; export const Onboarding = () => { const [accepted, setAccepted] = useState(false); @@ -23,14 +22,14 @@ export const Onboarding = () => { }, []); return ( -
    +
    -
    - Auto Drive +
    + Auto Drive
    -
    +
    {