Skip to content

Instantly share code, notes, and snippets.

@bodokaiser
Last active August 10, 2023 01:00
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save bodokaiser/a6377f5cecf6344cd131dce97694a2ad to your computer and use it in GitHub Desktop.
Save bodokaiser/a6377f5cecf6344cd131dce97694a2ad to your computer and use it in GitHub Desktop.
React Hook integration for AWS Amplify Auth
import React from "react"
import { CognitoUser } from "@aws-amplify/auth"
import { useAuth } from "./hooks"
import { SignInInput } from "./types"
interface AuthState {
user: CognitoUser | null
signIn(input : SignInInput): Promise<void>
signOut(): Promise<void>
deleteUser(): Promise<void>
}
export const AuthContext = React.createContext<AuthState>({
user: null,
signIn: async (input) => {},
signOut: async () => {},
deleteUser: async () => {},
})
interface AuthProps {
children: React.ReactNode
}
export const AuthProvider = ({ children } : AuthProps) => {
const auth = useAuth()
return (
<AuthContext.Provider value={auth}>
{children}
</AuthContext.Provider>
)
}
import React from "react"
import Auth, { CognitoUser } from "@aws-amplify/auth"
import {
SignInInput,
SignUpInput,
ConfirmSignUpInput,
ResendSignUpInput,
ForgotPasswordInput,
ResetPasswordInput,
} from "./types"
import { AuthContext } from "./context"
export function useAuth() {
const [user, setUser] = React.useState<CognitoUser | null>(null)
React.useEffect(() => {
let active = true
const check = async () => {
try {
const user = await Auth.currentAuthenticatedUser()
if (active) setUser(user)
} catch (error) {
if (active) setUser(null)
}
}
check()
return () => { active = false }
}, [setUser])
const signIn = React.useCallback(async ({ email, password } : SignInInput) => {
setUser(await Auth.signIn(email, password))
}, [setUser])
const signOut = React.useCallback(async () => {
await Auth.signOut()
setUser(null)
}, [setUser])
const deleteUser = React.useCallback(async () => {
user?.deleteUser((error?: Error) => {
if (error) throw error
setUser(null)
})
}, [user, setUser])
return { user, signIn, signOut, deleteUser }
}
export function useUser() {
const { user } = React.useContext(AuthContext)
if (!user) return null
// See https://github.com/aws-amplify/amplify-js/issues/4927
// @ts-ignore
return user.attributes
}
export function useSignIn() {
return React.useContext(AuthContext).signIn
}
export function useSignOut() {
return React.useContext(AuthContext).signOut
}
export function useSignUp() {
return async function signUp({ name, email, password } : SignUpInput) {
await Auth.signUp({ username: email, password, attributes: { name, email }, })
}
}
export function useConfirmSignUp() {
return async function confirmSignUp({ email, code } : ConfirmSignUpInput) {
await Auth.confirmSignUp(email, code)
}
}
export function useResendSignUp() {
return async function resendSignUp({ email } : ResendSignUpInput) {
await Auth.resendSignUp(email)
}
}
export function useForgotPassword() {
return async function forgotPassword({ email } : ForgotPasswordInput) {
await Auth.forgotPassword(email)
}
}
export function useResetPassword() {
return async function resetPassword({ email, code, password } : ResetPasswordInput) {
await Auth.forgotPasswordSubmit(email, code, password)
}
}
export function useDeleteUser() {
return React.useContext(AuthContext).deleteUser
}
@richardruiter
Copy link

You didn't add the types :-)

@olup
Copy link

olup commented Jan 20, 2021

export type SignInInput = {
  email: string;
  password: string;
};
export type SignUpInput = {
  name: string;
  email: string;
  password: string;
};
export type ConfirmSignUpInput = {
  email: string;
  code: string;
};
export type ResendSignUpInput = {
  email: string;
};
export type ForgotPasswordInput = {
  email: string;
};
export type ResetPasswordInput = {
  email: string;
  code: string;
  password: string;
};

@munibrahman
Copy link

Shouldn't context.ts be of file type .tsx?

@bodokaiser
Copy link
Author

Shouldn't context.ts be of file type .tsx?

yes

@csmcallister
Copy link

I suggest replacing import { CognitoUser } from "@aws-amplify/auth" with import { CognitoUserInterface } from '@aws-amplify/ui-components'; since the congito user attribute types don't exist on the former.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment