Skip to content
Merged
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
13 changes: 12 additions & 1 deletion apps/sim/app/oauth-error/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type { Metadata } from 'next'
import { SSO_REQUIRED_ERROR_CODE, SSO_REQUIRED_MESSAGE } from '@/lib/auth/constants'
import {
DISPOSABLE_EMAIL_ERROR_CODE,
DISPOSABLE_EMAIL_MESSAGE,
SSO_REQUIRED_ERROR_CODE,
SSO_REQUIRED_MESSAGE,
} from '@/lib/auth/constants'
import { DesktopHandoffShell } from '@/app/desktop/components/desktop-handoff-shell'

export const metadata: Metadata = {
Expand Down Expand Up @@ -46,6 +51,12 @@ const FRIENDLY: Record<string, string> = {
* refused. Retrying the same provider can never succeed — name the way in.
*/
[SSO_REQUIRED_ERROR_CODE]: SSO_REQUIRED_MESSAGE,
/**
* Account creation refused for a disposable email domain. Better Auth 1.7 redirects with the
* error's code; 1.6 redirects with its message, spaces joined by underscores.
*/
[DISPOSABLE_EMAIL_ERROR_CODE]: DISPOSABLE_EMAIL_MESSAGE,
[DISPOSABLE_EMAIL_MESSAGE.split(' ').join('_')]: DISPOSABLE_EMAIL_MESSAGE,
/** The provider returned no email claim, so there is nothing to sign in as. */
email_not_found:
'Your identity provider didn’t share an email address with us, so we couldn’t complete sign-in. Please contact your administrator.',
Expand Down
12 changes: 12 additions & 0 deletions apps/sim/lib/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import { stableExternalAccountId } from '@/lib/auth/connectors/account-id'
import { buildConnectorProviders } from '@/lib/auth/connectors/providers'
import {
applyRegistrationGate,
DISPOSABLE_EMAIL_ERROR_CODE,
DISPOSABLE_EMAIL_MESSAGE,
getRequestedSignInProviderId,
isSignInProviderAllowed,
} from '@/lib/auth/constants'
Expand Down Expand Up @@ -151,6 +153,7 @@ import {
processCredentialDraft,
refuseConflictingCredentialReconnect,
} from '@/lib/credentials/draft-processor'
import { isDisposableEmail } from '@/lib/messaging/email/disposable'
import { sendEmail } from '@/lib/messaging/email/mailer'
import { getFromEmailAddress, getPersonalEmailFrom } from '@/lib/messaging/email/utils'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
Expand Down Expand Up @@ -361,6 +364,15 @@ export const auth = betterAuth({
if (isEmailBlockedByAccessControl(user.email, accessControl)) {
throw new Error('Sign-ups from this email are not allowed.')
}
if (isHosted && (await isDisposableEmail(user.email))) {
logger.warn('Refusing account creation for a disposable email domain', {
domain: user.email.split('@')[1],
})
throw new APIError('FORBIDDEN', {
code: DISPOSABLE_EMAIL_ERROR_CODE,
message: DISPOSABLE_EMAIL_MESSAGE,
})
}
return { data: user }
},
after: async (user, context) => {
Expand Down
9 changes: 9 additions & 0 deletions apps/sim/lib/auth/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,12 @@ export const SSO_REQUIRED_ERROR_CODE = 'SSO_REQUIRED'

export const SSO_REQUIRED_MESSAGE =
'Your organization requires single sign-on. Sign in through your identity provider.'

/**
* How an account creation refused for a disposable email domain identifies itself, so the OAuth
* error page can name the way forward instead of telling the person to try again.
*/
export const DISPOSABLE_EMAIL_ERROR_CODE = 'DISPOSABLE_EMAIL'

export const DISPOSABLE_EMAIL_MESSAGE =
'Sign-ups from temporary email addresses aren’t supported. Use an account with a permanent email address.'
Loading
Loading