Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/common/src/api/tan-query/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export const QUERY_KEYS = {
sales: 'sales',
salesCount: 'salesCount',
mutualFollowers: 'mutualFollowers',
emailInUse: 'emailInUse',
handleInUse: 'handleInUse',
handleReservedStatus: 'handleReservedStatus',
search: 'search',
Expand Down
42 changes: 0 additions & 42 deletions packages/common/src/api/tan-query/users/useEmailInUse.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { useCallback, useEffect, useMemo } from 'react'

import { USDC, UsdcWei } from '@audius/fixed-decimal'
import { useQueryClient } from '@tanstack/react-query'
import { useDispatch, useSelector } from 'react-redux'
import { z } from 'zod'

import { useCurrentAccount, useCurrentAccountUser, useUSDCBalance } from '~/api'
import { useQueryContext } from '~/api/tan-query/utils/QueryContext'
import { UserCollectionMetadata } from '~/models'
import { PurchaseMethod, PurchaseVendor } from '~/models/PurchaseContent'
import { UserTrackMetadata } from '~/models/Track'
Expand Down Expand Up @@ -53,9 +51,6 @@ export const usePurchaseContentFormConfiguration = ({
presetValues: PayExtraAmountPresetValues
purchaseVendor?: PurchaseVendor
}) => {
const queryClient = useQueryClient()
const queryContext = useQueryContext()

const dispatch = useDispatch()
const isAlbum = isContentCollection(metadata)
const isTrack = isContentTrack(metadata)
Expand Down Expand Up @@ -99,14 +94,8 @@ export const usePurchaseContentFormConfiguration = ({
: undefined

const validationSchema = useMemo(
() =>
createPurchaseContentSchema(
queryContext,
queryClient,
page,
guestEmail ?? undefined
),
[queryContext, queryClient, guestEmail, page]
() => createPurchaseContentSchema(page),
[page]
)
type PurchaseContentValues = z.input<typeof validationSchema>

Expand Down
53 changes: 2 additions & 51 deletions packages/common/src/hooks/purchaseContent/validation.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { QueryClient } from '@tanstack/react-query'
import { z } from 'zod'

import { QUERY_KEYS } from '~/api'
import { fetchEmailInUse } from '~/api/tan-query/users/useEmailInUse'
import { QueryContextType } from '~/api/tan-query/utils/QueryContext'
import { PurchaseMethod, PurchaseVendor } from '~/models/PurchaseContent'
import { PurchaseContentPage } from '~/store'

Expand All @@ -21,20 +17,10 @@ import {
import { PayExtraPreset } from './types'

export const messages = {
amountInvalid: 'Please specify an amount between $1 and $100',
emailRequired: 'Please enter an email.',
invalidEmail: 'Please enter a valid email.',
emailInUse: 'Email already taken.',
somethingWentWrong: 'Something went wrong. Try again later.',
guestAccountExists: 'Guest account exists.'
amountInvalid: 'Please specify an amount between $1 and $100'
}

export const createPurchaseContentSchema = (
queryContext: QueryContextType,
queryClient: QueryClient,
page: PurchaseContentPage,
emailFromLocalStorage?: string
) => {
export const createPurchaseContentSchema = (page: PurchaseContentPage) => {
return z
.object({
[CUSTOM_AMOUNT]: z
Expand Down Expand Up @@ -77,39 +63,4 @@ export const createPurchaseContentSchema = (
path: [GUEST_EMAIL] // Specify the path to the error
}
)
.superRefine(async ({ guestEmail }, ctx) => {
if (
page !== PurchaseContentPage.GUEST_CHECKOUT ||
!guestEmail ||
guestEmail === emailFromLocalStorage
) {
// only validate email if on guest checkout page and email is different
return
}

const { exists: isEmailInUse, isGuest } = await queryClient.fetchQuery({
queryKey: [QUERY_KEYS.emailInUse, guestEmail],
queryFn: async () => await fetchEmailInUse(guestEmail, queryContext)
})

if (isEmailInUse === undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: messages.somethingWentWrong,
path: [GUEST_EMAIL]
})
} else if (isGuest) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: messages.guestAccountExists,
path: [GUEST_EMAIL]
})
} else if (isEmailInUse) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: messages.emailInUse,
path: [GUEST_EMAIL]
})
}
})
}
7 changes: 1 addition & 6 deletions packages/common/src/hooks/useChangeEmailFormConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState, useCallback, useMemo } from 'react'

import { useQueryClient } from '@tanstack/react-query'
import { FormikHelpers } from 'formik'
import { z } from 'zod'
import { toFormikValidationSchema } from 'zod-formik-adapter'
Expand Down Expand Up @@ -55,7 +54,6 @@ export const useChangeEmailFormConfiguration = (onComplete: () => void) => {
const [page, setPage] = useState(ChangeEmailPage.ConfirmPassword)
const queryContext = useQueryContext()
const { authService } = queryContext
const queryClient = useQueryClient()

// Move schema initializations inside the hook to prevent initialization timing issues
const confirmPasswordFormikSchema = toFormikValidationSchema(
Expand All @@ -67,10 +65,7 @@ export const useChangeEmailFormConfiguration = (onComplete: () => void) => {
)
const verifyEmailFormikSchema = toFormikValidationSchema(confirmEmailSchema)

const EmailSchema = useMemo(
() => toFormikValidationSchema(emailSchema(queryContext, queryClient)),
[queryContext, queryClient]
)
const EmailSchema = useMemo(() => toFormikValidationSchema(emailSchema()), [])

const validationSchema =
page === ChangeEmailPage.ConfirmPassword
Expand Down
38 changes: 2 additions & 36 deletions packages/common/src/schemas/sign-on/emailSchema.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,15 @@
import { QueryClient } from '@tanstack/react-query'
import { z } from 'zod'

import { QUERY_KEYS, QueryContextType } from '~/api'
import { fetchEmailInUse } from '~/api/tan-query/users/useEmailInUse'
import { EMAIL_REGEX } from '~/utils/email'

export const emailSchemaMessages = {
emailRequired: 'Please enter an email.',
invalidEmail: 'Please enter a valid email.',
emailInUse: 'Email already taken.',
somethingWentWrong: 'Something went wrong. Try again later.',
guestAccountExists: 'Guest account exists.'
invalidEmail: 'Please enter a valid email.'
}

export const emailSchema = (
queryContext: QueryContextType,
queryClient: QueryClient
) =>
export const emailSchema = () =>
z.object({
email: z
.string({ required_error: emailSchemaMessages.emailRequired })
.regex(EMAIL_REGEX, { message: emailSchemaMessages.invalidEmail })
.superRefine(async (email, ctx) => {
const { exists: isEmailInUse, isGuest } = await queryClient.fetchQuery({
queryKey: [QUERY_KEYS.emailInUse, email],
queryFn: async () => await fetchEmailInUse(email, queryContext)
})
if (isEmailInUse === undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: emailSchemaMessages.somethingWentWrong
})
} else if (isGuest) {
// complete guest accounts only
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: emailSchemaMessages.guestAccountExists
})
return true
} else if (isEmailInUse) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: emailSchemaMessages.emailInUse
})
}
return z.NEVER // The return value is not used, but we need to return something to satisfy the typing
})
})
33 changes: 4 additions & 29 deletions packages/common/src/schemas/sign-on/signInSchema.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,17 @@
import { QueryClient } from '@tanstack/react-query'
import { z } from 'zod'

import { QUERY_KEYS } from '~/api'
import { fetchEmailInUse } from '~/api/tan-query/users/useEmailInUse'
import { QueryContextType } from '~/api/tan-query/utils'

export const messages = {
emailRequired: 'Please enter an email.',
email: 'Please enter a valid email.',
passwordRequired: 'Please enter a password.',
invalidCredentials: 'Invalid credentials.',
guestAccountExists: 'Guest account exists.'
invalidCredentials: 'Invalid credentials.'
}

export const signInSchema = (
queryContext: QueryContextType,
queryClient: QueryClient
) =>
export const signInSchema = () =>
z.object({
email: z
.string({
required_error: messages.emailRequired
})
.email(messages.email)
.superRefine(async (email, ctx) => {
const { isGuest } = await queryClient.fetchQuery({
queryKey: [QUERY_KEYS.emailInUse, email],
queryFn: async () => await fetchEmailInUse(email, queryContext)
})
if (isGuest) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: messages.guestAccountExists
})
return true
}
return z.NEVER // The return value is not used, but we need to return something to satisfy the typing
}),
.string({ required_error: messages.emailRequired })
.email(messages.email),
password: z.string({
required_error: messages.passwordRequired
})
Expand Down
13 changes: 0 additions & 13 deletions packages/common/src/services/auth/identity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,6 @@ export class IdentityService {
})
}

/**
* Check if an email address has been previously registered.
*/
async checkIfEmailRegistered(email: string) {
return await this._makeRequest<{ exists: boolean; isGuest: boolean }>({
url: '/users/check',
method: 'get',
params: {
email
}
})
}

/**
* Get the user's email used for notifications and display.
*/
Expand Down
27 changes: 0 additions & 27 deletions packages/identity-service/src/routes/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,33 +123,6 @@ module.exports = function (app) {
})
)

/**
* Check if a email address is taken. email is passed in via query param
*/
app.get(
'/users/check',
handleResponse(async (req, res, next) => {
let email = req.query.email
if (email) {
email = email.toLowerCase()
const existingUser = await models.User.findOne({
where: {
email
}
})
if (existingUser) {
return successResponse({
exists: true,
isGuest: existingUser.isGuest
})
} else {
return successResponse({ exists: false })
}
} else
return errorResponseBadRequest('Please pass in a valid email address')
})
)

/**
* Update User Timezone / IP
*/
Expand Down
4 changes: 4 additions & 0 deletions packages/identity-service/test/expressAppTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ describe('test /health_check and /balance_check', function () {
await request(app).post('/wormhole_relay').send({}).expect(404)
await request(app).get('/sol_balance_check').expect(404)
})

it('does not expose email registration checks', async function () {
await request(app).get('/users/check?email=test@example.com').expect(404)
})
})
9 changes: 0 additions & 9 deletions packages/libs/src/api/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export class Account extends Base {
this.confirmCredentials = this.confirmCredentials.bind(this)
this.changeCredentials = this.changeCredentials.bind(this)
this.resetPassword = this.resetPassword.bind(this)
this.checkIfEmailRegistered = this.checkIfEmailRegistered.bind(this)
this.associateTwitterUser = this.associateTwitterUser.bind(this)
this.associateInstagramUser = this.associateInstagramUser.bind(this)
this.associateTikTokUser = this.associateTikTokUser.bind(this)
Expand Down Expand Up @@ -281,14 +280,6 @@ export class Account extends Base {
return await this.hedgehog.confirmCredentials(args)
}

/**
* Check if an email address has been previously registered.
*/
async checkIfEmailRegistered(email: string) {
this.REQUIRES(Services.IDENTITY_SERVICE)
return await this.identityService.checkIfEmailRegistered(email)
}

/**
* Associates a user with a twitter uuid.
* @param uuid from the Twitter API
Expand Down
13 changes: 0 additions & 13 deletions packages/libs/src/services/identity/IdentityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,6 @@ export class IdentityService {
})
}

/**
* Check if an email address has been previously registered.
*/
async checkIfEmailRegistered(email: string) {
return await this._makeRequest<{ exists: boolean }>({
url: '/users/check',
method: 'get',
params: {
email
}
})
}

/**
* Check if the lookupKey exists.
* WARNING: might not be the auth credentials for the current user!
Expand Down
Loading
Loading