Skip to content

Commit 6e47dd0

Browse files
waleedlatif1claude
andcommitted
fix(landing): align auth modal with login/signup page logic
- Add SSO button when NEXT_PUBLIC_SSO_ENABLED is set - Gate "Continue with email" behind EMAIL_PASSWORD_SIGNUP_ENABLED - Expose registrationDisabled from /api/auth/providers and hide the "Sign up" toggle when registration is disabled - Simplify skip-modal logic: redirect to full page when no social providers or SSO are available (hasModalContent) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f71e2c5 commit 6e47dd0

File tree

2 files changed

+60
-30
lines changed

2 files changed

+60
-30
lines changed

apps/sim/app/(landing)/components/auth-modal/auth-modal.tsx

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useRouter } from 'next/navigation'
88
import { Modal, ModalClose, ModalContent, ModalTitle, ModalTrigger } from '@/components/emcn'
99
import { GithubIcon, GoogleIcon } from '@/components/icons'
1010
import { client } from '@/lib/auth/auth-client'
11+
import { getEnv, isFalsy, isTruthy } from '@/lib/core/config/env'
1112
import { captureClientEvent } from '@/lib/posthog/client'
1213
import type { PostHogEventMap } from '@/lib/posthog/events'
1314
import { getBrandConfig } from '@/ee/whitelabeling'
@@ -25,13 +26,15 @@ interface AuthModalProps {
2526
interface ProviderStatus {
2627
githubAvailable: boolean
2728
googleAvailable: boolean
29+
registrationDisabled: boolean
2830
}
2931

3032
let fetchPromise: Promise<ProviderStatus> | null = null
3133

3234
const FALLBACK_STATUS: ProviderStatus = {
3335
githubAvailable: false,
3436
googleAvailable: false,
37+
registrationDisabled: false,
3538
}
3639

3740
const SOCIAL_BTN =
@@ -44,9 +47,10 @@ function fetchProviderStatus(): Promise<ProviderStatus> {
4447
if (!r.ok) throw new Error(`HTTP ${r.status}`)
4548
return r.json()
4649
})
47-
.then(({ githubAvailable, googleAvailable }: ProviderStatus) => ({
50+
.then(({ githubAvailable, googleAvailable, registrationDisabled }: ProviderStatus) => ({
4851
githubAvailable,
4952
googleAvailable,
53+
registrationDisabled,
5054
}))
5155
.catch(() => {
5256
fetchPromise = null
@@ -68,17 +72,20 @@ export function AuthModal({ children, defaultView = 'login', source }: AuthModal
6872
}, [])
6973

7074
const hasSocial = providerStatus?.githubAvailable || providerStatus?.googleAvailable
75+
const ssoEnabled = isTruthy(getEnv('NEXT_PUBLIC_SSO_ENABLED'))
76+
const emailEnabled = !isFalsy(getEnv('NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED'))
77+
const hasModalContent = hasSocial || ssoEnabled
7178

7279
useEffect(() => {
73-
if (open && providerStatus && !hasSocial) {
80+
if (open && providerStatus && !hasModalContent) {
7481
setOpen(false)
7582
router.push(defaultView === 'login' ? '/login' : '/signup')
7683
}
77-
}, [open, providerStatus, hasSocial, defaultView, router])
84+
}, [open, providerStatus, hasModalContent, defaultView, router])
7885

7986
const handleOpenChange = useCallback(
8087
(nextOpen: boolean) => {
81-
if (nextOpen && providerStatus && !hasSocial) {
88+
if (nextOpen && providerStatus && !hasModalContent) {
8289
router.push(defaultView === 'login' ? '/login' : '/signup')
8390
return
8491
}
@@ -88,7 +95,7 @@ export function AuthModal({ children, defaultView = 'login', source }: AuthModal
8895
captureClientEvent('auth_modal_opened', { view: defaultView, source })
8996
}
9097
},
91-
[defaultView, hasSocial, providerStatus, router, source]
98+
[defaultView, hasModalContent, providerStatus, router, source]
9299
)
93100

94101
const handleSocialLogin = useCallback(async (provider: 'github' | 'google') => {
@@ -102,6 +109,11 @@ export function AuthModal({ children, defaultView = 'login', source }: AuthModal
102109
}
103110
}, [])
104111

112+
const handleSSOLogin = useCallback(() => {
113+
setOpen(false)
114+
router.push('/sso')
115+
}, [router])
116+
105117
const handleEmailContinue = useCallback(() => {
106118
setOpen(false)
107119
router.push(view === 'login' ? '/login' : '/signup')
@@ -176,38 +188,51 @@ export function AuthModal({ children, defaultView = 'login', source }: AuthModal
176188
</span>
177189
</button>
178190
)}
191+
{ssoEnabled && (
192+
<button type='button' onClick={handleSSOLogin} className={SOCIAL_BTN}>
193+
Sign in with SSO
194+
</button>
195+
)}
179196
</div>
180197

181-
<div className='relative my-4'>
182-
<div className='absolute inset-0 flex items-center'>
183-
<div className='w-full border-[var(--landing-bg-elevated)] border-t' />
184-
</div>
185-
<div className='relative flex justify-center text-[13.5px]'>
186-
<span className='bg-[var(--landing-bg)] px-4 text-[var(--landing-text-muted)]'>
187-
Or
188-
</span>
189-
</div>
190-
</div>
198+
{emailEnabled && (
199+
<>
200+
<div className='relative my-4'>
201+
<div className='absolute inset-0 flex items-center'>
202+
<div className='w-full border-[var(--landing-bg-elevated)] border-t' />
203+
</div>
204+
<div className='relative flex justify-center text-[13.5px]'>
205+
<span className='bg-[var(--landing-bg)] px-4 text-[var(--landing-text-muted)]'>
206+
Or
207+
</span>
208+
</div>
209+
</div>
191210

192-
<button
193-
type='button'
194-
onClick={handleEmailContinue}
195-
className='flex h-[32px] w-full items-center justify-center rounded-[5px] border border-[var(--auth-primary-btn-border)] bg-[var(--auth-primary-btn-bg)] text-[13.5px] text-[var(--auth-primary-btn-text)] transition-colors hover:border-[var(--auth-primary-btn-hover-border)] hover:bg-[var(--auth-primary-btn-hover-bg)]'
196-
>
197-
Continue with email
198-
</button>
211+
<button
212+
type='button'
213+
onClick={handleEmailContinue}
214+
className='flex h-[32px] w-full items-center justify-center rounded-[5px] border border-[var(--auth-primary-btn-border)] bg-[var(--auth-primary-btn-bg)] text-[13.5px] text-[var(--auth-primary-btn-text)] transition-colors hover:border-[var(--auth-primary-btn-hover-border)] hover:bg-[var(--auth-primary-btn-hover-bg)]'
215+
>
216+
Continue with email
217+
</button>
218+
</>
219+
)}
199220

200221
<div className='mt-4 text-center text-[13.5px]'>
201222
<span className='text-[var(--landing-text-muted)]'>
202223
{view === 'login' ? "Don't have an account? " : 'Already have an account? '}
203224
</span>
204-
<button
205-
type='button'
206-
onClick={() => setView(view === 'login' ? 'signup' : 'login')}
207-
className='text-[var(--landing-text)] underline-offset-4 transition hover:text-white hover:underline'
208-
>
209-
{view === 'login' ? 'Sign up' : 'Sign in'}
210-
</button>
225+
{view === 'login' && providerStatus.registrationDisabled ? (
226+
<span className='text-[var(--landing-text-muted)]'>Registration is disabled</span>
227+
) : (
228+
<button
229+
type='button'
230+
onClick={() => setView(view === 'login' ? 'signup' : 'login')}
231+
className='text-[var(--landing-text)] underline-offset-4 transition hover:text-white hover:underline'
232+
>
233+
{view === 'login' ? 'Sign up' : 'Sign in'}
234+
</button>
235+
)}
211236
</div>
212237
</>
213238
)}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { NextResponse } from 'next/server'
2+
import { isRegistrationDisabled } from '@/lib/core/config/feature-flags'
23
import { getOAuthProviderStatus } from '@/app/(auth)/components/oauth-provider-checker'
34

45
export const dynamic = 'force-dynamic'
56

67
export async function GET() {
78
const { githubAvailable, googleAvailable } = await getOAuthProviderStatus()
8-
return NextResponse.json({ githubAvailable, googleAvailable })
9+
return NextResponse.json({
10+
githubAvailable,
11+
googleAvailable,
12+
registrationDisabled: isRegistrationDisabled,
13+
})
914
}

0 commit comments

Comments
 (0)