import axios from 'axios'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
} from 'aws-amplify/auth'
import { useRouter } from 'next/router'
import { notification } from 'antd'
getMe: () => axios.get('/me'),
updateMe: ({ data }) => axios.put('/me', { me: data }),
export function useCurrentUserQuery({ redirectOnNotAuth = true } = {}) {
const router = useRouter()
const currentUserQuery = useQuery(['currentUser'], async () => {
const currentAuthenticatedUser = await getCurrentUser()
return currentAuthenticatedUser
export function useSignInWithGoogleMutation() {
const signInWithGoogleMutation = useMutation(() => {
signInWithRedirect({ provider: 'Google' })
return new Promise(() => null)
onError: (err: Error) => {
message: 'Sign in with Google failed',
description: err.message,
return signInWithGoogleMutation
export function useSignInWithSsoMutation() {
const signInWithSsoMutation = useMutation(() => {
custom: process.env.NEXT_PUBLIC_GoogleSamlIdpName!,
return new Promise(() => null)
onError: (err: Error) => {
message: 'Sign in with SSO failed',
description: err.message,
return signInWithSsoMutation
export function useSignInMutation() {
const currentUserQuery = useCurrentUserQuery({ redirectOnNotAuth: false })
const signInMutation = useMutation(async ({ email, password }: any) => {
await signIn({ username: email, password })
await currentUserQuery.refetch()
onError: (err: Error) => {
description: err.message,
export function useSignUpMutation() {
const signInMutation = useSignInMutation()
const router = useRouter()
const signUpMutation = useMutation(async ({ name, password, email }: any) => {
userAttributes: { email, name },
if (process.env.NEXT_PUBLIC_AUTO_VERIFY_USERS) {
await signInMutation.mutateAsync({ email, password })
router.push(`/verify?email=${encodeURIComponent(email)}`)
onError: async (err: Error) => notification.error({
description: err.message,
export function useSignOutMutation({ includeEmailQueryStringParam = false } = {}) {
const queryClient = useQueryClient()
const currentUserQuery = useCurrentUserQuery({ redirectOnNotAuth: false })
const signOutMutation = useMutation(async () => {
await signOut({ global: true })
message: 'Error trying to logout',
description: error.message,
queryClient.cancelQueries()
queryClient.invalidateQueries()
queryClient.removeQueries()
window.localStorage.clear()
const signInRoute = includeEmailQueryStringParam ? `/?${currentUserQuery.data?.username}` : '/'
global.window.location.href = signInRoute
export function useMeQuery({ isAuthenticated = true } = {}) {
const meQuery = useQuery(['me'], async () => {
const apiResponse = await api.getMe()
}, { retry: false, enabled: isAuthenticated })
export function useUpdateMeMutation() {
const queryClient = useQueryClient()
const updateMeMutation = useMutation<any, any, any>(async ({ userId, data }) => {
const response = await api.updateMe({ data })
queryClient.invalidateQueries(['me']),
message: 'Update failed',
description: error?.response?.data?.message || error?.message || 'Unknown error',
export function useForgotPasswordMutation() {
const router = useRouter()
const forgotPasswordMutation = useMutation(
async ({ email }: { email: string }) => {
await resetPassword({ username: email })
message: 'Password reset link sent',
description: 'Instructions have been sent to your email.',
await router.push(`/reset-password?email=${email}`)
onError: async (err: Error) => {
message: 'Forgot password failed',
description: err.message,
return forgotPasswordMutation
export function useResetPasswordMutation() {
const signInMutation = useSignInMutation()
const router = useRouter()
const resetPasswordMutation = useMutation(async ({ email, code, password }: { email: string, code: string, password: string }) => {
await confirmResetPassword({
confirmationCode: code.trim(),
newPassword: password.trim(),
await signInMutation.mutateAsync({ email, password })
onError: async (err: Error) => notification.error({
message: 'Error resetting password',
description: err.message,
return resetPasswordMutation
export function useVerifyAccountMutation() {
const router = useRouter()
const verifyAccountMutation = useMutation(async ({ email, code }: { email: string, code: string }) => {
confirmationCode: code.trim(),
message: 'Account confirmed! π',
description: 'You may now sign in.',
router.push(`/?email=${encodeURIComponent(email)}`)
onError: async (err: Error) => notification.error({
message: 'Error confirming account',
description: err.message,
return verifyAccountMutation