@@ -30,6 +30,7 @@ import {
3030 renderPasswordResetEmail ,
3131 renderWelcomeEmail ,
3232} from '@/components/emails'
33+ import { getAccessControlConfig } from '@/lib/auth/access-control'
3334import { sendPlanWelcomeEmail } from '@/lib/billing'
3435import { authorizeSubscriptionReference } from '@/lib/billing/authorization'
3536import {
@@ -137,16 +138,6 @@ function getMicrosoftUserInfoFromIdToken(tokens: { accessToken?: string }, provi
137138 }
138139}
139140
140- const blockedSignupDomains = env . BLOCKED_SIGNUP_DOMAINS
141- ? Array . from (
142- new Set (
143- env . BLOCKED_SIGNUP_DOMAINS . split ( ',' )
144- . map ( ( d ) => d . trim ( ) . toLowerCase ( ) )
145- . filter ( Boolean )
146- )
147- )
148- : null
149-
150141export function isEmailInDenylist (
151142 email : string | undefined | null ,
152143 denylist : readonly string [ ] | null
@@ -157,10 +148,6 @@ export function isEmailInDenylist(
157148 return denylist . some ( ( entry ) => domain === entry || domain . endsWith ( `.${ entry } ` ) )
158149}
159150
160- function isSignupEmailBlocked ( email : string | undefined | null ) : boolean {
161- return isEmailInDenylist ( email , blockedSignupDomains )
162- }
163-
164151const additionalTrustedOrigins = parseOriginList ( env . TRUSTED_ORIGINS , ( value ) =>
165152 logger . warn ( 'Ignoring invalid entry in TRUSTED_ORIGINS' , { value } )
166153)
@@ -246,7 +233,12 @@ export const auth = betterAuth({
246233 user : {
247234 create : {
248235 before : async ( user ) => {
249- if ( isSignupEmailBlocked ( user . email ) ) {
236+ const accessControl = await getAccessControlConfig ( )
237+ const email = user . email ?. toLowerCase ( )
238+ if ( email && accessControl . bannedEmails . includes ( email ) ) {
239+ throw new Error ( 'Sign-ups from this email domain are not allowed.' )
240+ }
241+ if ( isEmailInDenylist ( user . email , accessControl . blockedSignupDomains ) ) {
250242 throw new Error ( 'Sign-ups from this email domain are not allowed.' )
251243 }
252244 return { data : user }
@@ -813,51 +805,55 @@ export const auth = betterAuth({
813805 } )
814806 }
815807
816- if (
817- ( ctx . path . startsWith ( '/sign-in' ) || ctx . path . startsWith ( '/sign-up' ) ) &&
818- ( env . ALLOWED_LOGIN_EMAILS || env . ALLOWED_LOGIN_DOMAINS )
819- ) {
820- const requestEmail = ctx . body ?. email ?. toLowerCase ( )
821-
822- if ( requestEmail ) {
823- let isAllowed = false
808+ const isSignIn = ctx . path . startsWith ( '/sign-in' )
809+ const isSignUp = ctx . path . startsWith ( '/sign-up' )
824810
825- if ( env . ALLOWED_LOGIN_EMAILS ) {
826- const allowedEmails = env . ALLOWED_LOGIN_EMAILS . split ( ',' ) . map ( ( email ) =>
827- email . trim ( ) . toLowerCase ( )
828- )
829- isAllowed = allowedEmails . includes ( requestEmail )
830- }
811+ if ( isSignIn || isSignUp ) {
812+ const accessControl = await getAccessControlConfig ( )
813+ const requestEmail = ctx . body ?. email ?. toLowerCase ( )
831814
832- if ( ! isAllowed && env . ALLOWED_LOGIN_DOMAINS ) {
833- const allowedDomains = env . ALLOWED_LOGIN_DOMAINS . split ( ',' ) . map ( ( domain ) =>
834- domain . trim ( ) . toLowerCase ( )
835- )
836- const emailDomain = requestEmail . split ( '@' ) [ 1 ]
837- isAllowed = emailDomain && allowedDomains . includes ( emailDomain )
838- }
815+ if ( requestEmail && accessControl . bannedEmails . includes ( requestEmail ) ) {
816+ throw new APIError ( 'FORBIDDEN' , {
817+ message : 'Access restricted. Please contact your administrator.' ,
818+ } )
819+ }
839820
821+ const hasAllowlist =
822+ accessControl . allowedLoginEmails . length > 0 ||
823+ accessControl . allowedLoginDomains . length > 0
824+ if ( hasAllowlist && requestEmail ) {
825+ const emailDomain = requestEmail . split ( '@' ) [ 1 ]
826+ const isAllowed =
827+ accessControl . allowedLoginEmails . includes ( requestEmail ) ||
828+ ( ! ! emailDomain && accessControl . allowedLoginDomains . includes ( emailDomain ) )
840829 if ( ! isAllowed ) {
841830 throw new APIError ( 'FORBIDDEN' , {
842831 message : 'Access restricted. Please contact your administrator.' ,
843832 } )
844833 }
845834 }
846- }
847-
848- if ( ctx . path . startsWith ( '/sign-up' ) && isSignupEmailBlocked ( ctx . body ?. email ) ) {
849- throw new APIError ( 'FORBIDDEN' , {
850- message : 'Sign-ups from this email domain are not allowed.' ,
851- } )
852- }
853835
854- if ( isSignupMxValidationEnabled && ctx . path . startsWith ( '/sign-up/email' ) && ctx . body ?. email ) {
855- const mxCheck = await validateSignupEmailMx ( ctx . body . email )
856- if ( ! mxCheck . allowed ) {
836+ if ( isSignUp && isEmailInDenylist ( ctx . body ?. email , accessControl . blockedSignupDomains ) ) {
857837 throw new APIError ( 'FORBIDDEN' , {
858838 message : 'Sign-ups from this email domain are not allowed.' ,
859839 } )
860840 }
841+
842+ if (
843+ isSignupMxValidationEnabled &&
844+ ctx . path . startsWith ( '/sign-up/email' ) &&
845+ ctx . body ?. email
846+ ) {
847+ const mxCheck = await validateSignupEmailMx (
848+ ctx . body . email ,
849+ accessControl . blockedEmailMxHosts
850+ )
851+ if ( ! mxCheck . allowed ) {
852+ throw new APIError ( 'FORBIDDEN' , {
853+ message : 'Sign-ups from this email domain are not allowed.' ,
854+ } )
855+ }
856+ }
861857 }
862858
863859 if ( ctx . path === '/sign-up/email' && ctx . body ?. email ) {
0 commit comments