From c05c2244e0af7712ac9c0b258177810cf787bdd0 Mon Sep 17 00:00:00 2001 From: Roman Matusevich Date: Tue, 14 Nov 2023 23:04:49 +0300 Subject: [PATCH] [web] - extend oauth (#628) * [web] - add oauth providers * [web] - oauth add more providers * [web] - oauth add google --- web/package.json | 2 +- web/src/supabase.ts | 10 ++- .../pages/Signup/components/CompleteForm.tsx | 61 ++++++++++++------- .../pages/Signup/components/OAuthForm.tsx | 45 ++++++++++++-- .../pages/Signup/components/UsernameForm.tsx | 43 +++++++++++-- 5 files changed, 126 insertions(+), 35 deletions(-) diff --git a/web/package.json b/web/package.json index d3dfaf4a2..8d020b3c0 100644 --- a/web/package.json +++ b/web/package.json @@ -54,7 +54,7 @@ "@mui/material": "^5.9.1", "@mui/utils": "^5.11.13", "@octokit/core": "^4.1.0", - "@supabase/supabase-js": "^2.31.0", + "@supabase/supabase-js": "^2.38.4", "@wysimark/react": "^2.2.15", "apexcharts": "^3.37.0", "buffer": "^6.0.3", diff --git a/web/src/supabase.ts b/web/src/supabase.ts index ee1e91bdf..80f3269be 100644 --- a/web/src/supabase.ts +++ b/web/src/supabase.ts @@ -5,7 +5,11 @@ import { GoshError } from './errors' export const supabase = { client: AppConfig.supabase, singinOAuth: async (provider: Provider, options?: { redirectTo?: string }) => { - const scopes = 'read:user read:org' + const scopes: { [key: string]: string } = { + github: 'read:user read:org', + google: 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile', + linkedin_oidc: '', + } const { redirectTo } = options || {} if (AppConfig.dockerclient) { @@ -17,7 +21,7 @@ export const supabase = { redirectTo: redirectTo || `https://open.docker.com/dashboard/extension-tab?extensionId=teamgosh/docker-extension&nounce=${nounce}`, - scopes, + scopes: scopes[provider], skipBrowserRedirect: true, }, }) @@ -33,7 +37,7 @@ export const supabase = { provider, options: { redirectTo: redirectTo || document.location.href, - scopes, + scopes: scopes[provider], }, }) if (error) { diff --git a/web/src/v6.1.0/pages/Signup/components/CompleteForm.tsx b/web/src/v6.1.0/pages/Signup/components/CompleteForm.tsx index c87d3fb35..85ec7ee45 100644 --- a/web/src/v6.1.0/pages/Signup/components/CompleteForm.tsx +++ b/web/src/v6.1.0/pages/Signup/components/CompleteForm.tsx @@ -1,14 +1,21 @@ import { Form, Formik } from 'formik' +import { useState } from 'react' +import { useNavigate } from 'react-router-dom' import { Button } from '../../../../components/Form' +import { useOauth } from '../../../hooks/oauth.hooks' import { useUserSignup } from '../../../hooks/user.hooks' -import { useNavigate } from 'react-router-dom' -import { useState } from 'react' const CompleteForm = () => { const navigate = useNavigate() + const { oauth } = useOauth() const { submitCompleteStep } = useUserSignup() const [isAnySubmitting, setIsAnySubmitting] = useState(false) + const is_github = + oauth.session?.user.identities?.find(({ id }) => { + return id === oauth.session?.user.user_metadata.provider_id + })?.provider === 'github' + const onGithubSubmit = async () => { try { setIsAnySubmitting(true) @@ -35,30 +42,38 @@ const CompleteForm = () => { return (
- Github + Almost there
- Do you want to upload your repository from GitHub + {is_github + ? 'Do you want to upload your repository from GitHub' + : 'Almost there'}
-
+
+ {is_github && ( +
+ + {({ isSubmitting }) => ( +
+ +
+ )} +
+
+ )} +
- - {({ isSubmitting }) => ( -
- -
- )} -
-
-
{({ isSubmitting }) => (
@@ -70,7 +85,7 @@ const CompleteForm = () => { disabled={isSubmitting || isAnySubmitting} isLoading={isSubmitting} > - No, thanks + {is_github ? 'No, thanks' : 'Create DAO and complete'}
)} diff --git a/web/src/v6.1.0/pages/Signup/components/OAuthForm.tsx b/web/src/v6.1.0/pages/Signup/components/OAuthForm.tsx index 40dc37a62..d0933c50d 100644 --- a/web/src/v6.1.0/pages/Signup/components/OAuthForm.tsx +++ b/web/src/v6.1.0/pages/Signup/components/OAuthForm.tsx @@ -1,11 +1,14 @@ +import { faGithub, faGoogle } from '@fortawesome/free-brands-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { Provider } from '@supabase/supabase-js' import { Button } from '../../../../components/Form' import { useOauth } from '../../../hooks/oauth.hooks' const OAuthForm = () => { const { oauth, signin } = useOauth() - const onOAuthSigninClick = async () => { - signin('github', { redirectTo: `${document.location.origin}/a/signup` }) + const onOAuthSigninClick = async (provider: Provider) => { + signin(provider, { redirectTo: `${document.location.origin}/a/signup` }) } return ( @@ -19,17 +22,51 @@ const OAuthForm = () => {

Sign in with

-
+
+ + {/* */}
diff --git a/web/src/v6.1.0/pages/Signup/components/UsernameForm.tsx b/web/src/v6.1.0/pages/Signup/components/UsernameForm.tsx index 92027b182..015a55a5e 100644 --- a/web/src/v6.1.0/pages/Signup/components/UsernameForm.tsx +++ b/web/src/v6.1.0/pages/Signup/components/UsernameForm.tsx @@ -1,10 +1,11 @@ import { Field, Form, Formik } from 'formik' -import yup from '../../../yup-extended' -import { FormikInput } from '../../../../components/Formik' +import { useCallback, useEffect, useState } from 'react' import Alert from '../../../../components/Alert' import { Button } from '../../../../components/Form' -import { useUserSignup } from '../../../hooks/user.hooks' +import { FormikInput } from '../../../../components/Formik' import { useOauth } from '../../../hooks/oauth.hooks' +import { useUserSignup } from '../../../hooks/user.hooks' +import yup from '../../../yup-extended' type TFormValues = { email: string @@ -12,8 +13,9 @@ type TFormValues = { } const UsernameForm = () => { - const { oauth } = useOauth() + const { oauth, signout } = useOauth() const { data, submitUsernameStep } = useUserSignup() + const [metadata, setMetadata] = useState() const onFormSubmit = async (values: TFormValues) => { try { @@ -23,11 +25,44 @@ const UsernameForm = () => { } } + const getOAuthMetadata = useCallback(() => { + if (!oauth.session) { + return + } + + const metadata = oauth.session.user.user_metadata + const identity = oauth.session.user.identities?.find(({ id }) => { + return id === metadata.provider_id + }) + setMetadata({ ...metadata, identity }) + }, []) + + useEffect(() => { + getOAuthMetadata() + }, [getOAuthMetadata]) + return (
Welcome to Gosh
Choose a short Nickname and Email
+ + {!!metadata && ( +
+

OAuth session

+
+ {metadata.name}{' '} + + via {metadata.identity.provider} + +
+
+ +
+
+ )}