Skip to content

Commit e985d51

Browse files
authored
fix(auth): refuse account creation from disposable email domains for every provider (#9516)
* fix(auth): refuse account creation from disposable email domains for every provider * fix(auth): keep permanent mail-relay aliases out of the disposable check
1 parent 4a7ba87 commit e985d51

5 files changed

Lines changed: 98807 additions & 1 deletion

File tree

‎apps/sim/app/oauth-error/page.tsx‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type { Metadata } from 'next'
2-
import { SSO_REQUIRED_ERROR_CODE, SSO_REQUIRED_MESSAGE } from '@/lib/auth/constants'
2+
import {
3+
DISPOSABLE_EMAIL_ERROR_CODE,
4+
DISPOSABLE_EMAIL_MESSAGE,
5+
SSO_REQUIRED_ERROR_CODE,
6+
SSO_REQUIRED_MESSAGE,
7+
} from '@/lib/auth/constants'
38
import { DesktopHandoffShell } from '@/app/desktop/components/desktop-handoff-shell'
49

510
export const metadata: Metadata = {
@@ -46,6 +51,12 @@ const FRIENDLY: Record<string, string> = {
4651
* refused. Retrying the same provider can never succeed — name the way in.
4752
*/
4853
[SSO_REQUIRED_ERROR_CODE]: SSO_REQUIRED_MESSAGE,
54+
/**
55+
* Account creation refused for a disposable email domain. Better Auth 1.7 redirects with the
56+
* error's code; 1.6 redirects with its message, spaces joined by underscores.
57+
*/
58+
[DISPOSABLE_EMAIL_ERROR_CODE]: DISPOSABLE_EMAIL_MESSAGE,
59+
[DISPOSABLE_EMAIL_MESSAGE.split(' ').join('_')]: DISPOSABLE_EMAIL_MESSAGE,
4960
/** The provider returned no email claim, so there is nothing to sign in as. */
5061
email_not_found:
5162
'Your identity provider didn’t share an email address with us, so we couldn’t complete sign-in. Please contact your administrator.',

‎apps/sim/lib/auth/auth.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import { stableExternalAccountId } from '@/lib/auth/connectors/account-id'
4545
import { buildConnectorProviders } from '@/lib/auth/connectors/providers'
4646
import {
4747
applyRegistrationGate,
48+
DISPOSABLE_EMAIL_ERROR_CODE,
49+
DISPOSABLE_EMAIL_MESSAGE,
4850
getRequestedSignInProviderId,
4951
isSignInProviderAllowed,
5052
} from '@/lib/auth/constants'
@@ -151,6 +153,7 @@ import {
151153
processCredentialDraft,
152154
refuseConflictingCredentialReconnect,
153155
} from '@/lib/credentials/draft-processor'
156+
import { isDisposableEmail } from '@/lib/messaging/email/disposable'
154157
import { sendEmail } from '@/lib/messaging/email/mailer'
155158
import { getFromEmailAddress, getPersonalEmailFrom } from '@/lib/messaging/email/utils'
156159
import { quickValidateEmail } from '@/lib/messaging/email/validation'
@@ -361,6 +364,15 @@ export const auth = betterAuth({
361364
if (isEmailBlockedByAccessControl(user.email, accessControl)) {
362365
throw new Error('Sign-ups from this email are not allowed.')
363366
}
367+
if (isHosted && (await isDisposableEmail(user.email))) {
368+
logger.warn('Refusing account creation for a disposable email domain', {
369+
domain: user.email.split('@')[1],
370+
})
371+
throw new APIError('FORBIDDEN', {
372+
code: DISPOSABLE_EMAIL_ERROR_CODE,
373+
message: DISPOSABLE_EMAIL_MESSAGE,
374+
})
375+
}
364376
return { data: user }
365377
},
366378
after: async (user, context) => {

‎apps/sim/lib/auth/constants.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,12 @@ export const SSO_REQUIRED_ERROR_CODE = 'SSO_REQUIRED'
105105

106106
export const SSO_REQUIRED_MESSAGE =
107107
'Your organization requires single sign-on. Sign in through your identity provider.'
108+
109+
/**
110+
* How an account creation refused for a disposable email domain identifies itself, so the OAuth
111+
* error page can name the way forward instead of telling the person to try again.
112+
*/
113+
export const DISPOSABLE_EMAIL_ERROR_CODE = 'DISPOSABLE_EMAIL'
114+
115+
export const DISPOSABLE_EMAIL_MESSAGE =
116+
'Sign-ups from temporary email addresses aren’t supported. Use an account with a permanent email address.'

0 commit comments

Comments
 (0)