feat: Add GitHub OAuth (#1050)

* Initial oauth

* Add Github authentication

* Add AuthMethods endpoint

* Add frontend

* Rename basic authentication to password

* Add flags for configuring GitHub auth

* Remove name from API keys

* Fix authmethods in test

* Add stories and display auth methods error
This commit is contained in:
Kyle Carberry
2022-04-23 22:58:57 +00:00
committed by GitHub
parent 3976994781
commit 7496c3da81
41 changed files with 1251 additions and 422 deletions
@@ -24,7 +24,26 @@ SignedOut.args = {
}
export const Loading = Template.bind({})
Loading.args = { ...SignedOut.args, isLoading: true }
Loading.args = {
...SignedOut.args,
isLoading: true,
authMethods: {
github: true,
password: true,
},
}
export const WithError = Template.bind({})
WithError.args = { ...SignedOut.args, authErrorMessage: "Email or password was invalid" }
export const WithLoginError = Template.bind({})
WithLoginError.args = { ...SignedOut.args, authErrorMessage: "Email or password was invalid" }
export const WithAuthMethodsError = Template.bind({})
WithAuthMethodsError.args = { ...SignedOut.args, methodsErrorMessage: "Failed to fetch auth methods" }
export const WithGithub = Template.bind({})
WithGithub.args = {
...SignedOut.args,
authMethods: {
password: true,
github: true,
},
}
+27 -3
View File
@@ -1,9 +1,12 @@
import Button from "@material-ui/core/Button"
import FormHelperText from "@material-ui/core/FormHelperText"
import Link from "@material-ui/core/Link"
import { makeStyles } from "@material-ui/core/styles"
import TextField from "@material-ui/core/TextField"
import { FormikContextType, useFormik } from "formik"
import React from "react"
import * as Yup from "yup"
import { AuthMethods } from "../../api/typesGenerated"
import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils"
import { Welcome } from "../Welcome/Welcome"
import { LoadingButton } from "./../LoadingButton/LoadingButton"
@@ -24,7 +27,9 @@ export const Language = {
emailInvalid: "Please enter a valid email address.",
emailRequired: "Please enter an email address.",
authErrorMessage: "Incorrect email or password.",
signIn: "Sign In",
methodsErrorMessage: "Unable to fetch auth methods.",
passwordSignIn: "Sign In",
githubSignIn: "GitHub",
}
const validationSchema = Yup.object({
@@ -49,10 +54,18 @@ const useStyles = makeStyles((theme) => ({
export interface SignInFormProps {
isLoading: boolean
authErrorMessage?: string
methodsErrorMessage?: string
authMethods?: AuthMethods
onSubmit: ({ email, password }: { email: string; password: string }) => Promise<void>
}
export const SignInForm: React.FC<SignInFormProps> = ({ isLoading, authErrorMessage, onSubmit }) => {
export const SignInForm: React.FC<SignInFormProps> = ({
authMethods,
isLoading,
authErrorMessage,
methodsErrorMessage,
onSubmit,
}) => {
const styles = useStyles()
const form: FormikContextType<BuiltInAuthFormValues> = useFormik<BuiltInAuthFormValues>({
@@ -76,6 +89,7 @@ export const SignInForm: React.FC<SignInFormProps> = ({ isLoading, authErrorMess
className={styles.loginTextField}
fullWidth
label={Language.emailLabel}
type="email"
variant="outlined"
/>
<TextField
@@ -89,12 +103,22 @@ export const SignInForm: React.FC<SignInFormProps> = ({ isLoading, authErrorMess
variant="outlined"
/>
{authErrorMessage && <FormHelperText error>{Language.authErrorMessage}</FormHelperText>}
{methodsErrorMessage && <FormHelperText error>{Language.methodsErrorMessage}</FormHelperText>}
<div className={styles.submitBtn}>
<LoadingButton color="primary" loading={isLoading} fullWidth type="submit" variant="contained">
{isLoading ? "" : Language.signIn}
{isLoading ? "" : Language.passwordSignIn}
</LoadingButton>
</div>
</form>
{authMethods?.github && (
<div className={styles.submitBtn}>
<Link href="/api/v2/users/oauth2/github/callback">
<Button color="primary" disabled={isLoading} fullWidth type="submit" variant="contained">
{Language.githubSignIn}
</Button>
</Link>
</div>
)}
</>
)
}